diff --git a/.babelrc b/.babelrc index 6488b0769..ab3dedbb3 100644 --- a/.babelrc +++ b/.babelrc @@ -1,6 +1,7 @@ { "presets": ["@babel/preset-react", "@babel/preset-env"], "plugins": [ + "@babel/plugin-proposal-optional-chaining", ["transform-imports", { "@nio/ui-kit": { "transform": "@nio/ui-kit/dist/components/${member}", "preventFullImport": true } }] ] } diff --git a/.eslintrc b/.eslintrc index db98d2e42..cdb8323c3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,7 +4,13 @@ "env": { "browser": true }, + "plugins": [ + "react-hooks" + ], "rules": { + "strict": 0, + "react-hooks/rules-of-hooks": "error", + "react-hooks/exhaustive-deps": 0, "camelcase": 0, "array-callback-return": 0, "react/require-extension": 0, @@ -28,6 +34,6 @@ "jsx-a11y/click-events-have-key-events": 0, "jsx-a11y/anchor-is-valid": 0, "no-param-reassign": 0, - "max-lines": ["warn", {"max": 100, "skipComments": false}] + "max-lines": ["warn", {"max": 135, "skipComments": false}] } } diff --git a/.sass-lint.yml b/.sass-lint.yml index 315747d09..71ec2f288 100644 --- a/.sass-lint.yml +++ b/.sass-lint.yml @@ -21,7 +21,7 @@ rules: no-color-hex: 0 no-color-keywords: 1 no-color-literals: 0 - no-combinators: 1 + no-combinators: 0 no-css-comments: 1 no-debug: 1 no-disallowed-properties: 1 diff --git a/README.md b/README.md index 062324235..80146f772 100644 --- a/README.md +++ b/README.md @@ -18,19 +18,17 @@ Follow these steps to create a simple UI to interact with your HarperDB instance 1. In your terminal, clone the UI scaffold, enter the directory, and install dependencies. ``` - git clone https://github.com/harperdb/ui-scaffold.git my-project - cd my-project + git clone https://github.com/harperdb/hdbms.git + cd hdbms npm i -s ``` -1. In the root of the project, rename `config.js.example` to `config.js`, and fill out the details for your HarperDB instance. - 1. Start the project. ``` npm start ``` -1. Visit the project at https://0.0.0.0:3000. +1. Visit the project at http://localhost:3000. - The development web server uses a self-signed certificate, and you may see a warning about the site being insecure. In your local development environment, it is safe to click "Advanced" > "proceed to site anyway." -You’ll see a simple UI with the result of a `describe_all` operation. +1. Log into the mock instances with admin/Abc1234! diff --git a/mock_data/LMS_API.aws_regions.json b/mock_data/LMS_API.aws_regions.json new file mode 100644 index 000000000..0a5e9415c --- /dev/null +++ b/mock_data/LMS_API.aws_regions.json @@ -0,0 +1,81 @@ +{ + "statusCode": 200, + "body": [ + { + "label": "US East (N. Virginia)", + "value": "us-east-1" + }, + { + "label": "US East (Ohio)", + "value": "us-east-2" + }, + { + "label": "US West (N. California)", + "value": "us-west-1" + }, + { + "label": "US West (Oregon)", + "value": "us-west-2" + }, + { + "label": "Asia Pacific (Hong Kong)", + "value": "ap-east-1" + }, + { + "label": "Asia Pacific (Mumbai)", + "value": "ap-south-1" + }, + { + "label": "Asia Pacific (Osaka-Local)", + "value": "ap-northeast-3" + }, + { + "label": "Asia Pacific (Seoul)", + "value": "ap-northeast-2" + }, + { + "label": "Asia Pacific (Singapore)", + "value": "ap-southeast-1" + }, + { + "label": "Asia Pacific (Sydney)", + "value": "ap-southeast-2" + }, + { + "label": "Asia Pacific (Tokyo)", + "value": "ap-northeast-1" + }, + { + "label": "Canada (Central)", + "value": "ca-central-1" + }, + { + "label": "Europe (Frankfurt)", + "value": "eu-central-1" + }, + { + "label": "Europe (Ireland)", + "value": "eu-west-1" + }, + { + "label": "Europe (London)", + "value": "eu-west-2" + }, + { + "label": "Europe (Paris)", + "value": "eu-west-3" + }, + { + "label": "Europe (Stockholm)", + "value": "eu-north-1" + }, + { + "label": "Middle East (Bahrain)", + "value": "me-south-1" + }, + { + "label": "South America (São Paulo)", + "value": "sa-east-1" + } + ] +} diff --git a/mock_data/LMS_API.customer.json b/mock_data/LMS_API.customer.json new file mode 100644 index 000000000..554547e7a --- /dev/null +++ b/mock_data/LMS_API.customer.json @@ -0,0 +1,52 @@ +{ + "statusCode": 200, + "body": { + "id": "customer-guid-1", + "name": "customer name", + "customer_hubspot_id": "guid", + "stripe_customer_object": { + "balance": 0, + "delinquent": true, + "discount": {}, + "id": "string", + "sources": { + "data": [ + + ] + }, + "subscriptions": { + "data": [ + { + "billing_cycle_anchor": 0, + "billing_thresholds": {}, + "cancel_at": 0, + "cancel_at_period_end": true, + "canceled_at": 0, + "created": 0, + "current_period_end": 0, + "current_period_start": 0, + "customer": "string", + "default_payment_method": "string", + "default_source": "string", + "discount": {}, + "ended_at": 0, + "id": "string", + "items": { + "data": [ + {} + ] + }, + "latest_invoice": {}, + "metadata": {}, + "next_pending_invoice_item_invoice": 0, + "plan": "string", + "quantity": 0, + "schedule": {}, + "start_date": 0, + "status": "active" + } + ] + } + } + } +} diff --git a/mock_data/LMS_API.customer_users.json b/mock_data/LMS_API.customer_users.json new file mode 100644 index 000000000..46fab6013 --- /dev/null +++ b/mock_data/LMS_API.customer_users.json @@ -0,0 +1,40 @@ +{ + "statusCode": 200, + "body": [ + { + "user_id": "user-guid-1", + "firstname": "First1", + "lastname": "Last1", + "email": "user1@harperdb.io", + "customer_id": "customer-id-guid" + }, + { + "user_id": "user-guid-2", + "firstname": "First2", + "lastname": "Last2", + "email": "user2@harperdb.io", + "customer_id": "customer-id-guid" + }, + { + "user_id": "user-guid-3", + "firstname": "First3", + "lastname": "Last3", + "email": "user3@harperdb.io", + "customer_id": "customer-id-guid" + }, + { + "user_id": "user-guid-4", + "firstname": "First4", + "lastname": "Last4", + "email": "user4@harperdb.io", + "customer_id": "customer-id-guid" + }, + { + "user_id": "user-guid-5", + "firstname": "First5", + "lastname": "Last5", + "email": "user5@harperdb.io", + "customer_id": "customer-id-guid" + } + ] +} diff --git a/mock_data/LMS_API.instances.json b/mock_data/LMS_API.instances.json index 455d3e3c0..316838a5b 100644 --- a/mock_data/LMS_API.instances.json +++ b/mock_data/LMS_API.instances.json @@ -1,51 +1,157 @@ -[ - { - "id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20de", - "name": "Cluster Demo 1", - "url": "dev.harperdb.io", - "port": 9931, - "is_ssl": false - }, - { - "id": "cee98941-8975-44d6-88e6-9a1a4fa02b25", - "name": "Cluster Demo 2", - "url": "dev.harperdb.io", - "port": 9932, - "is_ssl": false - }, - { - "id": "a32b2464-b5ca-4b9d-a10f-c6da23a7dcbe", - "name": "Cluster Demo 3", - "url": "dev.harperdb.io", - "port": 9933, - "is_ssl": false - }, - { - "id": "7a60b51d-7983-4659-a34b-cfb578a4db54", - "name": "Cluster Demo 4", - "url": "dev.harperdb.io", - "port": 9934, - "is_ssl": false - }, - { - "id": "f0d29404-9fb1-4d66-ab98-41f05e1ac665", - "name": "Cluster Demo 5", - "url": "dev.harperdb.io", - "port": 9935, - "is_ssl": false - }, - { - "id": "ccf2b958-0b0e-4bf6-a81d-6abee1e4eec5", - "name": "Cluster Demo 6", - "url": "dev.harperdb.io", - "port": 9936, - "is_ssl": false - }, - { - "id": "8291c224-6911-4155-b5a9-34559e5a45ff", - "name": "Cluster Demo 7", - "url": "dev.harperdb.io", - "port": 9937, - "is_ssl": false - } -] +{ + "statusCode":200, + "body":[ + { + "id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "instance_name": "3f6c9e35f6a84fb7b09f8b3e7d4e20df", + "host": "localhost", + "port": 9925, + "cluster_port": 12345, + "is_ssl": false, + "is_local": true, + "status": "ready", + "instance_region": null, + "domain_name": null, + "elastic_ip_address": null, + "customer_id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_GoB3yLzygPeGMu", + "stripe_plan_id": "plan_GoB4aP5U6PuR6u", + "stripe_storage_product_id": null, + "stripe_storage_plan_id": null, + "storage_qty_gb": null + }, + { + "id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20de", + "instance_name": "ClusterDemoA1", + "host": "ClusterDemoA1", + "port": 9925, + "cluster_port": 12345, + "is_ssl": false, + "is_local": false, + "status": "ready", + "instance_region": "us-east-1", + "domain_name": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20de.cloud.harperdb.io", + "elastic_ip_address": "172.168.2.12", + "customer_id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "plan_GoB54KxG5JRkwm", + "stripe_storage_product_id": "prod_GoUJnVwOYvTjU9", + "stripe_storage_plan_id": "plan_GoUmLEBX2KIiaF", + "storage_qty_gb": 10 + }, + { + "id": "cee98941-8975-44d6-88e6-9a1a4fa02b25", + "instance_name": "ClusterDemoA2", + "host": "ClusterDemoA2", + "port": 9925, + "cluster_port": 12345, + "is_ssl": false, + "is_local": false, + "status": "ready", + "instance_region": "us-east-1", + "domain_name": "cee98941-8975-44d6-88e6-9a1a4fa02b25.cloud.harperdb.io", + "elastic_ip_address": "172.168.2.12", + "customer_id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "2GB_Beta", + "stripe_storage_product_id": "prod_GoUJnVwOYvTjU9", + "stripe_storage_plan_id": "plan_GoUmLEBX2KIiaF", + "storage_qty_gb": 100 + }, + { + "id": "a32b2464-b5ca-4b9d-a10f-c6da23a7dcbe", + "instance_name": "ClusterDemoA3", + "host": "ClusterDemoA3", + "port": 9925, + "cluster_port": 12345, + "is_ssl": false, + "is_local": false, + "status": "ready", + "instance_region": "us-east-1", + "domain_name": "a32b2464-b5ca-4b9d-a10f-c6da23a7dcbe.cloud.harperdb.io", + "elastic_ip_address": "172.168.2.12", + "customer_id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "4GB_Beta", + "stripe_storage_product_id": "prod_GoUJnVwOYvTjU9", + "stripe_storage_plan_id": "plan_GoUmLEBX2KIiaF", + "storage_qty_gb": 250 + }, + { + "id": "7a60b51d-7983-4659-a34b-cfb578a4db54", + "instance_name": "ClusterDemoA4", + "host": "ClusterDemoA4", + "port": 9925, + "cluster_port": 12345, + "is_ssl": false, + "is_local": false, + "status": "ready", + "instance_region": "us-east-1", + "domain_name": "7a60b51d-7983-4659-a34b-cfb578a4db54.cloud.harperdb.io", + "elastic_ip_address": "172.168.2.12", + "customer_id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "8GB_Beta", + "stripe_storage_product_id": "prod_GoUJnVwOYvTjU9", + "stripe_storage_plan_id": "plan_GoUmLEBX2KIiaF", + "storage_qty_gb": 500 + }, + { + "id": "f0d29404-9fb1-4d66-ab98-41f05e1ac665", + "instance_name": "ClusterDemoA5", + "host": "ClusterDemoA5", + "port": 9925, + "cluster_port": 12345, + "is_ssl": false, + "is_local": false, + "status": "ready", + "instance_region": "us-east-1", + "domain_name": "f0d29404-9fb1-4d66-ab98-41f05e1ac665.cloud.harperdb.io", + "elastic_ip_address": "172.168.2.12", + "customer_id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "4GB_Beta", + "stripe_storage_product_id": "prod_GoUJnVwOYvTjU9", + "stripe_storage_plan_id": "plan_GoUmLEBX2KIiaF", + "storage_qty_gb": 1000 + }, + { + "id": "ccf2b958-0b0e-4bf6-a81d-6abee1e4eec5", + "instance_name": "ClusterDemoA6", + "host": "ClusterDemoA6", + "port": 9925, + "cluster_port": 12345, + "is_ssl": false, + "is_local": false, + "status": "ready", + "instance_region": "us-east-1", + "domain_name": "ccf2b958-0b0e-4bf6-a81d-6abee1e4eec5.cloud.harperdb.io", + "elastic_ip_address": "172.168.2.12", + "customer_id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "2GB_Beta", + "stripe_storage_product_id": "prod_GoUJnVwOYvTjU9", + "stripe_storage_plan_id": "plan_GoUmLEBX2KIiaF", + "storage_qty_gb": 500 + }, + { + "id": "8291c224-6911-4155-b5a9-34559e5a45ff", + "instance_name": "ClusterDemoA7", + "host": "ClusterDemoA7", + "port": 9925, + "cluster_port": 12345, + "is_ssl": false, + "is_local": false, + "status": "ready", + "instance_region": "us-east-1", + "domain_name": "8291c224-6911-4155-b5a9-34559e5a45ff.cloud.harperdb.io", + "elastic_ip_address": "172.168.2.12", + "customer_id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "plan_GoB54KxG5JRkwm", + "stripe_storage_product_id": "prod_GoUJnVwOYvTjU9", + "stripe_storage_plan_id": "plan_GoUmLEBX2KIiaF", + "storage_qty_gb": 250 + } + ] +} diff --git a/mock_data/LMS_API.invoices.json b/mock_data/LMS_API.invoices.json new file mode 100644 index 000000000..6a373620f --- /dev/null +++ b/mock_data/LMS_API.invoices.json @@ -0,0 +1,10085 @@ +{ + "statusCode": 200, + "body": [ + { + "id": "in_1GGqnBDzYFZjJeDRx7SGITwH", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582826941, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_GoTk70y3SRjO2wVgHQhMU55kZf1uKUk", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_GoTk70y3SRjO2wVgHQhMU55kZf1uKUk/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGqnBDzYFZjJeDRJ8paPOcz", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585332241, + "start": 1582826941 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GoTksFs4THRcSh", + "subscription_item": "si_GoTkVNZ9MrHTHv", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGqnBDzYFZjJeDRx7SGITwH/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0080", + "paid": true, + "payment_intent": null, + "period_end": 1582826941, + "period_start": 1582826941, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582826941, + "marked_uncollectible_at": null, + "paid_at": 1582826941, + "voided_at": null + }, + "subscription": "sub_GoTksFs4THRcSh", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582826943 + }, + { + "id": "in_1GGqmXDzYFZjJeDR3oISLJ2d", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582826901, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_GoTkzHcYqWqQHkekJbFLu4j2gaiHeFr", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_GoTkzHcYqWqQHkekJbFLu4j2gaiHeFr/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGqmXDzYFZjJeDRHavUMOQg", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585332201, + "start": 1582826901 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GoTkflQd0tjsLa", + "subscription_item": "si_GoTk80jQCjowZz", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGqmXDzYFZjJeDR3oISLJ2d/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0079", + "paid": true, + "payment_intent": null, + "period_end": 1582826901, + "period_start": 1582826901, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582826901, + "marked_uncollectible_at": null, + "paid_at": 1582826901, + "voided_at": null + }, + "subscription": "sub_GoTkflQd0tjsLa", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582826903 + }, + { + "id": "in_1GGqlaDzYFZjJeDRlJvpANX4", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582826842, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_GoTjrbQxwCdVdDTGrx3s63mB6uw3ru3", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_GoTjrbQxwCdVdDTGrx3s63mB6uw3ru3/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGqlaDzYFZjJeDRvNtovpsd", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585332141, + "start": 1582826841 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GoTjI4THKEGfgp", + "subscription_item": "si_GoTj5A2mt5B1nb", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGqlaDzYFZjJeDRlJvpANX4/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0078", + "paid": true, + "payment_intent": null, + "period_end": 1582826841, + "period_start": 1582826841, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582826842, + "marked_uncollectible_at": null, + "paid_at": 1582826842, + "voided_at": null + }, + "subscription": "sub_GoTjI4THKEGfgp", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582826843 + }, + { + "id": "in_1GGqkMDzYFZjJeDRFTxnrcXK", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582826766, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_GoThtFHfQQmrDUXPrjfTtPGvTrMsRlJ", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_GoThtFHfQQmrDUXPrjfTtPGvTrMsRlJ/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGqkMDzYFZjJeDRhSK8KyQu", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585332066, + "start": 1582826766 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GoThbxMRcr9zhX", + "subscription_item": "si_GoThvYnKN8gEjZ", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGqkMDzYFZjJeDRFTxnrcXK/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0077", + "paid": true, + "payment_intent": null, + "period_end": 1582826766, + "period_start": 1582826766, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582826766, + "marked_uncollectible_at": null, + "paid_at": 1582826767, + "voided_at": null + }, + "subscription": "sub_GoThbxMRcr9zhX", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582826769 + }, + { + "id": "in_1GGUXvDzYFZjJeDR5tTxS57f", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582741427, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_dIHeo1q793bHQmi4T7tVUjlKsu", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_dIHeo1q793bHQmi4T7tVUjlKsu/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGUXvDzYFZjJeDR9NKfd0Rx", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585246726, + "start": 1582741426 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go6lcvvsPhlmwz", + "subscription_item": "si_Go6lsEjhe5MSk1", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGUXvDzYFZjJeDR5tTxS57f/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0076", + "paid": true, + "payment_intent": null, + "period_end": 1582741426, + "period_start": 1582741426, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582741427, + "marked_uncollectible_at": null, + "paid_at": 1582741427, + "voided_at": null + }, + "subscription": "sub_Go6lcvvsPhlmwz", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582741429 + }, + { + "id": "in_1GGRhcDzYFZjJeDRB3VP8Pw5", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582730496, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_TMKea86ajpCYTBTMOBXUCApUXK", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_TMKea86ajpCYTBTMOBXUCApUXK/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGRhcDzYFZjJeDRQcM7uBWp", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585235796, + "start": 1582730496 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go3pe9VANDiTc9", + "subscription_item": "si_Go3puUNx6ZbEpG", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGRhcDzYFZjJeDRB3VP8Pw5/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0075", + "paid": true, + "payment_intent": null, + "period_end": 1582730496, + "period_start": 1582730496, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582730496, + "marked_uncollectible_at": null, + "paid_at": 1582730496, + "voided_at": null + }, + "subscription": "sub_Go3pe9VANDiTc9", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582730498 + }, + { + "id": "in_1GGRh3DzYFZjJeDR1SMMBe1W", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582730461, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_IW6cv8I5wBcd55QvaebrbegDIE", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_IW6cv8I5wBcd55QvaebrbegDIE/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGRh3DzYFZjJeDR3Yk2yD8b", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585235761, + "start": 1582730461 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go3oUx2kHM69KA", + "subscription_item": "si_Go3oyUkycK9FqW", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGRh3DzYFZjJeDR1SMMBe1W/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0074", + "paid": true, + "payment_intent": null, + "period_end": 1582730461, + "period_start": 1582730461, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582730461, + "marked_uncollectible_at": null, + "paid_at": 1582730461, + "voided_at": null + }, + "subscription": "sub_Go3oUx2kHM69KA", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582730463 + }, + { + "id": "in_1GGRedDzYFZjJeDRg8IjDYDy", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582730311, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_5CX8ZwjgraZ662YKX7U29zgDil", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_5CX8ZwjgraZ662YKX7U29zgDil/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGRedDzYFZjJeDR1IMR1pkN", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585235611, + "start": 1582730311 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go3m8tXxiKT4Ty", + "subscription_item": "si_Go3mGRTuf5rWZx", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGRedDzYFZjJeDRg8IjDYDy/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0073", + "paid": true, + "payment_intent": null, + "period_end": 1582730311, + "period_start": 1582730311, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582730311, + "marked_uncollectible_at": null, + "paid_at": 1582730311, + "voided_at": null + }, + "subscription": "sub_Go3m8tXxiKT4Ty", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582730313 + }, + { + "id": "in_1GGRdqDzYFZjJeDRjUzkk1Eh", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582730262, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_XD14M63eK2jYVSx9qixP7AAvjz", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_XD14M63eK2jYVSx9qixP7AAvjz/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGRdqDzYFZjJeDRzlZXvPii", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585235562, + "start": 1582730262 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go3lauL903bwh8", + "subscription_item": "si_Go3lnIuDonyrgf", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGRdqDzYFZjJeDRjUzkk1Eh/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0072", + "paid": true, + "payment_intent": null, + "period_end": 1582730262, + "period_start": 1582730262, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582730262, + "marked_uncollectible_at": null, + "paid_at": 1582730262, + "voided_at": null + }, + "subscription": "sub_Go3lauL903bwh8", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582730264 + }, + { + "id": "in_1GGRdPDzYFZjJeDRDvITFS77", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582730235, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_tSxW2jSIPe6fYX2oBdCoX34iiT", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_tSxW2jSIPe6fYX2oBdCoX34iiT/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGRdPDzYFZjJeDRwc55ihMT", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585235535, + "start": 1582730235 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go3k87xpcBIv6x", + "subscription_item": "si_Go3kUzIVzyRrmr", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGRdPDzYFZjJeDRDvITFS77/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0071", + "paid": true, + "payment_intent": null, + "period_end": 1582730235, + "period_start": 1582730235, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582730235, + "marked_uncollectible_at": null, + "paid_at": 1582730235, + "voided_at": null + }, + "subscription": "sub_Go3k87xpcBIv6x", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582730238 + }, + { + "id": "in_1GGRbyDzYFZjJeDRQNg9dq7u", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582730146, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_A8LoHr9sgzlNNNAlAH3KwHaBqY", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_A8LoHr9sgzlNNNAlAH3KwHaBqY/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGRbyDzYFZjJeDRUyzLvc17", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585235446, + "start": 1582730146 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go3jZHcnyeTkW6", + "subscription_item": "si_Go3jmqKRgLu2qd", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGRbyDzYFZjJeDRQNg9dq7u/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0070", + "paid": true, + "payment_intent": null, + "period_end": 1582730146, + "period_start": 1582730146, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582730146, + "marked_uncollectible_at": null, + "paid_at": 1582730146, + "voided_at": null + }, + "subscription": "sub_Go3jZHcnyeTkW6", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582730148 + }, + { + "id": "in_1GGRakDzYFZjJeDRQ7G5HBqs", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582730070, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_rUn371g8tF9YXRisLvb8uSKtT4", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_rUn371g8tF9YXRisLvb8uSKtT4/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGRakDzYFZjJeDRvsYSUAsD", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585235370, + "start": 1582730070 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go3iaBE7lzFdap", + "subscription_item": "si_Go3i9JPgQm0QHM", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGRakDzYFZjJeDRQ7G5HBqs/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0069", + "paid": true, + "payment_intent": null, + "period_end": 1582730070, + "period_start": 1582730070, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582730070, + "marked_uncollectible_at": null, + "paid_at": 1582730070, + "voided_at": null + }, + "subscription": "sub_Go3iaBE7lzFdap", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582730072 + }, + { + "id": "in_1GGRZVDzYFZjJeDRTplM7NAC", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582729993, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_rAwB48WWYBazPysFu8Ll6zyQy5", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_rAwB48WWYBazPysFu8Ll6zyQy5/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGRZVDzYFZjJeDR3ktOgruP", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585235293, + "start": 1582729993 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go3gSlNmpIJKdQ", + "subscription_item": "si_Go3gZm51HuGkDV", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGRZVDzYFZjJeDRTplM7NAC/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0068", + "paid": true, + "payment_intent": null, + "period_end": 1582729993, + "period_start": 1582729993, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582729993, + "marked_uncollectible_at": null, + "paid_at": 1582729993, + "voided_at": null + }, + "subscription": "sub_Go3gSlNmpIJKdQ", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582729995 + }, + { + "id": "in_1GGRYMDzYFZjJeDRfe9bBDKN", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582729922, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_davaEi03DD3tAMSKNvrBhMSOzq", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_davaEi03DD3tAMSKNvrBhMSOzq/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGRYMDzYFZjJeDRgAv6vS9y", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585235222, + "start": 1582729922 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go3fRflUF6FFzj", + "subscription_item": "si_Go3f9Tx2V5uW02", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGRYMDzYFZjJeDRfe9bBDKN/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0067", + "paid": true, + "payment_intent": null, + "period_end": 1582729922, + "period_start": 1582729922, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582729922, + "marked_uncollectible_at": null, + "paid_at": 1582729922, + "voided_at": null + }, + "subscription": "sub_Go3fRflUF6FFzj", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582729923 + }, + { + "id": "in_1GGREIDzYFZjJeDREO2HYOQK", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582728678, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_JP5cIekfQXgWFNrl3oXzADibKX", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_JP5cIekfQXgWFNrl3oXzADibKX/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGREIDzYFZjJeDRpvqByyvV", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585233978, + "start": 1582728678 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go3KLVABhAeYvf", + "subscription_item": "si_Go3K5vNTBl4ghy", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGREIDzYFZjJeDREO2HYOQK/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0066", + "paid": true, + "payment_intent": null, + "period_end": 1582728678, + "period_start": 1582728678, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582728678, + "marked_uncollectible_at": null, + "paid_at": 1582728678, + "voided_at": null + }, + "subscription": "sub_Go3KLVABhAeYvf", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582728680 + }, + { + "id": "in_1GGRCSDzYFZjJeDRkuyikBAT", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582728564, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_nam6PoBRBeEo8mskCGzR0JZCku", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_nam6PoBRBeEo8mskCGzR0JZCku/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGRCSDzYFZjJeDRFXvl9OFM", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585233864, + "start": 1582728564 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go3JR9FNrRdafq", + "subscription_item": "si_Go3JZiFdlAjzK3", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGRCSDzYFZjJeDRkuyikBAT/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0065", + "paid": true, + "payment_intent": null, + "period_end": 1582728564, + "period_start": 1582728564, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582728564, + "marked_uncollectible_at": null, + "paid_at": 1582728564, + "voided_at": null + }, + "subscription": "sub_Go3JR9FNrRdafq", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582728565 + }, + { + "id": "in_1GGR3vDzYFZjJeDRlF42G6IR", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582728035, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_eRxIalXOGzgpKKegjG9IuYphrq", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_eRxIalXOGzgpKKegjG9IuYphrq/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGR3vDzYFZjJeDR7RjNf4Qv", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582727735, + "start": 1582727611 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go33Kf2Dpdf9G8", + "subscription_item": "si_Go33jlRcVhNkWX", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGR3vDzYFZjJeDRlF42G6IR/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0064", + "paid": true, + "payment_intent": null, + "period_end": 1582728035, + "period_start": 1582727611, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582732514, + "marked_uncollectible_at": null, + "paid_at": 1582732514, + "voided_at": null + }, + "subscription": "sub_Go33Kf2Dpdf9G8", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582728036 + }, + { + "id": "in_1GGR3hDzYFZjJeDRWZabRdsr", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582728021, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_hhv5tbooD8svt325rcoirabRhD", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_hhv5tbooD8svt325rcoirabRhD/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGR3hDzYFZjJeDR4Zvq12Im", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582727721, + "start": 1582727764 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go35RQKNHYncyR", + "subscription_item": "si_Go35hcEvlqj1xN", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGR3hDzYFZjJeDRWZabRdsr/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0063", + "paid": true, + "payment_intent": null, + "period_end": 1582728021, + "period_start": 1582727764, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582732522, + "marked_uncollectible_at": null, + "paid_at": 1582732522, + "voided_at": null + }, + "subscription": "sub_Go35RQKNHYncyR", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582728022 + }, + { + "id": "in_1GGQzYDzYFZjJeDRjEyaLp4V", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582727764, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_Ttk3o3Z7qrqH1zptSzaKFRKzxL", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_Ttk3o3Z7qrqH1zptSzaKFRKzxL/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGQzYDzYFZjJeDRM4Xh4y3Z", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585233064, + "start": 1582727764 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go35RQKNHYncyR", + "subscription_item": "si_Go35hcEvlqj1xN", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGQzYDzYFZjJeDRjEyaLp4V/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0062", + "paid": true, + "payment_intent": null, + "period_end": 1582727764, + "period_start": 1582727764, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582727764, + "marked_uncollectible_at": null, + "paid_at": 1582727765, + "voided_at": null + }, + "subscription": "sub_Go35RQKNHYncyR", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582727771 + }, + { + "id": "in_1GGQx5DzYFZjJeDRvBmZdCIL", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582727611, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_UzonlvvDv4jGfQT4nItGuRjaez", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_UzonlvvDv4jGfQT4nItGuRjaez/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GGQx5DzYFZjJeDRTKcMCD9K", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585232911, + "start": 1582727611 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Go33Kf2Dpdf9G8", + "subscription_item": "si_Go33jlRcVhNkWX", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GGQx5DzYFZjJeDRvBmZdCIL/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0061", + "paid": true, + "payment_intent": null, + "period_end": 1582727611, + "period_start": 1582727611, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582727611, + "marked_uncollectible_at": null, + "paid_at": 1582727612, + "voided_at": null + }, + "subscription": "sub_Go33Kf2Dpdf9G8", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582727614 + }, + { + "id": "in_1GFobQDzYFZjJeDRDEnRquSp", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582580196, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_MR0RbKsm5vazs23kyVUeGKA6q4", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_MR0RbKsm5vazs23kyVUeGKA6q4/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFobQDzYFZjJeDRa30EKeAF", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585085496, + "start": 1582580196 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GnPQcLofZ66QHM", + "subscription_item": "si_GnPQ8oFy9uhxfL", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFobQDzYFZjJeDRDEnRquSp/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0060", + "paid": true, + "payment_intent": null, + "period_end": 1582580196, + "period_start": 1582580196, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582580196, + "marked_uncollectible_at": null, + "paid_at": 1582580196, + "voided_at": null + }, + "subscription": "sub_GnPQcLofZ66QHM", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582580198 + }, + { + "id": "in_1GFoaiDzYFZjJeDR8ykvUsfU", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582580152, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_ksXujMpdJjxCcsRAh96TQd9udt", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_ksXujMpdJjxCcsRAh96TQd9udt/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFoaiDzYFZjJeDRX3Y2TA71", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585085452, + "start": 1582580152 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GnPPzn3xfAStQ5", + "subscription_item": "si_GnPP3qzMZVyxKL", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFoaiDzYFZjJeDR8ykvUsfU/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0059", + "paid": true, + "payment_intent": null, + "period_end": 1582580152, + "period_start": 1582580152, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582580152, + "marked_uncollectible_at": null, + "paid_at": 1582580152, + "voided_at": null + }, + "subscription": "sub_GnPPzn3xfAStQ5", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582580159 + }, + { + "id": "in_1GFo3NDzYFZjJeDRvNCXZDvK", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582578085, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_hDsp19NVymdL9AdMsd2YKh3MkX", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_hDsp19NVymdL9AdMsd2YKh3MkX/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFo3NDzYFZjJeDRkJ1hsTAb", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585083385, + "start": 1582578085 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GnOr6WVuzCuXxL", + "subscription_item": "si_GnOrRV7K40EhjD", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFo3NDzYFZjJeDRvNCXZDvK/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0058", + "paid": true, + "payment_intent": null, + "period_end": 1582578085, + "period_start": 1582578085, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582578085, + "marked_uncollectible_at": null, + "paid_at": 1582578085, + "voided_at": null + }, + "subscription": "sub_GnOr6WVuzCuXxL", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582578087 + }, + { + "id": "in_1GFml6DzYFZjJeDRruR40Gsu", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582573108, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_seha2gR7yab2JUzzojZ4EzvNnI", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_seha2gR7yab2JUzzojZ4EzvNnI/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFml6DzYFZjJeDRvUzJrVmM", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585078408, + "start": 1582573108 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GnNWRqSyMj18TR", + "subscription_item": "si_GnNWrabXCKKktR", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFml6DzYFZjJeDRruR40Gsu/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0057", + "paid": true, + "payment_intent": null, + "period_end": 1582573108, + "period_start": 1582573108, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582573108, + "marked_uncollectible_at": null, + "paid_at": 1582573108, + "voided_at": null + }, + "subscription": "sub_GnNWRqSyMj18TR", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582573117 + }, + { + "id": "in_1GFmklDzYFZjJeDRYSZ4bDnr", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582573087, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_ZPjm1cr4WYuc3LktxAwJKNSjML", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_ZPjm1cr4WYuc3LktxAwJKNSjML/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFmklDzYFZjJeDRnTuaJMjI", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582572787, + "start": 1582221488 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlqzemuJUub4J2", + "subscription_item": "si_GlqzFkjDInRmBN", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFmklDzYFZjJeDRYSZ4bDnr/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0056", + "paid": true, + "payment_intent": null, + "period_end": 1582573087, + "period_start": 1582221488, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582577224, + "marked_uncollectible_at": null, + "paid_at": 1582577224, + "voided_at": null + }, + "subscription": "sub_GlqzemuJUub4J2", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582573088 + }, + { + "id": "in_1GFmkfDzYFZjJeDRHKwiTy4J", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582573081, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_E5wiQVGpD38cxo2f3I9nS0dqYk", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_E5wiQVGpD38cxo2f3I9nS0dqYk/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFmkfDzYFZjJeDRiQCBI0Dw", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582572781, + "start": 1582232582 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Glty5lWiwwQsSI", + "subscription_item": "si_Glty8AuagWpgnc", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFmkfDzYFZjJeDRHKwiTy4J/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0055", + "paid": true, + "payment_intent": null, + "period_end": 1582573081, + "period_start": 1582232582, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582577214, + "marked_uncollectible_at": null, + "paid_at": 1582577214, + "voided_at": null + }, + "subscription": "sub_Glty5lWiwwQsSI", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582573085 + }, + { + "id": "in_1GFmkZDzYFZjJeDRIJmX6B0W", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582573075, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_sxYNlA8I8OGn2lioxY7F8bmLap", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_sxYNlA8I8OGn2lioxY7F8bmLap/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFmkZDzYFZjJeDRfKXQomry", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582572775, + "start": 1582231098 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GltZ2afPg5EAGw", + "subscription_item": "si_GltZpXZrKPJnT2", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFmkZDzYFZjJeDRIJmX6B0W/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0054", + "paid": true, + "payment_intent": null, + "period_end": 1582573075, + "period_start": 1582231098, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582577205, + "marked_uncollectible_at": null, + "paid_at": 1582577205, + "voided_at": null + }, + "subscription": "sub_GltZ2afPg5EAGw", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582573077 + }, + { + "id": "in_1GFmkODzYFZjJeDRPmqf5yJF", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582573064, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_0zrzxZAJksyvR0RrlmmxciD0pf", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_0zrzxZAJksyvR0RrlmmxciD0pf/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFmkODzYFZjJeDRbwWTJX0N", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582572764, + "start": 1582571784 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GnNA0FQ4tZcOPu", + "subscription_item": "si_GnNAgOIhfYKe44", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFmkODzYFZjJeDRPmqf5yJF/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0053", + "paid": true, + "payment_intent": null, + "period_end": 1582573064, + "period_start": 1582571784, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582577203, + "marked_uncollectible_at": null, + "paid_at": 1582577203, + "voided_at": null + }, + "subscription": "sub_GnNA0FQ4tZcOPu", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582573065 + }, + { + "id": "in_1GFmkHDzYFZjJeDRO0nJCWjm", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582573057, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_snTXzinz9LfKAYoC6LV31avoHx", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_snTXzinz9LfKAYoC6LV31avoHx/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFmkHDzYFZjJeDRgF7ntWKZ", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582572757, + "start": 1582571856 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GnNBB7LK4xUktO", + "subscription_item": "si_GnNBpAidcb3UF0", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFmkHDzYFZjJeDRO0nJCWjm/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0052", + "paid": true, + "payment_intent": null, + "period_end": 1582573057, + "period_start": 1582571856, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582577210, + "marked_uncollectible_at": null, + "paid_at": 1582577210, + "voided_at": null + }, + "subscription": "sub_GnNBB7LK4xUktO", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582573059 + }, + { + "id": "in_1GFmk9DzYFZjJeDRa8O2XxdC", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582573049, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_XnATXkvzBlXj6ieMVuixXWwffJ", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_XnATXkvzBlXj6ieMVuixXWwffJ/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFmk9DzYFZjJeDR47NL0Cpl", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582572749, + "start": 1582572448 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GnNLqCSha2X98Y", + "subscription_item": "si_GnNLn0nygBRNWP", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFmk9DzYFZjJeDRa8O2XxdC/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0051", + "paid": true, + "payment_intent": null, + "period_end": 1582573049, + "period_start": 1582572448, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582577207, + "marked_uncollectible_at": null, + "paid_at": 1582577207, + "voided_at": null + }, + "subscription": "sub_GnNLqCSha2X98Y", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582573050 + }, + { + "id": "in_1GFmaTDzYFZjJeDRwOUFsXQY", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582572449, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_oxmuCDBPDlSOxvW52GxIaDWPKU", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_oxmuCDBPDlSOxvW52GxIaDWPKU/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFmaTDzYFZjJeDRdlvZWImt", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585077748, + "start": 1582572448 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GnNLqCSha2X98Y", + "subscription_item": "si_GnNLn0nygBRNWP", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFmaTDzYFZjJeDRwOUFsXQY/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0050", + "paid": true, + "payment_intent": null, + "period_end": 1582572448, + "period_start": 1582572448, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582572449, + "marked_uncollectible_at": null, + "paid_at": 1582572449, + "voided_at": null + }, + "subscription": "sub_GnNLqCSha2X98Y", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582572451 + }, + { + "id": "in_1GFmQuDzYFZjJeDR02FtxjNB", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582571856, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_XYXHFqGAyxuB7OO9egytLNFtPt", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_XYXHFqGAyxuB7OO9egytLNFtPt/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFmQuDzYFZjJeDRdCbfMZAv", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585077156, + "start": 1582571856 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GnNBB7LK4xUktO", + "subscription_item": "si_GnNBpAidcb3UF0", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFmQuDzYFZjJeDR02FtxjNB/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0049", + "paid": true, + "payment_intent": null, + "period_end": 1582571856, + "period_start": 1582571856, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582571856, + "marked_uncollectible_at": null, + "paid_at": 1582571856, + "voided_at": null + }, + "subscription": "sub_GnNBB7LK4xUktO", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582571860 + }, + { + "id": "in_1GFmPkDzYFZjJeDRBVmtKgYA", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582571784, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_gMrYXSjQviPzj8D9eTr8PNVFTI", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_gMrYXSjQviPzj8D9eTr8PNVFTI/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GFmPkDzYFZjJeDR2viZnco8", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1585077084, + "start": 1582571784 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GnNA0FQ4tZcOPu", + "subscription_item": "si_GnNAgOIhfYKe44", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GFmPkDzYFZjJeDRBVmtKgYA/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0048", + "paid": true, + "payment_intent": null, + "period_end": 1582571784, + "period_start": 1582571784, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582571784, + "marked_uncollectible_at": null, + "paid_at": 1582571784, + "voided_at": null + }, + "subscription": "sub_GnNA0FQ4tZcOPu", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582571788 + }, + { + "id": "in_1GEMAkDzYFZjJeDRdveo8Zvc", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582232582, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_KHdRJOV6HiiN9cIxWO9xI2oPn0", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_KHdRJOV6HiiN9cIxWO9xI2oPn0/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEMAkDzYFZjJeDR0L56OtvT", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584737882, + "start": 1582232582 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Glty5lWiwwQsSI", + "subscription_item": "si_Glty8AuagWpgnc", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEMAkDzYFZjJeDRdveo8Zvc/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0047", + "paid": true, + "payment_intent": null, + "period_end": 1582232582, + "period_start": 1582232582, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582232582, + "marked_uncollectible_at": null, + "paid_at": 1582232582, + "voided_at": null + }, + "subscription": "sub_Glty5lWiwwQsSI", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582232585 + }, + { + "id": "in_1GELmoDzYFZjJeDRiQ0f9LTf", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582231098, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_h7Nqq4BQiN3iU9kIHOuHdrWA50", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_h7Nqq4BQiN3iU9kIHOuHdrWA50/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GELmoDzYFZjJeDRS22jW51c", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584736398, + "start": 1582231098 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GltZ2afPg5EAGw", + "subscription_item": "si_GltZpXZrKPJnT2", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GELmoDzYFZjJeDRiQ0f9LTf/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0046", + "paid": true, + "payment_intent": null, + "period_end": 1582231098, + "period_start": 1582231098, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582231098, + "marked_uncollectible_at": null, + "paid_at": 1582231098, + "voided_at": null + }, + "subscription": "sub_GltZ2afPg5EAGw", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582231100 + }, + { + "id": "in_1GELmZDzYFZjJeDRIMJKP653", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582231083, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_bm11IFs3R8nYqdSiYZIGJeILXV", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_bm11IFs3R8nYqdSiYZIGJeILXV/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GELmZDzYFZjJeDRgOlb73L4", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582230783, + "start": 1582221576 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Glr1ZZbxUwPiGV", + "subscription_item": "si_Glr1tSio3TnB2P", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GELmZDzYFZjJeDRIMJKP653/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0045", + "paid": true, + "payment_intent": null, + "period_end": 1582231083, + "period_start": 1582221576, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582235157, + "marked_uncollectible_at": null, + "paid_at": 1582235157, + "voided_at": null + }, + "subscription": "sub_Glr1ZZbxUwPiGV", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582231084 + }, + { + "id": "in_1GELmTDzYFZjJeDRBQhRxdtx", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582231077, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_B9pWYmoIeeKmOg4WMOZQD2X4QD", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_B9pWYmoIeeKmOg4WMOZQD2X4QD/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GELmTDzYFZjJeDR2l9WNp3E", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582230777, + "start": 1582221643 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Glr2PDoSBxuZ6f", + "subscription_item": "si_Glr2mD15sxjhmI", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GELmTDzYFZjJeDRBQhRxdtx/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0044", + "paid": true, + "payment_intent": null, + "period_end": 1582231077, + "period_start": 1582221643, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582235154, + "marked_uncollectible_at": null, + "paid_at": 1582235154, + "voided_at": null + }, + "subscription": "sub_Glr2PDoSBxuZ6f", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582231078 + }, + { + "id": "in_1GELmNDzYFZjJeDRSHi4fXyn", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582231071, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_kVNBKDE2AZK2hOkEcMLgPuNo3R", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_kVNBKDE2AZK2hOkEcMLgPuNo3R/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GELmNDzYFZjJeDRFXLy9k6D", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582230771, + "start": 1582222981 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlrOBDgD24odPV", + "subscription_item": "si_GlrO0WKeQoaOMg", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GELmNDzYFZjJeDRSHi4fXyn/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0043", + "paid": true, + "payment_intent": null, + "period_end": 1582231071, + "period_start": 1582222981, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582235148, + "marked_uncollectible_at": null, + "paid_at": 1582235149, + "voided_at": null + }, + "subscription": "sub_GlrOBDgD24odPV", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582231072 + }, + { + "id": "in_1GELmHDzYFZjJeDRZKHxABp7", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582231065, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_Axk6Njz3WuluErq4h2WLQWgRkZ", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_Axk6Njz3WuluErq4h2WLQWgRkZ/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GELmHDzYFZjJeDR2M91LzCL", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582230765, + "start": 1582223033 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlrPgb4E5Me9eJ", + "subscription_item": "si_GlrPKqr4j9CXhc", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GELmHDzYFZjJeDRZKHxABp7/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0042", + "paid": true, + "payment_intent": null, + "period_end": 1582231065, + "period_start": 1582223033, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582235158, + "marked_uncollectible_at": null, + "paid_at": 1582235158, + "voided_at": null + }, + "subscription": "sub_GlrPgb4E5Me9eJ", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582231066 + }, + { + "id": "in_1GELmCDzYFZjJeDRRkN45vOH", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582231060, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_ExDIXy3vV8wrXHzusokemvey17", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_ExDIXy3vV8wrXHzusokemvey17/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GELmCDzYFZjJeDR8bve8Zu6", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582230760, + "start": 1582223252 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlrTxE9JkS0cAE", + "subscription_item": "si_GlrT0DHyfkMIHm", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GELmCDzYFZjJeDRRkN45vOH/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0041", + "paid": true, + "payment_intent": null, + "period_end": 1582231060, + "period_start": 1582223252, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582235147, + "marked_uncollectible_at": null, + "paid_at": 1582235147, + "voided_at": null + }, + "subscription": "sub_GlrTxE9JkS0cAE", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582231061 + }, + { + "id": "in_1GEJkGDzYFZjJeDRvKfc2XXe", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582223252, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_GZ4t6ysF37nDrdbEPFtWWgTY59", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_GZ4t6ysF37nDrdbEPFtWWgTY59/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJkGDzYFZjJeDRY9JPVVKs", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584728552, + "start": 1582223252 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlrTxE9JkS0cAE", + "subscription_item": "si_GlrT0DHyfkMIHm", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJkGDzYFZjJeDRvKfc2XXe/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0040", + "paid": true, + "payment_intent": null, + "period_end": 1582223252, + "period_start": 1582223252, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582223252, + "marked_uncollectible_at": null, + "paid_at": 1582223252, + "voided_at": null + }, + "subscription": "sub_GlrTxE9JkS0cAE", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582223254 + }, + { + "id": "in_1GEJgjDzYFZjJeDRp2f2qqKU", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582223033, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_chhdpbNFgIeWZan8b1NLqKHXyA", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_chhdpbNFgIeWZan8b1NLqKHXyA/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJgjDzYFZjJeDR9120arSs", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584728333, + "start": 1582223033 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlrPgb4E5Me9eJ", + "subscription_item": "si_GlrPKqr4j9CXhc", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJgjDzYFZjJeDRp2f2qqKU/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0039", + "paid": true, + "payment_intent": null, + "period_end": 1582223033, + "period_start": 1582223033, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582223033, + "marked_uncollectible_at": null, + "paid_at": 1582223033, + "voided_at": null + }, + "subscription": "sub_GlrPgb4E5Me9eJ", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582223038 + }, + { + "id": "in_1GEJfuDzYFZjJeDR2h8b9ehx", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582222982, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_baxuiFBRd705KVv7KEvgn7UmGx", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_baxuiFBRd705KVv7KEvgn7UmGx/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJfuDzYFZjJeDR1rZQ8TMp", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584728281, + "start": 1582222981 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlrOBDgD24odPV", + "subscription_item": "si_GlrO0WKeQoaOMg", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJfuDzYFZjJeDR2h8b9ehx/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0038", + "paid": true, + "payment_intent": null, + "period_end": 1582222981, + "period_start": 1582222981, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582222982, + "marked_uncollectible_at": null, + "paid_at": 1582222982, + "voided_at": null + }, + "subscription": "sub_GlrOBDgD24odPV", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582222984 + }, + { + "id": "in_1GEJKKDzYFZjJeDR6SsO85nF", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582221644, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_AHdbLFJEP7z78Z6vTcMaDlAZZD", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_AHdbLFJEP7z78Z6vTcMaDlAZZD/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJKKDzYFZjJeDRhqwRAi8N", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584726943, + "start": 1582221643 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Glr2PDoSBxuZ6f", + "subscription_item": "si_Glr2mD15sxjhmI", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJKKDzYFZjJeDR6SsO85nF/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0037", + "paid": true, + "payment_intent": null, + "period_end": 1582221643, + "period_start": 1582221643, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582221644, + "marked_uncollectible_at": null, + "paid_at": 1582221644, + "voided_at": null + }, + "subscription": "sub_Glr2PDoSBxuZ6f", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582221645 + }, + { + "id": "in_1GEJJEDzYFZjJeDRctYAuagR", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582221576, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_FxBcgiM20IqF1RcPrKOVldjZ22", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_FxBcgiM20IqF1RcPrKOVldjZ22/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJJEDzYFZjJeDRGvC3oB2Y", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584726876, + "start": 1582221576 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_Glr1ZZbxUwPiGV", + "subscription_item": "si_Glr1tSio3TnB2P", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJJEDzYFZjJeDRctYAuagR/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0036", + "paid": true, + "payment_intent": null, + "period_end": 1582221576, + "period_start": 1582221576, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582221576, + "marked_uncollectible_at": null, + "paid_at": 1582221576, + "voided_at": null + }, + "subscription": "sub_Glr1ZZbxUwPiGV", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582221578 + }, + { + "id": "in_1GEJJDDzYFZjJeDREaJEub1r", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582221575, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_Aek8XK16TeljdETsya55Deph5c", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_Aek8XK16TeljdETsya55Deph5c/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJJDDzYFZjJeDRgcFMBTlu", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582221275, + "start": 1582138370 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUeGWXnVwSjJH", + "subscription_item": "si_GlUe0gtM1vB8JB", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJJDDzYFZjJeDREaJEub1r/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0035", + "paid": true, + "payment_intent": null, + "period_end": 1582221575, + "period_start": 1582138370, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582225268, + "marked_uncollectible_at": null, + "paid_at": 1582225268, + "voided_at": null + }, + "subscription": "sub_GlUeGWXnVwSjJH", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582221577 + }, + { + "id": "in_1GEJHoDzYFZjJeDRi9J6mBcI", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582221488, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_C7WWa7DZeUoQpZ82mJs2MNBIq1", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_C7WWa7DZeUoQpZ82mJs2MNBIq1/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJHoDzYFZjJeDRrYTtcIoU", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584726788, + "start": 1582221488 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlqzemuJUub4J2", + "subscription_item": "si_GlqzFkjDInRmBN", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJHoDzYFZjJeDRi9J6mBcI/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0034", + "paid": true, + "payment_intent": null, + "period_end": 1582221488, + "period_start": 1582221488, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582221488, + "marked_uncollectible_at": null, + "paid_at": 1582221488, + "voided_at": null + }, + "subscription": "sub_GlqzemuJUub4J2", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582221490 + }, + { + "id": "in_1GEJG5DzYFZjJeDRsuv72EiP", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582221381, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_VA6JSOLOEWPwqxanRL3Cn2ThFJ", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_VA6JSOLOEWPwqxanRL3Cn2ThFJ/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJG5DzYFZjJeDRh6pAxiqm", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584726681, + "start": 1582221381 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlqyjH16RvI5op", + "subscription_item": "si_GlqyrYVz6CRHt8", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJG5DzYFZjJeDRsuv72EiP/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0033", + "paid": true, + "payment_intent": null, + "period_end": 1582221381, + "period_start": 1582221381, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582221381, + "marked_uncollectible_at": null, + "paid_at": 1582221381, + "voided_at": null + }, + "subscription": "sub_GlqyjH16RvI5op", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582221383 + }, + { + "id": "in_1GEJFmDzYFZjJeDRhzUSMki8", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582221362, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_o8wu4TDyXWBa5rSs6Xj8qwXn6W", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_o8wu4TDyXWBa5rSs6Xj8qwXn6W/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJFmDzYFZjJeDR2ammr3u2", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582221062, + "start": 1582138445 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUf9jU1du2sec", + "subscription_item": "si_GlUfAEkGHyeN3H", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJFmDzYFZjJeDRhzUSMki8/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0032", + "paid": true, + "payment_intent": null, + "period_end": 1582221362, + "period_start": 1582138445, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582225281, + "marked_uncollectible_at": null, + "paid_at": 1582225281, + "voided_at": null + }, + "subscription": "sub_GlUf9jU1du2sec", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582221364 + }, + { + "id": "in_1GEJFfDzYFZjJeDRoGejeFwH", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582221355, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_JOMHlNP1swNSmXct5rZNXrch27", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_JOMHlNP1swNSmXct5rZNXrch27/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJFfDzYFZjJeDRi1vgmna4", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582221055, + "start": 1582138470 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUgiX3ZLbSFWc", + "subscription_item": "si_GlUgyngaPGIGve", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJFfDzYFZjJeDRoGejeFwH/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0031", + "paid": true, + "payment_intent": null, + "period_end": 1582221355, + "period_start": 1582138470, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582225267, + "marked_uncollectible_at": null, + "paid_at": 1582225267, + "voided_at": null + }, + "subscription": "sub_GlUgiX3ZLbSFWc", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582221357 + }, + { + "id": "in_1GEJFZDzYFZjJeDRbYf5rRla", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582221348, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_xn6dWbOJWDYi5HTmSV7yhDf54D", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_xn6dWbOJWDYi5HTmSV7yhDf54D/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJFYDzYFZjJeDRtBUjs46p", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582221049, + "start": 1582138558 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUhSfsh4CvqKT", + "subscription_item": "si_GlUhRKEz1f6wu0", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJFZDzYFZjJeDRbYf5rRla/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0030", + "paid": true, + "payment_intent": null, + "period_end": 1582221348, + "period_start": 1582138558, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582225284, + "marked_uncollectible_at": null, + "paid_at": 1582225284, + "voided_at": null + }, + "subscription": "sub_GlUhSfsh4CvqKT", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582221350 + }, + { + "id": "in_1GEJFRDzYFZjJeDR8Zw42zWU", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582221341, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_VRzdnJzcchGHTclDylbhDpdXJM", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_VRzdnJzcchGHTclDylbhDpdXJM/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJFRDzYFZjJeDRS9d5fUpf", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582221041, + "start": 1582138615 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUim0w59Mh6OQ", + "subscription_item": "si_GlUibAb5untQG7", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJFRDzYFZjJeDR8Zw42zWU/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0029", + "paid": true, + "payment_intent": null, + "period_end": 1582221341, + "period_start": 1582138615, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582225276, + "marked_uncollectible_at": null, + "paid_at": 1582225276, + "voided_at": null + }, + "subscription": "sub_GlUim0w59Mh6OQ", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582221348 + }, + { + "id": "in_1GEJFJDzYFZjJeDRzLCGoCUR", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582221333, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_MSJ1yZmO7y5lPHzhN7ywJLB9tc", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_MSJ1yZmO7y5lPHzhN7ywJLB9tc/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJFJDzYFZjJeDRWTAJVcQ0", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582221033, + "start": 1582138691 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUjNq4ZVGr4s2", + "subscription_item": "si_GlUjvZDQUcqHcs", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJFJDzYFZjJeDRzLCGoCUR/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0028", + "paid": true, + "payment_intent": null, + "period_end": 1582221333, + "period_start": 1582138691, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582225265, + "marked_uncollectible_at": null, + "paid_at": 1582225265, + "voided_at": null + }, + "subscription": "sub_GlUjNq4ZVGr4s2", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582221335 + }, + { + "id": "in_1GEJFDDzYFZjJeDRYjK9gMfb", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582221327, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_QWvJnvWWyxFYYfA6Ufni4ZjvzU", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_QWvJnvWWyxFYYfA6Ufni4ZjvzU/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJFDDzYFZjJeDR8UlOzXJH", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1582221027, + "start": 1582221104 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlqtasOM0vvM54", + "subscription_item": "si_Glqt0tLUc20y7n", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJFDDzYFZjJeDRYjK9gMfb/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0027", + "paid": true, + "payment_intent": null, + "period_end": 1582221327, + "period_start": 1582221104, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582225274, + "marked_uncollectible_at": null, + "paid_at": 1582225274, + "voided_at": null + }, + "subscription": "sub_GlqtasOM0vvM54", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582221329 + }, + { + "id": "in_1GEJBdDzYFZjJeDR8njLPDxC", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582221105, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_UiNg1Omh8H8UVofgDvXJcwL2lQ", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_UiNg1Omh8H8UVofgDvXJcwL2lQ/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GEJBdDzYFZjJeDRJTK2mmbZ", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584726404, + "start": 1582221104 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlqtasOM0vvM54", + "subscription_item": "si_Glqt0tLUc20y7n", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GEJBdDzYFZjJeDR8njLPDxC/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0026", + "paid": true, + "payment_intent": null, + "period_end": 1582221104, + "period_start": 1582221104, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582221105, + "marked_uncollectible_at": null, + "paid_at": 1582221105, + "voided_at": null + }, + "subscription": "sub_GlqtasOM0vvM54", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582221107 + }, + { + "id": "in_1GDxkNDzYFZjJeDRRy69y28H", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582138691, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_rhuwrz3ce9GwwqP1scYZ2f8BU1", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_rhuwrz3ce9GwwqP1scYZ2f8BU1/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxkNDzYFZjJeDRwiGf9mgp", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584643991, + "start": 1582138691 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUjNq4ZVGr4s2", + "subscription_item": "si_GlUjvZDQUcqHcs", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxkNDzYFZjJeDRRy69y28H/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0025", + "paid": true, + "payment_intent": null, + "period_end": 1582138691, + "period_start": 1582138691, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582138691, + "marked_uncollectible_at": null, + "paid_at": 1582138691, + "voided_at": null + }, + "subscription": "sub_GlUjNq4ZVGr4s2", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582138695 + }, + { + "id": "in_1GDxj9DzYFZjJeDRpwkCs8My", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582138615, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_M1BkFtDZC5s4ksgBJpZiDrohLB", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_M1BkFtDZC5s4ksgBJpZiDrohLB/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxj9DzYFZjJeDRJLAkz8C6", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584643915, + "start": 1582138615 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUim0w59Mh6OQ", + "subscription_item": "si_GlUibAb5untQG7", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxj9DzYFZjJeDRpwkCs8My/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0024", + "paid": true, + "payment_intent": null, + "period_end": 1582138615, + "period_start": 1582138615, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582138615, + "marked_uncollectible_at": null, + "paid_at": 1582138615, + "voided_at": null + }, + "subscription": "sub_GlUim0w59Mh6OQ", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582138630 + }, + { + "id": "in_1GDxiEDzYFZjJeDR47VragFm", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582138558, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_1To0Ke7AXIWHR0MLADqrDq4YHD", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_1To0Ke7AXIWHR0MLADqrDq4YHD/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxiEDzYFZjJeDRCr0cys1S", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584643858, + "start": 1582138558 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUhSfsh4CvqKT", + "subscription_item": "si_GlUhRKEz1f6wu0", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxiEDzYFZjJeDR47VragFm/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0023", + "paid": true, + "payment_intent": null, + "period_end": 1582138558, + "period_start": 1582138558, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582138558, + "marked_uncollectible_at": null, + "paid_at": 1582138558, + "voided_at": null + }, + "subscription": "sub_GlUhSfsh4CvqKT", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582138560 + }, + { + "id": "in_1GDxgoDzYFZjJeDRwjguovBd", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582138470, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_JJubpCLawiMwCcRB6UD63OdcdK", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_JJubpCLawiMwCcRB6UD63OdcdK/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxgoDzYFZjJeDRKwFiwzLF", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584643770, + "start": 1582138470 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUgiX3ZLbSFWc", + "subscription_item": "si_GlUgyngaPGIGve", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxgoDzYFZjJeDRwjguovBd/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0022", + "paid": true, + "payment_intent": null, + "period_end": 1582138470, + "period_start": 1582138470, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582138470, + "marked_uncollectible_at": null, + "paid_at": 1582138471, + "voided_at": null + }, + "subscription": "sub_GlUgiX3ZLbSFWc", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582138473 + }, + { + "id": "in_1GDxgPDzYFZjJeDRmUvYzKnH", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582138445, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_WczSfrJhWTwl0RI8K2LhiCE5Tx", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_WczSfrJhWTwl0RI8K2LhiCE5Tx/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxgPDzYFZjJeDRJxpYUdcU", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584643745, + "start": 1582138445 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUf9jU1du2sec", + "subscription_item": "si_GlUfAEkGHyeN3H", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxgPDzYFZjJeDRmUvYzKnH/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0021", + "paid": true, + "payment_intent": null, + "period_end": 1582138445, + "period_start": 1582138445, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582138445, + "marked_uncollectible_at": null, + "paid_at": 1582138445, + "voided_at": null + }, + "subscription": "sub_GlUf9jU1du2sec", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582138447 + }, + { + "id": "in_1GDxfCDzYFZjJeDRocl25WjA", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582138370, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_rFubQ94u91PxyqpGNqJ6yHHpfF", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_rFubQ94u91PxyqpGNqJ6yHHpfF/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxfCDzYFZjJeDRror9keSq", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584643670, + "start": 1582138370 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUeGWXnVwSjJH", + "subscription_item": "si_GlUe0gtM1vB8JB", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxfCDzYFZjJeDRocl25WjA/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0020", + "paid": true, + "payment_intent": null, + "period_end": 1582138370, + "period_start": 1582138370, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582138370, + "marked_uncollectible_at": null, + "paid_at": 1582138370, + "voided_at": null + }, + "subscription": "sub_GlUeGWXnVwSjJH", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582138372 + }, + { + "id": "in_1GDxdFDzYFZjJeDRrt2wWyqa", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582138249, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_RrkFduIYbHxeMqJu8FKxUM8ZxH", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_RrkFduIYbHxeMqJu8FKxUM8ZxH/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxdFDzYFZjJeDRlPPwU89Z", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584643549, + "start": 1582138249 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUcjLnMZVWGZZ", + "subscription_item": "si_GlUctDNOUUBciF", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxdFDzYFZjJeDRrt2wWyqa/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0019", + "paid": true, + "payment_intent": null, + "period_end": 1582138249, + "period_start": 1582138249, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582138249, + "marked_uncollectible_at": null, + "paid_at": 1582138250, + "voided_at": null + }, + "subscription": "sub_GlUcjLnMZVWGZZ", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582138252 + }, + { + "id": "in_1GDxcYDzYFZjJeDRZmMMuZ0W", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582138206, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_d5eygzsfTcEr2IgMn74OXgRBvw", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_d5eygzsfTcEr2IgMn74OXgRBvw/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxcYDzYFZjJeDRWaUKVS3I", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584643506, + "start": 1582138206 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUbwEpPfiWMiR", + "subscription_item": "si_GlUbSIWttwvCCt", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxcYDzYFZjJeDRZmMMuZ0W/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0018", + "paid": true, + "payment_intent": null, + "period_end": 1582138206, + "period_start": 1582138206, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582138206, + "marked_uncollectible_at": null, + "paid_at": 1582138207, + "voided_at": null + }, + "subscription": "sub_GlUbwEpPfiWMiR", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582138208 + }, + { + "id": "in_1GDxb1DzYFZjJeDRBWN5wajW", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582138111, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_hq4lxUb7GswDtfaOuFwijDW2YN", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_hq4lxUb7GswDtfaOuFwijDW2YN/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxb1DzYFZjJeDRiCp9lx5M", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584643411, + "start": 1582138111 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUaM6dfbKUGds", + "subscription_item": "si_GlUa1FAupTxScr", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxb1DzYFZjJeDRBWN5wajW/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0017", + "paid": true, + "payment_intent": null, + "period_end": 1582138111, + "period_start": 1582138111, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582138111, + "marked_uncollectible_at": null, + "paid_at": 1582138111, + "voided_at": null + }, + "subscription": "sub_GlUaM6dfbKUGds", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582138117 + }, + { + "id": "in_1GDxZGDzYFZjJeDR6mO8JXll", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582138002, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_fWHcMkzSj2EfKwKuqsJ4tSvYX3", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_fWHcMkzSj2EfKwKuqsJ4tSvYX3/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxZGDzYFZjJeDRAHGXAhN3", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584643302, + "start": 1582138002 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUYlvLEIodNSY", + "subscription_item": "si_GlUYJxIix069vN", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxZGDzYFZjJeDR6mO8JXll/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0016", + "paid": true, + "payment_intent": null, + "period_end": 1582138002, + "period_start": 1582138002, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582138002, + "marked_uncollectible_at": null, + "paid_at": 1582138003, + "voided_at": null + }, + "subscription": "sub_GlUYlvLEIodNSY", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582138012 + }, + { + "id": "in_1GDxYFDzYFZjJeDRoW5GM5A4", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582137939, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_vFhcPAenWEmvGwQ5NJHWXvh1vS", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_vFhcPAenWEmvGwQ5NJHWXvh1vS/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxYFDzYFZjJeDRK0bSzvdY", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584643239, + "start": 1582137939 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUXi8Yd9Xfe0M", + "subscription_item": "si_GlUXLBqPbEiFcP", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxYFDzYFZjJeDRoW5GM5A4/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0015", + "paid": true, + "payment_intent": null, + "period_end": 1582137939, + "period_start": 1582137939, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582137939, + "marked_uncollectible_at": null, + "paid_at": 1582137939, + "voided_at": null + }, + "subscription": "sub_GlUXi8Yd9Xfe0M", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582137943 + }, + { + "id": "in_1GDxKoDzYFZjJeDR1hb7KXCm", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582137106, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_o5gRjsr8hXWwHccS7JI5Hgaf2S", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_o5gRjsr8hXWwHccS7JI5Hgaf2S/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxKoDzYFZjJeDRDz6L3Z5q", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584642406, + "start": 1582137106 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUJoR7VLN8sm3", + "subscription_item": "si_GlUJXbUYz9yJoN", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxKoDzYFZjJeDR1hb7KXCm/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0014", + "paid": true, + "payment_intent": null, + "period_end": 1582137106, + "period_start": 1582137106, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582137106, + "marked_uncollectible_at": null, + "paid_at": 1582137106, + "voided_at": null + }, + "subscription": "sub_GlUJoR7VLN8sm3", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582137108 + }, + { + "id": "in_1GDxHLDzYFZjJeDR5M59idXg", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582136891, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_GTfX0b7iGz0KX0kv1ZtP5cAcsH", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_GTfX0b7iGz0KX0kv1ZtP5cAcsH/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxHLDzYFZjJeDRAaOsz7aC", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584642191, + "start": 1582136891 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUFa2ffWb2BP0", + "subscription_item": "si_GlUFc6c4jMzCKf", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxHLDzYFZjJeDR5M59idXg/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0013", + "paid": true, + "payment_intent": null, + "period_end": 1582136891, + "period_start": 1582136891, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582136891, + "marked_uncollectible_at": null, + "paid_at": 1582136891, + "voided_at": null + }, + "subscription": "sub_GlUFa2ffWb2BP0", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582136893 + }, + { + "id": "in_1GDxGvDzYFZjJeDR59M9BVhX", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582136865, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_t5r6LdZDabqG3GZTzBNUcD9QGk", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_t5r6LdZDabqG3GZTzBNUcD9QGk/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxGvDzYFZjJeDRJoJvSRpy", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584642165, + "start": 1582136865 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUFxZvyuLjlPS", + "subscription_item": "si_GlUFUFOAAWpwpX", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxGvDzYFZjJeDR59M9BVhX/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0012", + "paid": true, + "payment_intent": null, + "period_end": 1582136865, + "period_start": 1582136865, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582136865, + "marked_uncollectible_at": null, + "paid_at": 1582136865, + "voided_at": null + }, + "subscription": "sub_GlUFxZvyuLjlPS", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582136867 + }, + { + "id": "in_1GDxGODzYFZjJeDRUiUY9ELj", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582136832, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_uKoaMQiGfhpvIVEH70Adso6r4c", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_uKoaMQiGfhpvIVEH70Adso6r4c/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDxGODzYFZjJeDReTY5QG0R", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584642132, + "start": 1582136832 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlUEGxNOQrruh9", + "subscription_item": "si_GlUExJvwt5ZcYp", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDxGODzYFZjJeDRUiUY9ELj/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0011", + "paid": true, + "payment_intent": null, + "period_end": 1582136832, + "period_start": 1582136832, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582136832, + "marked_uncollectible_at": null, + "paid_at": 1582136832, + "voided_at": null + }, + "subscription": "sub_GlUEGxNOQrruh9", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582136834 + }, + { + "id": "in_1GDwO3DzYFZjJeDR5OCtH3Lj", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582133463, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_S6F5i4exSwJgu0OOXHcWMdpIlB", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_S6F5i4exSwJgu0OOXHcWMdpIlB/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDwO3DzYFZjJeDRfyutrdOz", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584638762, + "start": 1582133462 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlTKjrybUjVIQu", + "subscription_item": "si_GlTKPDpfqQmojf", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDwO3DzYFZjJeDR5OCtH3Lj/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0010", + "paid": true, + "payment_intent": null, + "period_end": 1582133462, + "period_start": 1582133462, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582133463, + "marked_uncollectible_at": null, + "paid_at": 1582133463, + "voided_at": null + }, + "subscription": "sub_GlTKjrybUjVIQu", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582133466 + }, + { + "id": "in_1GDwLQDzYFZjJeDRorS3bmKJ", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582133300, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_YT40ktSmqfcaKtMv7uNC3HbYoE", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_YT40ktSmqfcaKtMv7uNC3HbYoE/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDwLQDzYFZjJeDRQPQSSjH9", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584638600, + "start": 1582133300 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlTIF4mdqfCD3K", + "subscription_item": "si_GlTIbSZLazgI3h", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDwLQDzYFZjJeDRorS3bmKJ/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0009", + "paid": true, + "payment_intent": null, + "period_end": 1582133300, + "period_start": 1582133300, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582133300, + "marked_uncollectible_at": null, + "paid_at": 1582133300, + "voided_at": null + }, + "subscription": "sub_GlTIF4mdqfCD3K", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582133308 + }, + { + "id": "in_1GDfKADzYFZjJeDRtZs12b7l", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582067874, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_zEoIn1pNoov3E6Ou6r4oVbt9kV", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_zEoIn1pNoov3E6Ou6r4oVbt9kV/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDfKADzYFZjJeDRGHYqRjxU", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584573174, + "start": 1582067874 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlBhPV1GGj7yK3", + "subscription_item": "si_GlBh2g4znedahj", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDfKADzYFZjJeDRtZs12b7l/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0008", + "paid": true, + "payment_intent": null, + "period_end": 1582067874, + "period_start": 1582067874, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582067874, + "marked_uncollectible_at": null, + "paid_at": 1582067875, + "voided_at": null + }, + "subscription": "sub_GlBhPV1GGj7yK3", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582067876 + }, + { + "id": "in_1GDeqBDzYFZjJeDRVbCjnTRU", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582066015, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_1osQL1WGWfuiE37cZ7OkGxYYkH", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_1osQL1WGWfuiE37cZ7OkGxYYkH/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDeqBDzYFZjJeDRRqeS96KM", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584571315, + "start": 1582066015 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlBCSGqVrCpCzo", + "subscription_item": "si_GlBCwgK9koazse", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDeqBDzYFZjJeDRVbCjnTRU/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0007", + "paid": true, + "payment_intent": null, + "period_end": 1582066015, + "period_start": 1582066015, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582066015, + "marked_uncollectible_at": null, + "paid_at": 1582066016, + "voided_at": null + }, + "subscription": "sub_GlBCSGqVrCpCzo", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582066018 + }, + { + "id": "in_1GDepMDzYFZjJeDRaOCO9OMU", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582065964, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_qXrWhuLLfrF36HiRTP8apK3JbK", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_qXrWhuLLfrF36HiRTP8apK3JbK/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDepMDzYFZjJeDRPVBFZ8xs", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584571264, + "start": 1582065964 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlBBuRPHRwBLOw", + "subscription_item": "si_GlBBtScHFXv3Yr", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDepMDzYFZjJeDRaOCO9OMU/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0006", + "paid": true, + "payment_intent": null, + "period_end": 1582065964, + "period_start": 1582065964, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582065964, + "marked_uncollectible_at": null, + "paid_at": 1582065964, + "voided_at": null + }, + "subscription": "sub_GlBBuRPHRwBLOw", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582065976 + }, + { + "id": "in_1GDemjDzYFZjJeDR7tMDvX3K", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582065801, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_IcGqiQzu5KtI2dRtZQpMDn5OTL", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_IcGqiQzu5KtI2dRtZQpMDn5OTL/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDemjDzYFZjJeDR4FnogVQr", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584571101, + "start": 1582065801 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlB9cNSo0coTLI", + "subscription_item": "si_GlB9l9qhL3AE2Q", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDemjDzYFZjJeDR7tMDvX3K/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0005", + "paid": true, + "payment_intent": null, + "period_end": 1582065801, + "period_start": 1582065801, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582065801, + "marked_uncollectible_at": null, + "paid_at": 1582065801, + "voided_at": null + }, + "subscription": "sub_GlB9cNSo0coTLI", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582065803 + }, + { + "id": "in_1GDemDDzYFZjJeDRGtcrZ1Pz", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582065769, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_Ld0LCENC7okwHhOMWhKQa6FRhK", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_Ld0LCENC7okwHhOMWhKQa6FRhK/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDemDDzYFZjJeDR4jWPn4VJ", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584571069, + "start": 1582065769 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlB8tLfO9NfXFY", + "subscription_item": "si_GlB8SOD5ZD4KDF", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDemDDzYFZjJeDRGtcrZ1Pz/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0004", + "paid": true, + "payment_intent": null, + "period_end": 1582065769, + "period_start": 1582065769, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582065769, + "marked_uncollectible_at": null, + "paid_at": 1582065769, + "voided_at": null + }, + "subscription": "sub_GlB8tLfO9NfXFY", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582065771 + }, + { + "id": "in_1GDelxDzYFZjJeDRAZms22bW", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1582065753, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_5ZxLXNu4gzVzENdYHtFnJsTGPM", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_5ZxLXNu4gzVzENdYHtFnJsTGPM/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDelxDzYFZjJeDRGe7duNko", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB Cloud (at $11.672 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1584571053, + "start": 1582065753 + }, + "plan": { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GlB8xHZn8RSgRA", + "subscription_item": "si_GlB8E5eZBRuAtP", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDelxDzYFZjJeDRAZms22bW/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0003", + "paid": true, + "payment_intent": null, + "period_end": 1582065753, + "period_start": 1582065753, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1582065753, + "marked_uncollectible_at": null, + "paid_at": 1582065753, + "voided_at": null + }, + "subscription": "sub_GlB8xHZn8RSgRA", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1582065755 + }, + { + "id": "in_1GDEmyDzYFZjJeDRSrd8yBJ8", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 43887, + "amount_paid": 43887, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 1, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_cycle", + "charge": "ch_1GDFzvDzYFZjJeDRnJaVK3JI", + "collection_method": "charge_automatically", + "created": 1581965872, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": 0, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_B3J7CEcDPJY1GGi9rPVxaAZtpy", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_B3J7CEcDPJY1GGi9rPVxaAZtpy/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1GDEmyDzYFZjJeDRlPA4VkCr", + "object": "line_item", + "amount": 47087, + "currency": "usd", + "description": "1090 hours × HarperDB Cloud (at $0.4319940823 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1581965572, + "start": 1579287455 + }, + "plan": { + "id": "plan_GZ6IV9XuGlb8a6", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "43.19940823", + "billing_scheme": "per_unit", + "created": 1579280118, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "8GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 1090, + "subscription": "sub_GZ8HPy9YV3jLA0", + "subscription_item": "si_GZ8HaCj22AxFzy", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1GDEmyDzYFZjJeDRSrd8yBJ8/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0002", + "paid": true, + "payment_intent": "pi_1GDFzuDzYFZjJeDR8HakZma4", + "period_end": 1581965855, + "period_start": 1579287455, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": null, + "starting_balance": -3200, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1581970518, + "marked_uncollectible_at": null, + "paid_at": 1581970520, + "voided_at": null + }, + "subscription": "sub_GZ8HPy9YV3jLA0", + "subtotal": 47087, + "tax": null, + "tax_percent": null, + "total": 47087, + "total_tax_amounts": [], + "webhooks_delivered_at": 1581965876 + }, + { + "id": "in_1G200hDzYFZjJeDR6ZHH7yjz", + "object": "invoice", + "account_country": "US", + "account_name": "HarperDB, Inc.", + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": true, + "auto_advance": false, + "billing_reason": "subscription_create", + "charge": null, + "collection_method": "charge_automatically", + "created": 1579287455, + "currency": "usd", + "custom_fields": null, + "customer": "cus_GY4SPXl27SyCPa", + "customer_address": null, + "customer_email": "gkhan@harperdb.io", + "customer_name": "Genghis Khan", + "customer_phone": null, + "customer_shipping": { + "address": { + "city": "", + "country": "", + "line1": "", + "line2": "", + "postal_code": "", + "state": "" + }, + "name": "Genghis Khan", + "phone": "" + }, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "due_date": null, + "ending_balance": -3200, + "footer": null, + "hosted_invoice_url": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_qBh3BJtfiJC1uebvwSUgmtjgTM", + "invoice_pdf": "https://pay.stripe.com/invoice/acct_1G0wyBDzYFZjJeDR/invst_qBh3BJtfiJC1uebvwSUgmtjgTM/pdf", + "lines": { + "object": "list", + "data": [ + { + "id": "il_1G200hDzYFZjJeDRdpbT8u63", + "object": "line_item", + "amount": 0, + "currency": "usd", + "description": "0 hours × HarperDB DBaaS (at $0.4319940823 / month)", + "discountable": true, + "livemode": false, + "metadata": {}, + "period": { + "end": 1581965555, + "start": 1579287455 + }, + "plan": { + "id": "plan_GZ6IV9XuGlb8a6", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": null, + "amount_decimal": "43.19940823", + "billing_scheme": "per_unit", + "created": 1579280118, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "8GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + }, + "proration": false, + "quantity": 0, + "subscription": "sub_GZ8HPy9YV3jLA0", + "subscription_item": "si_GZ8HaCj22AxFzy", + "tax_amounts": [], + "tax_rates": [], + "type": "subscription" + } + ], + "has_more": false, + "total_count": 1, + "url": "/v1/invoices/in_1G200hDzYFZjJeDR6ZHH7yjz/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": "8FA34C0A-0001", + "paid": true, + "payment_intent": null, + "period_end": 1579287455, + "period_start": 1579287455, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "receipt_number": "2963-3654", + "starting_balance": -3200, + "statement_descriptor": null, + "status": "paid", + "status_transitions": { + "finalized_at": 1579287455, + "marked_uncollectible_at": null, + "paid_at": 1579287456, + "voided_at": null + }, + "subscription": "sub_GZ8HPy9YV3jLA0", + "subtotal": 0, + "tax": null, + "tax_percent": null, + "total": 0, + "total_tax_amounts": [], + "webhooks_delivered_at": 1579287456 + } + ] +} diff --git a/mock_data/LMS_API.licenses.json b/mock_data/LMS_API.licenses.json new file mode 100644 index 000000000..492292c20 --- /dev/null +++ b/mock_data/LMS_API.licenses.json @@ -0,0 +1,101 @@ +{ + "statusCode": 200, + "body": [ + { + "license_id": "license-guid-0", + "instance_id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "customer_id": "customer-id-guid", + "version": "2.0.14-BETA", + "exp_date": 1582669908353, + "storage_type": "LMDB", + "ram_allocation": 1, + "fingerprint": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_GoB3yLzygPeGMu", + "stripe_plan_id": "plan_GoB4aP5U6PuR6u" + }, + { + "license_id": "license-guid-1", + "instance_id": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20de", + "customer_id": "customer-id-guid", + "version": "2.0.14-BETA", + "exp_date": 1582669908353, + "storage_type": "LMDB", + "ram_allocation": 1, + "fingerprint": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "plan_GoB54KxG5JRkwm" + }, + { + "license_id": "license-guid-2", + "instance_id": "cee98941-8975-44d6-88e6-9a1a4fa02b25", + "customer_id": "customer-id-guid", + "version": "2.0.14-BETA", + "exp_date": 1582669908353, + "storage_type": "LMDB", + "ram_allocation": 1, + "fingerprint": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "2GB_Beta" + }, + { + "license_id": "license-guid-3", + "instance_id": "a32b2464-b5ca-4b9d-a10f-c6da23a7dcbe", + "customer_id": "customer-id-guid", + "version": "2.0.14-BETA", + "exp_date": 1582669908353, + "storage_type": "LMDB", + "ram_allocation": 1, + "fingerprint": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "4GB_Beta" + }, + { + "license_id": "license-guid-4", + "instance_id": "7a60b51d-7983-4659-a34b-cfb578a4db54", + "customer_id": "customer-id-guid", + "version": "2.0.14-BETA", + "exp_date": 1582669908353, + "storage_type": "LMDB", + "ram_allocation": 1, + "fingerprint": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "8GB_Beta" + }, + { + "license_id": "license-guid-5", + "instance_id": "f0d29404-9fb1-4d66-ab98-41f05e1ac665", + "customer_id": "customer-id-guid", + "version": "2.0.14-BETA", + "exp_date": 1582669908353, + "storage_type": "LMDB", + "ram_allocation": 1, + "fingerprint": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "4GB_Beta" + }, + { + "license_id": "license-guid-6", + "instance_id": "ccf2b958-0b0e-4bf6-a81d-6abee1e4eec5", + "customer_id": "customer-id-guid", + "version": "2.0.14-BETA", + "exp_date": 1582669908353, + "storage_type": "LMDB", + "ram_allocation": 1, + "fingerprint": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "2GB_Beta" + }, + { + "license_id": "license-guid-7", + "instance_id": "8291c224-6911-4155-b5a9-34559e5a45ff", + "customer_id": "customer-id-guid", + "version": "2.0.14-BETA", + "exp_date": 1582669908353, + "storage_type": "LMDB", + "ram_allocation": 1, + "fingerprint": "3f6c9e35-f6a8-4fb7-b09f-8b3e7d4e20df", + "stripe_product_id": "prod_Gh1XXQx6J8YaJl", + "stripe_plan_id": "plan_GoB54KxG5JRkwm" + } + ] +} diff --git a/mock_data/LMS_API.products.json b/mock_data/LMS_API.products.json new file mode 100644 index 000000000..7e32fe390 --- /dev/null +++ b/mock_data/LMS_API.products.json @@ -0,0 +1,352 @@ +{ + "statusCode": 200, + "body": [ + { + "id": "prod_GoUJnVwOYvTjU9", + "object": "product", + "active": true, + "attributes": [], + "caption": null, + "created": 1582829029, + "deactivate_on": [], + "description": null, + "images": [], + "livemode": false, + "metadata": {}, + "name": "HarperDB Cloud Storage", + "package_dimensions": null, + "shippable": null, + "statement_descriptor": null, + "type": "service", + "unit_label": "GB", + "updated": 1582830761, + "url": null, + "plans": [ + { + "id": "plan_GoUmLEBX2KIiaF", + "object": "plan", + "active": true, + "aggregate_usage": null, + "amount": "$0.00", + "amount_decimal": null, + "billing_scheme": "tiered", + "created": 1582830760, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "General Purpose SSD", + "product": "prod_GoUJnVwOYvTjU9", + "tiers": [ + { + "flat_amount": null, + "flat_amount_decimal": null, + "unit_amount": 0, + "unit_amount_decimal": "0", + "up_to": 10 + }, + { + "flat_amount": null, + "flat_amount_decimal": null, + "unit_amount": 25, + "unit_amount_decimal": "25", + "up_to": null + } + ], + "tiers_mode": "graduated", + "transform_usage": null, + "trial_period_days": null, + "usage_type": "licensed" + } + ] + }, + { + "id": "prod_GoB3yLzygPeGMu", + "object": "product", + "active": true, + "attributes": [], + "caption": null, + "created": 1582757367, + "deactivate_on": [], + "description": null, + "images": [], + "livemode": false, + "metadata": {}, + "name": "HarperDB Local Annual", + "package_dimensions": null, + "shippable": null, + "statement_descriptor": null, + "type": "service", + "unit_label": null, + "updated": 1582829172, + "url": null, + "plans": [ + { + "id": "plan_GoB4aP5U6PuR6u", + "object": "plan", + "active": true, + "aggregate_usage": null, + "amount": "$0.00", + "amount_decimal": "0", + "billing_scheme": "per_unit", + "created": 1582757478, + "currency": "usd", + "interval": "year", + "interval_count": 1, + "livemode": false, + "metadata": { + "instance_ram": "1GB" + }, + "nickname": "1GB", + "product": "prod_GoB3yLzygPeGMu", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "licensed" + }, + { + "id": "plan_GoB35E9tX0o6sq", + "object": "plan", + "active": true, + "aggregate_usage": null, + "amount": "$191.90", + "amount_decimal": "19190", + "billing_scheme": "per_unit", + "created": 1582757416, + "currency": "usd", + "interval": "year", + "interval_count": 1, + "livemode": false, + "metadata": { + "instance_ram": "2GB" + }, + "nickname": "2GB", + "product": "prod_GoB3yLzygPeGMu", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "licensed" + }, + { + "id": "plan_GoB4qG61roJhhk", + "object": "plan", + "active": true, + "aggregate_usage": null, + "amount": "$575.90", + "amount_decimal": "57590", + "billing_scheme": "per_unit", + "created": 1582757440, + "currency": "usd", + "interval": "year", + "interval_count": 1, + "livemode": false, + "metadata": { + "instance_ram": "4GB" + }, + "nickname": "4GB", + "product": "prod_GoB3yLzygPeGMu", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "licensed" + }, + { + "id": "plan_GoB47PZG32KA2I", + "object": "plan", + "active": true, + "aggregate_usage": null, + "amount": "$1681.92", + "amount_decimal": "168192", + "billing_scheme": "per_unit", + "created": 1582757462, + "currency": "usd", + "interval": "year", + "interval_count": 1, + "livemode": false, + "metadata": { + "instance_ram": "8GB" + }, + "nickname": "8GB", + "product": "prod_GoB3yLzygPeGMu", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "licensed" + } + ] + }, + { + "id": "prod_Gh1XXQx6J8YaJl", + "object": "product", + "active": true, + "attributes": [], + "caption": null, + "created": 1581107534, + "deactivate_on": [], + "description": null, + "images": [], + "livemode": false, + "metadata": {}, + "name": "HarperDB Cloud Beta", + "package_dimensions": null, + "shippable": null, + "statement_descriptor": null, + "type": "service", + "unit_label": null, + "updated": 1582829185, + "url": null, + "plans": [ + { + "id": "plan_GoB54KxG5JRkwm", + "object": "plan", + "active": true, + "aggregate_usage": null, + "amount": "$0.00", + "amount_decimal": "0", + "billing_scheme": "per_unit", + "created": 1582757496, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": { + "instance_ram": "1GB", + "instance_type": "t3.micro" + }, + "nickname": "1GB", + "product": "prod_Gh1XXQx6J8YaJl", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "licensed" + }, + { + "id": "2GB_Beta", + "object": "plan", + "active": true, + "aggregate_usage": null, + "amount": "$19.99", + "amount_decimal": "1999", + "billing_scheme": "per_unit", + "created": 1581107607, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": { + "instance_type": "t3.medium", + "instance_ram": "2GB" + }, + "nickname": "2GB", + "product": "prod_Gh1XXQx6J8YaJl", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "licensed" + }, + { + "id": "4GB_Beta", + "object": "plan", + "active": true, + "aggregate_usage": null, + "amount": "$59.99", + "amount_decimal": "5999", + "billing_scheme": "per_unit", + "created": 1581377198, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": { + "instance_type": "t3.medium", + "instance_ram": "4GB" + }, + "nickname": "4GB", + "product": "prod_Gh1XXQx6J8YaJl", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "licensed" + }, + { + "id": "8GB_Beta", + "object": "plan", + "active": true, + "aggregate_usage": null, + "amount": "$175.20", + "amount_decimal": "17520", + "billing_scheme": "per_unit", + "created": 1581377234, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": { + "instance_type": "m5.large", + "instance_ram": "8GB" + }, + "nickname": "8GB", + "product": "prod_Gh1XXQx6J8YaJl", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "licensed" + } + ] + }, + { + "id": "prod_GZ5dZoytHIPTfD", + "object": "product", + "active": true, + "attributes": [], + "caption": null, + "created": 1579277621, + "deactivate_on": [], + "description": null, + "images": [], + "livemode": false, + "metadata": {}, + "name": "HarperDB Cloud", + "package_dimensions": null, + "shippable": null, + "statement_descriptor": "HarperDB DBaaS", + "type": "service", + "unit_label": "hours", + "updated": 1582829183, + "url": null, + "plans": [ + { + "id": "plan_GahFKupGaOFIuk", + "object": "plan", + "active": true, + "aggregate_usage": "sum", + "amount": "$0.00", + "amount_decimal": "1167.2", + "billing_scheme": "per_unit", + "created": 1579648193, + "currency": "usd", + "interval": "month", + "interval_count": 1, + "livemode": false, + "metadata": {}, + "nickname": "256GB", + "product": "prod_GZ5dZoytHIPTfD", + "tiers": null, + "tiers_mode": null, + "transform_usage": null, + "trial_period_days": null, + "usage_type": "metered" + } + ] + } + ] +} diff --git a/mock_data/LMS_API.user.json b/mock_data/LMS_API.user.json new file mode 100644 index 000000000..6bbfec9dd --- /dev/null +++ b/mock_data/LMS_API.user.json @@ -0,0 +1,10 @@ +{ + "statusCode": 200, + "body": { + "id": "user-id-guid1", + "firstname": "First1", + "lastname": "Last1", + "email": "user1@harperdb.io", + "customer_id": "customer-id-guid" + } +} diff --git a/package-lock.json b/package-lock.json index 2a722f02f..2ffb9daab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,13 @@ { "name": "harperdb-studio", - "version": "2.0.0", + "version": "3.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/cli": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.8.3.tgz", - "integrity": "sha512-K2UXPZCKMv7KwWy9Bl4sa6+jTNP7JyDiHKzoOiUUygaEDbC60vaargZDnO9oFMvlq8pIKOOyUUgeMYrsaN9djA==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.8.4.tgz", + "integrity": "sha512-XXLgAm6LBbaNxaGhMAznXXaxtCWfuv6PIDJ9Alsy9JYTOh+j2jJz+L/162kkfU1j/pTSxK1xGmlwI4pdIMkoag==", "dev": true, "requires": { "chokidar": "^2.1.8", @@ -22,9 +22,9 @@ }, "dependencies": { "commander": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.0.tgz", - "integrity": "sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true } } @@ -39,43 +39,43 @@ } }, "@babel/compat-data": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.8.1.tgz", - "integrity": "sha512-Z+6ZOXvyOWYxJ50BwxzdhRnRsGST8Y3jaZgxYig575lTjVSs3KtJnmESwZegg6e2Dn0td1eDhoWlp1wI4BTCPw==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.8.6.tgz", + "integrity": "sha512-CurCIKPTkS25Mb8mz267vU95vy+TyUpnctEX2lV33xWNmHAfjruztgiPBbXZRh3xZZy1CYvGx6XfxyTVS+sk7Q==", "dev": true, "requires": { - "browserslist": "^4.8.2", + "browserslist": "^4.8.5", "invariant": "^2.2.4", "semver": "^5.5.0" }, "dependencies": { "browserslist": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.5.tgz", - "integrity": "sha512-4LMHuicxkabIB+n9874jZX/az1IaZ5a+EUuvD7KFOu9x/Bd5YHyO0DIz2ls/Kl8g0ItS4X/ilEgf4T1Br0lgSg==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.0.tgz", + "integrity": "sha512-seffIXhwgB84+OCeT/aMjpZnsAsYDiMSC+CEs3UkF8iU64BZGYcu+TZYs/IBpo4nRi0vJywUJWYdbTsOhFTweg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001022", - "electron-to-chromium": "^1.3.338", - "node-releases": "^1.1.46" + "caniuse-lite": "^1.0.30001030", + "electron-to-chromium": "^1.3.361", + "node-releases": "^1.1.50" } }, "caniuse-lite": { - "version": "1.0.30001022", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001022.tgz", - "integrity": "sha512-FjwPPtt/I07KyLPkBQ0g7/XuZg6oUkYBVnPHNj3VHJbOjmmJ/GdSo/GUY6MwINEQvjhP6WZVbX8Tvms8xh0D5A==", + "version": "1.0.30001030", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001030.tgz", + "integrity": "sha512-QGK0W4Ft/Ac+zTjEiRJfwDNATvS3fodDczBXrH42784kcfqcDKpEPfN08N0HQjrAp8He/Jw8QiSS9QRn7XAbUw==", "dev": true }, "electron-to-chromium": { - "version": "1.3.339", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.339.tgz", - "integrity": "sha512-C1i/vH6/kQx9YV8RddMkmW216GwW4pTrnYIlKmDFIqXA4fPwqDxIdGyHsuG+fgurHoljRz7/oaD+tztcryW/9g==", + "version": "1.3.363", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.363.tgz", + "integrity": "sha512-4w19wPBkeunBjOA53lNFT36IdOD3Tk1OoIDtTX+VToJUUDX42QfuhtsNKXv25wmSnoBOExM3kTbj7/WDNBwHuQ==", "dev": true }, "node-releases": { - "version": "1.1.47", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.47.tgz", - "integrity": "sha512-k4xjVPx5FpwBUj0Gw7uvFOTF4Ep8Hok1I6qjwL3pLfwe7Y0REQSAqOwwv9TWBCUtMHxcXfY4PgRLRozcChvTcA==", + "version": "1.1.50", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.50.tgz", + "integrity": "sha512-lgAmPv9eYZ0bGwUYAKlr8MG6K4CvWliWqnkcT2P8mMAgVrH3lqfBPorFlxiG1pHQnqmavJZ9vbMXUTNyMLbrgQ==", "dev": true, "requires": { "semver": "^6.3.0" @@ -92,18 +92,18 @@ } }, "@babel/core": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz", - "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.6.tgz", + "integrity": "sha512-Sheg7yEJD51YHAvLEV/7Uvw95AeWqYPL3Vk3zGujJKIhJ+8oLw2ALaf3hbucILhKsgSoADOvtKRJuNVdcJkOrg==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helpers": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3", + "@babel/generator": "^7.8.6", + "@babel/helpers": "^7.8.4", + "@babel/parser": "^7.8.6", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.6", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -123,47 +123,6 @@ "@babel/highlight": "^7.8.3" } }, - "@babel/generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", - "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, "@babel/highlight": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", @@ -175,40 +134,6 @@ "js-tokens": "^4.0.0" } }, - "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/traverse": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", - "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -256,23 +181,15 @@ } }, "@babel/generator": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.0.tgz", - "integrity": "sha512-1wdJ6UxHyL1XoJQ119JmvuRX27LRih7iYStMPZOWAjQqeAabFg3dYXKMpgihma+to+0ADsTVVt6oRyUxWZw6Mw==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.6.tgz", + "integrity": "sha512-4bpOR5ZBz+wWcMeVtcf7FbjcFzCp+817z2/gHNncIRcM9MmKzUhtWCYAq27RAfUrAFwb+OCG1s9WEaVxfi6cjg==", "dev": true, "requires": { - "@babel/types": "^7.7.0", + "@babel/types": "^7.8.6", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, "@babel/helper-annotate-as-pure": { @@ -313,189 +230,48 @@ "@babel/helper-hoist-variables": "^7.8.3", "@babel/traverse": "^7.8.3", "@babel/types": "^7.8.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", - "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/traverse": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", - "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@babel/helper-compilation-targets": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.3.tgz", - "integrity": "sha512-JLylPCsFjhLN+6uBSSh3iYdxKdeO9MNmoY96PE/99d8kyBFaXLORtAVhqN6iHa+wtPeqxKLghDOZry0+Aiw9Tw==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.6.tgz", + "integrity": "sha512-UrJdk27hKVJSnibFcUWYLkCL0ZywTUoot8yii1lsHJcvwrypagmYKjHLMWivQPm4s6GdyygCL8fiH5EYLxhQwQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.8.1", - "browserslist": "^4.8.2", + "@babel/compat-data": "^7.8.6", + "browserslist": "^4.8.5", "invariant": "^2.2.4", - "levenary": "^1.1.0", + "levenary": "^1.1.1", "semver": "^5.5.0" }, "dependencies": { "browserslist": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.5.tgz", - "integrity": "sha512-4LMHuicxkabIB+n9874jZX/az1IaZ5a+EUuvD7KFOu9x/Bd5YHyO0DIz2ls/Kl8g0ItS4X/ilEgf4T1Br0lgSg==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.0.tgz", + "integrity": "sha512-seffIXhwgB84+OCeT/aMjpZnsAsYDiMSC+CEs3UkF8iU64BZGYcu+TZYs/IBpo4nRi0vJywUJWYdbTsOhFTweg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001022", - "electron-to-chromium": "^1.3.338", - "node-releases": "^1.1.46" + "caniuse-lite": "^1.0.30001030", + "electron-to-chromium": "^1.3.361", + "node-releases": "^1.1.50" } }, "caniuse-lite": { - "version": "1.0.30001022", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001022.tgz", - "integrity": "sha512-FjwPPtt/I07KyLPkBQ0g7/XuZg6oUkYBVnPHNj3VHJbOjmmJ/GdSo/GUY6MwINEQvjhP6WZVbX8Tvms8xh0D5A==", + "version": "1.0.30001030", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001030.tgz", + "integrity": "sha512-QGK0W4Ft/Ac+zTjEiRJfwDNATvS3fodDczBXrH42784kcfqcDKpEPfN08N0HQjrAp8He/Jw8QiSS9QRn7XAbUw==", "dev": true }, "electron-to-chromium": { - "version": "1.3.339", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.339.tgz", - "integrity": "sha512-C1i/vH6/kQx9YV8RddMkmW216GwW4pTrnYIlKmDFIqXA4fPwqDxIdGyHsuG+fgurHoljRz7/oaD+tztcryW/9g==", + "version": "1.3.363", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.363.tgz", + "integrity": "sha512-4w19wPBkeunBjOA53lNFT36IdOD3Tk1OoIDtTX+VToJUUDX42QfuhtsNKXv25wmSnoBOExM3kTbj7/WDNBwHuQ==", "dev": true }, "node-releases": { - "version": "1.1.47", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.47.tgz", - "integrity": "sha512-k4xjVPx5FpwBUj0Gw7uvFOTF4Ep8Hok1I6qjwL3pLfwe7Y0REQSAqOwwv9TWBCUtMHxcXfY4PgRLRozcChvTcA==", + "version": "1.1.50", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.50.tgz", + "integrity": "sha512-lgAmPv9eYZ0bGwUYAKlr8MG6K4CvWliWqnkcT2P8mMAgVrH3lqfBPorFlxiG1pHQnqmavJZ9vbMXUTNyMLbrgQ==", "dev": true, "requires": { "semver": "^6.3.0" @@ -512,11 +288,12 @@ } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.3.tgz", - "integrity": "sha512-Gcsm1OHCUr9o9TcJln57xhWHtdXbA2pgQ58S0Lxlks0WMGNXuki4+GLfX0p+L2ZkINUGZvfkz8rzoqJQSthI+Q==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.6.tgz", + "integrity": "sha512-bPyujWfsHhV/ztUkwGHz/RPV1T1TDEsSZDsN42JPehndA+p1KKTh3npvTadux0ZhCrytx9tvjpWNowKby3tM6A==", "dev": true, "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", "@babel/helper-regex": "^7.8.3", "regexpu-core": "^4.6.0" } @@ -530,94 +307,6 @@ "@babel/helper-function-name": "^7.8.3", "@babel/types": "^7.8.3", "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@babel/helper-explode-assignable-expression": { @@ -628,167 +317,26 @@ "requires": { "@babel/traverse": "^7.8.3", "@babel/types": "^7.8.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", - "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/traverse": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", - "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@babel/helper-function-name": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz", - "integrity": "sha512-tDsJgMUAP00Ugv8O2aGEua5I2apkaQO7lBGUq1ocwN3G23JE5Dcq0uh3GvFTChPa4b40AWiAsLvCZOA2rdnQ7Q==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.7.0", - "@babel/template": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" } }, "@babel/helper-get-function-arity": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz", - "integrity": "sha512-tLdojOTz4vWcEnHWHCuPN5P85JLZWbm5Fx5ZsMEMPhF3Uoe3O7awrbM2nQ04bDOUToH/2tH/ezKEOR8zEYzqyw==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", "dev": true, "requires": { - "@babel/types": "^7.7.0" + "@babel/types": "^7.8.3" } }, "@babel/helper-hoist-variables": { @@ -819,94 +367,18 @@ } }, "@babel/helper-module-transforms": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.3.tgz", - "integrity": "sha512-C7NG6B7vfBa/pwCOshpMbOYUmrYQDfCpVL/JCRu0ek8B5p8kue1+BCXpg2vOYs7w5ACB9GTOBYQ5U6NwrMg+3Q==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.6.tgz", + "integrity": "sha512-RDnGJSR5EFBJjG3deY0NiL0K9TO8SXxS9n/MPsbPK/s9LbQymuLNtlzvDiNS7IpecuL45cMeLVkA+HfmlrnkRg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", "@babel/helper-simple-access": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.8.6", "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@babel/helper-optimise-call-expression": { @@ -933,705 +405,73 @@ "lodash": "^4.17.13" } }, - "@babel/helper-remap-async-to-generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", - "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.8.3", - "@babel/helper-wrap-function": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", - "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/traverse": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", - "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helper-replace-supers": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.3.tgz", - "integrity": "sha512-xOUssL6ho41U81etpLoT2RTdvdus4VfHamCuAm4AHxGr+0it5fnwoVdwUJ7GFEqCsQYzJUhcbsN9wB9apcYKFA==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", - "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/traverse": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", - "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helper-simple-access": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", - "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", - "dev": true, - "requires": { - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz", - "integrity": "sha512-HgYSI8rH08neWlAH3CcdkFg9qX9YsZysZI5GD8LjhQib/mM0jGOZOVkoUiiV2Hu978fRtjtsGsW6w0pKHUWtqA==", - "dev": true, - "requires": { - "@babel/types": "^7.7.0" - } - }, - "@babel/helper-wrap-function": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", - "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", - "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/traverse": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", - "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helpers": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.3.tgz", - "integrity": "sha512-LmU3q9Pah/XyZU89QvBgGt+BCsTPoQa+73RxAQh8fb8qkDyIfeQnmgs+hvzhTCKTzqOyk7JTkS3MS1S8Mq5yrQ==", - "dev": true, - "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", - "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/traverse": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", - "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, + "@babel/helper-remap-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", + "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-wrap-function": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-replace-supers": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz", + "integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-wrap-function": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", + "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helpers": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", + "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3" + } + }, "@babel/highlight": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", @@ -1675,9 +515,9 @@ } }, "@babel/parser": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.0.tgz", - "integrity": "sha512-GqL+Z0d7B7ADlQBMXlJgvXEbtt5qlqd1YQ5fr12hTSfh7O/vgrEIvJxU2e7aSVrEUn75zTZ6Nd0s8tthrlZnrQ==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.6.tgz", + "integrity": "sha512-trGNYSfwq5s0SgM1BMEB8hX3NDmO7EP2wsDGDexiaKMB92BaRpS+qZfpkMqUBhcsOTBwNy9B/jieo4ad/t/z2g==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -1882,9 +722,9 @@ } }, "@babel/plugin-transform-classes": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.3.tgz", - "integrity": "sha512-SjT0cwFJ+7Rbr1vQsvphAHwUHvSUPmMjMU/0P59G8U2HLFqSa082JO7zkbDNWs9kH/IUqpHI6xWNesGf8haF1w==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.6.tgz", + "integrity": "sha512-k9r8qRay/R6v5aWZkrEclEhKO6mc1CCQr2dLsVHBmOQiMpN6I2bpjX3vgnldUWeEI1GHVNByULVxZ4BdP4Hmdg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", @@ -1892,106 +732,9 @@ "@babel/helper-function-name": "^7.8.3", "@babel/helper-optimise-call-expression": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", "@babel/helper-split-export-declaration": "^7.8.3", "globals": "^11.1.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@babel/plugin-transform-computed-properties": { @@ -2042,9 +785,9 @@ } }, "@babel/plugin-transform-for-of": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.3.tgz", - "integrity": "sha512-ZjXznLNTxhpf4Q5q3x1NsngzGA38t9naWH8Gt+0qYZEJAcvPI9waSStSh56u19Ofjr7QmD0wUsQ8hw8s/p1VnA==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.6.tgz", + "integrity": "sha512-M0pw4/1/KI5WAxPsdcUL/w2LJ7o89YHN3yLkzNjg7Yl15GlVGgzHyCU+FMeAxevHGsLVmUqbirlUIKTafPmzdw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" @@ -2058,94 +801,6 @@ "requires": { "@babel/helper-function-name": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", - "dev": true - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@babel/plugin-transform-literals": { @@ -2240,25 +895,14 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.3.tgz", - "integrity": "sha512-/pqngtGb54JwMBZ6S/D3XYylQDFtGjWrnoCF4gXZOUpFV/ujbxnoNGNvDGu6doFWRPBveE72qTx/RRU44j5I/Q==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.4.tgz", + "integrity": "sha512-IsS3oTxeTsZlE5KqzTbcC2sV0P9pXdec53SU+Yxv7o/6dvGM5AkTotQKhoSffhNgZ/dftsSiOoxy7evCYJXzVA==", "dev": true, "requires": { "@babel/helper-call-delegate": "^7.8.3", "@babel/helper-get-function-arity": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3" - }, - "dependencies": { - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - } } }, "@babel/plugin-transform-property-literals": { @@ -2367,9 +1011,9 @@ } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.3.tgz", - "integrity": "sha512-3TrkKd4LPqm4jHs6nPtSDI/SV9Cm5PRJkHLUgTcqRQQTMAZ44ZaAdDZJtvWFSaRcvT0a1rTmJ5ZA5tDKjleF3g==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", + "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" @@ -2396,13 +1040,13 @@ } }, "@babel/preset-env": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.3.tgz", - "integrity": "sha512-Rs4RPL2KjSLSE2mWAx5/iCH+GC1ikKdxPrhnRS6PfFVaiZeom22VFKN4X8ZthyN61kAaR05tfXTbCvatl9WIQg==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.6.tgz", + "integrity": "sha512-M5u8llV9DIVXBFB/ArIpqJuvXpO+ymxcJ6e8ZAmzeK3sQeBNOD1y+rHvHCGG4TlEmsNpIrdecsHGHT8ZCoOSJg==", "dev": true, "requires": { - "@babel/compat-data": "^7.8.0", - "@babel/helper-compilation-targets": "^7.8.3", + "@babel/compat-data": "^7.8.6", + "@babel/helper-compilation-targets": "^7.8.6", "@babel/helper-module-imports": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-proposal-async-generator-functions": "^7.8.3", @@ -2425,13 +1069,13 @@ "@babel/plugin-transform-async-to-generator": "^7.8.3", "@babel/plugin-transform-block-scoped-functions": "^7.8.3", "@babel/plugin-transform-block-scoping": "^7.8.3", - "@babel/plugin-transform-classes": "^7.8.3", + "@babel/plugin-transform-classes": "^7.8.6", "@babel/plugin-transform-computed-properties": "^7.8.3", "@babel/plugin-transform-destructuring": "^7.8.3", "@babel/plugin-transform-dotall-regex": "^7.8.3", "@babel/plugin-transform-duplicate-keys": "^7.8.3", "@babel/plugin-transform-exponentiation-operator": "^7.8.3", - "@babel/plugin-transform-for-of": "^7.8.3", + "@babel/plugin-transform-for-of": "^7.8.6", "@babel/plugin-transform-function-name": "^7.8.3", "@babel/plugin-transform-literals": "^7.8.3", "@babel/plugin-transform-member-expression-literals": "^7.8.3", @@ -2442,7 +1086,7 @@ "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", "@babel/plugin-transform-new-target": "^7.8.3", "@babel/plugin-transform-object-super": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.8.4", "@babel/plugin-transform-property-literals": "^7.8.3", "@babel/plugin-transform-regenerator": "^7.8.3", "@babel/plugin-transform-reserved-words": "^7.8.3", @@ -2450,43 +1094,43 @@ "@babel/plugin-transform-spread": "^7.8.3", "@babel/plugin-transform-sticky-regex": "^7.8.3", "@babel/plugin-transform-template-literals": "^7.8.3", - "@babel/plugin-transform-typeof-symbol": "^7.8.3", + "@babel/plugin-transform-typeof-symbol": "^7.8.4", "@babel/plugin-transform-unicode-regex": "^7.8.3", - "@babel/types": "^7.8.3", - "browserslist": "^4.8.2", + "@babel/types": "^7.8.6", + "browserslist": "^4.8.5", "core-js-compat": "^3.6.2", "invariant": "^2.2.2", - "levenary": "^1.1.0", + "levenary": "^1.1.1", "semver": "^5.5.0" }, "dependencies": { "browserslist": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.5.tgz", - "integrity": "sha512-4LMHuicxkabIB+n9874jZX/az1IaZ5a+EUuvD7KFOu9x/Bd5YHyO0DIz2ls/Kl8g0ItS4X/ilEgf4T1Br0lgSg==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.0.tgz", + "integrity": "sha512-seffIXhwgB84+OCeT/aMjpZnsAsYDiMSC+CEs3UkF8iU64BZGYcu+TZYs/IBpo4nRi0vJywUJWYdbTsOhFTweg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001022", - "electron-to-chromium": "^1.3.338", - "node-releases": "^1.1.46" + "caniuse-lite": "^1.0.30001030", + "electron-to-chromium": "^1.3.361", + "node-releases": "^1.1.50" } }, "caniuse-lite": { - "version": "1.0.30001022", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001022.tgz", - "integrity": "sha512-FjwPPtt/I07KyLPkBQ0g7/XuZg6oUkYBVnPHNj3VHJbOjmmJ/GdSo/GUY6MwINEQvjhP6WZVbX8Tvms8xh0D5A==", + "version": "1.0.30001030", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001030.tgz", + "integrity": "sha512-QGK0W4Ft/Ac+zTjEiRJfwDNATvS3fodDczBXrH42784kcfqcDKpEPfN08N0HQjrAp8He/Jw8QiSS9QRn7XAbUw==", "dev": true }, "electron-to-chromium": { - "version": "1.3.339", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.339.tgz", - "integrity": "sha512-C1i/vH6/kQx9YV8RddMkmW216GwW4pTrnYIlKmDFIqXA4fPwqDxIdGyHsuG+fgurHoljRz7/oaD+tztcryW/9g==", + "version": "1.3.363", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.363.tgz", + "integrity": "sha512-4w19wPBkeunBjOA53lNFT36IdOD3Tk1OoIDtTX+VToJUUDX42QfuhtsNKXv25wmSnoBOExM3kTbj7/WDNBwHuQ==", "dev": true }, "node-releases": { - "version": "1.1.47", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.47.tgz", - "integrity": "sha512-k4xjVPx5FpwBUj0Gw7uvFOTF4Ep8Hok1I6qjwL3pLfwe7Y0REQSAqOwwv9TWBCUtMHxcXfY4PgRLRozcChvTcA==", + "version": "1.1.50", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.50.tgz", + "integrity": "sha512-lgAmPv9eYZ0bGwUYAKlr8MG6K4CvWliWqnkcT2P8mMAgVrH3lqfBPorFlxiG1pHQnqmavJZ9vbMXUTNyMLbrgQ==", "dev": true, "requires": { "semver": "^6.3.0" @@ -2516,41 +1160,132 @@ } }, "@babel/runtime": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", - "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.4.tgz", + "integrity": "sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ==", "requires": { "regenerator-runtime": "^0.13.2" } }, "@babel/template": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.0.tgz", - "integrity": "sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0" + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "@babel/traverse": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.0.tgz", - "integrity": "sha512-ea/3wRZc//e/uwCpuBX2itrhI0U9l7+FsrKWyKGNyvWbuMcCG7ATKY2VI4wlg2b2TA39HHwIxnvmXvtiKsyn7w==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", + "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", "dev": true, "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.0", - "@babel/helper-function-name": "^7.7.0", - "@babel/helper-split-export-declaration": "^7.7.0", - "@babel/parser": "^7.7.0", - "@babel/types": "^7.7.0", + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.6", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" }, "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -2565,13 +1300,22 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, "@babel/types": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", - "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.6.tgz", + "integrity": "sha512-wqz7pgWMIrht3gquyEFPVXeXCti72Rm8ep9b5tQKz9Yg9LzJA3HxosF1SB3Kc81KD1A3XBkkVYtJvCKS2Z/QrA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -2590,31 +1334,28 @@ } }, "@nio/ui-kit": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@nio/ui-kit/-/ui-kit-2.1.2.tgz", - "integrity": "sha512-uglIDEjGU4fV3LZOEU7Gzucth4AXSSFZldUlAfWMPYK7pTN1x4oU39UHZLDrQEAl7m52Btk19FQVchE92JDuLw==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@nio/ui-kit/-/ui-kit-2.2.2.tgz", + "integrity": "sha512-PgpxCmi0v95S5xQdp4yRXqNTs1cgT96bwZZd80HZncJdBvV0F0CokrSzaUPXyUfweHxwHNGa/0ouO5SvYlR6iw==", "requires": { "@nio/icons": "^1.10.0", - "apexcharts": "^3.11.1", + "apexcharts": "^3.15.6", "bootstrap": "4.4.1", - "highlight.js": "^9.17.1", - "node-sass": "^4.13.0", - "node-sass-import": "^2.0.1", + "highlight.js": "^9.18.1", + "node-sass": "^4.13.1", "node-sass-magic-importer": "^5.3.2", - "prop-types": "^15.7.2", + "prop-types": "*", "react": "^16.12.0", - "react-apexcharts": "^1.3.3", + "react-apexcharts": "^1.3.6", "react-clock": "^2.4.0", - "react-css-themr": "^2.1.2", "react-dom": "^16.12.0", - "react-motion": "^0.5.2", "react-rangeslider": "^2.2.0", - "react-toggle-button": "^2.2.0", - "reactstrap": "^8.2.0" + "react-toggle": "^4.1.1", + "reactstrap": "^8.4.1" }, "dependencies": { "@babel/runtime": { - "version": "7.7.7", + "version": "7.8.4", "bundled": true, "requires": { "regenerator-runtime": "^0.13.2" @@ -2625,10 +1366,9 @@ "bundled": true }, "apexcharts": { - "version": "3.11.1", + "version": "3.15.6", "bundled": true, "requires": { - "promise-polyfill": "8.1.0", "svg.draggable.js": "^2.2.2", "svg.easing.js": "^2.0.0", "svg.filter.js": "^2.0.2", @@ -2687,22 +1427,6 @@ "version": "1.0.0", "bundled": true }, - "handlebars": { - "version": "4.5.3", - "bundled": true, - "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true - } - } - }, "has": { "version": "1.0.3", "bundled": true, @@ -2715,23 +1439,9 @@ "bundled": true }, "highlight.js": { - "version": "9.17.1", - "bundled": true, - "requires": { - "handlebars": "^4.5.3" - } - }, - "hoist-non-react-statics": { - "version": "1.2.0", + "version": "9.18.1", "bundled": true }, - "invariant": { - "version": "2.2.2", - "bundled": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, "is-arguments": { "version": "1.0.4", "bundled": true @@ -2773,14 +1483,6 @@ "version": "1.2.0", "bundled": true }, - "minimist": { - "version": "0.0.8", - "bundled": true - }, - "neo-async": { - "version": "2.6.1", - "bundled": true - }, "object-assign": { "version": "4.1.1", "bundled": true @@ -2807,30 +1509,8 @@ "object-keys": "^1.0.11" } }, - "optimist": { - "version": "0.6.1", - "bundled": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "bundled": true - } - } - }, - "performance-now": { - "version": "0.2.0", - "bundled": true - }, "popper.js": { - "version": "1.16.0", - "bundled": true - }, - "promise-polyfill": { - "version": "8.1.0", + "version": "1.16.1", "bundled": true }, "prop-types": { @@ -2851,19 +1531,6 @@ } } }, - "raf": { - "version": "3.4.0", - "bundled": true, - "requires": { - "performance-now": "^2.1.0" - }, - "dependencies": { - "performance-now": { - "version": "2.1.0", - "bundled": true - } - } - }, "react": { "version": "16.12.0", "bundled": true, @@ -2874,7 +1541,7 @@ } }, "react-apexcharts": { - "version": "1.3.3", + "version": "1.3.6", "bundled": true, "requires": { "prop-types": "^15.5.7" @@ -2888,14 +1555,6 @@ "prop-types": "^15.6.0" } }, - "react-css-themr": { - "version": "2.1.2", - "bundled": true, - "requires": { - "hoist-non-react-statics": "^1.2.0", - "invariant": "^2.2.1" - } - }, "react-dom": { "version": "16.12.0", "bundled": true, @@ -2914,15 +1573,6 @@ "version": "3.0.4", "bundled": true }, - "react-motion": { - "version": "0.5.2", - "bundled": true, - "requires": { - "performance-now": "^0.2.0", - "prop-types": "^15.5.8", - "raf": "^3.1.0" - } - }, "react-popper": { "version": "1.3.7", "bundled": true, @@ -2944,12 +1594,11 @@ "resize-observer-polyfill": "^1.4.2" } }, - "react-toggle-button": { - "version": "2.2.0", + "react-toggle": { + "version": "4.1.1", "bundled": true, "requires": { - "prop-types": "^15.6.0", - "react-motion": "^0.5.2" + "classnames": "^2.2.5" } }, "react-transition-group": { @@ -2972,14 +1621,14 @@ } }, "reactstrap": { - "version": "8.2.0", + "version": "8.4.1", "bundled": true, "requires": { "@babel/runtime": "^7.2.0", "classnames": "^2.2.3", "prop-types": "^15.5.8", "react-lifecycles-compat": "^3.0.4", - "react-popper": "^1.3.3", + "react-popper": "^1.3.6", "react-transition-group": "^2.3.1" } }, @@ -2996,20 +1645,20 @@ }, "dependencies": { "es-abstract": { - "version": "1.17.0-next.1", + "version": "1.17.4", "bundled": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" } }, "es-to-primitive": { @@ -3024,6 +1673,17 @@ "has-symbols": { "version": "1.0.1", "bundled": true + }, + "is-callable": { + "version": "1.1.5", + "bundled": true + }, + "is-regex": { + "version": "1.0.5", + "bundled": true, + "requires": { + "has": "^1.0.3" + } } } }, @@ -3106,27 +1766,6 @@ "version": "0.0.7", "bundled": true }, - "uglify-js": { - "version": "3.7.2", - "bundled": true, - "optional": true, - "requires": { - "commander": "~2.20.3", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "bundled": true, - "optional": true - }, - "source-map": { - "version": "0.6.1", - "bundled": true, - "optional": true - } - } - }, "warning": { "version": "4.0.3", "bundled": true, @@ -3141,6 +1780,19 @@ "resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz", "integrity": "sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q==" }, + "@stripe/react-stripe-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-1.0.3.tgz", + "integrity": "sha512-9E0HRAyd95B1jSS+nh5ol4M5RvQUnWTCB+Td9xKKa68OrEvmRqpNy/wvMyY9SGCy7fcMkZfiST9Oy09OkkDM/A==", + "requires": { + "prop-types": "^15.7.2" + } + }, + "@stripe/stripe-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-1.0.2.tgz", + "integrity": "sha512-YZNXVFCDSvjjE7aPP78qUt4cBrHlrj97Q/uXgrZbjDwJdPJYXv31EQGgBblbDjdIeq+kPfmZixulc/Hn1LZqJQ==" + }, "@testing-library/dom": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-6.11.0.tgz", @@ -3315,6 +1967,14 @@ "@types/react": "*" } }, + "@types/react-table": { + "version": "6.8.6", + "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-6.8.6.tgz", + "integrity": "sha512-mCgyjD1KiMfZMHixOEzv7qXh5TSfmvgNbOb8qKLcTJbnGgsVSalcEdrNqASyaMp79MvdbMzxAcFQ3lftzmH7MA==", + "requires": { + "@types/react": "*" + } + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -3988,14 +2648,6 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", - "requires": { - "lodash": "^4.14.0" - } - }, "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", @@ -4020,120 +2672,8 @@ }, "atob": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" - }, - "autoprefixer": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz", - "integrity": "sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==", - "dev": true, - "requires": { - "browserslist": "^4.8.3", - "caniuse-lite": "^1.0.30001020", - "chalk": "^2.4.2", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.26", - "postcss-value-parser": "^4.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "browserslist": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.5.tgz", - "integrity": "sha512-4LMHuicxkabIB+n9874jZX/az1IaZ5a+EUuvD7KFOu9x/Bd5YHyO0DIz2ls/Kl8g0ItS4X/ilEgf4T1Br0lgSg==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001022", - "electron-to-chromium": "^1.3.338", - "node-releases": "^1.1.46" - } - }, - "caniuse-lite": { - "version": "1.0.30001022", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001022.tgz", - "integrity": "sha512-FjwPPtt/I07KyLPkBQ0g7/XuZg6oUkYBVnPHNj3VHJbOjmmJ/GdSo/GUY6MwINEQvjhP6WZVbX8Tvms8xh0D5A==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "electron-to-chromium": { - "version": "1.3.339", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.339.tgz", - "integrity": "sha512-C1i/vH6/kQx9YV8RddMkmW216GwW4pTrnYIlKmDFIqXA4fPwqDxIdGyHsuG+fgurHoljRz7/oaD+tztcryW/9g==", - "dev": true - }, - "node-releases": { - "version": "1.1.47", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.47.tgz", - "integrity": "sha512-k4xjVPx5FpwBUj0Gw7uvFOTF4Ep8Hok1I6qjwL3pLfwe7Y0REQSAqOwwv9TWBCUtMHxcXfY4PgRLRozcChvTcA==", - "dev": true, - "requires": { - "semver": "^6.3.0" - } - }, - "postcss": { - "version": "7.0.26", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.26.tgz", - "integrity": "sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "aws-sign2": { "version": "0.7.0", @@ -4155,15 +2695,15 @@ } }, "babel-eslint": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz", - "integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", "eslint-visitor-keys": "^1.0.0", "resolve": "^1.12.0" } @@ -5200,32 +3740,32 @@ }, "dependencies": { "browserslist": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.5.tgz", - "integrity": "sha512-4LMHuicxkabIB+n9874jZX/az1IaZ5a+EUuvD7KFOu9x/Bd5YHyO0DIz2ls/Kl8g0ItS4X/ilEgf4T1Br0lgSg==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.0.tgz", + "integrity": "sha512-seffIXhwgB84+OCeT/aMjpZnsAsYDiMSC+CEs3UkF8iU64BZGYcu+TZYs/IBpo4nRi0vJywUJWYdbTsOhFTweg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001022", - "electron-to-chromium": "^1.3.338", - "node-releases": "^1.1.46" + "caniuse-lite": "^1.0.30001030", + "electron-to-chromium": "^1.3.361", + "node-releases": "^1.1.50" } }, "caniuse-lite": { - "version": "1.0.30001022", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001022.tgz", - "integrity": "sha512-FjwPPtt/I07KyLPkBQ0g7/XuZg6oUkYBVnPHNj3VHJbOjmmJ/GdSo/GUY6MwINEQvjhP6WZVbX8Tvms8xh0D5A==", + "version": "1.0.30001030", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001030.tgz", + "integrity": "sha512-QGK0W4Ft/Ac+zTjEiRJfwDNATvS3fodDczBXrH42784kcfqcDKpEPfN08N0HQjrAp8He/Jw8QiSS9QRn7XAbUw==", "dev": true }, "electron-to-chromium": { - "version": "1.3.339", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.339.tgz", - "integrity": "sha512-C1i/vH6/kQx9YV8RddMkmW216GwW4pTrnYIlKmDFIqXA4fPwqDxIdGyHsuG+fgurHoljRz7/oaD+tztcryW/9g==", + "version": "1.3.363", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.363.tgz", + "integrity": "sha512-4w19wPBkeunBjOA53lNFT36IdOD3Tk1OoIDtTX+VToJUUDX42QfuhtsNKXv25wmSnoBOExM3kTbj7/WDNBwHuQ==", "dev": true }, "node-releases": { - "version": "1.1.47", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.47.tgz", - "integrity": "sha512-k4xjVPx5FpwBUj0Gw7uvFOTF4Ep8Hok1I6qjwL3pLfwe7Y0REQSAqOwwv9TWBCUtMHxcXfY4PgRLRozcChvTcA==", + "version": "1.1.50", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.50.tgz", + "integrity": "sha512-lgAmPv9eYZ0bGwUYAKlr8MG6K4CvWliWqnkcT2P8mMAgVrH3lqfBPorFlxiG1pHQnqmavJZ9vbMXUTNyMLbrgQ==", "dev": true, "requires": { "semver": "^6.3.0" @@ -6796,9 +5336,9 @@ } }, "eslint-plugin-import": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.0.tgz", - "integrity": "sha512-NK42oA0mUc8Ngn4kONOPsPB1XhbUvNHqF+g307dPV28aknPoiNnKLFd9em4nkswwepdF5ouieqv5Th/63U7YJQ==", + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", + "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", "dev": true, "requires": { "array-includes": "^3.0.3", @@ -6910,9 +5450,9 @@ } }, "eslint-plugin-react": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.18.0.tgz", - "integrity": "sha512-p+PGoGeV4SaZRDsXqdj9OWcOrOpZn8gXoGPcIQTzo2IDMbAKhNDnME9myZWqO3Ic4R3YmwAZ1lDjWl2R2hMUVQ==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.18.3.tgz", + "integrity": "sha512-Bt56LNHAQCoou88s8ViKRjMB2+36XRejCQ1VoLj716KI1MoE99HpTVvIThJ0rvFmG4E4Gsq+UgToEjn+j044Bg==", "dev": true, "requires": { "array-includes": "^3.1.1", @@ -6923,7 +5463,8 @@ "object.fromentries": "^2.0.2", "object.values": "^1.1.1", "prop-types": "^15.7.2", - "resolve": "^1.14.2" + "resolve": "^1.14.2", + "string.prototype.matchall": "^4.0.2" }, "dependencies": { "array-includes": { @@ -7058,6 +5599,12 @@ } } }, + "eslint-plugin-react-hooks": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.5.0.tgz", + "integrity": "sha512-bzvdX47Jx847bgAYf0FPX3u1oxU+mKU8tqrpj4UX9A96SbAmj/HVEefEy6rJUog5u8QIlOPTKZcBpGn5kkKfAQ==", + "dev": true + }, "eslint-scope": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", @@ -7177,32 +5724,6 @@ "safe-buffer": "^5.1.1" } }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, "exit-hook": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", @@ -7479,15 +6000,41 @@ } }, "file-loader": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-5.0.2.tgz", - "integrity": "sha512-QMiQ+WBkGLejKe81HU8SZ9PovsU/5uaLo0JdTCEXOYv7i7jfAjHZi1tcwp9tSASJPOmmHZtbdCervFmXMH/Dcg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-5.1.0.tgz", + "integrity": "sha512-u/VkLGskw3Ue59nyOwUwXI/6nuBCo7KBkniB/l7ICwr/7cPNGsL1WCXUp3GB0qgOOKU1TiP49bv4DZF/LJqprg==", "dev": true, "requires": { - "loader-utils": "^1.2.3", + "loader-utils": "^1.4.0", "schema-utils": "^2.5.0" }, "dependencies": { + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, "schema-utils": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz", @@ -7613,9 +6160,9 @@ } }, "follow-redirects": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", - "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.10.0.tgz", + "integrity": "sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ==", "dev": true, "requires": { "debug": "^3.0.0" @@ -8383,11 +6930,6 @@ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -9214,6 +7756,96 @@ "ipaddr.js": "^1.9.0" } }, + "internal-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", + "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "has": "^1.0.3", + "side-channel": "^1.0.2" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + } + } + }, "interpret": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", @@ -9479,11 +8111,6 @@ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" - }, "is-path-cwd": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", @@ -9552,12 +8179,14 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true }, "is-string": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true }, "is-svg": { "version": "3.0.0", @@ -9719,22 +8348,28 @@ } }, "jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", - "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz", + "integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==", "dev": true, "requires": { "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" + "supports-color": "^7.0.0" }, "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } } } @@ -9910,9 +8545,9 @@ "dev": true }, "levenary": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.0.tgz", - "integrity": "sha512-VHcwhO0UTpUW7rLPN2/OiWJdgA1e9BqEDALhrgCe/F+uUJnep6CoUsTzMeP8Rh0NGr9uKquXxqe7lwLZo509nQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", "dev": true, "requires": { "leven": "^3.1.0" @@ -9970,6 +8605,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, "requires": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" @@ -9978,7 +8614,8 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true } } }, @@ -10130,14 +8767,6 @@ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "requires": { - "mimic-fn": "^1.0.0" - } - }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -10238,11 +8867,6 @@ "mime-db": "1.43.0" } }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" - }, "min-indent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz", @@ -10280,7 +8904,25 @@ "prepend-http": "^1.0.0", "query-string": "^4.1.0", "sort-keys": "^1.0.0" + }, + "dependencies": { + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + } } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true } } }, @@ -10629,142 +9271,9 @@ "node-gyp": "^3.8.0", "npmlog": "^4.0.0", "request": "^2.88.0", - "sass-graph": "^2.2.4", - "stdout-stream": "^1.4.0", - "true-case-path": "^1.0.2" - } - }, - "node-sass-import": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-sass-import/-/node-sass-import-2.0.1.tgz", - "integrity": "sha512-V0G3+bcVpLmOLD2tqUGy5DRi1FKpDIaJBuFCEYn/MmFp6EoJGnw4duM5419af0Xg4gFAOSFZPXX8MXEHpmFlGQ==", - "requires": { - "async": "2.6.0", - "glob": "7.1.2", - "path-format": "1.2.1", - "path-parse": "1.0.5", - "resolve": "1.5.0", - "yargs": "11.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" - }, - "resolve": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", - "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", - "requires": { - "path-parse": "^1.0.5" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "yargs": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", - "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" - } - }, - "yargs-parser": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", - "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", - "requires": { - "camelcase": "^4.1.0" - } - } + "sass-graph": "^2.2.4", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" } }, "node-sass-magic-importer": { @@ -10806,12 +9315,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true - }, "normalize-url": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", @@ -10822,6 +9325,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, "requires": { "path-key": "^2.0.0" } @@ -10846,12 +9350,6 @@ "boolbase": "~1.0.0" } }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -11201,7 +9699,8 @@ "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true }, "p-is-promise": { "version": "2.1.0", @@ -11213,6 +9712,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, "requires": { "p-try": "^1.0.0" } @@ -11221,6 +9721,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, "requires": { "p-limit": "^1.1.0" } @@ -11243,12 +9744,13 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true }, "pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "dev": true }, "papaparse": { @@ -11367,15 +9869,6 @@ "pinkie-promise": "^2.0.0" } }, - "path-format": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/path-format/-/path-format-1.2.1.tgz", - "integrity": "sha1-qkyffE3odLJP+rxCH7KygG68/VE=", - "requires": { - "is-object": "^1.0.1", - "is-string": "^1.0.4" - } - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -11390,7 +9883,8 @@ "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true }, "path-parse": { "version": "1.0.6", @@ -12129,12 +10623,12 @@ } }, "postcss-flexbugs-fixes": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.1.0.tgz", - "integrity": "sha512-jr1LHxQvStNNAHlgco6PzY308zvLklh7SJVYuWUwyUQncofaAlD2l+P/gxKHOdqWKe7xJSkVLFF/2Tp+JqMSZA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.0.tgz", + "integrity": "sha512-QRE0n3hpkxxS/OGvzOa+PDuy4mh/Jg4o9ui22/ko5iGYOG3M5dfJabjnAZjTdh2G9F85c7Hv8hWcEDEKW/xceQ==", "dev": true, "requires": { - "postcss": "^7.0.0" + "postcss": "^7.0.26" }, "dependencies": { "ansi-styles": { @@ -12169,9 +10663,9 @@ } }, "postcss": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", - "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", + "version": "7.0.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.26.tgz", + "integrity": "sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -13967,9 +12461,9 @@ } }, "postcss": { - "version": "7.0.26", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.26.tgz", - "integrity": "sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", @@ -14332,13 +12826,13 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "dev": true, + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.11.1.tgz", + "integrity": "sha512-1ZvJOUl8ifkkBxu2ByVM/8GijMIPx+cef7u3yroO3Ogm4DOdZcF5dcrWTIlSHe3Pg/mtlt6/eFjObDfJureZZA==", "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "decode-uri-component": "^0.2.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" } }, "querystring": { @@ -14405,9 +12899,9 @@ } }, "react": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz", - "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==", + "version": "16.13.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.13.0.tgz", + "integrity": "sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -14425,11 +12919,6 @@ "react-transition-group": "^4.3.0" } }, - "react-alert-template-basic": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/react-alert-template-basic/-/react-alert-template-basic-1.0.0.tgz", - "integrity": "sha512-6x5Us0oc+jj8BDNkvSWfQMESk5SdyGKitXdLb7CwIlIlecyATjCTKSWpLABg8tpKAPOSJu4Dv/fYUqxXEio/XA==" - }, "react-card-flip": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/react-card-flip/-/react-card-flip-1.0.10.tgz", @@ -14444,14 +12933,14 @@ } }, "react-dom": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.12.0.tgz", - "integrity": "sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw==", + "version": "16.13.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.0.tgz", + "integrity": "sha512-y09d2c4cG220DzdlFkPTnVvGTszVvNpC73v+AaLGLHbkpy3SSgvYq8x0rNwPJ/Rk/CicTNgk0hbHNw1gMEZAXg==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "scheduler": "^0.18.0" + "scheduler": "^0.19.0" } }, "react-is": { @@ -14499,11 +12988,13 @@ } }, "react-table": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/react-table/-/react-table-6.10.3.tgz", - "integrity": "sha512-sVlq2/rxVaQJywGD95+qGiMr/SMHFIFnXdx619BLOWE/Os5FOGtV6pQJNAjZixbQZiOu7dmBO1kME28uxh6wmA==", + "version": "6.11.5", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-6.11.5.tgz", + "integrity": "sha512-LM+AS9v//7Y7lAlgTWW/cW6Sn5VOb3EsSkKQfQTzOW8FngB1FUskLLNEVkAYsTX9LjOWR3QlGjykJqCE6eXT/g==", "requires": { - "classnames": "^2.2.5" + "@types/react-table": "^6.8.5", + "classnames": "^2.2.5", + "react-is": "^16.8.1" } }, "react-transition-group": { @@ -14769,9 +13260,9 @@ "dev": true }, "regjsparser": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.2.tgz", - "integrity": "sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.3.tgz", + "integrity": "sha512-8uZvYbnfAtEm9Ab8NTb3hdLwL4g/LQzEYP7Xs27T96abJCCE2d6r3cPZPQEsLKy0vRSGVNG+/zVGtLr86HQduA==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -15427,9 +13918,9 @@ "dev": true }, "scheduler": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz", - "integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.0.tgz", + "integrity": "sha512-xowbVaTPe9r7y7RUejcK73/j8tt2jfiyTednOvHbA8JoClvMYCp+r8QegLwK/n8zWQAtZb1fFnER4XLBZXrCxA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -15643,6 +14134,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, "requires": { "shebang-regex": "^1.0.0" } @@ -15650,7 +14142,8 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true }, "shelljs": { "version": "0.6.1", @@ -15658,6 +14151,95 @@ "integrity": "sha1-7GIRvtGSBEIIj+D3Cyg3Iy7SyKg=", "dev": true }, + "side-channel": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", + "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "object-inspect": "^1.7.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + } + } + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -16030,6 +14612,11 @@ } } }, + "split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==" + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -16148,10 +14735,9 @@ "dev": true }, "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=" }, "string-width": { "version": "1.0.2", @@ -16163,6 +14749,99 @@ "strip-ansi": "^3.0.0" } }, + "string.prototype.matchall": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", + "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "has-symbols": "^1.0.1", + "internal-slot": "^1.0.2", + "regexp.prototype.flags": "^1.3.0", + "side-channel": "^1.0.2" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + } + } + }, "string.prototype.trimleft": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", @@ -16210,7 +14889,8 @@ "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true }, "strip-indent": { "version": "1.0.1", @@ -16226,28 +14906,6 @@ "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", "dev": true }, - "style-loader": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.1.3.tgz", - "integrity": "sha512-rlkH7X/22yuwFYK357fMN/BxYOorfnfq0eD7+vqlemSK4wEcejFF1dg4zxP0euBW8NrYx2WZzZ8PPFevr7D+Kw==", - "dev": true, - "requires": { - "loader-utils": "^1.2.3", - "schema-utils": "^2.6.4" - }, - "dependencies": { - "schema-utils": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.4.tgz", - "integrity": "sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1" - } - } - } - }, "stylehacks": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", @@ -16483,15 +15141,16 @@ } }, "terser-webpack-plugin": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.2.tgz", - "integrity": "sha512-SmvB/6gtEPv+CJ88MH5zDOsZdKXPS/Uzv2//e90+wM1IHFUhsguPKEILgzqrM1nQ4acRXN/SV4Obr55SXC+0oA==", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.5.tgz", + "integrity": "sha512-WlWksUoq+E4+JlJ+h+U+QUzXpcsMSSNXkDy9lBVkSqDn1w23Gg29L/ary9GeJVYCGiNJJX7LnVc4bwL1N3/g1w==", "dev": true, "requires": { "cacache": "^13.0.1", "find-cache-dir": "^3.2.0", - "jest-worker": "^24.9.0", - "schema-utils": "^2.6.1", + "jest-worker": "^25.1.0", + "p-limit": "^2.2.2", + "schema-utils": "^2.6.4", "serialize-javascript": "^2.1.2", "source-map": "^0.6.1", "terser": "^4.4.3", @@ -16564,9 +15223,9 @@ } }, "make-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz", - "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", + "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==", "dev": true, "requires": { "semver": "^6.0.0" @@ -16660,6 +15319,11 @@ } } }, + "text-encoding": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", + "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==" + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -17097,9 +15761,14 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "use-async-effect": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/use-async-effect/-/use-async-effect-2.2.1.tgz", - "integrity": "sha512-nPsDhym63uBWMRwWwcBclUWb3aPRYEwMIgXDylytQjM3r0BvzsqtRwuuxiNi5EBUa5bmo4Q206xr2LlmBWmd/g==" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/use-async-effect/-/use-async-effect-2.2.2.tgz", + "integrity": "sha512-zFas5h1jm4FNCk+txUzfMUAQhIFJGdrhAmg2lSA+Q6BZKYFen/yZlHEx5RGWSUV1USjLFZ+yg989fFyzJHW3Zw==" + }, + "use-interval": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/use-interval/-/use-interval-1.2.1.tgz", + "integrity": "sha512-qKe8IigaK0WmwwgWB6yLEmb7olb0rY31+anvMk0QMO+UEHeHG3ABucuXMrjqc8F0NsTLHNFVL8BNo20x50FRwA==" }, "use-persisted-state": { "version": "0.3.0", @@ -17241,9 +15910,9 @@ } }, "webpack": { - "version": "4.41.5", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.5.tgz", - "integrity": "sha512-wp0Co4vpyumnp3KlkmpM5LWuzvZYayDwM2n17EHFr4qxBBbRokC7DJawPJC7TfSFZ9HZ6GsdH40EBj4UV0nmpw==", + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz", + "integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==", "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", @@ -17313,9 +15982,9 @@ } }, "webpack-cli": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.10.tgz", - "integrity": "sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz", + "integrity": "sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==", "dev": true, "requires": { "chalk": "2.4.2", @@ -17534,9 +16203,9 @@ } }, "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -17680,9 +16349,9 @@ } }, "webpack-dev-server": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.10.1.tgz", - "integrity": "sha512-AGG4+XrrXn4rbZUueyNrQgO4KGnol+0wm3MPdqGLmmA+NofZl3blZQKxZ9BND6RDNuvAK9OMYClhjOSnxpWRoA==", + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.10.3.tgz", + "integrity": "sha512-e4nWev8YzEVNdOMcNzNeCN947sWJNd43E5XvsJzbAL08kGc2frm1tQ32hTJslRS+H65LCb/AaUCYU7fjHCpDeQ==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -18197,11 +16866,6 @@ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" } } - }, - "zustand": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-2.2.2.tgz", - "integrity": "sha512-l51p5Ys4WcAqrds1pCd/lWQU5jzyayzyftyTmtwawhLLl/V9Wn9D0aX5Wu2fZ8XOco4C87UrurRVJ0Y/rNNrtg==" } } } diff --git a/package.json b/package.json index 798f7685d..b920f8ba5 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,12 @@ { "name": "harperdb-studio", - "version": "2.0.0", + "version": "3.0.0", "description": "A UI for HarperDB", "deploymentUrl": "studio.harperdb.io", "private": true, "scripts": { "build": "webpack --mode production --config webpack.prod.js", "clean-source": "rm ./public/hdb.css && rm ./public/hdb.js", - "clean-destination": "rm -rf /Users/jrepp/Developer/harperdb/harperdb/docs/*", - "transfer": "cp -r ./public/* /Users/jrepp/Developer/harperdb/harperdb/docs/", - "tohdb": "npm run build && npm run clean-source && npm run clean-destination && npm run transfer", "start": "webpack-dev-server --mode development --config webpack.dev.js", "lint": "eslint --fix src && sass-lint --verbose", "deploy": "npm run build && npm run clean-source && scp -r ./public/* ubuntu@fcfleet.demo.harperdb.io:/home/ubuntu/sites/studio-stage" @@ -17,34 +14,37 @@ "author": "harperdb", "license": "Apache-2.0", "dependencies": { - "@nio/ui-kit": "^2.1.2", + "@nio/ui-kit": "^2.2.2", + "@stripe/react-stripe-js": "^1.0.3", + "@stripe/stripe-js": "^1.0.2", "font-awesome": "^4.7.0", "json-stringify-pretty-compact": "^2.0.0", - "react": "^16.12.0", + "query-string": "^6.11.1", + "react": "^16.13.0", "react-alert": "^6.0.0", - "react-alert-template-basic": "^1.0.0", "react-card-flip": "^1.0.10", "react-csv-reader": "^2.0.2", - "react-dom": "^16.12.0", + "react-dom": "^16.13.0", "react-json-editor-ajrm": "^2.5.9", "react-router": "^5.1.2", "react-router-dom": "^5.1.2", - "react-table": "=6.10.3", - "use-async-effect": "^2.2.1", + "react-table": "^6.11.5", + "text-encoding": "^0.7.0", + "use-async-effect": "^2.2.2", + "use-interval": "^1.2.1", "use-persisted-state": "^0.3.0", - "worker-loader": "^2.0.0", - "zustand": "^2.2.2" + "worker-loader": "^2.0.0" }, "devDependencies": { - "@babel/cli": "^7.8.3", - "@babel/core": "^7.8.3", + "@babel/cli": "^7.8.4", + "@babel/core": "^7.8.6", + "@babel/plugin-proposal-optional-chaining": "^7.8.3", "@babel/polyfill": "^7.8.3", - "@babel/preset-env": "^7.8.3", + "@babel/preset-env": "^7.8.6", "@babel/preset-react": "^7.8.3", - "@babel/runtime": "^7.8.3", - "@babel/types": "^7.8.3", - "autoprefixer": "^9.7.4", - "babel-eslint": "^10.0.3", + "@babel/runtime": "^7.8.4", + "@babel/types": "^7.8.6", + "babel-eslint": "^10.1.0", "babel-loader": "^8.0.6", "babel-plugin-transform-imports": "^2.0.0", "clean-webpack-plugin": "^3.0.0", @@ -53,10 +53,11 @@ "cssnano": "^4.1.10", "eslint": "^6.8.0", "eslint-config-airbnb": "^18.0.1", - "eslint-plugin-import": "^2.20.0", + "eslint-plugin-import": "^2.20.1", "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-react": "^7.18.0", - "file-loader": "^5.0.2", + "eslint-plugin-react": "^7.18.3", + "eslint-plugin-react-hooks": "^2.5.0", + "file-loader": "^5.1.0", "html-loader": "^0.5.5", "html-webpack-inline-source-plugin": "0.0.10", "html-webpack-plugin": "^3.2.0", @@ -64,15 +65,14 @@ "mini-css-extract-plugin": "^0.9.0", "node-sass": "^4.13.1", "optimize-css-assets-webpack-plugin": "^5.0.3", - "postcss-flexbugs-fixes": "^4.1.0", + "postcss-flexbugs-fixes": "^4.2.0", "postcss-loader": "^3.0.0", "sass-lint": "^1.13.1", "sass-loader": "^8.0.2", - "style-loader": "^1.1.3", - "terser-webpack-plugin": "^2.3.2", - "webpack": "^4.41.5", - "webpack-cli": "^3.3.10", - "webpack-dev-server": "^3.10.1", + "terser-webpack-plugin": "^2.3.5", + "webpack": "^4.42.0", + "webpack-cli": "^3.3.11", + "webpack-dev-server": "^3.10.3", "webpack-merge": "^4.2.2" } } diff --git a/src/api/instance/addNode.js b/src/api/instance/addNode.js new file mode 100644 index 000000000..f6baf4da4 --- /dev/null +++ b/src/api/instance/addNode.js @@ -0,0 +1,7 @@ +import queryInstance from '../queryInstance'; + +export default async ({ id, host, clusterPort, auth, refreshInstance }) => { + await queryInstance({ operation: 'remove_node', name: id }, auth); + await queryInstance({ operation: 'add_node', name: id, host, port: clusterPort, subscriptions: [] }, auth); + return setTimeout(() => refreshInstance(Date.now()), 100); +}; diff --git a/src/api/instance/addUser.js b/src/api/instance/addUser.js new file mode 100644 index 000000000..7cffef00f --- /dev/null +++ b/src/api/instance/addUser.js @@ -0,0 +1,4 @@ +import queryInstance from '../queryInstance'; + +export default async ({ auth, role, username, password }) => queryInstance({ operation: 'add_user', role, username, password, active: true }, auth); + diff --git a/src/api/instance/clusterStatus.js b/src/api/instance/clusterStatus.js new file mode 100644 index 000000000..79afa7eac --- /dev/null +++ b/src/api/instance/clusterStatus.js @@ -0,0 +1,38 @@ +import queryInstance from '../queryInstance'; + +const processConnections = (connections) => (connections ? connections.filter((c) => c.host_address.indexOf('::ffff') === -1).map((c) => ({ + name: c.node_name, + host: c.host_address, + port: c.host_port, + subscriptions: c.subscriptions, +})) : []); + +export default async (auth) => { + const clusterResponse = await queryInstance({ operation: 'cluster_status' }, auth); + const instanceRoles = await queryInstance({ operation: 'list_roles' }, auth); + const cluster_role = instanceRoles.find((r) => r.role === 'cluster_user'); + const instanceUsers = await queryInstance({ operation: 'list_users' }, auth); + const cluster_user = cluster_role && instanceUsers.find((u) => u.role.id === cluster_role.id); + + if (clusterResponse.message || !clusterResponse.is_enabled) { + return { + is_enabled: false, + cluster_role: cluster_role && cluster_role.id, + cluster_user: cluster_user && cluster_user.username, + inbound_connections: [], + outbound_connections: [], + name: false, + }; + } + + const { is_enabled, status: { inbound_connections, outbound_connections, __originator } } = clusterResponse; + + return { + is_enabled, + cluster_role: cluster_role && cluster_role.id, + cluster_user: cluster_user && cluster_user.username, + inbound_connections: processConnections(inbound_connections), + outbound_connections: processConnections(outbound_connections), + name: __originator && Object.keys(__originator)[0], + }; +}; diff --git a/src/api/instance/configureCluster.js b/src/api/instance/configureCluster.js new file mode 100644 index 000000000..d2425181f --- /dev/null +++ b/src/api/instance/configureCluster.js @@ -0,0 +1,15 @@ +import queryInstance from '../queryInstance'; + +export default async ({ instanceId, username, port, auth, refreshInstance }) => { + const query = { + operation: 'configure_cluster', + CLUSTERING: true, + CLUSTERING_PORT: parseInt(port, 10), + NODE_NAME: instanceId.replace(/[\W_]+/g, ''), + CLUSTERING_USER: username, + }; + const result = await queryInstance(query, auth); + // const restart = await queryInstance({ operation: 'restart' }, auth); + refreshInstance(Date.now()); + return result; +}; diff --git a/src/api/instance/createClusterUser.js b/src/api/instance/createClusterUser.js new file mode 100644 index 000000000..7fe33aa9b --- /dev/null +++ b/src/api/instance/createClusterUser.js @@ -0,0 +1,14 @@ +import queryInstance from '../queryInstance'; + +export default async ({ username, password, role, auth, refreshInstance }) => { + const query = { + operation: 'add_user', + role, + username, + password, + active: true, + }; + const result = await queryInstance(query, auth); + refreshInstance(Date.now()); + return result; +}; diff --git a/src/api/instance/createClusterUserRole.js b/src/api/instance/createClusterUserRole.js new file mode 100644 index 000000000..f8d11bc5f --- /dev/null +++ b/src/api/instance/createClusterUserRole.js @@ -0,0 +1,14 @@ +import queryInstance from '../queryInstance'; + +export default async ({ auth, refreshInstance }) => { + const query = { + operation: 'add_role', + role: 'cluster_user', + permission: { + cluster_user: true, + }, + }; + const result = await queryInstance(query, auth); + refreshInstance(Date.now()); + return result; +}; diff --git a/src/api/instance/csvDataLoad.js b/src/api/instance/csvDataLoad.js new file mode 100644 index 000000000..31ba97bd8 --- /dev/null +++ b/src/api/instance/csvDataLoad.js @@ -0,0 +1,3 @@ +import queryInstance from '../queryInstance'; + +export default async ({ schema, table, data, auth }) => queryInstance({ operation: 'csv_data_load', action: 'insert', schema, table, data }, auth); diff --git a/src/api/instance/dropUser.js b/src/api/instance/dropUser.js new file mode 100644 index 000000000..5664f2554 --- /dev/null +++ b/src/api/instance/dropUser.js @@ -0,0 +1,3 @@ +import queryInstance from '../queryInstance'; + +export default async ({ auth, username }) => queryInstance({ operation: 'drop_user', username }, auth); diff --git a/src/api/instance/getFingerprint.js b/src/api/instance/getFingerprint.js new file mode 100644 index 000000000..37e7614b3 --- /dev/null +++ b/src/api/instance/getFingerprint.js @@ -0,0 +1,6 @@ +import queryInstance from '../queryInstance'; + +export default async ({ auth }) => { + const { message } = await queryInstance({ operation: 'get_fingerprint' }, auth); + return message; +}; diff --git a/src/api/instance/getTableData.js b/src/api/instance/getTableData.js new file mode 100644 index 000000000..74194ee94 --- /dev/null +++ b/src/api/instance/getTableData.js @@ -0,0 +1,42 @@ +import queryInstance from '../queryInstance'; + +export default async ({ schema, table, tableState, auth }) => { + if (!tableState.sorted.length) return false; + + let fetchError = false; + let newTotalPages = 1; + let newTotalRecords = 0; + let newData = []; + + try { + let countSQL = `SELECT count(*) as newTotalRecords FROM ${schema}.${table} `; + if (tableState.filtered.length) countSQL += `WHERE ${tableState.filtered.map((f) => ` \`${f.id}\` LIKE '%${f.value}%'`).join(' AND ')} `; + [{ newTotalRecords }] = await queryInstance({ operation: 'sql', sql: countSQL }, auth); + newTotalPages = newTotalRecords && Math.ceil(newTotalRecords / tableState.pageSize); + } catch (e) { + // console.log('Failed to get row count'); + fetchError = true; + } + + try { + let dataSQL = `SELECT * FROM ${schema}.${table} `; + if (tableState.filtered.length) dataSQL += `WHERE ${tableState.filtered.map((f) => ` \`${f.id}\` LIKE '%${f.value}%'`).join(' AND ')} `; + if (tableState.sorted.length) dataSQL += `ORDER BY \`${tableState.sorted[0].id}\` ${tableState.sorted[0].desc ? 'DESC' : 'ASC'}`; + dataSQL += ` LIMIT ${(tableState.page * tableState.pageSize) + tableState.pageSize} OFFSET ${tableState.page * tableState.pageSize}`; + newData = await queryInstance({ operation: 'sql', sql: dataSQL }, auth); + } catch (e) { + // console.log('Failed to get table data'); + fetchError = true; + } + + const result = { tableData: [], totalPages: 1, totalRecords: 0 }; + + if (fetchError) { + return result; + } + + if (newData) result.tableData = newData; + if (newTotalPages) result.totalPages = newTotalPages; + result.totalRecords = newTotalRecords; + return result; +}; diff --git a/src/api/instance/getTotalRecords.js b/src/api/instance/getTotalRecords.js new file mode 100644 index 000000000..ec6f718c4 --- /dev/null +++ b/src/api/instance/getTotalRecords.js @@ -0,0 +1,11 @@ +import queryInstance from '../queryInstance'; + +export default async ({ schema, table, auth }) => { + let newTotalRecords = 0; + try { + [{ newTotalRecords }] = await queryInstance({ operation: 'sql', sql: `SELECT count(*) as newTotalRecords FROM ${schema}.${table} ` }, auth); + } catch (e) { + // console.log('Failed to get row count'); + } + return newTotalRecords; +}; diff --git a/src/api/instance/listUsers.js b/src/api/instance/listUsers.js new file mode 100644 index 000000000..813fe3aa9 --- /dev/null +++ b/src/api/instance/listUsers.js @@ -0,0 +1,4 @@ +import queryInstance from '../queryInstance'; + +export default async ({ auth }) => queryInstance({ operation: 'list_users' }, auth); + diff --git a/src/api/instance/setLicense.js b/src/api/instance/setLicense.js new file mode 100644 index 000000000..0d89a4656 --- /dev/null +++ b/src/api/instance/setLicense.js @@ -0,0 +1,3 @@ +import queryInstance from '../queryInstance'; + +export default async ({ auth, key, company }) => queryInstance({ operation: 'set_license', key, company }, auth); diff --git a/src/api/instance/updateNode.js b/src/api/instance/updateNode.js new file mode 100644 index 000000000..3891475ca --- /dev/null +++ b/src/api/instance/updateNode.js @@ -0,0 +1,32 @@ +import queryInstance from '../queryInstance'; + +export default async ({ channel, subscriptions, buttonState, id, host, clusterPort, auth, refreshInstance }) => { + const existingChannelSubscriptionIndex = subscriptions.findIndex((s) => s.channel === channel); + + // if we have no subscription for this node, add it to the subscriptions array + if (existingChannelSubscriptionIndex === -1) { + subscriptions.push({ + channel, + publish: buttonState === 'togglePublish', + subscribe: buttonState === 'toggleSubscribe', + }); + + // if we're changing the publish status + } else if (buttonState === 'togglePublish') { + subscriptions[existingChannelSubscriptionIndex].publish = !subscriptions[existingChannelSubscriptionIndex].publish; + + // if we're changing the subscribe status + } else if (buttonState === 'toggleSubscribe') { + subscriptions[existingChannelSubscriptionIndex].subscribe = !subscriptions[existingChannelSubscriptionIndex].subscribe; + } + + // get rid of subscription node if it's neither publishing or subscribing + if (subscriptions[existingChannelSubscriptionIndex] && !subscriptions[existingChannelSubscriptionIndex].publish && !subscriptions[existingChannelSubscriptionIndex].subscribe) { + subscriptions.splice(existingChannelSubscriptionIndex, 1); + } + + // send the query + const operation = { operation: 'update_node', name: id, host, port: clusterPort, subscriptions }; + await queryInstance(operation, auth); + return setTimeout(() => refreshInstance(Date.now()), 100); +}; diff --git a/src/api/lms/addCustomer.js b/src/api/lms/addCustomer.js new file mode 100644 index 000000000..23db06ed8 --- /dev/null +++ b/src/api/lms/addCustomer.js @@ -0,0 +1,12 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, payload: { firstname, lastname, email, company, subdomain } }) => { + const response = await queryLMS({ + endpoint: 'addCustomer', + method: 'POST', + payload: { firstname, lastname, email, company, subdomain }, + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/addInstance.js b/src/api/lms/addInstance.js new file mode 100644 index 000000000..e38093097 --- /dev/null +++ b/src/api/lms/addInstance.js @@ -0,0 +1,12 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, payload }) => { + const response = await queryLMS({ + endpoint: 'addInstance', + method: 'POST', + payload, + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/addLicense.js b/src/api/lms/addLicense.js new file mode 100644 index 000000000..9a9bc0a35 --- /dev/null +++ b/src/api/lms/addLicense.js @@ -0,0 +1,12 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, payload: { instance_id, customer_id, stripe_product_id, fingerprint } }) => { + const response = await queryLMS({ + endpoint: 'addLicense', + method: 'POST', + payload: { instance_id, customer_id, stripe_product_id, fingerprint }, + auth, + }); + + return response.body +}; diff --git a/src/api/lms/addPaymentMethod.js b/src/api/lms/addPaymentMethod.js new file mode 100644 index 000000000..5e078f6f9 --- /dev/null +++ b/src/api/lms/addPaymentMethod.js @@ -0,0 +1,12 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, payload: { payment_method_id, stripe_customer_id } }) => { + const response = await queryLMS({ + endpoint: 'addPaymentMethod', + method: 'POST', + payload: { payment_method_id, stripe_customer_id }, + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/addTCAcceptance.js b/src/api/lms/addTCAcceptance.js new file mode 100644 index 000000000..c68a656ce --- /dev/null +++ b/src/api/lms/addTCAcceptance.js @@ -0,0 +1,12 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, payload }) => { + const response = await queryLMS({ + endpoint: 'addTCAcceptance', + method: 'POST', + payload, + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/addUser.js b/src/api/lms/addUser.js new file mode 100644 index 000000000..aeafabc77 --- /dev/null +++ b/src/api/lms/addUser.js @@ -0,0 +1,12 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, payload }) => { + const response = await queryLMS({ + endpoint: 'addUser', + method: 'POST', + payload, + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/getCustomer.js b/src/api/lms/getCustomer.js new file mode 100644 index 000000000..7ea8e5467 --- /dev/null +++ b/src/api/lms/getCustomer.js @@ -0,0 +1,11 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth }) => { + const response = await queryLMS({ + endpoint: 'getCustomer', + method: 'POST', + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/getInstances.js b/src/api/lms/getInstances.js new file mode 100644 index 000000000..411e67d7a --- /dev/null +++ b/src/api/lms/getInstances.js @@ -0,0 +1,17 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, products, regions, licenses }) => { + const response = await queryLMS({ + endpoint: 'getInstances', + method: 'POST', + auth, + }); + + return response.body.map((i) => ({ + ...i, + compute: products[i.is_local ? 'localCompute' : 'cloudCompute'].find((p) => p.value === i.stripe_plan_id), + storage: i.is_local ? false : products.cloudStorage.find((p) => p.value === i.storage_qty_gb), + region: i.is_local ? false : regions.find((r) => r.value === i.instance_region), + license: licenses.find((l) => l.instance_id === i.id), + })); +}; diff --git a/src/api/lms/getInvoices.js b/src/api/lms/getInvoices.js new file mode 100644 index 000000000..1d1998fcc --- /dev/null +++ b/src/api/lms/getInvoices.js @@ -0,0 +1,11 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth }) => { + const response = await queryLMS({ + endpoint: 'getInvoices', + method: 'POST', + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/getLicenses.js b/src/api/lms/getLicenses.js new file mode 100644 index 000000000..298f76660 --- /dev/null +++ b/src/api/lms/getLicenses.js @@ -0,0 +1,11 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth }) => { + const response = await queryLMS({ + endpoint: 'getLicenses', + method: 'POST', + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/getProducts.js b/src/api/lms/getProducts.js new file mode 100644 index 000000000..c1fe916e0 --- /dev/null +++ b/src/api/lms/getProducts.js @@ -0,0 +1,46 @@ +import queryLMS from '../queryLMS'; + +const buildRadioSelectProductOptions = ({ id, amount_decimal, interval, amount, metadata: { instance_ram } }) => { + return { + price: amount_decimal !== '0' ? (amount_decimal / 100).toFixed(2) : 'FREE', + ram: instance_ram, + interval, + label: `${instance_ram} RAM | ${amount_decimal !== '0' ? `${amount}/${interval}` : 'FREE'}`, + value: id, + }; +}; + +const buildRadioSelectStorageOptions = (size, { tiers, interval }) => { + const pricingTier = tiers.find((p) => (p.up_to && size <= p.up_to) || !p.up_to); + const price = (size * (pricingTier.unit_amount / 100)).toFixed(2); + return { + price: pricingTier.unit_amount ? (size * (pricingTier.unit_amount / 100)).toFixed(2) : 'FREE', + disk_space: size === 1000 ? '1TB' : `${size}GB`, + interval, + label: `${size === 1000 ? '1TB' : `${size}GB`} Disk Space | ${pricingTier.unit_amount ? `$${price}/${interval}` : 'FREE'}`, + value: size, + }; +}; + +export default async () => { + const response = await queryLMS({ + endpoint: 'getProducts', + method: 'POST', + auth: { user: 'harperdb', pass: 'harperdb' }, + }); + + const localComputeOptions = response.body.find((p) => p.name === 'HarperDB Local Annual'); + const cloudComputeOptions = response.body.find((p) => p.name === 'HarperDB Cloud Beta'); + const cloudStoragePlans = response.body.find((p) => p.name === 'HarperDB Cloud Storage'); + const cloudStorageOptions = [10, 100, 250, 500, 1000]; + + const cloudStorage = cloudStorageOptions.map((size) => buildRadioSelectStorageOptions(size, cloudStoragePlans.plans[0])); + const cloudCompute = cloudComputeOptions.plans.map((p) => buildRadioSelectProductOptions(p)); + const localCompute = localComputeOptions.plans.map((p) => buildRadioSelectProductOptions(p)); + + return { + cloudStorage, + cloudCompute, + localCompute, + }; +}; diff --git a/src/api/lms/getRegions.js b/src/api/lms/getRegions.js new file mode 100644 index 000000000..54cafab4a --- /dev/null +++ b/src/api/lms/getRegions.js @@ -0,0 +1,10 @@ +import queryLMS from '../queryLMS'; + +export default async () => { + const response = await queryLMS({ + endpoint: 'getRegions', + method: 'POST', + auth: { user: 'harperdb', pass: 'harperdb' }, + }); + return response.body; +}; diff --git a/src/api/lms/getUser.js b/src/api/lms/getUser.js new file mode 100644 index 000000000..9fdbc69d0 --- /dev/null +++ b/src/api/lms/getUser.js @@ -0,0 +1,12 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, payload: { email } }) => { + const response = await queryLMS({ + endpoint: 'getUser', + method: 'POST', + payload: { email }, + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/getUsers.js b/src/api/lms/getUsers.js new file mode 100644 index 000000000..e3be668a4 --- /dev/null +++ b/src/api/lms/getUsers.js @@ -0,0 +1,11 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth }) => { + const response = await queryLMS({ + endpoint: 'getUsers', + method: 'POST', + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/removeInstance.js b/src/api/lms/removeInstance.js new file mode 100644 index 000000000..854268468 --- /dev/null +++ b/src/api/lms/removeInstance.js @@ -0,0 +1,12 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, payload: { customer_id, instance_id } }) => { + const response = await queryLMS({ + endpoint: 'removeInstance', + method: 'POST', + payload: { customer_id, instance_id }, + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/removePaymentMethod.js b/src/api/lms/removePaymentMethod.js new file mode 100644 index 000000000..1bfddf606 --- /dev/null +++ b/src/api/lms/removePaymentMethod.js @@ -0,0 +1,12 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, payload: { customer_id, stripe_card_id, customer_stripe_id } }) => { + const response = await queryLMS({ + endpoint: 'removePaymentMethod', + method: 'POST', + payload: { customer_id, stripe_card_id, customer_stripe_id }, + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/removeUser.js b/src/api/lms/removeUser.js new file mode 100644 index 000000000..788710140 --- /dev/null +++ b/src/api/lms/removeUser.js @@ -0,0 +1,12 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, payload: { user_id, customer_id, setLastUpdate } }) => { + const response = await queryLMS({ + endpoint: 'removeUser', + method: 'POST', + payload: { user_id, customer_id }, + auth, + }); + setLastUpdate(Date.now()); + return response.body; +}; diff --git a/src/api/lms/updateInstance.js b/src/api/lms/updateInstance.js new file mode 100644 index 000000000..2778cd187 --- /dev/null +++ b/src/api/lms/updateInstance.js @@ -0,0 +1,12 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, payload: { instance_name, stripe_product_id, instance_id, customer_id, storage_qty_gb } }) => { + const response = await queryLMS({ + endpoint: 'updateInstance', + method: 'POST', + payload: { stripe_product_id, instance_id, customer_id, instance_name, storage_qty_gb }, + auth, + }); + + return response.body; +}; diff --git a/src/api/lms/updateLicense.js b/src/api/lms/updateLicense.js new file mode 100644 index 000000000..6610c3d47 --- /dev/null +++ b/src/api/lms/updateLicense.js @@ -0,0 +1,12 @@ +import queryLMS from '../queryLMS'; + +export default async ({ auth, payload: { license_id, instance_id, customer_id, stripe_product_id, fingerprint } }) => { + const response = await queryLMS({ + endpoint: 'updateLicense', + method: 'POST', + payload: { license_id, instance_id, customer_id, stripe_product_id, fingerprint }, + auth, + }); + + return response.body; +} diff --git a/src/util/queryInstance.js b/src/api/queryInstance.js similarity index 81% rename from src/util/queryInstance.js rename to src/api/queryInstance.js index 3cea45a5f..10cb5468c 100644 --- a/src/util/queryInstance.js +++ b/src/api/queryInstance.js @@ -1,6 +1,6 @@ export default async (operation, auth) => { const request = await fetch( - `${auth.is_ssl ? 'https://' : 'http://'}${auth.url}:${auth.port}`, + `${auth.is_ssl ? 'https://' : 'http://'}${auth.host}:${auth.port}`, { method: 'POST', body: JSON.stringify(operation), diff --git a/src/api/queryLMS.js b/src/api/queryLMS.js new file mode 100644 index 000000000..ce77d0d0d --- /dev/null +++ b/src/api/queryLMS.js @@ -0,0 +1,87 @@ +import instances from '../../mock_data/LMS_API.instances.json'; +import products from '../../mock_data/LMS_API.products.json'; +import regions from '../../mock_data/LMS_API.aws_regions.json'; +import customer from '../../mock_data/LMS_API.customer.json'; +import user from '../../mock_data/LMS_API.user.json'; +import customer_users from '../../mock_data/LMS_API.customer_users.json'; +import invoices from '../../mock_data/LMS_API.invoices.json'; +import licenses from '../../mock_data/LMS_API.licenses.json'; + +// eslint-disable-next-line no-unused-vars +export default async ({ endpoint, payload, auth }) => { + if ((auth.user !== 'test@harperdb.io' || auth.pass !== 'a') && (auth.user !== 'david@harperdb.io' || auth.pass !== 'harperdb')) { + return { + body: { + result: false, + message: 'unknown user or password', + }, + }; + } + + const completedEndpoints = ['addCustomer']; + + if (completedEndpoints.includes(endpoint)) { + const request = await fetch( + `https://api.harperdbcloudservices.com/Prod/${endpoint}`, + { + method: 'POST', + body: JSON.stringify(payload), + headers: { + 'Content-Type': 'application/json', + authorization: `Basic ${btoa(`${auth.user}:${auth.pass}`)}`, + }, + }, + ); + const response = await request.json(); + + if (response.errorType) { + const errorObject = JSON.parse(response.errorMessage); + return { + body: { + result: false, + message: errorObject.errorMessage, + }, + }; + } + return response; + } + + switch (endpoint) { + case 'getProducts': + return products; + case 'getRegions': + return regions; + case 'getUser': + return user; + case 'getCustomer': + return customer; + case 'getInstances': + return instances; + case 'getUsers': + return customer_users; + case 'getLicenses': + return licenses; + case 'getInvoices': + return invoices; + case 'addLicense': + return { statusCode: 200, body: { result: true, message: 'Created license', key: '78rfh334ofholhfdoeh3f48hfq', company: 'customer-guid-1' } }; + case 'updateLicense': + return { statusCode: 200, body: { result: true, message: 'Updated license', key: '78rfh334ofholhfdoeh3f48hfq', company: 'customer-guid-1' } }; + case 'addTCAcceptance': + return { statusCode: 200, body: { result: true, message: 'Received Terms and Conditions acceptance' } }; + case 'addPaymentMethod': + return { statusCode: 200, body: { result: true, message: 'Payment method added to account' } }; + case 'removePaymentMethod': + return { statusCode: 200, body: { result: true, message: 'Payment method removed from account' } }; + case 'removeUser': + return { statusCode: 200, body: { result: true, message: 'User removed from account' } }; + case 'updateInstance': + return { statusCode: 200, body: { result: true, message: 'Instance is being updated' } }; + case 'addInstance': + return { statusCode: 200, body: { result: true, message: 'Instance is being created||added', instance_id: 'instance-guid-1' } }; + case 'addUser': + return { statusCode: 200, body: { result: true, message: 'User created successfully', user_id: 'user-guid-6' } }; + default: + return { statusCode: 404, body: { error: 'unknown endpoint' } }; + } +}; diff --git a/src/app.scss b/src/app.scss index 9dd5f2f03..4786f1195 100644 --- a/src/app.scss +++ b/src/app.scss @@ -1,19 +1,27 @@ +// external resources @import '~@nio/ui-kit/dist/nio'; @import '~react-table/react-table'; + +// core styles @import './assets/styles/vars'; -@import '~font-awesome/scss/font-awesome'; @import './assets/styles/base'; +@import './assets/styles/typography'; + +// global styles +@import './assets/styles/forms'; @import './assets/styles/alert'; @import './assets/styles/divider'; -@import './assets/styles/typography'; -@import './assets/styles/react-table'; @import './assets/styles/card'; -@import './assets/styles/db-browser'; -@import './assets/styles/login'; @import './assets/styles/button'; -@import './assets/styles/dropdown'; @import './assets/styles/code'; -@import './assets/styles/topnav'; + +// component styles +@import './assets/styles/db-browser'; +@import './assets/styles/react-table'; +@import './assets/styles/login'; @import './assets/styles/csv-input'; -@import './assets/styles/network'; +@import './assets/styles/clustering'; +@import './assets/styles/modal'; + +@import '~font-awesome/scss/font-awesome'; diff --git a/src/assets/fonts/raleway-v14-latin-100.eot b/src/assets/fonts/raleway-v14-latin-100.eot new file mode 100644 index 000000000..375c9d813 Binary files /dev/null and b/src/assets/fonts/raleway-v14-latin-100.eot differ diff --git a/src/assets/fonts/raleway-v14-latin-100.svg b/src/assets/fonts/raleway-v14-latin-100.svg new file mode 100644 index 000000000..1d7d59945 --- /dev/null +++ b/src/assets/fonts/raleway-v14-latin-100.svg @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/fonts/raleway-v14-latin-100.ttf b/src/assets/fonts/raleway-v14-latin-100.ttf new file mode 100644 index 000000000..c8eaba200 Binary files /dev/null and b/src/assets/fonts/raleway-v14-latin-100.ttf differ diff --git a/src/assets/fonts/raleway-v14-latin-100.woff b/src/assets/fonts/raleway-v14-latin-100.woff new file mode 100644 index 000000000..fecf72e5d Binary files /dev/null and b/src/assets/fonts/raleway-v14-latin-100.woff differ diff --git a/src/assets/fonts/raleway-v14-latin-100.woff2 b/src/assets/fonts/raleway-v14-latin-100.woff2 new file mode 100644 index 000000000..dbeefad48 Binary files /dev/null and b/src/assets/fonts/raleway-v14-latin-100.woff2 differ diff --git a/src/assets/fonts/raleway-v14-latin-200.eot b/src/assets/fonts/raleway-v14-latin-200.eot new file mode 100644 index 000000000..6af49a8f2 Binary files /dev/null and b/src/assets/fonts/raleway-v14-latin-200.eot differ diff --git a/src/assets/fonts/raleway-v14-latin-200.svg b/src/assets/fonts/raleway-v14-latin-200.svg new file mode 100644 index 000000000..958f46b76 --- /dev/null +++ b/src/assets/fonts/raleway-v14-latin-200.svg @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/fonts/raleway-v14-latin-200.ttf b/src/assets/fonts/raleway-v14-latin-200.ttf new file mode 100644 index 000000000..88e34739f Binary files /dev/null and b/src/assets/fonts/raleway-v14-latin-200.ttf differ diff --git a/src/assets/fonts/raleway-v14-latin-200.woff b/src/assets/fonts/raleway-v14-latin-200.woff new file mode 100644 index 000000000..d1bbeaaca Binary files /dev/null and b/src/assets/fonts/raleway-v14-latin-200.woff differ diff --git a/src/assets/fonts/raleway-v14-latin-200.woff2 b/src/assets/fonts/raleway-v14-latin-200.woff2 new file mode 100644 index 000000000..e13afef7d Binary files /dev/null and b/src/assets/fonts/raleway-v14-latin-200.woff2 differ diff --git a/src/assets/styles/_alert.scss b/src/assets/styles/_alert.scss index d40e8cdab..0e22bbd19 100644 --- a/src/assets/styles/_alert.scss +++ b/src/assets/styles/_alert.scss @@ -1,15 +1,21 @@ .alert { padding: 13px; border-radius: 6px; - width: 300px; margin-top: 5px; z-index: 9999; + display: flex; + + .icon { + width: 40px; + flex-grow: 0; + } .message { padding-top: 7px; white-space: nowrap; text-overflow: clip; overflow: hidden; + flex-grow: 1; } &.success { diff --git a/src/assets/styles/_base.scss b/src/assets/styles/_base.scss index ad394e61c..71b6b770e 100644 --- a/src/assets/styles/_base.scss +++ b/src/assets/styles/_base.scss @@ -1,5 +1,7 @@ +$min-width: 314px; + body { - min-width: 320px; + min-width: $min-width; overflow-x: hidden; #app-bg { @@ -15,27 +17,30 @@ body { } #app { - min-width: 320px; + min-width: $min-width; #app-container { - min-width: 320px; - margin-top: 70px; - padding: 2rem; - height: calc(100vh - 70px); + min-width: $min-width; + margin-top: 135px; + padding: 0 2rem; + height: calc(100vh - 135px); + transition: all 250ms; + @media screen and (max-width: 991px) { - padding: 1rem; + padding: 0 1rem; } } #app-nav { - min-width: 320px; - background: rgba(0, 0, 0, .3) !important; - padding: .5rem 2rem; + min-width: $min-width; + background: $gradient-purple-magenta !important; + padding: 0 2rem; position: fixed; z-index: 99 !important; + height: 60px; @media screen and (max-width: 991px) { - padding: .5rem 1rem; + padding: 0 1rem; } #logo { @@ -46,6 +51,83 @@ body { background-position: top left; background-size: contain; } + + .nav-item { + margin-left: 1.5rem; + } + } + + #app-subnav { + width: 100%; + min-width: $min-width; + background: $dark-grey-overlay !important; + padding: 5px 2rem; + position: fixed; + z-index: 98 !important; + height: 50px; + top: 60px !important; + text-align: center; + transition: top 250ms; + box-shadow: inset 0 10px 5px -10px $color-black, inset 0 -10px 5px -10px $color-black; + + .navbar-nav { + width: 100%; + max-width: 400px; + margin: 0 auto; + justify-content: center; + + .nav-item { + padding: 0 10px; + + @media screen and (max-width: 991px) { + padding: 0 5px; + font-size: .875rem; + } + + + &:first-child { + padding-left: 0; + } + + &:last-child { + padding-right: 0; + } + } + } + + .nav-link, + a { + padding: 0 !important; + } + + @media screen and (max-width: 991px) { + padding: 0 1rem; + } + } + + .nav-item { + display: inline-block; + white-space: nowrap; + + .nav-link, + a { + display: inline-block; + color: $white-overlay !important; + padding: 5px 0 0 !important; + text-shadow: 0 2px 3px $grey-overlay; + transition: color 250ms; + + &.active, + &:hover { + color: $color-white !important; + } + } + + .nav-divider { + display: inline-block; + color: $color-lightgrey !important; + padding: 5px 0 0 !important; + } } } } diff --git a/src/assets/styles/_button.scss b/src/assets/styles/_button.scss index 3aea993d9..5afb39377 100644 --- a/src/assets/styles/_button.scss +++ b/src/assets/styles/_button.scss @@ -1,13 +1,23 @@ .btn { - border-radius: 6px !important; + border-radius: 4px; box-shadow: none !important; line-height: 1 !important; transition: none !important; + padding-left: 5px; + padding-right: 5px; + font-family: $font-family-sans; + font-weight: $font-weight-light; &.round { padding: 0; - width: 25px; - height: 25px; + width: 25px !important; + height: 25px !important; + } + + &.connect { + padding: 0 !important; + height: 25px !important; + font-size: 12px; } &.btn-link { @@ -16,27 +26,48 @@ &.btn-grey { color: $color-white !important; - border: 0 !important; + border-color: $grey-overlay !important; background-color: $grey-overlay !important; } &.btn-black { color: $color-white !important; - border: 0 !important; + border-color: $color-black !important; background-color: $color-black !important; } &.btn-purple { color: $color-white !important; - border: 0 !important; + border-color: $color-purple !important; background-color: $color-purple !important; } + &.btn-darkpurple { + color: $color-white !important; + border-color: $color-darkpurple !important; + background-color: $color-darkpurple !important; + } + &.btn-outline-purple { color: $color-purple !important; border-color: $color-purple !important; background-color: $color-white !important; } + + &.btn-filter { + border-color: transparent !important; + background: $faint-white-overlay !important; + color: $white-overlay !important; + + &.active { + background: $white-overlay !important; + color: $color-white !important; + } + } +} + +.btn-group { + width: 100%; } .btn-group>.btn-group:not(:last-child)>.btn, diff --git a/src/assets/styles/_card.scss b/src/assets/styles/_card.scss index b31ec1160..1ed076c7b 100644 --- a/src/assets/styles/_card.scss +++ b/src/assets/styles/_card.scss @@ -1,10 +1,13 @@ +.floating-card-header { + text-shadow: 0 2px 3px $grey-overlay; + color: $color-white !important; +} + .card { background: $light-white-overlay !important; color: $color-black; - - &.dark { - background: $white-overlay !important; - } + border-radius: 4px !important; + box-shadow: 0 0 5px $dark-grey-overlay; .card-body { padding: 15px; @@ -12,28 +15,32 @@ .scrollable { overflow-x: hidden; overflow-y: auto; - height: 75px; + height: 77px; } } &.instance { - height: 140px; + height: 150px; cursor: pointer; - input, - .btn { - border-color: transparent; - } - input { - background: $color-white; - } - .btn { + .instance-name { white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; } + &.error { input { border-color: $color-danger; } } } + + &.no-shadow { + box-shadow: none; + } + + &.no-background { + background: none !important; + } } diff --git a/src/assets/styles/_clustering.scss b/src/assets/styles/_clustering.scss new file mode 100644 index 000000000..71b6c47e9 --- /dev/null +++ b/src/assets/styles/_clustering.scss @@ -0,0 +1,36 @@ +#clustering { + .cluster-system { + border-bottom: 1px solid $color-lightgrey; + padding-bottom: 15px; + margin-bottom: 15px; + } + + .cluster-form { + &.error { + input { + border-color: $color-danger; + } + } + + .form-cell { + width: 20%; + } + } + + .config-row { + padding-top: 15px; + padding-bottom: 15px; + border-bottom: 1px solid $color-grey; + + &:last-child { + border-bottom: 0; + } + + .text { + padding-top: 10px; + height: 36px; + } + } +} + + diff --git a/src/assets/styles/_csv-input.scss b/src/assets/styles/_csv-input.scss index eba3e4474..8a43b32fc 100644 --- a/src/assets/styles/_csv-input.scss +++ b/src/assets/styles/_csv-input.scss @@ -1,4 +1,4 @@ -#csv-uploader{ +#csv-uploader { position: relative; height: 300px; border: 0; @@ -9,7 +9,8 @@ width: 100%; text-align: center; - .clear-files { + .clear-files, + .browse-files { z-index: 99999; } } @@ -26,6 +27,7 @@ top: -30px; width: 100%; height: 330px; + background: none !important; } } diff --git a/src/assets/styles/_db-browser.scss b/src/assets/styles/_db-browser.scss index 1340f1191..260ddcf3a 100644 --- a/src/assets/styles/_db-browser.scss +++ b/src/assets/styles/_db-browser.scss @@ -5,7 +5,7 @@ padding: 0 15px; .item-row { - border-bottom: 1px solid $color-purple; + border-bottom: 1px solid $light-grey-overlay; padding-top: 12px; padding-bottom: 6px; height: 49px; diff --git a/src/assets/styles/_dropdown.scss b/src/assets/styles/_dropdown.scss deleted file mode 100644 index 846501e37..000000000 --- a/src/assets/styles/_dropdown.scss +++ /dev/null @@ -1,60 +0,0 @@ -.dropdown { - width: 100%; - - &.nav-item { - width: 250px; - } - - span { - display: block; - text-overflow: ellipsis; - overflow: hidden; - padding-right: 15px; - white-space: nowrap; - } - - .dropdown-menu { - width: 100%; - border-radius: 6px; - background-color: $color-black !important; - z-index: 9999; - margin: 0; - padding: 0; - - .dropdown-item { - color: $color-white; - border-bottom: 1px solid $white-overlay; - padding: .5rem 1.5rem; - background-color: $color-black !important; - border-radius: 6px; - - span { - padding-right: 0; - } - - &:last-child { - border-bottom: 0; - } - - &:hover { - background-color: $color-black !important; - color: $color-white; - } - } - } - - .dropdown-toggle { - padding-left: 1.5rem; - width: 100%; - text-align: left; - position: relative; - - &::after { - position: absolute; - top: 15px; - right: 15px; - } - } - - -} diff --git a/src/assets/styles/_forms.scss b/src/assets/styles/_forms.scss new file mode 100644 index 000000000..6fff12a51 --- /dev/null +++ b/src/assets/styles/_forms.scss @@ -0,0 +1,205 @@ +input, +select, +textarea, +.stripe-input-holder, +input:-webkit-autofill, +input:-webkit-autofill:hover, +input:-webkit-autofill:focus, +input:-webkit-autofill:active { + border: 1px solid $color-lightgrey !important; + background: $light-white-overlay !important; + color: $color-black; + font-family: $font-family-sans; + font-weight: $font-weight-light; + font-size: $font-size-root; + outline: none !important; + border-radius: 4px !important; + box-shadow: none !important; + -webkit-box-shadow: 0 0 0 1000px $light-white-overlay inset; + transition: none; + + &::placeholder { + text-align: left !important; + color: $color-grey !important; + font-family: $font-family-sans; + font-weight: $font-weight-light; + } + + &.text-center { + &::placeholder { + text-align: center !important; + } + } + + &.outline { + &-dark { + border-color: transparent !important; + background: $faint-white-overlay !important; + color: $color-white !important; + width: 100%; + max-width: 280px; + + &::placeholder { + color: $white-overlay !important; + } + } + } +} + +.instance-toggle-holder { + padding-top: 6px; + position: relative; + overflow: hidden; + display: inline-block; + width: 170px; + font-size: 12px; + + @media screen and (max-width: 575px) { + width: 160px !important; + } + + .react-toggle-track { + background-color: $light-grey-overlay !important; + + .react-toggle-track-x, + .react-toggle-track-check { + font-weight: 100 !important; + + @media screen and (max-width: 575px) { + font-size: .75rem !important; + } + } + } + + .react-toggle-thumb { + &::after { + position: absolute; + top: 3px; + left: 0; + right: 0; + font-size: 14px; + content: '\f00d'; + font-family: 'FontAwesome' !important; + color: $color-danger; + } + } + + .react-toggle--checked { + .react-toggle-track { + background-color: $faint-white-overlay !important; + } + + .react-toggle-thumb { + &::after { + content: '\f00c'; + color: $color-success; + } + } + } +} + +.instance-filter-holder { + position: relative; + width: 100%; + max-width: 280px; + overflow: hidden; + margin-left: 15px; + + .clear-filter { + background: none !important; + border: 0 !important; + position: absolute; + right: 8px; + top: 0; + } +} + +textarea { + height: auto !important; +} + +.form-control { + box-shadow: none !important; +} + +.stripe-input-holder { + padding: 8px 12px 0; + text-align: left; + height: 36px; +} + +.nio-check-mark::before { + content: '\f00c'; +} + +.nio::before { + font-family: 'FontAwesome' !important; + font-style: normal; + font-weight: 400 !important; + font-variant: normal; + text-transform: none; + vertical-align: top; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.radio-button > div { + border-bottom: 1px solid $lighter-grey-overlay; + padding: 8px 0; + white-space: nowrap; + + &:last-child { + border-bottom: 0; + padding-bottom: 4px; + } +} + +.radio-checkbox-label { + white-space: nowrap; + overflow-x: hidden; +} + +.fieldset-label { + font-weight: 700; + font-size: 12px; + margin-bottom: 5px; +} + +.fieldset { + border-top: 1px solid $lighter-grey-overlay; + padding: 5px 0; + max-height: 131px; + margin-bottom: 25px; + overflow-x: hidden; + overflow-y: auto; + + &.full-height { + max-height: none; + } + + &:last-child { + margin-bottom: 0; + } +} + +#__lpform_input_idx_0, +#__lpform_input_idx_0_numspan, +#__lpform_input_idx_1, +#__lpform_input_idx_1_numspan { + display: none; +} + +#add-customer-background { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #fff; + height: 100%; + width: 100%; +} + + + + diff --git a/src/assets/styles/_login.scss b/src/assets/styles/_login.scss index c9f774f10..9604a078e 100644 --- a/src/assets/styles/_login.scss +++ b/src/assets/styles/_login.scss @@ -18,21 +18,23 @@ background-size: cover; } - input, - input:-webkit-autofill, - input:-webkit-autofill:hover, - input:-webkit-autofill:focus, - input:-webkit-autofill:active { - border: 0 !important; - background: $color-black !important; - color: $color-white !important; - -webkit-box-shadow: 0 0 0 30px $color-black inset !important; - -webkit-text-fill-color: $color-white !important; + .card { + background: $white-overlay !important; + box-shadow: none !important; } - ::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */ - color: $color-grey !important; - opacity: 0.5; /* Firefox */ + input { + text-align: center !important; + background: $white-overlay !important; + color: $color-black !important; + border: 0 !important; + + &::placeholder { + text-align: center !important; + color: $grey-overlay !important; + font-family: $font-family-sans; + font-weight: $font-weight-light; + } } #login-error { diff --git a/src/assets/styles/_modal.scss b/src/assets/styles/_modal.scss new file mode 100644 index 000000000..511c7aa5e --- /dev/null +++ b/src/assets/styles/_modal.scss @@ -0,0 +1,19 @@ +#new-instance-modal { + + .card { + box-shadow: none !important; + + .instance-form-card-body { + background: $lighter-grey-overlay; + } + } + + .instance-form-card-holder { + + &:first-child { + @media screen and (max-width: 991px) { + margin-bottom: 1rem; + } + } + } +} diff --git a/src/assets/styles/_network.scss b/src/assets/styles/_network.scss deleted file mode 100644 index b787d1a38..000000000 --- a/src/assets/styles/_network.scss +++ /dev/null @@ -1,38 +0,0 @@ -#fabric { - height: 100%; - background-color: $light-white-overlay !important; - background-size: 50px 50px; - border-radius: 6px; - position:relative; - overflow: hidden; - - .fabric-node { - text-align: center; - - .node-scroller { - max-height: 75px; - overflow-x: hidden; - overflow-y: auto; - } - } - - .label-content { - padding: 5px 10px; - background: cornflowerblue; - color: white; - border-radius: 5px; - display: flex; - align-items: center; - justify-content: center; - font-size: 10px; - cursor: pointer; - } - - -} - -#fabric-editor.modal-dialog { - max-width: 800px !important; - -} - diff --git a/src/assets/styles/_react-table.scss b/src/assets/styles/_react-table.scss index 1e5269eb9..50f5c021f 100755 --- a/src/assets/styles/_react-table.scss +++ b/src/assets/styles/_react-table.scss @@ -7,12 +7,12 @@ .rt-thead { &.-header { border-top: 1px solid rgba(0, 0, 0, .05) !important; + font-weight: 700; } &.-filters { input { - background: rgba(0, 0, 0, .2); - border: 0; + background: rgba(0, 0, 0, .2) !important; } } } @@ -28,6 +28,7 @@ .rt-td, .rt-th { text-align: left !important; + border-right: 0 !important; &.-sort-desc { box-shadow: inset 0 -2px 0 0 $color-black; @@ -42,27 +43,57 @@ .rt-tbody { .rt-td { overflow: visible; + font-family: Roboto, Helvetica, Arial, SansSerif !important; } } + .-pagination { border-top: 1px solid rgba(0, 0, 0, .05); box-shadow: none; padding-top: 1rem; - input, - select { - height: 30px; - } - .-btn { background: $color-purple !important; color: $color-white !important; + font-family: $font-family-sans; + font-weight: $font-weight-light; + min-width: 100px; + height: 33px; + margin-top: 3px; &:hover { background: $color-purple !important; color: $color-white !important; } } + + .-previous, + .-next { + flex: 0 1; + } + + .-center { + flex: none; + } + + .-previous, + .-center, + .-next { + @media screen and (max-width: 905px) { + display: block; + width: 100%; + flex: none; + margin-bottom: 5px; + + .-pageInfo { + margin-left: 0; + } + + .-pageSizeOptions { + margin-right: 0; + } + } + } } .rt-noData { @@ -74,6 +105,14 @@ text-overflow: ellipsis; } + input, + select { + height: 33px !important; + color: $color-white; + border: 0 !important; + box-shadow: none; + } + .image-renderer { position: relative; @@ -89,3 +128,7 @@ } } + +.react-table-holder { + min-height: 714px; +} diff --git a/src/assets/styles/_topnav.scss b/src/assets/styles/_topnav.scss deleted file mode 100644 index 541bfd78a..000000000 --- a/src/assets/styles/_topnav.scss +++ /dev/null @@ -1,76 +0,0 @@ -#app-nav { - - .nav-item { - margin-left: 1.5rem; - display: inline-block; - white-space: nowrap; - - @media screen and (max-width: 991px) { - width: 100%; - } - - .nav-link, - a { - display: inline-block; - color: $color-lightgrey !important; - padding: 5px 0 0 !important; - - &.active, - &:hover { - color: $color-white !important; - } - } - - .nav-divider { - display: inline-block; - color: $color-lightgrey !important; - padding: 5px 0 0 !important; - } - } - - .collapse.show, - .collapsing { - left: 0; - right: 0; - margin: 0; - top: 70px !important; - background: $black-overlay; - text-align: center !important; - border: 0; - padding-top: .5rem; - padding-bottom: .5rem; - - .navbar-nav { - padding: 0; - - .nav-item { - margin-left: 0; - text-align: center; - border-bottom: 1px solid $white-overlay; - - &:last-child { - border-bottom: 0; - } - - .nav-link, - .nav-divider, - a { - display: block; - padding: .5rem 0 !important; - } - - .btn { - margin: 5px auto; - max-width: 250px; - } - - .dropdown-menu { - margin: 0 auto; - max-width: 250px; - } - } - } - } -} - - diff --git a/src/assets/styles/_typography.scss b/src/assets/styles/_typography.scss index ff7759fc3..72d9891a2 100755 --- a/src/assets/styles/_typography.scss +++ b/src/assets/styles/_typography.scss @@ -1,23 +1,3 @@ -$font-family-sans: 'Raleway', Helvetica-Neue, Helvetica, Verdana, Sans-Serif !default; - -$font-size-root: 16px !important; -$font-size-h1: calc(3vw + 3vh) !important; -$font-size-h1-max: 65px !important; -$font-size-h2: calc(2.5vw + 2.5vh) !important; -$font-size-h2-max: 54px !important; -$font-size-h3: calc(2vw + 2vh) !important; -$font-size-h3-max: 43px !important; -$font-size-h4: calc(1.5vw + 1.5vh) !important; -$font-size-h4-max: 32px !important; -$font-size-h5: 1.5rem !important; -$font-size-h5-max: 1.5rem !important; -$font-size-h6: 1.25rem !important; -$font-size-h6-max: 1.25rem !important; - -$font-weight-light: 300 !important; -$font-weight-bold: 700 !important; -$font-line-height: 1 !important; - body { font-weight: $font-weight-light; font-family: $font-family-sans; @@ -31,7 +11,7 @@ h1 { font-size: $font-size-h1; font-weight: $font-weight-light; margin: 0 !important; - @media (min-width: 1200px) { + @media (min-width: 1100px) { font-size: $font-size-h1-max; } } @@ -40,7 +20,7 @@ h2 { font-size: $font-size-h2; font-weight: $font-weight-light; margin: 0 !important; - @media (min-width: 1200px) { + @media (min-width: 1100px) { font-size: $font-size-h2-max; } } @@ -49,7 +29,7 @@ h3 { font-size: $font-size-h3; font-weight: $font-weight-light; margin: 0 !important; - @media (min-width: 1200px) { + @media (min-width: 1100px) { font-size: $font-size-h3-max; } } @@ -58,7 +38,7 @@ h4 { font-size: $font-size-h4; font-weight: $font-weight-light; margin: 0 !important; - @media (min-width: 1200px) { + @media (min-width: 1100px) { font-size: $font-size-h4-max; } } @@ -67,7 +47,7 @@ h5 { font-size: $font-size-h5; font-weight: $font-weight-light; margin: 0 !important; - @media (min-width: 1200px) { + @media (min-width: 1100px) { font-size: $font-size-h5-max; } } @@ -76,15 +56,11 @@ h6 { font-size: $font-size-h6; font-weight: $font-weight-light; margin: 0 !important; - @media (min-width: 1200px) { + @media (min-width: 1100px) { font-size: $font-size-h6-max; } } -.line-height-1 { - line-height: 1 !important; -} - a { color: $color-purple; text-decoration: none !important; @@ -113,7 +89,7 @@ h6 { b, .text-bold, strong { - font-weight: $font-weight-bold !important; + font-weight: $font-weight-bold; } .text-small { @@ -150,14 +126,14 @@ strong { @font-face { font-family: 'Raleway'; font-style: normal; - font-weight: 300; - src: url('/fonts/raleway-v14-latin-300.eot'); + font-weight: 100; + src: url('/fonts/raleway-v14-latin-100.eot'); src: local('Raleway Light'), local('Raleway-Light'), - url('/fonts/raleway-v14-latin-300.eot?#iefix') format('embedded-opentype'), - url('/fonts/raleway-v14-latin-300.woff2') format('woff2'), - url('/fonts/raleway-v14-latin-300.woff') format('woff'), - url('/fonts/raleway-v14-latin-300.ttf') format('truetype'), - url('/fonts/raleway-v14-latin-300.svg#Raleway') format('svg'); + url('/fonts/raleway-v14-latin-100.eot?#iefix') format('embedded-opentype'), + url('/fonts/raleway-v14-latin-100.woff2') format('woff2'), + url('/fonts/raleway-v14-latin-100.woff') format('woff'), + url('/fonts/raleway-v14-latin-100.ttf') format('truetype'), + url('/fonts/raleway-v14-latin-100.svg#Raleway') format('svg'); } @font-face { diff --git a/src/assets/styles/_vars.scss b/src/assets/styles/_vars.scss index 86e6bf50a..035caee37 100644 --- a/src/assets/styles/_vars.scss +++ b/src/assets/styles/_vars.scss @@ -15,12 +15,35 @@ $color-purple: #403b8a; $color-lightpurple: #7a3a87; $gradient-purple-magenta: linear-gradient(45deg, $color-darkpurple, $color-purple, $color-lightpurple); -$white-overlay: rgba(255, 255, 255, .2); -$light-white-overlay: rgba(255, 255, 255, .7); +$faint-white-overlay: rgba(255, 255, 255, .1); +$white-overlay: rgba(255, 255, 255, .5); +$light-white-overlay: rgba(255, 255, 255, .9); -$grey-overlay: rgba(0, 0, 0, .2); -$dark-grey-overlay: rgba(0, 0, 0, .5); -$black-overlay: rgba(0, 0, 0, .8); +$lighter-grey-overlay: rgba(0, 0, 0, .05); +$light-grey-overlay: rgba(0, 0, 0, .3); +$grey-overlay: rgba(0, 0, 0, .5); +$dark-grey-overlay: rgba(0, 0, 0, .7); +$black-overlay: rgba(0, 0, 0, .9); $fa-font-path: '/fonts'; $border-radius-base: 6px; + +$font-family-sans: 'Raleway', Helvetica-Neue, Helvetica, Verdana, Sans-Serif !important; + +$font-size-root: 15px !important; +$font-size-h1: calc(3vw + 3vh) !important; +$font-size-h1-max: 65px !important; +$font-size-h2: calc(2.5vw + 2.5vh) !important; +$font-size-h2-max: 54px !important; +$font-size-h3: calc(2vw + 2vh) !important; +$font-size-h3-max: 43px !important; +$font-size-h4: calc(1.5vw + 1.5vh) !important; +$font-size-h4-max: 32px !important; +$font-size-h5: 1.5rem !important; +$font-size-h5-max: 1.5rem !important; +$font-size-h6: 1.25rem !important; +$font-size-h6-max: 1.25rem !important; + +$font-weight-light: 100 !important; +$font-weight-bold: 700 !important; +$font-line-height: 1.2 !important; diff --git a/src/components/account/billing/cardEdit.js b/src/components/account/billing/cardEdit.js new file mode 100644 index 000000000..f2139d2ad --- /dev/null +++ b/src/components/account/billing/cardEdit.js @@ -0,0 +1,132 @@ +import React, { useState } from 'react'; +import { Button, Row, Col, Input } from '@nio/ui-kit'; +import { CardNumberElement, CardExpiryElement, CardCvcElement, useElements, useStripe } from '@stripe/react-stripe-js'; +import useAsyncEffect from 'use-async-effect'; +import { useLocation, useHistory } from 'react-router-dom'; +import queryString from 'query-string' + +import cardOptions from '../../../util/stripe/cardOptions'; +import useLMS from '../../../state/stores/lmsAuth'; +import defaultLMSAuth from '../../../state/defaults/defaultLMSAuth'; +import addPaymentMethod from '../../../api/lms/addPaymentMethod'; +import getCustomer from '../../../api/lms/getCustomer'; +import useApp from '../../../state/stores/appData'; +import defaultAppData from '../../../state/defaults/defaultAppData'; + +export default ({ setEditingCard, customerCard }) => { + const [lmsAuth] = useLMS(defaultLMSAuth); + const [appData, setAppData] = useApp(defaultAppData); + const [postalCode, setPostalCode] = useState(false); + const [cardSubmitted, setCardSubmitted] = useState(false); + const [error, setError] = useState(null); + const [cardComplete, setCardComplete] = useState(false); + const [processing, setProcessing] = useState(false); + const stripe = useStripe(); + const elements = useElements(); + const location = useLocation(); + const history = useHistory(); + const { returnURL } = queryString.parse(location.search); + + + useAsyncEffect(async () => { + if (cardSubmitted && stripe && elements) { + if (cardComplete) setProcessing(true); + const newCardObject = { type: 'card', card: elements.getElement(CardNumberElement), billing_details: { address: { postal_code: postalCode } } }; + const payload = await stripe.createPaymentMethod(newCardObject); + + if (payload.error) { + setError(payload.error); + } else { + await addPaymentMethod({ auth: lmsAuth, payload: { payment_method_id: payload.paymentMethod.id, stripe_customer_id: appData.customer.stripe_customer_object.id } }); + const customer = await getCustomer({ auth: lmsAuth }); + setAppData({ ...appData, customer }); + setEditingCard(false); + if (returnURL) { + setTimeout(() => history.push(returnURL), 100); + } + } + setCardSubmitted(false); + setProcessing(false); + } + }, [cardSubmitted]); + + return ( +
+ + + card number + + +
+ { setError(e.error); setCardComplete(e.complete); }} + /> +
+ +
+
+ + + expiration + + +
+ { setError(e.error); setCardComplete(e.complete); }} + /> +
+ +
+
+ + + cvcc + + +
+ { setError(e.error); setCardComplete(e.complete); }} + /> +
+ +
+
+ + + billing postal code + + + setPostalCode(e.target.value)} + /> + + +
+ {customerCard ? ( + + + + + + + + + ) : ( + + + + + + )} + {error && ( +
+
+ {error.message} +
+ )} +
+ ); +}; diff --git a/src/components/account/billing/cardStatic.js b/src/components/account/billing/cardStatic.js new file mode 100644 index 000000000..4373cefea --- /dev/null +++ b/src/components/account/billing/cardStatic.js @@ -0,0 +1,87 @@ +import React, { useState } from 'react'; +import useAsyncEffect from 'use-async-effect'; +import { Row, Col, Button } from '@nio/ui-kit'; +import { useAlert } from 'react-alert'; + +import removePaymentMethod from '../../../api/lms/removePaymentMethod'; + +export default ({ customerId, customerCard, customerStripeId, setEditingCard, auth }) => { + const [removing, setRemoving] = useState(false); + const alert = useAlert(); + + useAsyncEffect(async () => { + if (removing) { + const response = await removePaymentMethod({ + auth, + payload: { + customer_id: customerId, + stripe_card_id: customerCard.id, + customer_stripe_id: customerStripeId, + }, + }); + setRemoving(false); + if (response.result) { + alert.success(response.message); + } else { + alert.error(response.message); + } + } + }, [removing]); + + return ( +
+ + + card number + + +
**** **** **** {customerCard.last4}
+ +
+
+ + + expiration + + +
{customerCard.exp_month} / {customerCard.exp_year}
+ +
+
+ + + cvcc + + +
***
+ +
+
+ + + billing postal code + + +
{customerCard.address_zip}
+ +
+
+ + + + + + + + +
+ ); +}; diff --git a/src/components/account/billing/index.js b/src/components/account/billing/index.js new file mode 100644 index 000000000..629a30a2a --- /dev/null +++ b/src/components/account/billing/index.js @@ -0,0 +1,52 @@ +import React, { useState } from 'react'; +import { Row, Col, Card, CardBody } from '@nio/ui-kit'; + +import customerHasChargeableCard from '../../../util/stripe/customerHasChargeableCard'; +import useLMS from '../../../state/stores/lmsAuth'; +import defaultLMSAuth from '../../../state/defaults/defaultLMSAuth'; +import StaticCard from './cardStatic'; +import EditCard from './cardEdit'; +import Invoices from './invoices'; +import useApp from '../../../state/stores/appData'; +import defaultAppData from '../../../state/defaults/defaultAppData'; + +export default () => { + const [lmsAuth] = useLMS(defaultLMSAuth); + const [appData] = useApp(defaultAppData); + const [editingCard, setEditingCard] = useState(false); + const customerCard = customerHasChargeableCard(appData.customer); + + return ( + + + card + + + {(editingCard || !customerCard) ? ( + + ) : ( + + )} + + + + + invoices + + + + + + + + ); +}; diff --git a/src/components/account/billing/invoices.js b/src/components/account/billing/invoices.js new file mode 100644 index 000000000..442a9c3b2 --- /dev/null +++ b/src/components/account/billing/invoices.js @@ -0,0 +1,32 @@ +import React, { useState } from 'react'; +import { Row, Col } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; + +import getInvoices from '../../../api/lms/getInvoices'; +import useLMS from '../../../state/stores/lmsAuth'; +import defaultLMSAuth from '../../../state/defaults/defaultLMSAuth'; + +export default () => { + const [lmsAuth] = useLMS(defaultLMSAuth); + const [customerInvoices, setCustomerInvoices] = useState([]); + + useAsyncEffect(async () => { + const newCustomerInvoices = await getInvoices({ auth: lmsAuth }); + setCustomerInvoices(newCustomerInvoices); + }, []); + + return customerInvoices.map((i) => ( +
+ + + {new Date(i.created * 1000).toLocaleString()} + + + $ + {(i.total / 100).toFixed(2)} + + +
+
+ )); +}; diff --git a/src/components/account/index.js b/src/components/account/index.js new file mode 100644 index 000000000..e79a0e587 --- /dev/null +++ b/src/components/account/index.js @@ -0,0 +1,17 @@ +import React from 'react'; +import { Redirect, Route, Switch } from 'react-router-dom'; + +import routes from './routes'; +import SubNav from '../navs/subnav'; + +export default () => ( + <> + + + {routes.map((route) => ( + + ))} + + + +); diff --git a/src/components/account/profile/index.js b/src/components/account/profile/index.js new file mode 100644 index 000000000..f019e4357 --- /dev/null +++ b/src/components/account/profile/index.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { Row, Col, Card, CardBody } from '@nio/ui-kit'; + +import ProfileForm from './profile'; +import PasswordForm from './password'; + +export default () => ( + + + profile + + + + + + + + password + + + + + + + +); diff --git a/src/components/account/profile/password.js b/src/components/account/profile/password.js new file mode 100644 index 000000000..a45ac782a --- /dev/null +++ b/src/components/account/profile/password.js @@ -0,0 +1,81 @@ +import React, { useState } from 'react'; +import { Row, Col, Input, Button } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; + +import defaultPasswordFormData from '../../../state/defaults/defaultPasswordFormData'; + +export default () => { + const [passwordForm, updatePasswordForm] = useState(defaultPasswordFormData); + + useAsyncEffect(async () => { + if (passwordForm.submitted) { + console.log(passwordForm); + // await updatePassword(passwordForm); + } + }, [passwordForm]); + + return ( + <> + + + current password + + + updatePasswordForm({ ...passwordForm, oldpassword: e.target.value, error: false })} + /> + + +
+ + + new password + + + updatePasswordForm({ ...passwordForm, newpassword: e.target.value, error: false })} + /> + + +
+ + + verify password + + + updatePasswordForm({ ...passwordForm, newpassword2: e.target.value, error: false })} + /> + + +
+ + + + + + + {passwordForm.error && ( +
+
+ {passwordForm.error} +
+ )} + + ); +}; diff --git a/src/components/account/profile/profile.js b/src/components/account/profile/profile.js new file mode 100644 index 000000000..c921c0a42 --- /dev/null +++ b/src/components/account/profile/profile.js @@ -0,0 +1,84 @@ +import React, { useState } from 'react'; +import { Row, Col, Input, Button } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; + +import defaultProfileFormData from '../../../state/defaults/defaultProfileFormData'; + +export default () => { + const [profileForm, updateProfileForm] = useState(defaultProfileFormData); + + useAsyncEffect(async () => { + if (profileForm.submitted) { + console.log(profileForm); + // await updateProfile(profileForm); + } + }, [profileForm]); + + return ( + <> + + + first name + + + updateProfileForm({ ...profileForm, firstname: e.target.value, error: false })} + /> + + +
+ + + last name + + + updateProfileForm({ ...profileForm, lastname: e.target.value, error: false })} + /> + + +
+ + + email address + + + updateProfileForm({ ...profileForm, email: e.target.value, error: false })} + /> + + +
+ + + + + + + {profileForm.error && ( +
+
+ {profileForm.error} +
+ )} + + ); +}; diff --git a/src/components/account/routes.js b/src/components/account/routes.js new file mode 100644 index 000000000..cd6ffe868 --- /dev/null +++ b/src/components/account/routes.js @@ -0,0 +1,9 @@ +import Profile from './profile'; +import Users from './users'; +import Billing from './billing'; + +export default [ + { component: Profile, path: '/account/profile', link: 'profile', icon: 'user' }, + { component: Billing, path: '/account/billing', link: 'billing', icon: 'credit-card-alt' }, + { component: Users, path: '/account/users/:hash?', link: 'users', icon: 'users' }, +]; diff --git a/src/components/account/users/add.js b/src/components/account/users/add.js new file mode 100644 index 000000000..296f7520f --- /dev/null +++ b/src/components/account/users/add.js @@ -0,0 +1,90 @@ +import React, { useState } from 'react'; +import { Input, Button, Card, CardBody } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; +import { useAlert } from 'react-alert'; + +import addUser from '../../../api/lms/addUser'; +import defaultUserFormData from '../../../state/defaults/defaultUserFormData'; +import isEmail from '../../../util/isEmail'; +import useLMS from '../../../state/stores/lmsAuth'; +import defaultLMSAuth from '../../../state/defaults/defaultLMSAuth'; + +export default ({ setLastUpdate, customerId }) => { + const [lmsAuth] = useLMS(defaultLMSAuth); + const alert = useAlert(); + const [userForm, updateUserForm] = useState(defaultUserFormData); + + useAsyncEffect(async () => { + if (userForm.submitted) { + userForm.customer_id = customerId; + if (!userForm.customer_id || !userForm.firstname || !userForm.lastname || !isEmail(userForm.email)) { + updateUserForm({ ...userForm, submitted: false, error: 'All fields must be filled out' }); + } else { + const response = await addUser({ auth: lmsAuth, payload: userForm }); + if (response.result) { + updateUserForm(defaultUserFormData); + setLastUpdate(Date.now()); + alert.success(response.message); + } else { + alert.error(response.message); + } + } + } + }, [userForm]); + + return ( + <> + add user + + +
first name
+
+ updateUserForm({ ...userForm, firstname: e.target.value, error: false })} + /> +
+ +
last name
+
+ updateUserForm({ ...userForm, lastname: e.target.value, error: false })} + /> +
+ +
email address
+
+ updateUserForm({ ...userForm, email: e.target.value, error: false })} + /> +
+ + + {userForm.error && ( +
+
+ {userForm.error} +
+ )} +
+
+ + ); +}; diff --git a/src/components/account/users/datatable.js b/src/components/account/users/datatable.js new file mode 100644 index 000000000..df85ecb3f --- /dev/null +++ b/src/components/account/users/datatable.js @@ -0,0 +1,44 @@ +import React, { useState } from 'react'; +import { Card, CardBody, Row, Col } from '@nio/ui-kit'; +import ReactTable from 'react-table'; + +import defaultTableState from '../../../state/defaults/defaultTableState'; + +export default ({ tableData }) => { + const [tableState, setTableState] = useState({ ...defaultTableState, sorted: [{ id: 'lastname', desc: false }] }); + + return ( + <> + + + existing users + + + setTableState({ ...tableState, filtered: tableState.showFilter ? [] : tableState.filtered, showFilter: !tableState.showFilter })}> + + + + + + + setTableState({ ...tableState, filtered: value })} + filtered={tableState.filtered} + onSortedChange={(value) => setTableState({ ...tableState, sorted: value })} + sorted={tableState.sorted} + onPageChange={(value) => setTableState({ ...tableState, page: value })} + page={tableState.page} + filterable={tableState.showFilter} + defaultPageSize={tableState.pageSize} + pageSize={tableState.pageSize} + onPageSizeChange={(value) => setTableState({ ...tableState, pageSize: value })} + resizable={false} + /> + + + + ); +}; diff --git a/src/components/account/users/index.js b/src/components/account/users/index.js new file mode 100644 index 000000000..99e87817c --- /dev/null +++ b/src/components/account/users/index.js @@ -0,0 +1,37 @@ +import React, { useState } from 'react'; +import { Row, Col } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; + +import useLMS from '../../../state/stores/lmsAuth'; + +import DataTable from './datatable'; +import AddUserForm from './add'; +import getUsers from '../../../api/lms/getUsers'; + +import defaultLMSAuth from '../../../state/defaults/defaultLMSAuth'; +import customerUserColumns from '../../../util/datatable/customerUserColumns'; +import useApp from '../../../state/stores/appData'; +import defaultAppData from '../../../state/defaults/defaultAppData'; + +export default () => { + const [lmsAuth] = useLMS(defaultLMSAuth); + const [{ customer }] = useApp(defaultAppData); + const [lastUpdate, setLastUpdate] = useState(false); + const [tableData, setTableData] = useState({ data: [], columns: customerUserColumns({ auth: lmsAuth, setLastUpdate, customer_id: customer?.id }) }); + + useAsyncEffect(async () => { + const newTableData = await getUsers({ auth: lmsAuth }); + setTableData({ ...tableData, data: newTableData }); + }, [lastUpdate]); + + return ( + + + + + + + + + ); +}; diff --git a/src/components/app.js b/src/components/app.js index c6d4cf97d..595cda7fe 100644 --- a/src/components/app.js +++ b/src/components/app.js @@ -1,16 +1,22 @@ import React from 'react'; -import { Route, Switch } from 'react-router-dom'; +import { Route, Switch, Redirect } from 'react-router-dom'; +import ProtectedRoute from './shared/protectedRoute'; import Instances from './instances'; import Instance from './instance'; +import Register from './register'; import Login from './login'; +import Account from './account'; export default () => (
- - + + + + +
); diff --git a/src/components/instance/browse/csvuploader.js b/src/components/instance/browse/csvuploader.js index 1e13de266..8a3a221ea 100644 --- a/src/components/instance/browse/csvuploader.js +++ b/src/components/instance/browse/csvuploader.js @@ -4,7 +4,8 @@ import { useHistory, useParams } from 'react-router'; import CSVReader from 'react-csv-reader'; import useAsyncEffect from 'use-async-effect'; -import queryInstance from '../../../util/queryInstance'; +import getTotalRecords from '../../../api/instance/getTotalRecords'; +import csvDataLoad from '../../../api/instance/csvDataLoad'; import commaNumbers from '../../../util/commaNumbers'; import Worker from '../../../util/processCSV.worker'; @@ -20,24 +21,13 @@ export default ({ refreshInstance, instance_id, auth }) => { const [initialRecordCount, setInitialRecordCount] = useState(0); const [fileError, setFileError] = useState(false); - // get the current record count of the table - const getCurrentRecordCount = async () => { - const [{ newTotalRecords }] = await queryInstance({ operation: 'sql', sql: `SELECT count(*) as newTotalRecords FROM ${schema}.${table} ` }, auth); - return newTotalRecords; - }; - // query the table to determine if all the records have been processed. const validateData = async () => { setStatus('validating'); - const validatedCount = await getCurrentRecordCount(); + const validatedCount = await getTotalRecords({ schema, table, auth }); setValidatedRecordCount(validatedCount); - - if (validatedCount < (newRecordCount + initialRecordCount)) { - return setTimeout(() => validateData(), 1000); - } - - refreshInstance(); - + if (validatedCount < (newRecordCount + initialRecordCount)) return setTimeout(() => validateData(), 1000); + refreshInstance(Date.now()); return setTimeout(() => { setStatus(false); history.push(`/instances/${instance_id}/browse/${schema}/${table}`); @@ -47,9 +37,8 @@ export default ({ refreshInstance, instance_id, auth }) => { // insert the processed data into HarperDB const insertData = async () => { if (!processedData) return false; - setStatus('inserting'); - await queryInstance({ operation: 'csv_data_load', action: 'insert', schema, table, data: processedData }, auth); + await csvDataLoad({ schema, table, data: processedData, auth }); setProcessedData(false); return setTimeout(() => validateData(), 1000); }; @@ -58,7 +47,6 @@ export default ({ refreshInstance, instance_id, auth }) => { const processData = (data) => { setStatus('processing'); setNewRecordCount(data.length - 1); - worker.postMessage(data); worker.addEventListener('message', (event) => { setProcessedData(event.data); @@ -77,14 +65,14 @@ export default ({ refreshInstance, instance_id, auth }) => { history.push(`/instances/${instance_id}/browse/${schema}/${table}`); }; - useAsyncEffect(async () => setInitialRecordCount(await getCurrentRecordCount()), []); + useAsyncEffect(async () => setInitialRecordCount(await getTotalRecords({ schema, table, auth })), []); return ( <> - {schema} > {table} > csv upload + {schema} > {table} > csv upload - +
{status === 'validating' ? (
validated {validatedRecordCount ? commaNumbers(validatedRecordCount - initialRecordCount) : '0'} of {commaNumbers(newRecordCount)} records
@@ -93,14 +81,17 @@ export default ({ refreshInstance, instance_id, auth }) => { ) : status === 'processed' ? (
successfully prepared {commaNumbers(newRecordCount)} records
- +
) : status === 'processing' ? (
pre-processing {commaNumbers(newRecordCount)} records
) : fileError ? (
{fileError}
) : ( -
Click to select or drag and drop a .csv file to insert into {schema}.{table}
+
+ Click to select or drag and drop a .csv file to insert into {schema}.{table}
+ +
)}
{ !status && ( diff --git a/src/components/instance/browse/datatable.js b/src/components/instance/browse/datatable.js index 2b2fd7fb4..4a7a4c3a5 100644 --- a/src/components/instance/browse/datatable.js +++ b/src/components/instance/browse/datatable.js @@ -1,145 +1,88 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import ReactTable from 'react-table'; import { useHistory, useParams } from 'react-router'; import useAsyncEffect from 'use-async-effect'; +import useInterval from 'use-interval'; import { Card, CardBody, Col, Row } from '@nio/ui-kit'; import commaNumbers from '../../../util/commaNumbers'; -import queryInstance from '../../../util/queryInstance'; +import getTableData from '../../../api/instance/getTableData'; +import defaultTableState from '../../../state/defaults/defaultTableState'; -export default ({ dataTableColumns, hashAttribute, onFilteredChange, filtered, onSortedChange, sorted, onPageChange, page, auth, instance_id, refreshInstance, structure }) => { +const dataRefreshInterval = 3000; +let tableChangeTimeout = false; + +export default ({ activeTable: { hashAttribute, dataTableColumns }, auth, instance_id, refreshInstance, structure }) => { const history = useHistory(); const { schema, table } = useParams(); - - const [tableData, setTableData] = useState([]); - const [pages, setTotalPages] = useState(-1); - const [loading, setLoading] = useState(true); - const [pageSize, onPageSizeChange] = useState(20); - const [totalRecords, setTotalRecords] = useState(0); - const [showFilter, toggleShowFilter] = useState(false); - const [autoRefresh, toggleAutoRefresh] = useState(false); - const [lastUpdate, setLastUpdate] = useState(); - - const dataRefreshInterval = 3000; - let dataRefreshTimeout = false; - let tableChangeTimeout = false; - - const loadNewData = async (showSpinner = true) => { - setLoading(showSpinner); - - if (!sorted.length) return false; - - let newTotalPages = 1; - let newTotalRecords = 0; - let newData = []; - - try { - let countSQL = `SELECT count(*) as newTotalRecords FROM ${schema}.${table} `; - if (filtered.length) countSQL += `WHERE ${filtered.map((f) => ` \`${f.id}\` LIKE '%${f.value}%'`).join(' AND ')} `; - [{ newTotalRecords }] = await queryInstance({ operation: 'sql', sql: countSQL }, auth); - newTotalPages = newTotalRecords && Math.ceil(newTotalRecords / pageSize); - } catch (e) { - // console.log('Failed to get row count'); - } - - try { - let dataSQL = `SELECT * FROM ${schema}.${table} `; - if (filtered.length) dataSQL += `WHERE ${filtered.map((f) => ` \`${f.id}\` LIKE '%${f.value}%'`).join(' AND ')} `; - if (sorted.length) dataSQL += `ORDER BY \`${sorted[0].id}\` ${sorted[0].desc ? 'DESC' : 'ASC'}`; - dataSQL += ` LIMIT ${(page * pageSize) + pageSize} OFFSET ${page * pageSize}`; - newData = await queryInstance({ operation: 'sql', sql: dataSQL }, auth); - } catch (e) { - // console.log('Failed to get table data'); - } - - if (newData) setTableData(newData); - if (newTotalPages) setTotalPages(newTotalPages); - setTotalRecords(newTotalRecords); - return setLoading(false); - }; - - const handleRefreshClick = () => refreshInstance(Date.now()); - - const handleNewRecordClick = () => history.push(`/instances/${instance_id}/browse/${schema}/${table}/add`); - - const handleCSVUploadClick = () => history.push(`/instances/${instance_id}/browse/${schema}/${table}/csv`); - - const handleRowClick = (newActiveRecord) => history.push(`/instances/${instance_id}/browse/${schema}/${table}/edit/${newActiveRecord[hashAttribute]}`); - - const handleFilterClick = () => { if (showFilter) onFilteredChange([]); toggleShowFilter(!showFilter); }; + const [tableState, setTableState] = useState(defaultTableState); useAsyncEffect( - () => { + async () => { clearTimeout(tableChangeTimeout); - tableChangeTimeout = setTimeout(() => loadNewData(), 0); + tableChangeTimeout = setTimeout(async () => { + setTableState({ ...tableState, loading: true }); + const newData = await getTableData({ schema, table, tableState, auth }); + setTableState({ ...tableState, tableData: newData.tableData, totalPages: newData.totalPages, totalRecords: newData.totalRecords, loading: false }); + }, 100); }, () => { clearTimeout(tableChangeTimeout); }, - [sorted, table, pageSize, page, filtered, structure], + [table, structure, tableState.sorted, tableState.page, tableState.filtered, tableState.pageSize, tableState.lastUpdate], ); - useAsyncEffect( - async () => { - if (autoRefresh) { - clearTimeout(dataRefreshTimeout); - const [{ newTotalRecords }] = await queryInstance({ - operation: 'sql', - sql: `SELECT count(*) as newTotalRecords FROM ${schema}.${table} `, - }, auth); - if (newTotalRecords !== totalRecords) { - loadNewData(false); - setTimeout(() => refreshInstance(Date.now()), 100); - } - dataRefreshTimeout = setTimeout(() => setLastUpdate(Date.now()), dataRefreshInterval); - } - }, - () => clearTimeout(dataRefreshTimeout), - [lastUpdate, autoRefresh], - ); + useEffect(() => { + if (table) { + setTableState({ ...tableState, filtered: [], sorted: [{ id: hashAttribute, desc: false }], page: 0 }); + } + }, [table]); + + useInterval(() => { + if (tableState.autoRefresh) { + setTableState({ ...tableState, lastUpdate: Date.now() }); + } + }, dataRefreshInterval); return ( <> - + {schema}  {table && `> ${table} > `} - {loading ? ( - - ) : ( - {commaNumbers(totalRecords)} record{totalRecords !== 1 ? 's' : ''} - )} + {commaNumbers(tableState.totalRecords)} record{tableState.totalRecords !== 1 ? 's' : ''} - - + + refreshInstance(Date.now())} /> auto - toggleAutoRefresh(!autoRefresh)} /> + setTableState({ ...tableState, autoRefresh: !tableState.autoRefresh, lastUpdate: Date.now() })} /> | - - - + setTableState({ ...tableState, filtered: tableState.showFilter ? [] : tableState.filtered, showFilter: !tableState.showFilter })} /> + history.push(`/instances/${instance_id}/browse/${schema}/${table}/add`)} /> + history.push(`/instances/${instance_id}/browse/${schema}/${table}/csv`)} /> - + ({ onClick: () => handleRowClick(rowInfo.original) })} + hashAttribute={hashAttribute} + onFilteredChange={(value) => setTableState({ ...tableState, filtered: value })} + filtered={tableState.filtered} + onSortedChange={(value) => setTableState({ ...tableState, sorted: value })} + sorted={tableState.sorted} + onPageChange={(value) => setTableState({ ...tableState, page: value })} + page={tableState.page} + filterable={tableState.showFilter} + defaultPageSize={tableState.pageSize} + pageSize={tableState.pageSize} + onPageSizeChange={(value) => setTableState({ ...tableState, pageSize: value })} + getTrProps={(state, rowInfo) => ({ onClick: () => history.push(`/instances/${instance_id}/browse/${schema}/${table}/edit/${rowInfo.original[hashAttribute]}`) })} /> diff --git a/src/components/instance/browse/index.js b/src/components/instance/browse/index.js index a225ccd68..311222aef 100644 --- a/src/components/instance/browse/index.js +++ b/src/components/instance/browse/index.js @@ -1,57 +1,35 @@ -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; import { Row, Col, CardBody, Card } from '@nio/ui-kit'; import { useHistory } from 'react-router'; import { useParams } from 'react-router-dom'; +import useAsyncEffect from 'use-async-effect'; import DataTable from './datatable'; -import EntityManager from '../shared/entityManager'; +import EntityManager from '../../shared/entityManager'; import JSONViewer from './jsonviewer'; import CSVUploader from './csvuploader'; +import buildInstanceStructure from '../../../util/buildInstanceStructure'; +import handleSchemaTableRedirect from '../../../util/handleSchemaTableRedirect'; -export default ({ auth, structure, network, refreshInstance }) => { +export default ({ auth, structure, refreshInstance }) => { const history = useHistory(); const { instance_id, schema, table, action } = useParams(); + const [entities, setEntities] = useState({ schemas: [], tables: [], activeTable: false }); - const [filtered, onFilteredChange] = useState([]); - const [sorted, onSortedChange] = useState([]); - const [page, onPageChange] = useState(0); + useAsyncEffect(() => { + handleSchemaTableRedirect({ entities, instance_id, schema, table, history, targetPath: '/browse' }); + }, [schema, table, entities]); - const schemas = structure && Object.keys(structure); - const tables = structure && schemas && structure[schema] && Object.keys(structure[schema]); - const activeTable = structure && schemas && structure[schema] && tables && structure[schema][table] && structure[schema][table]; - - useEffect(() => { - if (activeTable) { - onFilteredChange([]); - onSortedChange([{ id: activeTable.hashAttribute, desc: false }]); - onPageChange(0); - } - }, [activeTable]); - - useEffect(() => { - switch (true) { - case (!schemas && history.location.pathname !== '/browse'): - history.push(`/instances/${instance_id}/browse`); - break; - case (schemas && schemas.length && !schema): - case (schemas && schemas.length && schema && !schemas.includes(schema)): - history.push(`/instances/${instance_id}/browse/${schemas[0]}`); - break; - case (tables && tables.length && !table): - case (tables && tables.length && table && !tables.includes(table)): - history.push(`/instances/${instance_id}/browse/${schema}/${tables[0]}`); - break; - default: - break; - } - }, [schema, schemas, table, tables]); + useAsyncEffect(() => { + if (structure) setEntities(buildInstanceStructure({ structure, schema, table })); + }, [structure, schema, table]); return ( { { schema && ( { /> )} - - { schema && table && action === 'csv' && activeTable ? ( + + { schema && table && action === 'csv' && entities.activeTable ? ( - ) : schema && table && action && activeTable ? ( + ) : schema && table && action && entities.activeTable ? ( - ) : schema && table && activeTable ? ( + ) : schema && table && entities.activeTable ? ( {   -
Please {(schema && tables && !tables.length) || !schemas.length ? 'create' : 'choose'} a {schema ? 'table' : 'schema'}
+
Please {(schema && entities.tables && !entities.tables.length) || !entities.schemas.length ? 'create' : 'choose'} a {schema ? 'table' : 'schema'}
diff --git a/src/components/instance/browse/jsonviewer.js b/src/components/instance/browse/jsonviewer.js index 9e08b1261..afd5d6269 100644 --- a/src/components/instance/browse/jsonviewer.js +++ b/src/components/instance/browse/jsonviewer.js @@ -5,7 +5,7 @@ import { Button, Card, CardBody, Col, Form, Row } from '@nio/ui-kit'; import { useHistory, useParams } from 'react-router'; import useAsyncEffect from 'use-async-effect'; -import queryInstance from '../../../util/queryInstance'; +import queryInstance from '../../../api/queryInstance'; export default ({ newEntityColumns, hashAttribute, instance_id, refreshInstance, auth }) => { const history = useHistory(); @@ -57,7 +57,7 @@ export default ({ newEntityColumns, hashAttribute, instance_id, refreshInstance, return ( <> - {schema} {table && '>'} {table} {action === 'add' ? '> add new' : hash ? `> ${hash}` : ''}  + {schema} {table && '>'} {table} {action === 'add' ? '> add new' : hash ? `> ${hash}` : ''} 
diff --git a/src/components/instance/clustering/clusterCard.js b/src/components/instance/clustering/clusterCard.js deleted file mode 100644 index e6071edbc..000000000 --- a/src/components/instance/clustering/clusterCard.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import { Button, Card, CardBody, Col, Row } from '@nio/ui-kit'; -import { useAlert } from 'react-alert'; - -export default ({ id, name }) => { - const alert = useAlert(); - - return ( - - - - {name} -
- - - - - - - - -
-
- - ); -}; diff --git a/src/components/instance/clustering/datatable.js b/src/components/instance/clustering/datatable.js new file mode 100644 index 000000000..4d253593d --- /dev/null +++ b/src/components/instance/clustering/datatable.js @@ -0,0 +1,65 @@ +import React, { useEffect, useState } from 'react'; +import ReactTable from 'react-table'; +import { Card, CardBody, Col, Row } from '@nio/ui-kit'; + +import defaultTableState from '../../../state/defaults/defaultTableState'; +import clusterConfigColumns from '../../../util/datatable/clusterConfigColumns'; + +export default ({ instances, network, schema, table, auth, refreshInstance }) => { + const [tableState, setTableState] = useState(defaultTableState); + const [tableData, setTableData] = useState({ data: [], columns: clusterConfigColumns({ auth, refreshInstance }) }); + + useEffect(() => { + if (table) { + const newTableData = instances.map((i) => { + const connection = network && network.outbound_connections.find((n) => n.name === i.id); + const subscriptions = schema && table && connection && connection.subscriptions ? connection.subscriptions : []; + const channel = schema && table && `${schema}:${table}`; + const channelSubscription = channel && subscriptions.find((s) => s.channel === channel); + const publish = channelSubscription && channelSubscription.publish; + const subscribe = channelSubscription && channelSubscription.subscribe; + const clusterPort = 12345; + const { id, instance_name, is_ssl, host, port } = i; + const url = `http${is_ssl ? 's' : ''}://${host}:${port}`; + return { id, instance_name, is_ssl, host, port, url, clusterPort, publish, subscribe, connection, channel, subscriptions }; + }); + setTableData({ ...tableData, data: newTableData }); + setTableState({ ...tableState, filtered: [], sorted: [{ id: 'instance_name', desc: false }], page: 0 }); + } + }, [table]); + + return ( + <> + + + + {schema} > {table} + + + + setTableState({ ...tableState, filtered: tableState.showFilter ? [] : tableState.filtered, showFilter: !tableState.showFilter })} /> + + + + + setTableState({ ...tableState, filtered: value })} + filtered={tableState.filtered} + onSortedChange={(value) => setTableState({ ...tableState, sorted: value })} + sorted={tableState.sorted} + onPageChange={(value) => setTableState({ ...tableState, page: value })} + page={tableState.page} + filterable={tableState.showFilter} + defaultPageSize={tableState.pageSize} + pageSize={tableState.pageSize} + onPageSizeChange={(value) => setTableState({ ...tableState, pageSize: value })} + resizable={false} + /> + + + + ); +}; diff --git a/src/components/instance/clustering/index.js b/src/components/instance/clustering/index.js index 1f7de8716..21b0d3a9e 100644 --- a/src/components/instance/clustering/index.js +++ b/src/components/instance/clustering/index.js @@ -1,78 +1,21 @@ -import React, { useEffect } from 'react'; -import { Code, Row, Col, Card, CardBody, Button } from '@nio/ui-kit'; -import { useParams } from 'react-router-dom'; -import { useHistory } from 'react-router'; -import stringify from 'json-stringify-pretty-compact'; -import { useAlert } from 'react-alert'; +import React from 'react'; -import EntityManager from '../shared/entityManager'; -import useLMS from '../../../stores/lmsData'; -import ClusterCard from './clusterCard'; +import Setup from './setup'; +import Manage from './manage'; -export default ({ auth, structure, network, refreshInstance }) => { - const history = useHistory(); - const [lmsData] = useLMS({ auth: false, instances: [] }); - const { instance_id, schema, table } = useParams(); - - const schemas = structure && Object.keys(structure); - const tables = structure && schemas && structure[schema] && Object.keys(structure[schema]); - - useEffect(() => { - switch (true) { - case (!schemas && history.location.pathname !== '/clustering'): - history.push(`/instances/${instance_id}/clustering`); - break; - case (schemas && schemas.length && !schema): - case (schemas && schemas.length && schema && !schemas.includes(schema)): - history.push(`/instances/${instance_id}/clustering/${schemas[0]}`); - break; - case (tables && tables.length && !table): - case (tables && tables.length && table && !tables.includes(table)): - history.push(`/instances/${instance_id}/clustering/${schema}/${tables[0]}`); - break; - default: - break; - } - }, [schema, schemas, table, tables]); - - return ( - - - - { schema && ( - - )} - - -
- {schema} > {table} > data replication -
- - {lmsData.instances.filter((i) => i.id !== instance_id).map((i) => ( - - ))} - -
- - {stringify(network.outbound_connections, { maxLength: 20 })} - -
- -
- ); -}; +export default ({ auth, structure, network, refreshInstance }) => (!network ? ( + +) : network.is_enabled && network.cluster_user && network.cluster_role ? ( + +) : ( + +)); diff --git a/src/components/instance/clustering/manage.js b/src/components/instance/clustering/manage.js new file mode 100644 index 000000000..14fa01476 --- /dev/null +++ b/src/components/instance/clustering/manage.js @@ -0,0 +1,64 @@ +import React, { useState } from 'react'; +import { Row, Col } from '@nio/ui-kit'; +import { useParams } from 'react-router-dom'; +import { useHistory } from 'react-router'; +import useAsyncEffect from 'use-async-effect'; + +import EntityManager from '../../shared/entityManager'; +import DataTable from './datatable'; +import buildInstanceStructure from '../../../util/buildInstanceStructure'; +import handleSchemaTableRedirect from '../../../util/handleSchemaTableRedirect'; +import useApp from '../../../state/stores/appData'; +import defaultAppData from '../../../state/defaults/defaultAppData'; + +export default ({ auth, network, refreshInstance, structure }) => { + const history = useHistory(); + const [appData] = useApp(defaultAppData); + const { instance_id, schema, table } = useParams(); + const [entities, setEntities] = useState({ schemas: [], tables: [] }); + + useAsyncEffect(() => { + handleSchemaTableRedirect({ entities, instance_id, schema, table, history, targetPath: '/clustering' }); + }, [schema, table, entities]); + + useAsyncEffect(() => { + if (structure) setEntities(buildInstanceStructure({ structure, schema, table })); + }, [structure, schema, table]); + + return ( + + + + { schema && ( + + )} + + + i.id !== instance_id)} + network={network} + schema={schema} + table={table} + auth={auth} + instance_id={instance_id} + refreshInstance={refreshInstance} + /> + + + ); +}; diff --git a/src/components/instance/clustering/setup.js b/src/components/instance/clustering/setup.js new file mode 100644 index 000000000..c2f7fa551 --- /dev/null +++ b/src/components/instance/clustering/setup.js @@ -0,0 +1,65 @@ +import React, { useState } from 'react'; +import { Row, Col, Card, CardBody } from '@nio/ui-kit'; +import { useParams } from 'react-router-dom'; + +import Role from './setup_role'; +import User from './setup_user'; +import Port from './setup_port'; +import Enable from './setup_enable'; + +export default ({ auth, network, refreshInstance }) => { + const [port, setPort] = useState(false); + const { instance_id } = useParams(); + + return ( + + + clustering + + + HarperDB allows you to replicate data between one or more instances. We call this feature "clustering". +
+ This instance does not yet have clustering enabled. To enable clustering, follow the steps outlined at right. +
+ The Cluster User and Password must be the same between all instances in a HarperDB cluster. +
+
+ + + follow the steps below to enable clustering for this instance. + + + + {network.cluster_role && ( + + )} + {network.cluster_user && ( + + )} + {port && ( + + )} + + + +
+ ); +}; diff --git a/src/components/instance/clustering/setup_enable.js b/src/components/instance/clustering/setup_enable.js new file mode 100644 index 000000000..4a820e476 --- /dev/null +++ b/src/components/instance/clustering/setup_enable.js @@ -0,0 +1,28 @@ +import React, { useState } from 'react'; +import { Row, Col, Button } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; + +import configureCluster from '../../../api/instance/configureCluster'; + +export default ({ port, username, instanceId, auth, refreshInstance }) => { + const [submitted, setSubmitted] = useState(false); + + useAsyncEffect(async () => { + if (submitted) await configureCluster({ port, username, instanceId, auth, refreshInstance }); + }, [submitted]); + + return ( + + + + + + ); +}; diff --git a/src/components/instance/clustering/setup_port.js b/src/components/instance/clustering/setup_port.js new file mode 100644 index 000000000..d035df952 --- /dev/null +++ b/src/components/instance/clustering/setup_port.js @@ -0,0 +1,51 @@ +import React, { useState } from 'react'; +import { Row, Col, Button, Input } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; +import { useAlert } from 'react-alert'; + +import defaultFormData from '../../../state/defaults/defaultClusterFormData'; + +export default ({ port, setPort }) => { + const alert = useAlert(); + const [portFormData, updatePortForm] = useState(defaultFormData); + + useAsyncEffect(async () => { + const { submitted, newPort } = portFormData; + if (submitted) { + if (!newPort) { + updatePortForm({ ...portFormData, error: true, submitted: false }); + alert.error('All fields are required.'); + } else { + setPort(newPort); + updatePortForm({ ...defaultFormData }); + } + } + }, [portFormData]); + + return port ? ( + + Cluster Port + {port} + + + + + ) : ( + + Choose a Cluster Port + + updatePortForm({ ...portFormData, newPort: e.target.value, error: false })} + className="mb-1" + type="number" + title="port" + placeholder="cluster port" + /> + + + + + + + ); +}; diff --git a/src/components/instance/clustering/setup_role.js b/src/components/instance/clustering/setup_role.js new file mode 100644 index 000000000..966c6e4aa --- /dev/null +++ b/src/components/instance/clustering/setup_role.js @@ -0,0 +1,21 @@ +import React from 'react'; +import { Row, Col, Button } from '@nio/ui-kit'; + +import createClusterUserRole from '../../../api/instance/createClusterUserRole'; + +export default ({ auth, clusterRole, refreshInstance }) => (clusterRole ? ( + + Cluster Role + {clusterRole} + + + + +) : ( + + First, create a Cluster Role + + + + +)); diff --git a/src/components/instance/clustering/setup_user.js b/src/components/instance/clustering/setup_user.js new file mode 100644 index 000000000..1ac6be243 --- /dev/null +++ b/src/components/instance/clustering/setup_user.js @@ -0,0 +1,62 @@ +import React, { useState } from 'react'; +import { Row, Col, Button, Input } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; +import { useAlert } from 'react-alert'; + +import defaultFormData from '../../../state/defaults/defaultClusterFormData'; +import createClusterUser from '../../../api/instance/createClusterUser'; + +export default ({ clusterUser, clusterRole, auth, refreshInstance }) => { + const alert = useAlert(); + const [userFormData, updateUserForm] = useState(defaultFormData); + + useAsyncEffect(async () => { + const { submitted, username, password } = userFormData; + if (submitted) { + if (!username || !password) { + updateUserForm({ ...userFormData, error: true, submitted: false }); + alert.error('All fields are required.'); + } else { + const result = await createClusterUser({ username, password, role: clusterRole, auth, refreshInstance }); + if (result.message.indexOf('successfully') === -1) { + alert.error(result.message); + } + } + } + }, [userFormData]); + + return clusterUser ? ( + + Cluster User + {clusterUser} + + + + + ) : ( + + Create a Cluster User + + updateUserForm({ ...userFormData, username: e.target.value, error: false })} + className="mb-1" + type="text" + title="username" + placeholder="username" + /> + + + updateUserForm({ ...userFormData, password: e.target.value, error: false })} + className="mb-1" + type="password" + title="password" + placeholder="password" + /> + + + + + + ); +}; diff --git a/src/components/instance/config/index.js b/src/components/instance/config/index.js new file mode 100644 index 000000000..3ff163315 --- /dev/null +++ b/src/components/instance/config/index.js @@ -0,0 +1,26 @@ +import React from 'react'; + +import UpdateInstanceForm from './updateInstanceForm'; +import useApp from '../../../state/stores/appData'; +import defaultAppData from '../../../state/defaults/defaultAppData'; + +export default ({ auth, details, refreshInstance }) => { + const [{ products }] = useApp(defaultAppData); + + return ( + <> + resize instance + {products && details ? ( + + ) : ( + + )} + + ); +} diff --git a/src/components/instance/config/instanceDetails.js b/src/components/instance/config/instanceDetails.js new file mode 100644 index 000000000..8b924aa80 --- /dev/null +++ b/src/components/instance/config/instanceDetails.js @@ -0,0 +1,103 @@ +import React from 'react'; +import { Card, CardBody, Row, Col } from '@nio/ui-kit'; + +export default ({ details: { instance_name, is_local, host, port, is_ssl, instance_region, disk_space }, activeCompute, activeStorage }) => { + let totalPrice = 0; + if (activeCompute.price !== 'FREE') totalPrice += parseFloat(activeCompute.price); + if (activeStorage.price !== 'FREE') totalPrice += parseFloat(activeStorage.price); + + return ( + + + + + + + Instance Name + + + {instance_name} + + +
+ {is_local ? ( + <> + + + Host + + + {host} + + +
+ + + Port + + + {port} + + +
+ + + Uses SSL + + + {is_ssl.toString()} + + +
+ + ) : ( + <> + + + Instance Region + + + {instance_region} + + +
+ + + Instance Storage + + + {disk_space} + + + {activeStorage.price === 'FREE' ? 'FREE' : `$${activeStorage.price}/${activeStorage.interval}`} + + +
+ + )} + + + Instance RAM + + + {activeCompute.ram} + + + {activeCompute.price === 'FREE' ? 'FREE' : `$${activeCompute.price}/${activeCompute.interval}`} + + +
+ + + Instance Total Price + + + {totalPrice ? `$${totalPrice.toFixed(2)}/${activeCompute.interval}` : 'FREE'} + + +
+
+
+
+ ); +}; diff --git a/src/components/instance/config/updateInstanceForm.js b/src/components/instance/config/updateInstanceForm.js new file mode 100644 index 000000000..cc5673e6a --- /dev/null +++ b/src/components/instance/config/updateInstanceForm.js @@ -0,0 +1,140 @@ +import React, { useState } from 'react'; +import { Button, Card, CardBody, Col, Input, RadioCheckbox, Row } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; +import { useHistory } from 'react-router'; + +import useLMS from '../../../state/stores/lmsAuth'; +import updateInstance from '../../../api/lms/updateInstance'; +import updateLicense from '../../../api/lms/updateLicense'; +import setLicense from '../../../api/instance/setLicense'; +import defaultLMSAuth from '../../../state/defaults/defaultLMSAuth'; +import customerHasChargeableCard from '../../../util/stripe/customerHasChargeableCard'; +import useApp from '../../../state/stores/appData'; +import defaultAppData from '../../../state/defaults/defaultAppData'; + +export default ({ instanceAuth, details, refreshInstance, computeProducts, storageProducts }) => { + const [lmsAuth] = useLMS(defaultLMSAuth); + const [{ customer }] = useApp(defaultAppData); + const history = useHistory(); + const [formState, setFormState] = useState({ submitted: false, error: false }); + const [formData, updateForm] = useState({ instance_name: details.instance_name, stripe_plan_id: details.stripe_plan_id, storage_qty_gb: details.storage_qty_gb }); + const hasCard = customerHasChargeableCard(customer); + + let totalPrice = 0; + const newComputePrice = computeProducts.find((p) => p.value === formData.stripe_plan_id); + if (newComputePrice.price !== 'FREE') totalPrice += parseFloat(newComputePrice.price); + + if (storageProducts) { + const newStoragePrice = storageProducts.find((p) => p.value === formData.storage_qty_gb); + if (newStoragePrice.price !== 'FREE') totalPrice += parseFloat(newStoragePrice.price); + } + + const hasChanged = details.stripe_plan_id !== formData.stripe_plan_id || details.storage_qty_gb !== formData.storage_qty_gb; + + useAsyncEffect(async () => { + const { submitted } = formState; + if (submitted) { + const { stripe_product_id, instance_name, instance_id, customer_id, license_id, fingerprint, storage_qty_gb } = formData; + + const newLicense = await updateLicense({ auth: lmsAuth, payload: { license_id, stripe_product_id, instance_id, customer_id, fingerprint } }); + await setLicense({ auth: instanceAuth, key: newLicense.key, company: newLicense.company }); + await updateInstance({ auth: lmsAuth, payload: { stripe_product_id, instance_id, customer_id, instance_name, storage_qty_gb } }); + setFormState({ submitted: false }); + refreshInstance(Date.now()); + } + }, [formState]); + + return ( + + +
Instance Name
+
+ updateForm({ ...formData, instance_name: e.target.value, error: false })} + type="text" + title="instance_name" + value={formData.instance_name} + /> +
+ + {details.region && ( + <> +
Instance Region (no modification)
+
+ {details.region.label} +
+ + )} + + {storageProducts && ( + <> +
Storage Size
+
+ updateForm({ ...formData, storage_qty_gb: value })} + options={storageProducts} + value={formData.storage_qty_gb} + defaultValue={details.storage} + /> +
+ + )} + +
Instance Type
+
+ {computeProducts && ( + updateForm({ ...formData, stripe_plan_id: value })} + options={computeProducts} + value={formData.stripe_plan_id} + defaultValue={details.compute} + /> + )} +
+ +
+ + + + {!hasChanged ? 'Current' : 'New'} Price + + + ${totalPrice.toFixed(2)}/{details.compute.interval} + + + +
+ + {hasChanged && totalPrice && !hasCard ? ( + + ) : ( + + )} +
+
+ ); +}; diff --git a/src/components/instance/index.js b/src/components/instance/index.js index 7958aac15..fe6a23be2 100644 --- a/src/components/instance/index.js +++ b/src/components/instance/index.js @@ -2,22 +2,39 @@ import React, { useState } from 'react'; import { Route, Switch, useParams } from 'react-router-dom'; import useAsyncEffect from 'use-async-effect'; -import TopNav from '../topnav'; +import SubNav from '../navs/subnav'; import routes from './routes'; -import useLMS from '../../stores/lmsData'; -import useInstanceAuth from '../../stores/instanceAuths'; +import useLMS from '../../state/stores/lmsAuth'; +import useInstanceAuth from '../../state/stores/instanceAuths'; import buildActiveInstanceObject from '../../util/buildActiveInstanceObject'; +import defaultLMSAuth from '../../state/defaults/defaultLMSAuth'; +import defaultActiveInstance from '../../state/defaults/defaultActiveInstance'; +import getInstances from '../../api/lms/getInstances'; +import getLicenses from '../../api/lms/getLicenses'; +import useApp from '../../state/stores/appData'; +import defaultAppData from '../../state/defaults/defaultAppData'; +import getProducts from '../../api/lms/getProducts'; +import getRegions from '../../api/lms/getRegions'; +import getCustomer from '../../api/lms/getCustomer'; export default () => { const { instance_id } = useParams(); - const [lmsData] = useLMS({ auth: false, instances: [] }); + const [lmsAuth] = useLMS(defaultLMSAuth); + const [appData, setAppData] = useApp(defaultAppData); const [instanceAuths] = useInstanceAuth({}); - const [activeInstance, setActiveInstance] = useState({ auth: false, structure: false, network: false }); - const [lastUpdate, refreshInstance] = useState({ auth: false, structure: false, network: false }); + const [activeInstance, setActiveInstance] = useState(defaultActiveInstance); + const [lastUpdate, refreshInstance] = useState(false); useAsyncEffect(async () => { if (instance_id) { - const activeInstanceObject = await buildActiveInstanceObject({ instance_id, instanceAuths, lmsData }); + const products = await getProducts(); + const regions = await getRegions(); + const customer = await getCustomer({ auth: lmsAuth }); + const licenses = await getLicenses({ auth: lmsAuth }); + const instances = await getInstances({ auth: lmsAuth, products, regions, licenses }); + const newAppData = { ...appData, customer, products, regions, instances, licenses }; + setAppData(newAppData); + const activeInstanceObject = await buildActiveInstanceObject({ instance_id, instanceAuths, appData: newAppData }); if (!activeInstanceObject.error) { setActiveInstance(activeInstanceObject); } @@ -26,7 +43,7 @@ export default () => { return ( <> - + {routes.map((route) => { const ThisRouteComponent = route.component; diff --git a/src/components/instance/license/index.js b/src/components/instance/license/index.js deleted file mode 100644 index d5e4428b2..000000000 --- a/src/components/instance/license/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import { Card, CardBody, Row, Col } from '@nio/ui-kit'; - -export default () => ( - - - License - - - content here - - - - -); diff --git a/src/components/instance/roles/index.js b/src/components/instance/roles/index.js index 3a569d8f5..f217df3d6 100644 --- a/src/components/instance/roles/index.js +++ b/src/components/instance/roles/index.js @@ -4,8 +4,8 @@ import { Card, CardBody, Row, Col } from '@nio/ui-kit'; export default () => ( - Roles - + roles + content here diff --git a/src/components/instance/routes.js b/src/components/instance/routes.js index 157c45a32..0b78979fa 100644 --- a/src/components/instance/routes.js +++ b/src/components/instance/routes.js @@ -1,13 +1,13 @@ import Browse from './browse'; import Clustering from './clustering'; -import License from './license'; +import Config from './config'; import Users from './users'; import Roles from './roles'; export default [ - { component: Browse, path: '/instances/:instance_id/browse/:schema?/:table?/:action?/:hash?', link: 'browse' }, - { component: Clustering, path: '/instances/:instance_id/clustering/:schema?/:table?', link: 'clustering' }, - { component: License, path: '/instances/:instance_id/license', link: 'license' }, - { component: Users, path: '/instances/:instance_id/users', link: 'users' }, - { component: Roles, path: '/instances/:instance_id/roles', link: 'roles' }, + { component: Browse, path: '/instances/:instance_id/browse/:schema?/:table?/:action?/:hash?', link: 'browse', icon: 'list' }, + { component: Clustering, path: '/instances/:instance_id/clustering/:schema?/:table?', link: 'clustering', icon: 'share-alt' }, + { component: Config, path: '/instances/:instance_id/config', link: 'config', icon: 'wrench' }, + { component: Users, path: '/instances/:instance_id/users', link: 'users', icon: 'users' }, + { component: Roles, path: '/instances/:instance_id/roles', link: 'roles', icon: 'check-square' }, ]; diff --git a/src/components/instance/users/add.js b/src/components/instance/users/add.js new file mode 100644 index 000000000..48fe3b510 --- /dev/null +++ b/src/components/instance/users/add.js @@ -0,0 +1,98 @@ +import React, { useState } from 'react'; +import { Input, Button, Card, CardBody, RadioCheckbox } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; +import { useAlert } from 'react-alert'; + +import addUser from '../../../api/instance/addUser'; + +export default ({ auth, roles, users, refreshInstance }) => { + const alert = useAlert(); + const [formState, setFormState] = useState({ submitted: false, error: false }); + const [formData, updateForm] = useState({ username: '', password: '' }); + + useAsyncEffect(async () => { + const { submitted } = formState; + if (submitted) { + const { username, password, role } = formData; + + if (!username || !role || !password) { + setFormState({ submitted: false, error: 'All fields must be filled out' }); + } else if (username.indexOf(' ') !== -1) { + setFormState({ submitted: false, error: 'Username may not have spaces' }); + } else if (users.find((u) => u.username.toLowerCase() === username.toLowerCase())) { + setFormState({ submitted: false, error: 'User already exists' }); + } else { + const response = await addUser({ auth, role, username, password }); + if (response.message.indexOf('successfully') !== -1) { + updateForm({ username: '', password: '', role: roles[0].id }); + refreshInstance(Date.now()); + alert.success(response.message); + } else { + alert.error(response.message); + } + setFormState({ submitted: false, error: false }); + } + } + }, [formState]); + + useAsyncEffect(() => { if (roles) updateForm({ ...formData, role: roles[0].id }); }, [roles]); + + return ( + <> + add user + + +
username
+
+ updateForm({ ...formData, username: e.target.value, error: false })} + /> +
+ +
password
+
+ updateForm({ ...formData, password: e.target.value, error: false })} + /> +
+ +
role
+
+ {roles && ( + updateForm({ ...formData, role: value })} + options={roles ? roles.map((r) => ({ label: r.role, value: r.id })) : []} + value={formData.role} + defaultValue={formData.role} + /> + )} +
+ + + {formState.error && ( +
+
+ {formState.error} +
+ )} +
+
+ + ); +}; diff --git a/src/components/instance/users/datatable.js b/src/components/instance/users/datatable.js new file mode 100644 index 000000000..9b2b6efed --- /dev/null +++ b/src/components/instance/users/datatable.js @@ -0,0 +1,44 @@ +import React, { useState } from 'react'; +import { Card, CardBody, Row, Col } from '@nio/ui-kit'; +import ReactTable from 'react-table'; + +import defaultTableState from '../../../state/defaults/defaultTableState'; + +export default ({ tableData }) => { + const [tableState, setTableState] = useState({ ...defaultTableState, sorted: [{ id: 'username', desc: false }] }); + + return ( + <> + + + existing users + + + setTableState({ ...tableState, filtered: tableState.showFilter ? [] : tableState.filtered, showFilter: !tableState.showFilter })}> + + + + + + + setTableState({ ...tableState, filtered: value })} + filtered={tableState.filtered} + onSortedChange={(value) => setTableState({ ...tableState, sorted: value })} + sorted={tableState.sorted} + onPageChange={(value) => setTableState({ ...tableState, page: value })} + page={tableState.page} + filterable={tableState.showFilter} + defaultPageSize={tableState.pageSize} + pageSize={tableState.pageSize} + onPageSizeChange={(value) => setTableState({ ...tableState, pageSize: value })} + resizable={false} + /> + + + + ); +}; diff --git a/src/components/instance/users/index.js b/src/components/instance/users/index.js index 227faca60..d9f52b9b8 100644 --- a/src/components/instance/users/index.js +++ b/src/components/instance/users/index.js @@ -1,15 +1,42 @@ -import React from 'react'; -import { Card, CardBody, Row, Col } from '@nio/ui-kit'; - -export default () => ( - - - Users - - - content here - - - - -); +import React, { useState, useEffect } from 'react'; +import { Row, Col } from '@nio/ui-kit'; +import { useAlert } from 'react-alert'; + +import DataTable from './datatable'; +import AddUserForm from './add'; + +import dropUser from '../../../api/instance/dropUser'; +import instanceUserColumns from '../../../util/datatable/instanceUserColumns'; + +export default ({ auth, users, roles, refreshInstance }) => { + const alert = useAlert(); + const [tableData, setTableData] = useState({ data: [], columns: [] }); + + const deleteUser = async ({ username }) => { + const response = await dropUser({ auth, username }); + + if (response.message.indexOf('successfully') !== -1) { + alert.success(response.message); + setTimeout(() => refreshInstance(Date.now()), 0); + } else { + alert.error(response.message); + } + }; + + useEffect(() => { + if (users && auth) { + setTableData({ data: users, columns: instanceUserColumns({ deleteUser }) }); + } + }, [users, auth]); + + return ( + + + + + + + + + ); +}; diff --git a/src/components/instances/cardBack.js b/src/components/instances/cardBack.js deleted file mode 100644 index 235ff4354..000000000 --- a/src/components/instances/cardBack.js +++ /dev/null @@ -1,68 +0,0 @@ -import React, { useState } from 'react'; -import { Button, Card, CardBody, Input, Row, Col } from '@nio/ui-kit'; -import useAsyncEffect from 'use-async-effect'; -import { useAlert } from 'react-alert'; -import queryInstance from '../../util/queryInstance'; -import defaultFormData from '../../util/defaultFormData'; - -export default ({ id, url, port, is_ssl, setAuth, flipCard }) => { - const alert = useAlert(); - const [formData, updateForm] = useState(defaultFormData); - - useAsyncEffect(async () => { - if (formData.submitted) { - const instance = await queryInstance({ operation: 'describe_all' }, { ...formData, url, port, is_ssl }); - if (instance.error) { - alert.error(instance.error); - updateForm({ ...formData, error: instance.error, submitted: false }); - } else { - updateForm(defaultFormData); - setAuth({ id, user: formData.user, pass: formData.pass }); - flipCard(); - } - } - }, [formData]); - - return ( - - - updateForm({ ...formData, user: e.target.value, error: false })} - className="text-center mb-1" - type="text" - title="username" - placeholder="user" - /> - updateForm({ ...formData, pass: e.target.value, error: false })} - className="text-center mb-1" - type="password" - title="password" - placeholder="pass" - /> - - - - - - - - - - - ); -}; diff --git a/src/components/instances/index.js b/src/components/instances/index.js index 251ef5397..a88bb6270 100644 --- a/src/components/instances/index.js +++ b/src/components/instances/index.js @@ -1,23 +1,66 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Row } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; -import TopNav from '../topnav'; -import useLMS from '../../stores/lmsData'; -import useInstanceAuth from '../../stores/instanceAuths'; -import InstanceCard from './instanceCard'; -import NewInstanceCard from './newInstanceCard'; +import useInstanceAuth from '../../state/stores/instanceAuths'; +import useApp from '../../state/stores/appData'; +import useLMS from '../../state/stores/lmsAuth'; + +import defaultAppData from '../../state/defaults/defaultAppData'; +import defaultLMSAuth from '../../state/defaults/defaultLMSAuth'; + +import InstanceCard from './list/instanceCard'; +import NewInstanceCard from './list/newInstanceCard'; +import SubNav from '../navs/subnav'; + +import getInstances from '../../api/lms/getInstances'; +import getLicenses from '../../api/lms/getLicenses'; +import filterInstances from '../../util/filterInstances'; +import getCustomer from '../../api/lms/getCustomer'; +import getProducts from '../../api/lms/getProducts'; +import getRegions from '../../api/lms/getRegions'; export default () => { - const [lmsData] = useLMS({ auth: false, instances: [] }); + const [lmsAuth] = useLMS(defaultLMSAuth); const [instanceAuths, setInstanceAuths] = useInstanceAuth({}); + const [appData, setAppData] = useApp(defaultAppData); + const [search, setSearch] = useState(''); + const [local, setLocal] = useState(true); + const [cloud, setCloud] = useState(true); + const [filteredInstances, setFilteredInstances] = useState([]); + + useAsyncEffect(() => { + setFilteredInstances(filterInstances({ local, cloud, search, instances: appData.instances })); + }, [search, local, cloud, appData.instances]); + + useAsyncEffect(async () => { + const products = await getProducts(); + const regions = await getRegions(); + const customer = await getCustomer({ auth: lmsAuth }); + const licenses = await getLicenses({ auth: lmsAuth }); + const instances = await getInstances({ auth: lmsAuth, products, regions, licenses }); + setAppData({ ...appData, customer, products, regions, instances, licenses }); + }, []); return ( <> - + - {lmsData.instances.map((i) => ( - setInstanceAuths({ ...instanceAuths, [id]: { user, pass } })} /> + {filteredInstances?.map((i) => ( + setInstanceAuths({ ...instanceAuths, [id]: user && pass ? { user, pass } : false })} + /> ))} diff --git a/src/components/instances/list/cardBack.js b/src/components/instances/list/cardBack.js new file mode 100644 index 000000000..497d67c40 --- /dev/null +++ b/src/components/instances/list/cardBack.js @@ -0,0 +1,70 @@ +import React, { useState } from 'react'; +import { Button, Card, CardBody, Input, Row, Col } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; +import { useAlert } from 'react-alert'; +import queryInstance from '../../../api/queryInstance'; +import defaultAuthFormData from '../../../state/defaults/defaultAuthFormData'; + +export default ({ id, host, port, is_ssl, setAuth, flipCard, flipState }) => { + const alert = useAlert(); + const [formData, updateForm] = useState(defaultAuthFormData); + + useAsyncEffect(async () => { + if (formData.submitted) { + const instance = await queryInstance({ operation: 'describe_all' }, { ...formData, host, port, is_ssl }); + if (instance.error) { + alert.error(instance.error); + updateForm({ ...formData, error: instance.error, submitted: false }); + } else { + updateForm(defaultAuthFormData); + setAuth({ id, user: formData.user, pass: formData.pass }); + flipCard(); + } + } + }, [formData]); + + return ( + + {flipState && ( // don't render the forms unless the card is flipped, as the autocomplete icon shows through + + updateForm({ ...formData, user: e.target.value, error: false })} + className="text-center mb-1" + type="text" + title="username" + placeholder="user" + /> + updateForm({ ...formData, pass: e.target.value, error: false })} + className="text-center mb-2" + type="password" + title="password" + placeholder="pass" + /> + + + + + + + + + + )} + + ); +}; diff --git a/src/components/instances/cardFront.js b/src/components/instances/list/cardFront.js similarity index 66% rename from src/components/instances/cardFront.js rename to src/components/instances/list/cardFront.js index 9b0522d25..9298bdfb0 100644 --- a/src/components/instances/cardFront.js +++ b/src/components/instances/list/cardFront.js @@ -3,7 +3,7 @@ import { Card, CardBody, Col, Row } from '@nio/ui-kit'; import { useHistory } from 'react-router'; import { useAlert } from 'react-alert'; -export default ({ id, name, url, port, is_ssl, flipCard, setAuth, hasAuth }) => { +export default ({ id, instance_name, host, port, is_ssl, is_local, flipCard, setAuth, hasAuth, compute, storage }) => { const history = useHistory(); const alert = useAlert(); @@ -11,8 +11,8 @@ export default ({ id, name, url, port, is_ssl, flipCard, setAuth, hasAuth }) => (hasAuth ? history.push(`/instances/${id}/browse`) : alert.error('You must log in first.') && flipCard())}> - - {name} + + {instance_name} {hasAuth ? ( @@ -22,20 +22,21 @@ export default ({ id, name, url, port, is_ssl, flipCard, setAuth, hasAuth }) => )} -
+
- + URL - http{is_ssl && 's'}://{url}:{port} + http{is_ssl && 's'}://{host}:{port}
TYPE - local -
- LICENSE - free + {is_local ? 'Local' : 'HarperDB Cloud'}
RAM - 1GB + {compute ? compute.ram : } +
+ STORAGE + {storage ? storage.disk_space : 'n/a'} +
diff --git a/src/components/instances/instanceCard.js b/src/components/instances/list/instanceCard.js similarity index 95% rename from src/components/instances/instanceCard.js rename to src/components/instances/list/instanceCard.js index 3901a1ee6..07fd71e9d 100644 --- a/src/components/instances/instanceCard.js +++ b/src/components/instances/list/instanceCard.js @@ -7,7 +7,6 @@ import CardBack from './cardBack'; export default (props) => { const [flipState, setFlipState] = useState(false); - return ( @@ -18,6 +17,7 @@ export default (props) => { setFlipState(false)} + flipState={flipState} {...props} /> diff --git a/src/components/instances/list/newInstanceCard.js b/src/components/instances/list/newInstanceCard.js new file mode 100644 index 000000000..ebfefcea8 --- /dev/null +++ b/src/components/instances/list/newInstanceCard.js @@ -0,0 +1,21 @@ +import React, { useState } from 'react'; +import { Card, CardBody, Col } from '@nio/ui-kit'; + +import NewInstanceModal from '../new'; + +export default () => { + const [showForm, setShowForm] = useState(false); + + return ( + <> + + setShowForm(true)}> + + + + + + {showForm && ()} + + ); +}; diff --git a/src/components/instances/new/cloud.js b/src/components/instances/new/cloud.js new file mode 100644 index 000000000..ed1150d2f --- /dev/null +++ b/src/components/instances/new/cloud.js @@ -0,0 +1,110 @@ +import React, { useState } from 'react'; +import { RadioCheckbox, Button, Card, CardBody, Col, Row } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; + +export default ({ products, storage, regions, hasCard, newInstance, setNewInstance, setPurchaseStep }) => { + const [formState, setFormState] = useState({ submitted: false, error: false }); + const [formData, updateForm] = useState({ + storage_qty_gb: newInstance.storage_qty_gb || storage[0].value, + stripe_plan_id: newInstance.stripe_plan_id || products[0].value, + instance_region: newInstance.instance_region || regions[0].value, + stripe_product_id: 'prod_Gh1XXQx6J8YaJl', + stripe_storage_product_id: 'prod_GoUJnVwOYvTjU9', + stripe_storage_plan_id: 'plan_GoUmLEBX2KIiaF', + }); + + const computePrice = products && products.find((p) => p.value === formData.stripe_plan_id).price; + const storagePrice = storage && storage.find((p) => p.value === formData.storage_qty_gb).price; + const needsCard = products && storage && !hasCard && computePrice && (computePrice !== 'FREE' || storagePrice !== 'FREE'); + + useAsyncEffect(() => { + const { submitted } = formState; + const { stripe_plan_id, instance_region, storage_qty_gb } = formData; + if (submitted) { + if (stripe_plan_id && instance_region && storage_qty_gb) { + setNewInstance({ ...newInstance, ...formData }); + setPurchaseStep(needsCard ? 'payment' : 'confirm'); + } else { + setFormState({ submitted: false, error: 'All fields must be filled out.' }); + } + } + }, [formState]); + + return ( + <> + + +
Storage Size (scroll for more)
+
+ updateForm({ ...formData, storage_qty_gb: value })} + options={storage} + value={formData.storage_qty_gb} + defaultValue={newInstance.storage_qty_gb ? storage.find((p) => p.value === newInstance.storage_qty_gb) : storage[0]} + /> +
+ +
Instance RAM (scroll for more)
+
+ updateForm({ ...formData, stripe_plan_id: value })} + options={products} + value={formData.stripe_plan_id} + defaultValue={newInstance.stripe_plan_id ? products.find((p) => p.value === newInstance.stripe_plan_id) : products[0]} + /> +
+ +
Instance Region (scroll for more)
+
+ updateForm({ ...formData, instance_region: value })} + options={regions} + value={formData.instance_region} + defaultValue={newInstance.instance_region ? regions.find((p) => p.value === newInstance.instance_region) : regions[0]} + /> +
+
+
+ + + + + + + + + {formState.error && ( +
+
+ {formState.error} +
+ )} + + ); +}; diff --git a/src/components/instances/new/confirm.js b/src/components/instances/new/confirm.js new file mode 100644 index 000000000..82f4e5c9e --- /dev/null +++ b/src/components/instances/new/confirm.js @@ -0,0 +1,170 @@ +import React, { useState } from 'react'; +import { Col, Row, Button, Card, CardBody } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; + +import addInstance from '../../../api/lms/addInstance'; +import useInstanceAuth from '../../../state/stores/instanceAuths'; + +export default ({ newInstance, computeProduct, storageProduct, setShowForm, setPurchaseStep, lmsAuth }) => { + const [formData, updateForm] = useState({ submitted: false, error: false }); + const [instanceAuths, setInstanceAuths] = useInstanceAuth({}); + + let totalPrice = 0; + if (computeProduct.price !== 'FREE') totalPrice += parseFloat(computeProduct.price); + if (storageProduct.price !== 'FREE') totalPrice += parseFloat(storageProduct.price); + + useAsyncEffect(async () => { + const { submitted } = formData; + if (submitted) { + const newInstanceAuth = { user: newInstance.user, pass: newInstance.pass }; + delete newInstance.user; + delete newInstance.pass; + + const response = await addInstance({ auth: lmsAuth, payload: { ...newInstance } }); + if (response.result) { + setInstanceAuths({ ...instanceAuths, [response.instance_id]: newInstanceAuth }); + updateForm({ submitted: false, error: false }); + setTimeout(() => setShowForm(false), 0); + } else { + updateForm({ submitted: false, error: response.message }); + } + } + }, [formData]); + + return ( + <> + + + + + Instance Name + + + {newInstance.instance_name} + + +
+ + + Admin User + + + {newInstance.user} + + +
+ + + Admin Password + + + {newInstance.pass} + + +
+ {newInstance.is_local ? ( + <> + + + Host + + + {newInstance.host} + + +
+ + + Port + + + {newInstance.port} + + +
+ + + Uses SSL + + + {newInstance.is_ssl.toString()} + + +
+ + ) : ( + <> + + + Instance Region + + + {newInstance.instance_region} + + +
+ + + Instance Storage + + + {storageProduct.disk_space} + + + {storageProduct.price === 'FREE' ? 'FREE' : `$${storageProduct.price}/${storageProduct.interval}`} + + +
+ + )} + + + Instance RAM + + + {computeProduct.ram} + + + {computeProduct.price === 'FREE' ? 'FREE' : `$${computeProduct.price}/${computeProduct.interval}`} + + +
+ + + Instance Total Price + + + {totalPrice ? `$${totalPrice.toFixed(2)}/${computeProduct.interval}` : 'FREE'} + + + +
+
+ + + + + + + + + + ); +}; diff --git a/src/components/instances/new/index.js b/src/components/instances/new/index.js new file mode 100644 index 000000000..8fe027273 --- /dev/null +++ b/src/components/instances/new/index.js @@ -0,0 +1,85 @@ +import React, { useState } from 'react'; +import { Modal, ModalHeader, ModalBody, Loader } from '@nio/ui-kit'; + +import customerHasChargeableCard from '../../../util/stripe/customerHasChargeableCard'; +import steps from '../../../util/addInstanceSteps'; + +import InstanceTypeForm from './type'; +import InstanceMetadataForm from './meta'; +import LocalInstanceForm from './local'; +import CloudInstanceForm from './cloud'; +import CustomerPaymentForm from './payment'; +import ConfirmOrderForm from './confirm'; +import useLMS from '../../../state/stores/lmsAuth'; +import defaultLMSAuth from '../../../state/defaults/defaultLMSAuth'; +import useApp from '../../../state/stores/appData'; +import defaultAppData from '../../../state/defaults/defaultAppData'; + +export default ({ setShowForm }) => { + const [lmsAuth] = useLMS(defaultLMSAuth); + const [appData] = useApp(defaultAppData); + const [purchaseStep, setPurchaseStep] = useState('type'); + const [newInstance, setNewInstance] = useState({}); + const hasCard = customerHasChargeableCard(appData.customer); + + return ( + setShowForm(false)}> + setShowForm(false)}> + {steps[purchaseStep].label} + + + {!appData.products ? ( + + ) : purchaseStep === 'type' ? ( + + ) : purchaseStep === 'meta' ? ( + + ) : purchaseStep === 'details_local' ? ( + + ) : purchaseStep === 'details_cloud' ? ( + + ) : purchaseStep === 'payment' ? ( + p.value === newInstance.stripe_plan_id)} + storageProduct={newInstance.is_local ? { price: 'FREE' } : appData.products.cloudStorage.find((p) => p.value === newInstance.storage_qty_gb)} + setPurchaseStep={setPurchaseStep} + /> + ) : purchaseStep === 'confirm' ? ( + p.value === newInstance.stripe_plan_id)} + storageProduct={newInstance.is_local ? { price: 'FREE' } : appData.products.cloudStorage.find((p) => p.value === newInstance.storage_qty_gb)} + setShowForm={setShowForm} + setPurchaseStep={setPurchaseStep} + /> + ) : null} + + + ); +}; diff --git a/src/components/instances/new/local.js b/src/components/instances/new/local.js new file mode 100644 index 000000000..28c8496b6 --- /dev/null +++ b/src/components/instances/new/local.js @@ -0,0 +1,75 @@ +import React, { useState } from 'react'; +import { RadioCheckbox, Button, Card, CardBody, Col, Row } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; + +export default ({ products, hasCard, newInstance, setNewInstance, setPurchaseStep }) => { + const [formState, setFormState] = useState({ submitted: false, error: false }); + const [formData, updateForm] = useState({ stripe_plan_id: newInstance.stripe_plan_id || products[0].value }); + + const computePrice = products && products.find((p) => p.value === formData.stripe_plan_id).price; + const needsCard = products && !hasCard && computePrice && (computePrice !== 'FREE'); + + useAsyncEffect(() => { + const { submitted } = formState; + const { stripe_plan_id } = formData; + if (submitted) { + if (stripe_plan_id) { + setNewInstance({ ...newInstance, stripe_plan_id }); + setPurchaseStep(needsCard ? 'payment' : 'confirm'); + } else { + setFormState({ submitted: false, error: 'All fields must be filled out.' }); + } + } + }, [formState]); + + return ( + <> + + +
Instance Type
+
+ updateForm({ ...formData, stripe_plan_id: value })} + options={products} + value={formData.stripe_plan_id} + defaultValue={newInstance.stripe_plan_id ? products.find((p) => p.value === newInstance.stripe_plan_id) : products[0]} + /> +
+
+
+ + + + + + + + + {formState.error && ( +
+
+ {formState.error} +
+ )} + + ); +}; diff --git a/src/components/instances/new/meta.js b/src/components/instances/new/meta.js new file mode 100644 index 000000000..c32aa3d21 --- /dev/null +++ b/src/components/instances/new/meta.js @@ -0,0 +1,172 @@ +import React, { useState } from 'react'; +import { Col, Input, Row, Button, Card, CardBody, RadioCheckbox } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; + +export default ({ newInstance, setNewInstance, setPurchaseStep }) => { + const [formState, setFormState] = useState({ submitted: false, error: false }); + const [formData, updateForm] = useState({ + instance_name: newInstance.instance_name || '', + user: newInstance.user || '', + pass: newInstance.pass || '', + host: newInstance.host || '', + port: newInstance.port || '', + is_ssl: newInstance.is_ssl || false, + }); + + useAsyncEffect(() => { + const { submitted } = formState; + const { instance_name, user, pass, host, port, is_ssl } = formData; + if (submitted) { + if (newInstance.is_local) { + if ((instance_name.length && user.length && pass.length && host.length && port.length)) { + setNewInstance({ ...newInstance, instance_name, user, pass, host, port, is_ssl }); + setPurchaseStep('details_local'); + } else { + setFormState({ submitted: false, error: 'All fields must be filled out.' }); + } + } else if ((instance_name.length && user.length && pass.length)) { + setNewInstance({ ...newInstance, instance_name, user, pass, is_ssl: true }); + setPurchaseStep('details_cloud'); + } else { + setFormState({ submitted: false, error: 'All fields must be filled out.' }); + } + } + }, [formState]); + + return ( + <> + + +
Instance Name
+
+ + + example: "HDB-1" + + + updateForm({ ...formData, instance_name: e.target.value, error: false })} + type="text" + title="instance_name" + value={formData.instance_name} + /> + + +
+ +
Admin Credentials
+
+ + + Username + + + updateForm({ ...formData, user: e.target.value, error: false })} + type="text" + title="username" + value={formData.user} + /> + + +
+ + + Password + + + updateForm({ ...formData, pass: e.target.value, error: false })} + type="password" + title="password" + value={formData.pass} + /> + + +
+ + {newInstance.is_local && ( + <> +
Instance Details
+
+ + + Host + + + updateForm({ ...formData, host: e.target.value, error: false })} + type="text" + title="host" + value={formData.host || ''} + /> + + +
+ + + Port + + + updateForm({ ...formData, port: e.target.value, error: false })} + type="number" + title="port" + value={formData.port || ''} + /> + + +
+ + + SSL + + + updateForm({ ...formData, is_ssl: value || false, error: false })} + options={{ label: '', value: true }} + value={formData.is_ssl} + /> + + +
+ + )} + +
+
+ + + + + + + + + {formState.error && ( +
+
+ {formState.error} +
+ )} + + ); +}; diff --git a/src/components/instances/new/payment.js b/src/components/instances/new/payment.js new file mode 100644 index 000000000..e5e02ff86 --- /dev/null +++ b/src/components/instances/new/payment.js @@ -0,0 +1,173 @@ +import React, { useState } from 'react'; +import { CardNumberElement, CardExpiryElement, CardCvcElement, useElements, useStripe } from '@stripe/react-stripe-js'; +import { Button, Card, CardBody, Col, Input, Row } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; + +import cardOptions from '../../../util/stripe/cardOptions'; +import addPaymentMethod from '../../../api/lms/addPaymentMethod'; +import getCustomer from '../../../api/lms/getCustomer'; +import useApp from '../../../state/stores/appData'; +import defaultAppData from '../../../state/defaults/defaultAppData'; + +export default ({ hasCard, computeProduct, newInstance, storageProduct, setPurchaseStep, lmsAuth }) => { + const [appData, setAppData] = useApp(defaultAppData); + const [postalCode, setPostalCode] = useState(false); + const [cardSubmitted, setCardSubmitted] = useState(false); + const [error, setError] = useState(null); + const [cardComplete, setCardComplete] = useState(false); + const [processing, setProcessing] = useState(false); + const [addedCard, setAddedCard] = useState(false); + const stripe = useStripe(); + const elements = useElements(); + + useAsyncEffect(async () => { + if (cardSubmitted) { + if (cardComplete) setProcessing(true); + const newCardObject = { type: 'card', card: elements.getElement(CardNumberElement), billing_details: { address: { postal_code: postalCode } } }; + const payload = await stripe.createPaymentMethod(newCardObject); + + if (payload.error) { + setError(payload.error); + setProcessing(false); + } else { + console.log(lmsAuth); + await addPaymentMethod({ auth: lmsAuth, payload: { payment_method_id: payload.paymentMethod.id, stripe_customer_id: appData.customer.stripe_customer_object.id } }); + const customer = await getCustomer({ auth: lmsAuth }); + setAppData({ ...appData, customer }); + setProcessing(false); + setAddedCard(true); + } + setCardSubmitted(false); + } + }, [cardSubmitted]); + + return ( + + +
Credit Card Details
+
+ {addedCard || hasCard ? ( + <> + Credit Card was successfully added to your account. +
+ + + + + + + + + + ) : ( + <> + {computeProduct.price !== 'FREE' &&
The selected instance type has a cost of ${computeProduct.price}/{computeProduct.interval}.
} + {storageProduct.price !== 'FREE' &&
The selected storage size has a cost of ${storageProduct.price}/{storageProduct.interval}.
} + Please add a credit card to your account using the form below. If you registered using a promo code, your card will not be charged until your promo credits run out. +
+ + + card number + + +
+ { setError(e.error); setCardComplete(e.complete); }} + /> +
+ +
+
+ + + expiration + + +
+ { setError(e.error); setCardComplete(e.complete); }} + /> +
+ +
+
+ + + cvcc + + +
+ { setError(e.error); setCardComplete(e.complete); }} + /> +
+ +
+
+ + + billing postal code + + + setPostalCode(e.target.value)} + /> + + +
+ + + + + + + + + {error && ( +
+
+ {error.message} +
+ )} + + )} +
+
+
+ ); +}; diff --git a/src/components/instances/new/type.js b/src/components/instances/new/type.js new file mode 100644 index 000000000..b2a713844 --- /dev/null +++ b/src/components/instances/new/type.js @@ -0,0 +1,68 @@ +import React, { useState } from 'react'; +import { Row, Col, Card, CardBody, Button } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; + +export default ({ newInstance, setNewInstance, setPurchaseStep }) => { + const [formData, updateForm] = useState({ + is_local: undefined, + storage_qty_gb: false, + stripe_plan_id: false, + instance_region: false, + stripe_product_id: false, + stripe_storage_product_id: false, + stripe_storage_plan_id: false, + }); + + useAsyncEffect(() => { + const { is_local } = formData; + if (is_local !== undefined) { + setNewInstance({ ...newInstance, ...formData }); + setPurchaseStep('meta'); + } + }, [formData]); + + useAsyncEffect(() => setNewInstance({ ...formData }), []); + + return ( + + + + +
Add HarperDB Cloud Instance
+
+
    +
  • Free License Tier Available!
  • +
  • Hosted on AWS
  • +
  • Managed by HarperDB
  • +
  • HarperDB License Included
  • +
  • 24/7 Customer Support
  • +
  • Choose RAM and Disk Size
  • +
  • Scale On Demand
  • +
+
+ +
+
+ + + + +
Register A Local Instance
+
+
    +
  • Free License Tier Available!
  • +
  • For HarperDB Instances You Install
  • +
  • Browse Instance Data
  • +
  • Configure Users, Roles, and Clustering
  • +
  • Manage Instance Licenses
  • +
  • Handle Version Upgrades
  • +
  • Instance Credentials Stay Local
  • +
+
+ +
+
+ +
+ ); +}; diff --git a/src/components/instances/newInstanceCard.js b/src/components/instances/newInstanceCard.js deleted file mode 100644 index 41cb8d252..000000000 --- a/src/components/instances/newInstanceCard.js +++ /dev/null @@ -1,88 +0,0 @@ -import React, { useState } from 'react'; -import { Button, Card, CardBody, Col, Input, Row } from '@nio/ui-kit'; -import { useAlert } from 'react-alert'; -import useAsyncEffect from 'use-async-effect'; - -import defaultFormData from '../../util/defaultFormData'; -import useLMS from '../../stores/lmsData'; -import defaultLMSData from '../../util/defaultLMSData'; -import queryLMS from '../../util/queryLMS'; - -export default () => { - const [showForm, setShowForm] = useState(false); - const [lmsData] = useLMS(defaultLMSData); - const alert = useAlert(); - const [formData, updateForm] = useState(defaultFormData); - - useAsyncEffect(async () => { - if (formData.submitted) { - const newInstance = await queryLMS({ - endpoint: 'addInstance', - method: 'POST', - payload: formData, - auth: lmsData.auth, - }); - if (newInstance.error) { - alert.error(newInstance.error); - updateForm({ ...formData, error: newInstance.error, submitted: false }); - } else { - updateForm(defaultFormData); - } - } - }, [formData]); - - return ( - - {showForm ? ( - - - updateForm({ ...formData, user: e.target.value, error: false })} - className="text-center mb-2" - type="text" - title="username" - placeholder="user" - bsSize="sm" - /> - updateForm({ ...formData, pass: e.target.value, error: false })} - className="text-center mb-2" - type="password" - title="password" - placeholder="pass" - bsSize="sm" - /> - - - - - - - - - - - ) : ( - setShowForm(true)}> - - - - - )} - - ); -}; diff --git a/src/components/login.js b/src/components/login.js deleted file mode 100644 index 78dfd04e3..000000000 --- a/src/components/login.js +++ /dev/null @@ -1,75 +0,0 @@ -import React, { useState } from 'react'; -import { Card, CardBody, Input, Button } from '@nio/ui-kit'; -import useAsyncEffect from 'use-async-effect'; -import { useHistory } from 'react-router'; - -import useLMS from '../stores/lmsData'; -import queryLMS from '../util/queryLMS'; -import defaultFormData from '../util/defaultFormData'; -import defaultLMSData from '../util/defaultLMSData'; - -export default () => { - const [lmsData, setLMSData] = useLMS(defaultLMSData); - const [formData, updateForm] = useState(defaultFormData); - const history = useHistory(); - - useAsyncEffect(async () => { - if (formData.submitted) { - const instances = await queryLMS({ - endpoint: 'getInstances', - method: 'GET', - auth: lmsData.auth, - }); - if (instances.error) { - updateForm({ ...formData, error: instances.error, submitted: false }); - setLMSData(defaultLMSData); - } else { - setLMSData({ auth: { user: formData.user, pass: formData.pass }, instances }); - history.push('/instances'); - } - } - }, [formData]); - - useAsyncEffect(() => { - if (lmsData.auth.user && lmsData.auth.pass && !formData.submitted) { - updateForm({ user: lmsData.auth.user, pass: lmsData.auth.pass, submitted: true, error: false }); - } - }, [lmsData]); - - return ( -
- - ); -}; diff --git a/src/components/login/index.js b/src/components/login/index.js new file mode 100644 index 000000000..b33aa4b21 --- /dev/null +++ b/src/components/login/index.js @@ -0,0 +1,92 @@ +import React, { useState } from 'react'; +import { Card, CardBody, Input, Button } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; +import { useHistory } from 'react-router'; + +import useLMS from '../../state/stores/lmsAuth'; + +import defaultAuthFormData from '../../state/defaults/defaultAuthFormData'; +import defaultLMSAuth from '../../state/defaults/defaultLMSAuth'; + +import getUser from '../../api/lms/getUser'; +import useApp from '../../state/stores/appData'; +import defaultAppData from '../../state/defaults/defaultAppData'; +import isEmail from '../../util/isEmail'; + +export default () => { + const [lmsAuth, setLMSAuth] = useLMS(defaultLMSAuth); + const [appData, setAppData] = useApp(defaultAppData); + const [formState, setFormState] = useState({ submitted: false, error: false }); + const [formData, updateForm] = useState(defaultAuthFormData); + const history = useHistory(); + + const handleKeydown = (e) => { if (e.keyCode === 13) setFormState({ submitted: true }); }; + + useAsyncEffect(async () => { + const { user, pass } = formData; + const { submitted } = formState; + if (submitted) { + if (!isEmail(user)) { + setFormState({ error: 'invalid email supplied', submitted: false }); + } else if (!user || !pass) { + setFormState({ error: 'all fields are required', submitted: false }); + } else { + const response = await getUser({ auth: { user, pass }, payload: { email: user } }); + if (response.result === false) { + setFormState({ error: response.message, submitted: false }); + setLMSAuth(defaultLMSAuth); + } else { + setLMSAuth({ user, pass }); + setFormState({ error: false, submitted: false }); + setAppData({ ...appData, user: response }); + history.push('/instances'); + } + } + } + }, [formState]); + + useAsyncEffect(() => { + const { user, pass } = lmsAuth; + const { submitted } = formData; + if (user && pass && !submitted) { + updateForm({ user, pass, submitted: true, error: false }); + } + }, [lmsAuth]); + + return ( +
+ + ); +}; diff --git a/src/components/navs/subnav.js b/src/components/navs/subnav.js new file mode 100644 index 000000000..5209ab216 --- /dev/null +++ b/src/components/navs/subnav.js @@ -0,0 +1,57 @@ +import React from 'react'; +import { Navbar, Nav, NavItem, Input, Button, ToggleButton } from '@nio/ui-kit'; +import { NavLink } from 'react-router-dom'; + +export default ({ routes = [], instanceId = false, setSearch = false, search, setLocal = false, local, setCloud = false, cloud }) => ( + +
+
+ cloud
, + unchecked:
cloud
, + }} + checked={cloud} + onChange={(e) => setCloud(e.target.checked)} + /> +
+
+ setSearch(e.target.value)} + placeholder="filter instances" + value={search} + /> + {search && ( + + )} +
+ + ) : routes.map((route) => ( + + + + {route.link} + + + ))} + + +); diff --git a/src/components/navs/topnav.js b/src/components/navs/topnav.js new file mode 100644 index 000000000..32c538ea9 --- /dev/null +++ b/src/components/navs/topnav.js @@ -0,0 +1,40 @@ +import React from 'react'; +import { Navbar, Nav, NavItem, NavLink as DumbLink } from '@nio/ui-kit'; +import { useHistory } from 'react-router'; +import { NavLink } from 'react-router-dom'; + +import useLMS from '../../state/stores/lmsAuth'; +import defaultLMSAuth from '../../state/defaults/defaultLMSAuth'; +import useApp from '../../state/stores/appData'; +import defaultAppData from '../../state/defaults/defaultAppData'; + +export default () => { + const history = useHistory(); + const [lmsAuth, setLMSAuth] = useLMS(defaultLMSAuth); + const [, setAppData] = useApp(defaultAppData); + + return lmsAuth.user ? ( + +
+ + + + ) : null; +}; diff --git a/src/components/register/index.js b/src/components/register/index.js new file mode 100644 index 000000000..2db02bfab --- /dev/null +++ b/src/components/register/index.js @@ -0,0 +1,140 @@ +import React, { useState } from 'react'; +import { Input, Button, Card, CardBody, Row, Col } from '@nio/ui-kit'; +import useAsyncEffect from 'use-async-effect'; +import { useAlert } from 'react-alert'; + +import isEmail from '../../util/isEmail'; +import addCustomer from '../../api/lms/addCustomer'; + +export default () => { + const alert = useAlert(); + const [formState, setFormState] = useState({ submitted: false, error: false }); + const [formData, updateForm] = useState({ firstname: '', lastname: '', email: '', company: '', subdomain: '' }); + + useAsyncEffect(async () => { + const { submitted } = formState; + if (submitted) { + const { firstname, lastname, email, company, subdomain } = formData; + + if (!firstname || !lastname || !email || !company || !subdomain) { + setFormState({ submitted: false, error: 'All fields must be filled out' }); + } else if (!isEmail(email)) { + setFormState({ submitted: false, error: 'Please provide a valid email' }); + } else { + const response = await addCustomer({ auth: { user: 'david@harperdb.io', pass: 'harperdb' }, payload: { firstname, lastname, email, company, subdomain } }); + if (response.result) { + updateForm({ firstname: '', lastname: '', email: '', company: '', subdomain: '' }); + setFormState({ submitted: false, error: false, success: true }); + alert.success(response.message); + } else { + setFormState({ submitted: false, error: response.message }); + } + } + } + }, [formState]); + + return ( +
+ + + {formState.success ? ( +
+
Success!
+
+ +
+ Check your email for your username and password. +
+ ) : formState.submitted ? ( +
+
Submitting
+
+ +
+ The office dogs are setting up your account. +
+ ) : ( + <> +
first name
+
+ updateForm({ ...formData, firstname: e.target.value, error: false })} + /> +
+ +
last name
+
+ updateForm({ ...formData, lastname: e.target.value, error: false })} + /> +
+ +
email address
+
+ updateForm({ ...formData, email: e.target.value, error: false })} + /> +
+ +
company
+
+ updateForm({ ...formData, company: e.target.value, error: false })} + /> +
+ +
subdomain
+
+ + + updateForm({ ...formData, subdomain: e.target.value, error: false })} + /> + + + .harperdbcloud.com + + + +
+ + + {formState.error && ( +
+
+ {formState.error} +
+ )} + + )} +
+
+
+ ); +}; diff --git a/src/components/shared/alert.js b/src/components/shared/alert.js index 7c405de03..529da2429 100644 --- a/src/components/shared/alert.js +++ b/src/components/shared/alert.js @@ -1,17 +1,14 @@ import React from 'react'; -import { Row, Col } from '@nio/ui-kit'; export default ({ message, options, close }) => (
- - - {options.type === 'info' && } - {options.type === 'success' && } - {options.type === 'error' && } - - - {message} - - +
+ {options.type === 'info' && } + {options.type === 'success' && } + {options.type === 'error' && } +
+
+ {message} +
); diff --git a/src/components/instance/shared/entityManager.js b/src/components/shared/entityManager.js similarity index 97% rename from src/components/instance/shared/entityManager.js rename to src/components/shared/entityManager.js index 632a26e47..5108ce74b 100644 --- a/src/components/instance/shared/entityManager.js +++ b/src/components/shared/entityManager.js @@ -40,9 +40,7 @@ export default ({ items, activeItem, activeSchema = false, auth, refreshInstance auth={auth} refreshInstance={refreshInstance} /> - )) : ( - null - )} + )) : null} {((items && !items.length) || isCreating) && ( { const history = useHistory(); @@ -47,7 +47,7 @@ export default ({ items, itemType, activeSchema, toggleDropItem, toggleCreate, b return setTimeout(() => history.push(`${baseUrl}/${entityName}`), 100); }; - useEffect(() => toggleDropItem(), []); + useEffect(() => toggleDropItem(), [toggleDropItem]); return ( diff --git a/src/components/instance/shared/entityManagerHeader.js b/src/components/shared/entityManagerHeader.js similarity index 100% rename from src/components/instance/shared/entityManagerHeader.js rename to src/components/shared/entityManagerHeader.js diff --git a/src/components/instance/shared/entityManagerRow.js b/src/components/shared/entityManagerRow.js similarity index 98% rename from src/components/instance/shared/entityManagerRow.js rename to src/components/shared/entityManagerRow.js index 0b35880c6..5b663b762 100644 --- a/src/components/instance/shared/entityManagerRow.js +++ b/src/components/shared/entityManagerRow.js @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { Row, Col, Button } from '@nio/ui-kit'; import { useHistory, useParams } from 'react-router'; -import queryInstance from '../../../util/queryInstance'; +import queryInstance from '../../api/queryInstance'; export default ({ item, itemType, baseUrl, isActive, toggleDropItem, isDropping, activeSchema, auth, refreshInstance }) => { const history = useHistory(); diff --git a/src/components/shared/protectedRoute.js b/src/components/shared/protectedRoute.js new file mode 100644 index 000000000..8409a199b --- /dev/null +++ b/src/components/shared/protectedRoute.js @@ -0,0 +1,17 @@ +import React from 'react'; +import { Route, Redirect } from 'react-router-dom'; +import useLMS from '../../state/stores/lmsAuth'; +import defaultLMSAuth from '../../state/defaults/defaultLMSAuth'; +import TopNav from '../navs/topnav'; + +export default ({ component, path }) => { + const [lmsAuth] = useLMS(defaultLMSAuth); + return lmsAuth.user && lmsAuth.pass ? ( + <> + + + + ) : ( + + ); +}; diff --git a/src/components/topnav.js b/src/components/topnav.js deleted file mode 100644 index 54fd87952..000000000 --- a/src/components/topnav.js +++ /dev/null @@ -1,57 +0,0 @@ -import React, { useState } from 'react'; -import { Navbar, NavbarToggler, Nav, NavItem, Collapse, NavLink as DumbLink } from '@nio/ui-kit'; -import { useParams, useHistory } from 'react-router'; -import { NavLink } from 'react-router-dom'; - -import routes from './instance/routes'; -import useLMS from '../stores/lmsData'; -import defaultLMSData from '../util/defaultLMSData'; - -export default () => { - const { instance_id } = useParams(); - const history = useHistory(); - const [lmsData, setLMSData] = useLMS(defaultLMSData); - const [navOpen, toggleNav] = useState(false); - - return ( - -
- - toggleNav(!navOpen)} isOpen={navOpen} /> - - - - - ); -}; diff --git a/src/index.html b/src/index.html index 39bfdba21..307e553aa 100644 --- a/src/index.html +++ b/src/index.html @@ -9,5 +9,6 @@
+
diff --git a/src/index.js b/src/index.js index 47ca3ef48..a1503d242 100644 --- a/src/index.js +++ b/src/index.js @@ -2,18 +2,23 @@ import React from 'react'; import { render } from 'react-dom'; import { BrowserRouter } from 'react-router-dom'; import { positions, Provider } from 'react-alert'; +import { Elements } from '@stripe/react-stripe-js'; + +import './util/textDecoderPolyfill'; +import stripePromise from './util/stripe/stripePromise'; import AlertTemplate from './components/shared/alert'; import App from './components/app'; import './app.scss'; render( ( - - - - -
- + + + + + + + ), document.getElementById('app'), ); diff --git a/src/providers/harperdb.js b/src/providers/harperdb.js deleted file mode 100644 index a464839a2..000000000 --- a/src/providers/harperdb.js +++ /dev/null @@ -1,63 +0,0 @@ -import React, { useState } from 'react'; -import createPersistedState from 'use-persisted-state'; -import useAsyncEffect from 'use-async-effect'; - -import updateInstanceStates from '../util/updateInstanceStates'; -import getInstanceDataStructure from '../util/getInstanceDataStructure'; -import getInstanceClusterStatus from '../util/getInstanceClusterStatus'; - -const useInstanceState = createPersistedState('instances'); -export const HarperDBContext = React.createContext(); - -export const HarperDBProvider = ({ children }) => { - const [instances, setInstances] = useInstanceState([]); - const [structure, setStructure] = useState(false); - const [authError, setAuthError] = useState(false); - - const queryHarperDB = async (operation, authObject = false) => { - const { url, auth } = authObject || instances.find((i) => i.active); - const body = JSON.stringify(operation); - try { - const response = await fetch(url, { method: 'POST', body, headers: { 'Content-Type': 'application/json', authorization: `Basic ${auth}` } }); - return response.json(); - } catch { - return { error: 'Could not connect. Is HarperDB running?' }; - } - }; - - const login = async (authObject) => { - const dbResponse = await queryHarperDB({ operation: 'describe_all' }, authObject); - - if (dbResponse.error) { - setAuthError(dbResponse.error); - return false; - } - - setInstances(updateInstanceStates(instances, authObject)); - return setStructure(getInstanceDataStructure(dbResponse)); - }; - - const logout = () => { - setStructure(false); - setInstances(instances.map((i) => { i.active = false; return i; })); - }; - - const refreshNetwork = async () => setInstances(await getInstanceClusterStatus(instances, queryHarperDB)); - - const refreshInstance = async () => { - const dbResponse = await queryHarperDB({ operation: 'describe_all' }); - setStructure(getInstanceClusterStatus(dbResponse)); - }; - - useAsyncEffect(async () => { - const activeInstance = instances.find((i) => i.active); - if (activeInstance) login(activeInstance); - refreshNetwork(); - }, []); - - return ( - - {children} - - ); -}; diff --git a/src/state/defaults/defaultActiveInstance.js b/src/state/defaults/defaultActiveInstance.js new file mode 100644 index 000000000..f697b97a1 --- /dev/null +++ b/src/state/defaults/defaultActiveInstance.js @@ -0,0 +1,8 @@ +export default { + auth: false, + structure: false, + network: false, + product: false, + license: false, + details: false, +}; diff --git a/src/state/defaults/defaultAppData.js b/src/state/defaults/defaultAppData.js new file mode 100644 index 000000000..a5c5adbe6 --- /dev/null +++ b/src/state/defaults/defaultAppData.js @@ -0,0 +1 @@ +export default { user: false, customer: false, instances: [], products: [], regions: [] }; diff --git a/src/state/defaults/defaultAuthFormData.js b/src/state/defaults/defaultAuthFormData.js new file mode 100644 index 000000000..a45f40c1b --- /dev/null +++ b/src/state/defaults/defaultAuthFormData.js @@ -0,0 +1,4 @@ +export default { + user: false, + pass: false, +}; diff --git a/src/state/defaults/defaultClusterFormData.js b/src/state/defaults/defaultClusterFormData.js new file mode 100644 index 000000000..4e8838178 --- /dev/null +++ b/src/state/defaults/defaultClusterFormData.js @@ -0,0 +1 @@ +export default { submitted: false, error: false, username: false, password: false, port: false }; diff --git a/src/state/defaults/defaultLMSAuth.js b/src/state/defaults/defaultLMSAuth.js new file mode 100644 index 000000000..64494df83 --- /dev/null +++ b/src/state/defaults/defaultLMSAuth.js @@ -0,0 +1 @@ +export default { email: false, pass: false }; diff --git a/src/state/defaults/defaultPasswordFormData.js b/src/state/defaults/defaultPasswordFormData.js new file mode 100644 index 000000000..561455f2b --- /dev/null +++ b/src/state/defaults/defaultPasswordFormData.js @@ -0,0 +1 @@ +export default { oldpassword: '', newpassword: '', newpassword2: '', submitted: false, error: false }; diff --git a/src/state/defaults/defaultProfileFormData.js b/src/state/defaults/defaultProfileFormData.js new file mode 100644 index 000000000..3a628aa84 --- /dev/null +++ b/src/state/defaults/defaultProfileFormData.js @@ -0,0 +1 @@ +export default { firstname: '', lastname: '', email: '', submitted: false, error: false }; diff --git a/src/state/defaults/defaultTableState.js b/src/state/defaults/defaultTableState.js new file mode 100644 index 000000000..0629a795b --- /dev/null +++ b/src/state/defaults/defaultTableState.js @@ -0,0 +1,13 @@ +export default { + filtered: [], + sorted: [], + page: 0, + loading: true, + tableData: [], + pages: -1, + totalRecords: 0, + pageSize: 20, + autoRefresh: false, + showFilter: false, + lastUpdate: false, +}; diff --git a/src/state/defaults/defaultUserFormData.js b/src/state/defaults/defaultUserFormData.js new file mode 100644 index 000000000..848ff4aff --- /dev/null +++ b/src/state/defaults/defaultUserFormData.js @@ -0,0 +1,7 @@ +export default { + submitted: false, + error: false, + firstname: '', + lastname: '', + email: '', +}; diff --git a/src/state/stores/appData.js b/src/state/stores/appData.js new file mode 100644 index 000000000..8306b8bb7 --- /dev/null +++ b/src/state/stores/appData.js @@ -0,0 +1,3 @@ +import createPersistedState from 'use-persisted-state'; + +export default createPersistedState('appData'); diff --git a/src/stores/instanceAuths.js b/src/state/stores/instanceAuths.js similarity index 100% rename from src/stores/instanceAuths.js rename to src/state/stores/instanceAuths.js diff --git a/src/stores/lmsData.js b/src/state/stores/lmsAuth.js similarity index 100% rename from src/stores/lmsData.js rename to src/state/stores/lmsAuth.js diff --git a/src/util/addInstanceSteps.js b/src/util/addInstanceSteps.js new file mode 100644 index 000000000..8bf50d0e5 --- /dev/null +++ b/src/util/addInstanceSteps.js @@ -0,0 +1,20 @@ +export default { + type: { + label: 'Select Instance Type', + }, + meta: { + label: 'Basic Information', + }, + details_local: { + label: 'Local Instance Details', + }, + details_cloud: { + label: 'Cloud Instance Details', + }, + payment: { + label: 'Payment Details', + }, + confirm: { + label: 'Confirm Instance Details', + }, +}; diff --git a/src/util/buildActiveInstanceObject.js b/src/util/buildActiveInstanceObject.js index 6f2b1c1ce..69c0aa6de 100644 --- a/src/util/buildActiveInstanceObject.js +++ b/src/util/buildActiveInstanceObject.js @@ -1,15 +1,22 @@ -import queryInstance from './queryInstance'; -import getInstanceDataStructure from './getInstanceDataStructure'; -import getInstanceClusterStatus from './getInstanceClusterStatus'; +import queryInstance from '../api/queryInstance'; +import browseTableColumns from './datatable/browseTableColumns'; +import clusterStatus from '../api/instance/clusterStatus'; -export default async ({ instance_id, instanceAuths, lmsData }) => { - const auth = { ...instanceAuths[instance_id], ...lmsData.instances.find((i) => i.id === instance_id) }; +export default async ({ instance_id, instanceAuths, appData: { products, instances, licenses } }) => { + const thisInstance = instances.find((i) => i.id === instance_id); + const auth = { ...instanceAuths[instance_id], host: thisInstance.host, port: thisInstance.port, is_ssl: thisInstance.is_ssl }; const instance = await queryInstance({ operation: 'describe_all' }, auth); + const users = await queryInstance({ operation: 'list_users' }, auth); + const roles = await queryInstance({ operation: 'list_roles' }, auth); + const license = licenses.find((l) => l.instance_id === instance_id); + const product = products[thisInstance.is_local ? 'localCompute' : 'cloudCompute'].find((p) => p.value === thisInstance.stripe_plan_id); + const storage = thisInstance.is_local ? null : products.cloudStorage.find((p) => p.value === thisInstance.storage_qty_gb); if (instance.error) { return instance; } - const structure = getInstanceDataStructure(instance); - const network = await getInstanceClusterStatus(auth); - return { auth, structure, network }; + const structure = browseTableColumns(instance); + const network = await clusterStatus(auth); + + return { auth, structure, network, users, roles, details: { ...license, ...product, ...storage, ...thisInstance } }; }; diff --git a/src/util/buildInstanceStructure.js b/src/util/buildInstanceStructure.js new file mode 100644 index 000000000..82fad9af0 --- /dev/null +++ b/src/util/buildInstanceStructure.js @@ -0,0 +1,6 @@ +export default ({ structure, schema, table }) => { + const schemas = structure && Object.keys(structure).sort(); + const tables = structure && schemas && structure[schema] && Object.keys(structure[schema]).sort(); + const activeTable = structure && schemas && structure[schema] && tables && structure[schema][table] && structure[schema][table]; + return { schemas, tables, activeTable }; +}; diff --git a/src/util/getInstanceDataStructure.js b/src/util/datatable/browseTableColumns.js similarity index 95% rename from src/util/getInstanceDataStructure.js rename to src/util/datatable/browseTableColumns.js index 2a4a2a9d0..f935b14d2 100644 --- a/src/util/getInstanceDataStructure.js +++ b/src/util/datatable/browseTableColumns.js @@ -16,6 +16,7 @@ export default (dbResponse) => { dataTableColumns: orderedColumns.map((k) => ({ Header: k.replace(/__/g, ''), accessor: k, + style: { height: 29, paddingTop: 10 }, Cell: (props) => handleCellValues(props.value), })), }; diff --git a/src/util/datatable/clusterConfigColumns.js b/src/util/datatable/clusterConfigColumns.js new file mode 100644 index 000000000..ac5f7b75b --- /dev/null +++ b/src/util/datatable/clusterConfigColumns.js @@ -0,0 +1,38 @@ +import React from 'react'; +import { Button, ToggleButton } from '@nio/ui-kit'; + +import addNode from '../../api/instance/addNode'; +import updateNode from '../../api/instance/updateNode'; + +const toggleCellPadding = { paddingTop: 3, paddingBottom: 0, paddingLeft: 0, paddingRight: 2 }; + +export default ({ auth, refreshInstance }) => [{ + Header: 'name', + accessor: 'instance_name', + style: { paddingTop: 10 }, +}, { + Header: 'url', + accessor: 'url', + style: { paddingTop: 10 }, +}, { + Header: 'publish', + Cell: ({ + original: { id, host, port, clusterPort, publish, connection, channel, subscriptions }, + }) => ( + connection + ? updateNode({ channel, subscriptions, buttonState: 'togglePublish', id, host, clusterPort, auth, refreshInstance })} /> + : ), + width: 80, + style: toggleCellPadding, +}, { + Header: 'subscribe', + Cell: ({ + original: { id, host, clusterPort, subscribe, connection, channel, subscriptions }, + }) => ( + connection + ? updateNode({ channel, subscriptions, buttonState: 'toggleSubscribe', id, host, clusterPort, auth, refreshInstance })} /> + : '' + ), + width: 80, + style: toggleCellPadding, +}]; diff --git a/src/util/datatable/customerUserColumns.js b/src/util/datatable/customerUserColumns.js new file mode 100644 index 000000000..57659bf12 --- /dev/null +++ b/src/util/datatable/customerUserColumns.js @@ -0,0 +1,28 @@ +import React from 'react'; +import { Button } from '@nio/ui-kit'; + +import removeUser from '../../api/lms/removeUser'; + +const toggleCellPadding = { paddingTop: 3, paddingBottom: 0, paddingLeft: 0, paddingRight: 2 }; + +export default ({ auth, customer_id, setLastUpdate }) => [{ + Header: 'last name', + accessor: 'lastname', + style: { paddingTop: 10 }, +}, { + Header: 'first name', + accessor: 'firstname', + style: { paddingTop: 10 }, +}, { + Header: 'email address', + accessor: 'email', + style: { paddingTop: 10 }, +}, { + Header: '', + Cell: ({ + original: { user_id }, + }) => ( + ), + width: 80, + style: toggleCellPadding, +}]; diff --git a/src/util/handleCellValues.js b/src/util/datatable/handleCellValues.js similarity index 100% rename from src/util/handleCellValues.js rename to src/util/datatable/handleCellValues.js diff --git a/src/util/datatable/instanceUserColumns.js b/src/util/datatable/instanceUserColumns.js new file mode 100644 index 000000000..762cd5579 --- /dev/null +++ b/src/util/datatable/instanceUserColumns.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { Button } from '@nio/ui-kit'; + + + +const toggleCellPadding = { paddingTop: 3, paddingBottom: 0, paddingLeft: 0, paddingRight: 2 }; + +export default ({ deleteUser }) => [{ + Header: 'username', + accessor: 'username', + style: { paddingTop: 10 }, +}, { + Header: 'role', + accessor: 'role.role', + style: { paddingTop: 10 }, +}, { + Header: '', + Cell: ({ + original: { username }, + }) => ( + ), + width: 80, + style: toggleCellPadding, +}]; diff --git a/src/util/isImage.js b/src/util/datatable/isImage.js similarity index 100% rename from src/util/isImage.js rename to src/util/datatable/isImage.js diff --git a/src/util/defaultFormData.js b/src/util/defaultFormData.js deleted file mode 100644 index 8e1ebe214..000000000 --- a/src/util/defaultFormData.js +++ /dev/null @@ -1 +0,0 @@ -export default { submitted: false, error: false, user: false, pass: false }; diff --git a/src/util/defaultLMSData.js b/src/util/defaultLMSData.js deleted file mode 100644 index b93204378..000000000 --- a/src/util/defaultLMSData.js +++ /dev/null @@ -1 +0,0 @@ -export default { auth: false, instances: [] }; diff --git a/src/util/filterInstances.js b/src/util/filterInstances.js new file mode 100644 index 000000000..834ac494e --- /dev/null +++ b/src/util/filterInstances.js @@ -0,0 +1,16 @@ +export default ({ local, cloud, search, instances }) => { + if (!local && !cloud) return []; + if (search === '' && local && cloud) return instances; + + return instances.filter((i) => { + if (!local && i.is_local) return false; + if (!cloud && !i.is_local) return false; + if (search === '') return true; + + let pass = false; + if (i.instance_name && i.instance_name.indexOf(search) !== -1) pass = true; + if (i.host && i.host.indexOf(search) !== -1) pass = true; + if (i.domain_name && i.domain_name.indexOf(search) !== -1) pass = true; + return pass; + }); +}; diff --git a/src/util/getInstanceClusterStatus.js b/src/util/getInstanceClusterStatus.js deleted file mode 100644 index 4f8a7335a..000000000 --- a/src/util/getInstanceClusterStatus.js +++ /dev/null @@ -1,21 +0,0 @@ -import queryInstance from './queryInstance'; - -export default async (auth) => { - const clusterResponse = await queryInstance({ operation: 'cluster_status' }, auth); - - if (clusterResponse.message) { - return { - inbound_connections: [], - outbound_connections: [], - name: false, - }; - } - - const { status: { inbound_connections, outbound_connections, __originator } } = clusterResponse; - - return { - inbound_connections: inbound_connections ? inbound_connections.filter((c) => c.host_address.indexOf('::ffff') === -1) : [], - outbound_connections: outbound_connections ? outbound_connections.filter((c) => c.host_address.indexOf('::ffff') === -1) : [], - name: __originator && Object.keys(__originator)[0], - }; -}; diff --git a/src/util/handleSchemaTableRedirect.js b/src/util/handleSchemaTableRedirect.js new file mode 100644 index 000000000..a96f03347 --- /dev/null +++ b/src/util/handleSchemaTableRedirect.js @@ -0,0 +1,17 @@ +export default ({ entities, instance_id, schema, table, history, targetPath }) => { + switch (true) { + case (!entities.schemas && history.location.pathname !== targetPath): + history.push(`/instances/${instance_id}${targetPath}`); + break; + case (entities.schemas && entities.schemas.length && !schema): + case (entities.schemas && entities.schemas.length && schema && !entities.schemas.includes(schema)): + history.push(`/instances/${instance_id}${targetPath}/${entities.schemas[0]}`); + break; + case (entities.tables && entities.tables.length && !table): + case (entities.tables && entities.tables.length && table && !entities.tables.includes(table)): + history.push(`/instances/${instance_id}${targetPath}/${schema}/${entities.tables[0]}`); + break; + default: + break; + } +}; diff --git a/src/util/isEmail.js b/src/util/isEmail.js new file mode 100644 index 000000000..174e2e9ad --- /dev/null +++ b/src/util/isEmail.js @@ -0,0 +1,4 @@ +export default (email) => { + const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + return re.test(String(email).toLowerCase()); +}; diff --git a/src/util/queryLMS.js b/src/util/queryLMS.js deleted file mode 100644 index d4186fdee..000000000 --- a/src/util/queryLMS.js +++ /dev/null @@ -1,25 +0,0 @@ -import instances from '../../mock_data/LMS_API.instances.json'; - -export default async ({ endpoint, method, payload, auth }) => { - /* - const request = await fetch( - `https://api.harperdb.io/v1/${endpoint}`, - { - method, - body: JSON.stringify(payload), - headers: { - 'Content-Type': 'application/json', - authorization: `Basic ${btoa(`${auth.user}:${auth.pass}`)}`, - }, - }, - ); - return request.json(); - */ - - switch (endpoint) { - case 'getInstances': - return instances; - default: - return { error: 'unknown endpoint' }; - } -}; diff --git a/src/util/stripe/cardOptions.js b/src/util/stripe/cardOptions.js new file mode 100644 index 000000000..5d18da125 --- /dev/null +++ b/src/util/stripe/cardOptions.js @@ -0,0 +1,23 @@ +export default { + iconStyle: 'solid', + style: { + base: { + iconColor: '#403b8a', + color: '#212121', + fontWeight: 100, + fontFamily: 'Raleway, Open Sans, Segoe UI, sans-serif', + fontSize: '16px', + fontSmoothing: 'antialiased', + ':-webkit-autofill': { + color: '#fff', + }, + '::placeholder': { + color: '#bcbcbc', + }, + }, + invalid: { + iconColor: '#ea4c89', + color: '#ea4c89', + }, + }, +}; diff --git a/src/util/stripe/customerHasChargeableCard.js b/src/util/stripe/customerHasChargeableCard.js new file mode 100644 index 000000000..0ad8a6477 --- /dev/null +++ b/src/util/stripe/customerHasChargeableCard.js @@ -0,0 +1 @@ +export default (customer) => customer?.stripe_customer_object?.sources?.data?.[0]; diff --git a/src/util/stripe/getInstancePrice.js b/src/util/stripe/getInstancePrice.js new file mode 100644 index 000000000..ae05764eb --- /dev/null +++ b/src/util/stripe/getInstancePrice.js @@ -0,0 +1,4 @@ +export default ({ products, plan_id }) => { + const selectedPlan = products.find((p) => p.stripe_product_id === instanceDetails.stripe_product_id); + return instanceDetails.is_local ? selectedProduct.local_price_annual : selectedProduct.cloud_price_monthly; +}; diff --git a/src/util/stripe/stripePromise.js b/src/util/stripe/stripePromise.js new file mode 100644 index 000000000..479187c98 --- /dev/null +++ b/src/util/stripe/stripePromise.js @@ -0,0 +1,5 @@ +import { loadStripe } from '@stripe/stripe-js'; + +const stripePromise = loadStripe('pk_test_QeKQj2ThQ4mqatyLsXCexOmB00he3FXx2P'); + +export default stripePromise; diff --git a/src/util/textDecoderPolyfill.js b/src/util/textDecoderPolyfill.js new file mode 100644 index 000000000..661da5e89 --- /dev/null +++ b/src/util/textDecoderPolyfill.js @@ -0,0 +1,3 @@ +import { TextDecoder } from 'text-encoding'; + +if (!window.TextDecoder) window.TextDecoder = TextDecoder; diff --git a/src/util/updateInstanceStates.js b/src/util/updateInstanceStates.js deleted file mode 100644 index a0ce75d21..000000000 --- a/src/util/updateInstanceStates.js +++ /dev/null @@ -1,6 +0,0 @@ -export default (instances, authObject) => { - const existingAuthObjectIndex = instances.findIndex((i) => i.auth === authObject.auth && i.url === authObject.url); - if (existingAuthObjectIndex !== -1) instances.splice(existingAuthObjectIndex, 1); - const newInstancesObject = [...instances.map((i) => { i.active = false; return i; }), { ...authObject, active: true }].sort((a, b) => (a.url.toLowerCase() > b.url.toLowerCase() ? 1 : -1)); - return newInstancesObject; -}; diff --git a/src/util/useWindowSize.js b/src/util/useWindowSize.js deleted file mode 100644 index 7e056897e..000000000 --- a/src/util/useWindowSize.js +++ /dev/null @@ -1,19 +0,0 @@ -import { useState, useEffect } from 'react'; - -export default () => { - const [width, setWidth] = useState(window.innerWidth); - const [height, setHeight] = useState(window.innerHeight); - - useEffect(() => { - const handleResize = () => { - setWidth(window.innerWidth); - setHeight(window.innerHeight - 130); - }; - window.addEventListener('resize', handleResize); - return () => { - window.removeEventListener('resize', handleResize); - }; - }); - - return { width, height }; -}; diff --git a/webpack.common.js b/webpack.common.js index 6af8ce9d7..1835f5aa3 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -7,7 +7,6 @@ const TerserPlugin = require('terser-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); -const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin'); const cssNano = require('cssnano'); const CopyWebpackPlugin = require('copy-webpack-plugin'); /* eslint-enable import/no-extraneous-dependencies */ @@ -17,7 +16,7 @@ module.exports = { output: { path: path.join(__dirname, 'public'), - filename: 'hdb.js', + filename: '[contenthash].js', publicPath: '/', }, @@ -36,8 +35,7 @@ module.exports = { inject: 'body', inlineSource: '.(js|css)$', }), - new HtmlWebpackInlineSourcePlugin(), - new MiniCssExtractPlugin({ filename: 'hdb.css' }), + new MiniCssExtractPlugin({ filename: '[contenthash].css' }), new CopyWebpackPlugin([ { from: path.join(__dirname, '/src/assets/images/'), to: 'images/' }, { from: path.join(__dirname, '/src/assets/fonts/'), to: 'fonts/' },