diff --git a/docs/site/Importing-LB3-models.md b/docs/site/Importing-LB3-models.md
new file mode 100644
index 000000000000..4f1756ddc756
--- /dev/null
+++ b/docs/site/Importing-LB3-models.md
@@ -0,0 +1,113 @@
+---
+lang: en
+title: 'Importing models from LoopBack 3 projects'
+keywords: LoopBack 4.0, Migration
+sidebar: lb4_sidebar
+permalink: /doc/en/lb4/Importing-LB3-models.html
+---
+
+## Synopsis
+
+To simplify migration from LoopBack 3, LoopBack 4 provides a CLI tool to import
+LoopBack 3 models into your LoopBack 4 project.
+
+{% include warning.html content="
+This command is experimental and not feature-complete yet.
+See the list of known limitations below.
+" %}
+
+## Overview
+
+Import one or more models from your LB 3.x application by running
+`lb4 import-lb3-models` command.
+
+### Arguments
+
+`lb3app`: Path to the directory containing your LoopBack 3.x application.
+
+{% include important.html content="
+The generator loads the application via `require()`, it does not
+support applications that are unable to boot (throw errors at startup).
+" %}
+
+### Options
+
+`outDir`: Directory where to write the generated source file. Default:
+`src/models`
+
+## Known limitations
+
+{% include note.html content="
+Please up-vote the tracking GitHub issue for scenarios that are important to
+your project. It will help us to better prioritize which limitations to remove
+first.
+" %}
+
+### Connector-specific metadata in property definitions is not imported
+
+_The tracking GitHub issue:
+[loopback-next#3810](https://github.com/strongloop/loopback-next/issues/3810)_
+
+Workaround: Add this metadata manually to the generated file.
+
+### Nested properties are not upgraded
+
+_The tracking GitHub issue:
+[loopback-next#3811](https://github.com/strongloop/loopback-next/issues/3811)_
+
+When a property is defined with a complex object type, the nested property
+definitions are not converted from LB3 to LB4 format.
+
+Workaround: Fix the generated definition manually.
+
+### Model relations are not imported
+
+_The tracking GitHub issue:
+[loopback-next#3812](https://github.com/strongloop/loopback-next/issues/3812)_
+
+Workaround: define relational metadata & navigational properties manually.
+
+### Models inheriting from custom base class
+
+_The tracking GitHub issue:
+[loopback-next#3813](https://github.com/strongloop/loopback-next/issues/3813)_
+
+Models inheriting from application-specific models (including LB3 built-in
+models like `User`) cannot be imported yet.
+
+Workaround:
+
+1. Modify your LB3 model to inherit from `Model`, `PersistedModel` or
+ `KeyValueModel`.
+
+2. Import the model to LB4
+
+3. Update the imported model to inherit for the desired application-specific
+ model.
+
+### MongoDB's `ObjectID` type
+
+The tracking GitHub issue:
+[loopback-next#3814](https://github.com/strongloop/loopback-next/issues/3814).
+
+For models attached to MongoDB datasource, the imported LB4 model contains
+incorrect definition of the primary key property of `ObjectID` type.
+
+As a workaround, you can change the property definition from:
+
+```ts
+@property({
+ type: ObjectID;
+})
+id: ObjectID;
+```
+
+to:
+
+```ts
+@property({
+ type: 'string',
+ mongodb: {dataType: 'ObjectID'}
+})
+id: string;
+```
diff --git a/docs/site/sidebars/lb4_sidebar.yml b/docs/site/sidebars/lb4_sidebar.yml
index 171ecbdc85e7..f9d672fda331 100644
--- a/docs/site/sidebars/lb4_sidebar.yml
+++ b/docs/site/sidebars/lb4_sidebar.yml
@@ -384,6 +384,10 @@ children:
url: DataSource-generator.html
output: 'web, pdf'
+ - title: 'Import models from LoopBack 3'
+ url: Importing-LB3-models.html
+ output: 'web, pdf'
+
- title: 'Model generator'
url: Model-generator.html
output: 'web, pdf'
diff --git a/docs/site/tables/lb4-artifact-commands.html b/docs/site/tables/lb4-artifact-commands.html
index 983021640f4f..1f77827137fa 100644
--- a/docs/site/tables/lb4-artifact-commands.html
+++ b/docs/site/tables/lb4-artifact-commands.html
@@ -23,6 +23,11 @@
DataSource generator |
+
+ lb4 import-lb3-models |
+ Import one or more LoopBack 3 models to a LoopBack 4 application |
+ Importer for LoopBack 3 models |
+
lb4 model |
Add a new model to a LoopBack 4 application |
@@ -70,7 +75,5 @@
Generate interceptors |
Global interceptor generator |
-
-
diff --git a/packages/cli/generators/import-lb3-models/index.js b/packages/cli/generators/import-lb3-models/index.js
new file mode 100644
index 000000000000..d05e8cb355f9
--- /dev/null
+++ b/packages/cli/generators/import-lb3-models/index.js
@@ -0,0 +1,162 @@
+// Copyright IBM Corp. 2019. All Rights Reserved.
+// Node module: @loopback/cli
+// This file is licensed under the MIT License.
+// License text available at https://opensource.org/licenses/MIT
+
+'use strict';
+
+const chalk = require('chalk');
+const path = require('path');
+const BaseGenerator = require('../../lib/base-generator');
+const modelUtils = require('../../lib/model-discoverer');
+const debug = require('../../lib/debug')('import-lb3-models');
+const utils = require('../../lib/utils');
+const {loadLb3App} = require('./lb3app-loader');
+const {importLb3ModelDefinition} = require('./migrate-model');
+const {canImportModelName} = require('./model-names');
+
+module.exports = class Lb3ModelImporter extends BaseGenerator {
+ constructor(args, opts) {
+ super(args, opts);
+
+ this.argument('lb3app', {
+ type: String,
+ required: true,
+ description:
+ 'Path to your LoopBack 3.x application. ' +
+ 'This can be a project directory (e.g. "my-lb3-app") or ' +
+ 'the server file (e.g. "my-lb3-app/server/server.js").',
+ });
+
+ this.option('outDir', {
+ type: String,
+ description: 'Directory where to write the generated source file',
+ default: 'src/models',
+ });
+ }
+
+ async processOptions() {
+ this.sourceAppDir = this.args[0];
+ this.artifactInfo.outDir = this.options.outDir;
+ this.artifactInfo.relPath = path.relative(
+ this.destinationPath(),
+ this.artifactInfo.outDir,
+ );
+ return super.setOptions();
+ }
+
+ async logExperimentalStatus() {
+ this.log(
+ chalk.red(`
+WARNING: This command is experimental and not feature-complete yet.
+Learn more at https://loopback.io/doc/en/lb4/Importing-LB3-models.html
+`),
+ );
+ }
+
+ /**
+ * Ensure CLI is being run in a LoopBack 4 project.
+ */
+ checkLoopBackProject() {
+ if (this.shouldExit()) return;
+ return super.checkLoopBackProject();
+ }
+
+ async loadTheApp() {
+ this.lb3app = await loadLb3App(this.sourceAppDir);
+ this.modelRegistry = this.lb3app.registry.modelBuilder.models;
+ }
+
+ async promptModels() {
+ const modelNames = Object.keys(this.modelRegistry).filter(
+ canImportModelName,
+ );
+
+ debug('Available LB3 models', modelNames);
+
+ const prompts = [
+ {
+ name: 'modelNames',
+ message: 'Select models to import:',
+ type: 'checkbox',
+ choices: modelNames,
+ validate: result => !!result.length,
+ // TODO: add a CLI flag to supply these names programmatically
+ },
+ ];
+
+ const answers = await this.prompt(prompts);
+ debug('Models chosen:', answers.modelNames);
+ this.modelNames = answers.modelNames;
+ }
+
+ async migrateSelectedModels() {
+ if (this.shouldExit()) return;
+ this.modelFiles = [];
+
+ try {
+ for (const name of this.modelNames) {
+ await this._migrateSingleModel(name);
+ }
+ } catch (err) {
+ if (err.exit) {
+ this.exit(err.message);
+ } else {
+ throw err;
+ }
+ }
+ }
+
+ async _migrateSingleModel(name) {
+ utils.logClassCreation('model', 'models', name, this.log.bind(this));
+ const modelCtor = this.modelRegistry[name];
+ if (typeof modelCtor !== 'function') {
+ const availableModels = Object.keys(this.modelRegistry)
+ .filter(canImportModelName)
+ .join(', ');
+
+ this.exit(
+ `Unknown model name ${name}. Available models: ${availableModels}.`,
+ );
+ return;
+ }
+
+ const templateData = importLb3ModelDefinition(
+ modelCtor,
+ this.log.bind(this),
+ );
+ debug('LB4 model data', templateData);
+
+ const fileName = utils.getModelFileName(name);
+ const fullTargetPath = path.resolve(this.artifactInfo.relPath, fileName);
+ debug('Model %s output file', name, fullTargetPath);
+
+ this.copyTemplatedFiles(
+ modelUtils.MODEL_TEMPLATE_PATH,
+ fullTargetPath,
+ templateData,
+ );
+
+ this.modelFiles.push(fileName);
+ }
+
+ /**
+ * Iterate through all the models we have discovered and scaffold
+ */
+ async scaffold() {
+ if (this.shouldExit()) return;
+ }
+
+ async end() {
+ if (this.shouldExit() || !this._isGenerationSuccessful()) {
+ await super.end();
+ return;
+ }
+
+ for (const f of this.modelFiles) {
+ await this._updateIndexFile(this.artifactInfo.outDir, f);
+ }
+
+ await super.end();
+ }
+};
diff --git a/packages/cli/generators/import-lb3-models/lb3app-loader.js b/packages/cli/generators/import-lb3-models/lb3app-loader.js
new file mode 100644
index 000000000000..49e829770523
--- /dev/null
+++ b/packages/cli/generators/import-lb3-models/lb3app-loader.js
@@ -0,0 +1,31 @@
+// Copyright IBM Corp. 2019. All Rights Reserved.
+// Node module: @loopback/cli
+// This file is licensed under the MIT License.
+// License text available at https://opensource.org/licenses/MIT
+
+'use strict';
+
+const debug = require('../../lib/debug')('import-lb3-models');
+const path = require('path');
+const pEvent = require('p-event');
+
+module.exports = {
+ loadLb3App,
+};
+
+// TODO: do we want to share this code with `Lb3AppBooter.loadAndBootTheApp`?
+async function loadLb3App(dir) {
+ debug('Loading LB3 app from', dir);
+ const lb3App = require(path.resolve(dir));
+
+ debug(
+ 'If your LB3 app does not boot correctly then make sure it is using loopback-boot version 3.2.1 or higher.',
+ );
+
+ if (lb3App.booting) {
+ debug(' waiting for boot process to finish');
+ // Wait until the legacy LB3 app boots
+ await pEvent(lb3App, 'booted');
+ }
+ return lb3App;
+}
diff --git a/packages/cli/generators/import-lb3-models/migrate-model.js b/packages/cli/generators/import-lb3-models/migrate-model.js
new file mode 100644
index 000000000000..a3c9070a006c
--- /dev/null
+++ b/packages/cli/generators/import-lb3-models/migrate-model.js
@@ -0,0 +1,206 @@
+// Copyright IBM Corp. 2019. All Rights Reserved.
+// Node module: @loopback/cli
+// This file is licensed under the MIT License.
+// License text available at https://opensource.org/licenses/MIT
+
+'use strict';
+
+const {
+ validateClassName,
+ logNamingIssues,
+ pascalCase,
+ stringifyModelSettings,
+} = require('../../lib/utils');
+const {sanitizeProperty} = require('../../lib/model-discoverer');
+const {
+ createPropertyTemplateData,
+ BUILTIN_TYPES,
+} = require('../model/property-definition');
+const chalk = require('chalk');
+
+module.exports = {
+ importLb3ModelDefinition,
+};
+
+/**
+ * Convert definition of a LB3 model into template data used by
+ * LB4 model generator.
+ *
+ * @param {Function} modelCtor LB3 model class
+ * @param {(msg: string, ...args: any) => void} log Logging function
+ * @returns {object} Template data for model source file template
+ */
+function importLb3ModelDefinition(modelCtor, log) {
+ const modelName = modelCtor.modelName;
+ const result = validateClassName(modelName);
+ if (!result) {
+ const err = new Error(
+ `Cannot import model: the name ${modelName} is not valid. ${result}`,
+ );
+ err.exit = true;
+ throw err;
+ }
+
+ logNamingIssues(modelName, log);
+
+ const templateData = {
+ name: modelName,
+ className: pascalCase(modelName),
+ ...migrateBaseClass(modelCtor.settings.base),
+ properties: migrateModelProperties(modelCtor.definition.properties),
+ settings: migrateModelSettings(modelCtor.definition.settings, log),
+ };
+
+ const settings = templateData.settings;
+ delete settings.base; // already handled by migrateBaseClass
+ templateData.allowAdditionalProperties = !settings.strict;
+ templateData.modelSettings = stringifyModelSettings(settings);
+
+ return templateData;
+}
+
+function migrateModelProperties(properties) {
+ const templateData = {};
+
+ // In LB 3.x, primary keys are typically contributed by connectors later in
+ // the startup process, therefore they end up at the end of the property list.
+ // Here we create placeholder entries for PKs to get them generated first.
+ Object.keys(properties)
+ .filter(p => !!properties[p].id)
+ .forEach(pk => {
+ templateData[pk] = null;
+ });
+
+ for (const prop in properties) {
+ const def = migratePropertyDefinition(properties[prop]);
+ templateData[prop] = createPropertyTemplateData(def);
+ }
+
+ return templateData;
+}
+
+function migratePropertyDefinition(lb3PropDef) {
+ const def = {...lb3PropDef};
+
+ if (!Array.isArray(def.type)) {
+ // scalar type
+ def.type = migratePropertyType(def.type);
+ } else {
+ // array type - conversion is slightly more complex
+ def.itemType = migratePropertyType(def.type[0]);
+ def.type = 'array';
+
+ // workaround for a weird behavior of LB3
+ if (0 in def && def[0] === def.itemType) {
+ delete def[0];
+ }
+ }
+
+ if (def.updateOnly === false) {
+ // updateOnly is disabled by default, no need to specify "false" value
+ delete def.updateOnly;
+ }
+ sanitizeProperty(def);
+ return def;
+}
+
+function migratePropertyType(typeDef) {
+ if (typeof typeDef === 'function') {
+ typeDef = typeDef.name.toString();
+ }
+
+ const builtin = BUILTIN_TYPES.find(t => t === typeDef.toLowerCase());
+ if (builtin) typeDef = builtin;
+
+ // TODO: handle anonymous object types (nested properties)
+
+ return typeDef;
+}
+
+const BUILTIN_BASE_MODELS = {
+ Model: 'Model',
+ PersistedModel: 'Entity',
+ KeyValueModel: 'KeyValueModel',
+};
+
+function migrateBaseClass(base) {
+ const baseModelName = base.modelName || base.name || base;
+ if (baseModelName in BUILTIN_BASE_MODELS) {
+ return {
+ modelBaseClass: BUILTIN_BASE_MODELS[baseModelName],
+ isModelBaseBuiltin: true,
+ };
+ }
+
+ // TODO: handle inheritance from application models
+ throw new Error(
+ 'Models inheriting from app-specific models cannot be migrated yet. ' +
+ `Base model configured: ${baseModelName}`,
+ );
+}
+
+function migrateModelSettings(settings = {}, log) {
+ // Shallow-clone the object to prevent modification of external data
+ settings = {...settings};
+
+ // "strict" mode is enabled only when explicitly requested
+ // LB3 models allow additional properties by default
+ settings.strict = settings.strict === true;
+
+ if (settings.forceId === 'auto') {
+ // The value 'auto' is used when a parent model wants to let the child
+ // model make the decision automatically, depending on whether the child
+ // model has a database-generated PK.
+ // See https://github.com/strongloop/loopback-datasource-juggler/blob/15251880a1d07ccc2ca6d2dccdd065d00a7375eb/lib/model-builder.js#L347-L355
+ //
+ // Let's delete the flag from the generated model settings and
+ // leave it up to the runtime to decide.
+ delete settings.forceId;
+ }
+
+ // Notable settings that are not supported yet:
+ // relations, acls, methods, mixins, validations
+
+ const relationNames = Object.keys(settings.relations || {});
+ if (relationNames.length) {
+ log(
+ chalk.yellow(
+ 'Import of model relations is not supported yet. ' +
+ 'Skipping the following relations: ' +
+ relationNames.join(', '),
+ ),
+ );
+ }
+ delete settings.relations;
+
+ const unsupportedSettings = [];
+ if ((settings.acls || []).length) {
+ unsupportedSettings.push('acls');
+ }
+ delete settings.acls;
+
+ for (const k of ['methods', 'mixins', 'validations']) {
+ if (k in settings && Object.keys(settings[k]).length) {
+ unsupportedSettings.push(k);
+ }
+ delete settings[k];
+ }
+
+ if (unsupportedSettings.length) {
+ log(
+ chalk.yellow(
+ 'Ignoring the following unsupported settings: ' +
+ unsupportedSettings.join(', '),
+ ),
+ );
+ }
+
+ if (
+ typeof settings.hiddenProperties === 'object' &&
+ Object.keys(settings.hiddenProperties).length === 0
+ ) {
+ delete settings.hiddenProperties;
+ }
+
+ return settings;
+}
diff --git a/packages/cli/generators/import-lb3-models/model-names.js b/packages/cli/generators/import-lb3-models/model-names.js
new file mode 100644
index 000000000000..e7f2a6fea971
--- /dev/null
+++ b/packages/cli/generators/import-lb3-models/model-names.js
@@ -0,0 +1,32 @@
+// Copyright IBM Corp. 2019. All Rights Reserved.
+// Node module: @loopback/cli
+// This file is licensed under the MIT License.
+// License text available at https://opensource.org/licenses/MIT
+
+'use strict';
+
+module.exports = {
+ canImportModelName,
+};
+
+// List of built-in LB models to exclude from the prompt
+const EXCLUDED_MODEL_NAMES = [
+ // base models
+ 'Model',
+ 'PersistedModel',
+ 'KeyValueModel',
+ // change tracking & replication
+ 'Change',
+ 'Checkpoint',
+ // Email - a dummy model used to attach email-connector methods only
+ 'Email',
+];
+
+function canImportModelName(name) {
+ if (EXCLUDED_MODEL_NAMES.includes(name)) return false;
+ // TODO: find out where are anonymous models coming from
+ // (perhaps from object types defined inside property definitions?)
+ // and add test cases to verify that we are handling those scenarios correctly
+ if (name.startsWith('AnonymousModel_')) return false;
+ return true;
+}
diff --git a/packages/cli/lib/cli.js b/packages/cli/lib/cli.js
index 829b59707b61..d6fb1063add8 100644
--- a/packages/cli/lib/cli.js
+++ b/packages/cli/lib/cli.js
@@ -62,6 +62,10 @@ function setupGenerators() {
path.join(__dirname, '../generators/datasource'),
PREFIX + 'datasource',
);
+ env.register(
+ path.join(__dirname, '../generators/import-lb3-models'),
+ PREFIX + 'import-lb3-models',
+ );
env.register(path.join(__dirname, '../generators/model'), PREFIX + 'model');
env.register(
path.join(__dirname, '../generators/repository'),
diff --git a/packages/cli/lib/utils.js b/packages/cli/lib/utils.js
index 9cdf1403228f..998f3de6dc28 100644
--- a/packages/cli/lib/utils.js
+++ b/packages/cli/lib/utils.js
@@ -564,6 +564,7 @@ exports.dataSourceToJSONFileName = function(dataSourceClass) {
};
exports.stringifyModelSettings = function(modelSettings) {
+ if (!modelSettings || !Object.keys(modelSettings).length) return '';
return stringifyObject(
{settings: modelSettings},
{
diff --git a/packages/cli/package-lock.json b/packages/cli/package-lock.json
index f7e2a03cf262..2d073e0f418e 100644
--- a/packages/cli/package-lock.json
+++ b/packages/cli/package-lock.json
@@ -128,6 +128,23 @@
"defer-to-connect": "^1.0.1"
}
},
+ "@types/body-parser": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz",
+ "integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==",
+ "requires": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/connect": {
+ "version": "3.4.32",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz",
+ "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@types/ejs": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-2.6.3.tgz",
@@ -139,6 +156,25 @@
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
},
+ "@types/express": {
+ "version": "4.17.1",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.1.tgz",
+ "integrity": "sha512-VfH/XCP0QbQk5B5puLqTLEeFgR8lfCJHZJKkInZ9mkYd+u8byX0kztXEQxEk4wZXJs8HI+7km2ALXjn4YKcX9w==",
+ "requires": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "@types/express-serve-static-core": {
+ "version": "4.16.9",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.9.tgz",
+ "integrity": "sha512-GqpaVWR0DM8FnRUJYKlWgyARoBUAVfRIeVDZQKOttLFp5SmhhF9YFIYeTPwMd/AXfxlP7xVO2dj1fGu0Q+krKQ==",
+ "requires": {
+ "@types/node": "*",
+ "@types/range-parser": "*"
+ }
+ },
"@types/glob": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
@@ -156,6 +192,11 @@
}
}
},
+ "@types/mime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz",
+ "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw=="
+ },
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@@ -172,6 +213,20 @@
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA=="
},
+ "@types/range-parser": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
+ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA=="
+ },
+ "@types/serve-static": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz",
+ "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==",
+ "requires": {
+ "@types/express-serve-static-core": "*",
+ "@types/mime": "*"
+ }
+ },
"JSONStream": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
@@ -185,12 +240,20 @@
"version": "3.0.18",
"resolved": "https://registry.npmjs.org/accept-language/-/accept-language-3.0.18.tgz",
"integrity": "sha1-9QJfF79lpGaoRYOMz5jNuHfYM4Q=",
- "dev": true,
"requires": {
"bcp47": "^1.1.2",
"stable": "^0.1.6"
}
},
+ "accepts": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+ "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "requires": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ }
+ },
"agent-base": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
@@ -302,6 +365,11 @@
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
"integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg=="
},
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
"array-from": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz",
@@ -332,7 +400,6 @@
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
- "dev": true,
"requires": {
"safer-buffer": "~2.1.0"
}
@@ -340,8 +407,7 @@
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
- "dev": true
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"assign-symbols": {
"version": "1.0.0",
@@ -359,8 +425,7 @@
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
- "dev": true
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"atob": {
"version": "2.1.2",
@@ -370,14 +435,12 @@
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
- "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
- "dev": true
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
- "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
- "dev": true
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
},
"balanced-match": {
"version": "1.0.0",
@@ -434,21 +497,29 @@
}
}
},
+ "base64-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.0.2.tgz",
+ "integrity": "sha1-R0IRyV5s8qVH20YeT2d4tR0I+mU="
+ },
"bcp47": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/bcp47/-/bcp47-1.1.2.tgz",
- "integrity": "sha1-NUvjMH/9CEM6ePXh4glYRfifx/4=",
- "dev": true
+ "integrity": "sha1-NUvjMH/9CEM6ePXh4glYRfifx/4="
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
- "dev": true,
"requires": {
"tweetnacl": "^0.14.3"
}
},
+ "bcryptjs": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
+ "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms="
+ },
"better-ajv-errors": {
"version": "0.6.7",
"resolved": "https://registry.npmjs.org/better-ajv-errors/-/better-ajv-errors-0.6.7.tgz",
@@ -472,7 +543,6 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz",
"integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==",
- "dev": true,
"requires": {
"readable-stream": "^2.3.5",
"safe-buffer": "^5.1.1"
@@ -483,6 +553,57 @@
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
"integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w=="
},
+ "body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+ "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "requires": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
+ }
+ }
+ },
+ "bops": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/bops/-/bops-1.0.0.tgz",
+ "integrity": "sha1-YxqJKPEXhBfrb3Bs9prNteWk6q0=",
+ "requires": {
+ "base64-js": "1.0.2",
+ "to-utf8": "0.0.1"
+ }
+ },
"boxen": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/boxen/-/boxen-3.2.0.tgz",
@@ -574,6 +695,11 @@
"resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz",
"integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og="
},
+ "bytes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
+ },
"cacache": {
"version": "12.0.3",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz",
@@ -685,6 +811,11 @@
"quick-lru": "^4.0.1"
}
},
+ "canonical-json": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/canonical-json/-/canonical-json-0.0.4.tgz",
+ "integrity": "sha1-ZXnAcsPbXEd+xB3JePvyuPQQdKM="
+ },
"capture-stack-trace": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
@@ -693,8 +824,7 @@
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
- "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
- "dev": true
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"chalk": {
"version": "2.4.2",
@@ -739,8 +869,7 @@
"charenc": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
- "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=",
- "dev": true
+ "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
},
"chownr": {
"version": "1.1.2",
@@ -776,8 +905,7 @@
"cldrjs": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/cldrjs/-/cldrjs-0.5.1.tgz",
- "integrity": "sha512-xyiP8uAm8K1IhmpDndZLraloW1yqu0L+HYdQ7O1aGPxx9Cr+BMnPANlNhSt++UKfxytL2hd2NPXgTjiy7k43Ew==",
- "dev": true
+ "integrity": "sha512-xyiP8uAm8K1IhmpDndZLraloW1yqu0L+HYdQ7O1aGPxx9Cr+BMnPANlNhSt++UKfxytL2hd2NPXgTjiy7k43Ew=="
},
"cli-boxes": {
"version": "2.2.0",
@@ -928,7 +1056,6 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "dev": true,
"requires": {
"delayed-stream": "~1.0.0"
}
@@ -936,8 +1063,7 @@
"commander": {
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
- "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
- "optional": true
+ "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ=="
},
"commondir": {
"version": "1.0.1",
@@ -999,6 +1125,36 @@
"upper-case": "^1.1.1"
}
},
+ "content-disposition": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+ "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "requires": {
+ "safe-buffer": "5.1.2"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ }
+ }
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ },
+ "cookie": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+ "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
"copy-concurrently": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
@@ -1067,8 +1223,7 @@
"crypt": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
- "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=",
- "dev": true
+ "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
},
"crypto-random-string": {
"version": "1.0.0",
@@ -1089,7 +1244,6 @@
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
- "dev": true,
"requires": {
"assert-plus": "^1.0.0"
}
@@ -1135,6 +1289,14 @@
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.0.2.tgz",
"integrity": "sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw=="
},
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
"define-property": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
@@ -1175,8 +1337,7 @@
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
- "dev": true
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"depd": {
"version": "2.0.0",
@@ -1184,6 +1345,11 @@
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
"dev": true
},
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
"detect-conflict": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/detect-conflict/-/detect-conflict-1.0.1.tgz",
@@ -1218,6 +1384,16 @@
"is-obj": "^1.0.0"
}
},
+ "duplex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/duplex/-/duplex-1.0.0.tgz",
+ "integrity": "sha1-arxcFuwX5MV4V4cnEmcAWQ06Ldo="
+ },
+ "duplexer": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.0.4.tgz",
+ "integrity": "sha1-r8t/H4uNdPggcmFx1dZKyeSo/yA="
+ },
"duplexer3": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
@@ -1238,7 +1414,6 @@
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
- "dev": true,
"requires": {
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
@@ -1253,6 +1428,11 @@
"semver": "^6.3.0"
}
},
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
"ejs": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.1.tgz",
@@ -1263,6 +1443,11 @@
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+ },
"encoding": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
@@ -1308,6 +1493,33 @@
"is-arrayish": "^0.2.1"
}
},
+ "es-abstract": {
+ "version": "1.14.2",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.2.tgz",
+ "integrity": "sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==",
+ "requires": {
+ "es-to-primitive": "^1.2.0",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.0",
+ "is-callable": "^1.1.4",
+ "is-regex": "^1.0.4",
+ "object-inspect": "^1.6.0",
+ "object-keys": "^1.1.1",
+ "string.prototype.trimleft": "^2.0.0",
+ "string.prototype.trimright": "^2.0.0"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
+ "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
"es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
@@ -1321,6 +1533,11 @@
"es6-promise": "^4.0.3"
}
},
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -1349,6 +1566,16 @@
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
},
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+ },
+ "eventemitter2": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz",
+ "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI="
+ },
"execa": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
@@ -1408,11 +1635,82 @@
}
}
},
+ "express": {
+ "version": "4.17.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+ "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+ "requires": {
+ "accepts": "~1.3.7",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.19.0",
+ "content-disposition": "0.5.3",
+ "content-type": "~1.0.4",
+ "cookie": "0.4.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.5",
+ "qs": "6.7.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.1.2",
+ "send": "0.17.1",
+ "serve-static": "1.14.1",
+ "setprototypeof": "1.1.1",
+ "statuses": "~1.5.0",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ }
+ }
+ },
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
- "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
- "dev": true
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
"extend-shallow": {
"version": "3.0.2",
@@ -1505,8 +1803,12 @@
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
- "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
- "dev": true
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "eyes": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
+ "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A="
},
"fast-deep-equal": {
"version": "1.1.0",
@@ -1560,6 +1862,35 @@
"to-regex-range": "^5.0.1"
}
},
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@@ -1593,20 +1924,23 @@
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
- "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
- "dev": true
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
- "dev": true,
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+ },
"fragment-cache": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -1615,6 +1949,11 @@
"map-cache": "^0.2.2"
}
},
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ },
"from2": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
@@ -1658,6 +1997,11 @@
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
"genfun": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz",
@@ -1690,7 +2034,6 @@
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
- "dev": true,
"requires": {
"assert-plus": "^1.0.0"
}
@@ -1788,7 +2131,6 @@
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/globalize/-/globalize-1.4.2.tgz",
"integrity": "sha512-IfKeYI5mAITBmT5EnH8kSQB5uGson4Fkj2XtTpyEbIS7IHNfLHoeTyLJ6tfjiKC6cJXng3IhVurDk5C7ORqFhQ==",
- "dev": true,
"requires": {
"cldrjs": "^0.5.0"
}
@@ -1847,14 +2189,12 @@
"har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
- "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
- "dev": true
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
},
"har-validator": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
- "dev": true,
"requires": {
"ajv": "^6.5.5",
"har-schema": "^2.0.0"
@@ -1864,7 +2204,6 @@
"version": "6.10.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
"integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
- "dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -1875,17 +2214,23 @@
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
- "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
- "dev": true
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
}
}
},
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@@ -1897,6 +2242,11 @@
"integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
"dev": true
},
+ "has-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+ "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q="
+ },
"has-to-string-tag-x": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
@@ -1977,6 +2327,30 @@
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
"integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w=="
},
+ "http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ }
+ }
+ },
"http-proxy-agent": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
@@ -2005,18 +2379,36 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
- "dev": true,
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
}
},
+ "http-status": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.3.2.tgz",
+ "integrity": "sha512-vR1YTaDyi2BukI0UiH01xy92oiZi4in7r0dmSPnrZg72Vu1SzyOLalwWP5NUk1rNiB2L+XVK2lcSVOqaertX8A=="
+ },
"http2-client": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.3.tgz",
"integrity": "sha512-nUxLymWQ9pzkzTmir24p2RtsgruLmhje7lH3hLX1IpwvyTg77fW+1brenPPP3USAR+rQ36p5sTA/x7sjCJVkAA=="
},
+ "httpntlm": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz",
+ "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=",
+ "requires": {
+ "httpreq": ">=0.4.22",
+ "underscore": "~1.7.0"
+ }
+ },
+ "httpreq": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz",
+ "integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8="
+ },
"https-proxy-agent": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz",
@@ -2088,8 +2480,7 @@
"inflection": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz",
- "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=",
- "dev": true
+ "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY="
},
"inflight": {
"version": "1.0.6",
@@ -2145,6 +2536,11 @@
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
},
+ "ipaddr.js": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
+ "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
+ },
"is-absolute": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
@@ -2182,6 +2578,11 @@
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
},
+ "is-callable": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
+ "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
+ },
"is-ci": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
@@ -2208,6 +2609,11 @@
}
}
},
+ "is-date-object": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY="
+ },
"is-descriptor": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
@@ -2322,6 +2728,14 @@
"resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
"integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ="
},
+ "is-regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "requires": {
+ "has": "^1.0.1"
+ }
+ },
"is-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
@@ -2353,6 +2767,14 @@
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
},
+ "is-symbol": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
+ "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
+ "requires": {
+ "has-symbols": "^1.0.0"
+ }
+ },
"is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
@@ -2399,6 +2821,11 @@
"resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.2.tgz",
"integrity": "sha512-C3FSxJdNrEr2F4z6uFtNzECDM5hXk+46fxaa+cwBe5/XrWSmzdG8DDgyjfX6/NRdBB21q2JXuRAzPCUs+fclnQ=="
},
+ "isemail": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/isemail/-/isemail-2.2.1.tgz",
+ "integrity": "sha1-A1PT2aYpUQgMJiwqoKQrjqjp4qY="
+ },
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -2412,8 +2839,7 @@
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
- "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
- "dev": true
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"istextorbinary": {
"version": "2.5.1",
@@ -2435,6 +2861,21 @@
"is-object": "^1.0.1"
}
},
+ "jayson": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/jayson/-/jayson-2.1.2.tgz",
+ "integrity": "sha512-2GejcQnEV35KYTXoBvzALIDdO/1oyEIoJHBnaJFhJhcurv0x2JqUXQW6xlDUhcNOpN9t+d2w+JGA6vOphb+5mg==",
+ "requires": {
+ "@types/node": "^10.3.5",
+ "JSONStream": "^1.3.1",
+ "commander": "^2.12.2",
+ "es6-promisify": "^5.0.0",
+ "eyes": "^0.1.8",
+ "json-stringify-safe": "^5.0.1",
+ "lodash": "^4.17.11",
+ "uuid": "^3.2.1"
+ }
+ },
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -2449,11 +2890,18 @@
"esprima": "^4.0.0"
}
},
+ "js2xmlparser": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-3.0.0.tgz",
+ "integrity": "sha1-P7YOqgicVED5MZ9RdgzNB+JJlzM=",
+ "requires": {
+ "xmlcreate": "^1.0.1"
+ }
+ },
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
- "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
- "dev": true
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
"json-buffer": {
"version": "3.0.0",
@@ -2468,8 +2916,7 @@
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
- "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
- "dev": true
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
},
"json-schema-ref-parser": {
"version": "7.1.1",
@@ -2489,8 +2936,7 @@
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
- "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
- "dev": true
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"json-to-ast": {
"version": "2.1.0",
@@ -2531,7 +2977,6 @@
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
- "dev": true,
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
@@ -2652,11 +3097,96 @@
"integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==",
"dev": true
},
+ "loopback": {
+ "version": "3.26.0",
+ "resolved": "https://registry.npmjs.org/loopback/-/loopback-3.26.0.tgz",
+ "integrity": "sha512-QDREGpTTjLwMgteSIajFXMklW4slbVO5PvY2bPXBn3EUfPzmWXfaDiSlzwbbRbw+cyMUAr2EorL1r0+IsIslWg==",
+ "requires": {
+ "async": "^2.0.1",
+ "bcryptjs": "^2.1.0",
+ "bluebird": "^3.1.1",
+ "body-parser": "^1.12.0",
+ "canonical-json": "0.0.4",
+ "debug": "^2.1.2",
+ "depd": "^1.0.0",
+ "ejs": "^2.3.1",
+ "express": "^4.14.0",
+ "inflection": "^1.6.0",
+ "isemail": "^2.2.1",
+ "loopback-connector-remote": "^3.0.0",
+ "loopback-datasource-juggler": "^3.28.0",
+ "loopback-filters": "^1.0.0",
+ "loopback-phase": "^3.0.0",
+ "nodemailer": "^4.0.1",
+ "nodemailer-direct-transport": "^3.3.2",
+ "nodemailer-stub-transport": "^1.1.0",
+ "serve-favicon": "^2.2.0",
+ "stable": "^0.1.5",
+ "strong-globalize": "^4.1.1",
+ "strong-remoting": "^3.11.0",
+ "uid2": "0.0.3",
+ "underscore.string": "^3.3.5"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "loopback-datasource-juggler": {
+ "version": "3.33.1",
+ "resolved": "https://registry.npmjs.org/loopback-datasource-juggler/-/loopback-datasource-juggler-3.33.1.tgz",
+ "integrity": "sha512-VltMiPJxVWQjjWRM1TeSvGL/NF6Ey9575gsEva54+wgtuTO7gRAJTX0DDhpHvwTCflW+s0vWXPFPoTgQaThXEw==",
+ "requires": {
+ "async": "^2.6.0",
+ "bluebird": "^3.1.1",
+ "debug": "^3.1.0",
+ "depd": "^1.0.0",
+ "inflection": "^1.6.0",
+ "lodash": "^4.17.4",
+ "loopback-connector": "^4.4.0",
+ "minimatch": "^3.0.3",
+ "qs": "^6.5.0",
+ "shortid": "^2.2.6",
+ "strong-globalize": "^4.1.1",
+ "traverse": "^0.6.6",
+ "uuid": "^3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "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=="
+ }
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
"loopback-connector": {
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/loopback-connector/-/loopback-connector-4.9.0.tgz",
"integrity": "sha512-WtHPxItqNLOxuonsOthuOIZrkd9kW+t0HtMweU0pjtEquCvKJAV8s9xqaNs8q8kmbv6rgmYEtmzxkRUsRcV+xQ==",
- "dev": true,
"requires": {
"async": "^3.1.0",
"bluebird": "^3.4.6",
@@ -2669,20 +3199,17 @@
"async": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/async/-/async-3.1.0.tgz",
- "integrity": "sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ==",
- "dev": true
+ "integrity": "sha512-4vx/aaY6j/j3Lw3fbCHNWP0pPaTCew3F6F3hYyl/tHs/ndmV1q7NW9T5yuJ2XAGwdQrP+6Wu20x06U4APo/iQQ=="
},
"invert-kv": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-3.0.0.tgz",
- "integrity": "sha512-JzF8q2BeZA1ZkE3XROwRpoMQ9ObMgTtp0JH8EXewlbkikuOj2GPLIpUipdO+VL8QsTr2teAJD02EFGGL5cO7uw==",
- "dev": true
+ "integrity": "sha512-JzF8q2BeZA1ZkE3XROwRpoMQ9ObMgTtp0JH8EXewlbkikuOj2GPLIpUipdO+VL8QsTr2teAJD02EFGGL5cO7uw=="
},
"lcid": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/lcid/-/lcid-3.1.0.tgz",
"integrity": "sha512-HC0Rr2YRxWISzAJ9K0ZiCVRUdjDT6fE6kUKZkXZOZgy968cKWOYy++xwUHO497RRQPPNiABY7SwdoQMMNcZmDQ==",
- "dev": true,
"requires": {
"invert-kv": "^3.0.0"
}
@@ -2691,7 +3218,6 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/mem/-/mem-5.1.1.tgz",
"integrity": "sha512-qvwipnozMohxLXG1pOqoLiZKNkC4r4qqRucSoDwXowsNGDSULiqFTRUF05vcZWnwJSG22qTsynQhxbaMtnX9gw==",
- "dev": true,
"requires": {
"map-age-cleaner": "^0.1.3",
"mimic-fn": "^2.1.0",
@@ -2702,7 +3228,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-4.0.0.tgz",
"integrity": "sha512-HsSR1+2l6as4Wp2SGZxqLnuFHxVvh1Ir9pvZxyujsC13egZVe7P0YeBLN0ijQzM/twrO5To3ia3jzBXAvpMTEA==",
- "dev": true,
"requires": {
"execa": "^1.0.0",
"lcid": "^3.0.0",
@@ -2713,7 +3238,6 @@
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/strong-globalize/-/strong-globalize-5.0.2.tgz",
"integrity": "sha512-Y5iuJLEcjI5iUusOvPlen0Q6ej11jUFMzJF4er9gMGy1+yVv/i7v2TuFvD/8lhMAPrE++RRawNQZMpJYsdju/Q==",
- "dev": true,
"requires": {
"accept-language": "^3.0.18",
"debug": "^4.1.1",
@@ -2727,24 +3251,111 @@
}
}
},
- "loopback-datasource-juggler": {
- "version": "4.13.0",
- "resolved": "https://registry.npmjs.org/loopback-datasource-juggler/-/loopback-datasource-juggler-4.13.0.tgz",
- "integrity": "sha512-y0dWSD6BAgY3twhYsa4SmLzOgmp6REAzRJ6gNcc0dhSJ+qur2Ne54BQLqg/bs3KKl9l6AJcLVqB/DRrbjXFn6Q==",
- "dev": true,
+ "loopback-connector-remote": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/loopback-connector-remote/-/loopback-connector-remote-3.4.1.tgz",
+ "integrity": "sha512-O22X2Gcq8YzZF9DvRjOCyktQlASw1/22i/zzqxJHNKSQA5aQYeTB0w5FttOiKxcw6Q/jzL476hUvUE/NaZVZ1Q==",
+ "requires": {
+ "loopback-datasource-juggler": "^3.0.0",
+ "strong-remoting": "^3.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "loopback-datasource-juggler": {
+ "version": "3.33.1",
+ "resolved": "https://registry.npmjs.org/loopback-datasource-juggler/-/loopback-datasource-juggler-3.33.1.tgz",
+ "integrity": "sha512-VltMiPJxVWQjjWRM1TeSvGL/NF6Ey9575gsEva54+wgtuTO7gRAJTX0DDhpHvwTCflW+s0vWXPFPoTgQaThXEw==",
+ "requires": {
+ "async": "^2.6.0",
+ "bluebird": "^3.1.1",
+ "debug": "^3.1.0",
+ "depd": "^1.0.0",
+ "inflection": "^1.6.0",
+ "lodash": "^4.17.4",
+ "loopback-connector": "^4.4.0",
+ "minimatch": "^3.0.3",
+ "qs": "^6.5.0",
+ "shortid": "^2.2.6",
+ "strong-globalize": "^4.1.1",
+ "traverse": "^0.6.6",
+ "uuid": "^3.0.1"
+ }
+ }
+ }
+ },
+ "loopback-datasource-juggler": {
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/loopback-datasource-juggler/-/loopback-datasource-juggler-4.13.0.tgz",
+ "integrity": "sha512-y0dWSD6BAgY3twhYsa4SmLzOgmp6REAzRJ6gNcc0dhSJ+qur2Ne54BQLqg/bs3KKl9l6AJcLVqB/DRrbjXFn6Q==",
+ "dev": true,
+ "requires": {
+ "async": "^2.6.0",
+ "debug": "^4.1.0",
+ "depd": "^2.0.0",
+ "inflection": "^1.6.0",
+ "lodash": "^4.17.11",
+ "loopback-connector": "^4.4.0",
+ "minimatch": "^3.0.3",
+ "qs": "^6.5.0",
+ "shortid": "^2.2.6",
+ "strong-globalize": "^4.1.1",
+ "traverse": "^0.6.6",
+ "uuid": "^3.0.1"
+ }
+ },
+ "loopback-datatype-geopoint": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/loopback-datatype-geopoint/-/loopback-datatype-geopoint-1.0.0.tgz",
+ "integrity": "sha1-/apcerjXMKmrflRVS+Fl8xzfYQA="
+ },
+ "loopback-filters": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/loopback-filters/-/loopback-filters-1.0.0.tgz",
+ "integrity": "sha512-uFQQLfj4T27CM6dzlWMH6aF1lf/Qj97VmXMlVnNWcG+Pd8R8ZbU4i/shArYXArXfis+ICD80YadrPbf9DYRbOA==",
+ "requires": {
+ "debug": "^3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "loopback-phase": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/loopback-phase/-/loopback-phase-3.3.0.tgz",
+ "integrity": "sha512-0NAMtZ2P7VHtW2vgADmDFzFCeniCJwL4I3AdAxX5Ds8IFDQNbnRFnBQSvg+F50HcB7ZkKmR5gtOxtr7bXbqaAQ==",
"requires": {
- "async": "^2.6.0",
- "debug": "^4.1.0",
- "depd": "^2.0.0",
- "inflection": "^1.6.0",
- "lodash": "^4.17.11",
- "loopback-connector": "^4.4.0",
- "minimatch": "^3.0.3",
- "qs": "^6.5.0",
- "shortid": "^2.2.6",
- "strong-globalize": "^4.1.1",
- "traverse": "^0.6.6",
- "uuid": "^3.0.1"
+ "async": "^2.6.1",
+ "debug": "^3.1.0",
+ "strong-globalize": "^4.1.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
}
},
"lower-case": {
@@ -2829,13 +3440,17 @@
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz",
"integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=",
- "dev": true,
"requires": {
"charenc": "~0.0.1",
"crypt": "~0.0.1",
"is-buffer": "~1.1.1"
}
},
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
"mem": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
@@ -3112,11 +3727,21 @@
}
}
},
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
"merge2": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz",
"integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw=="
},
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
"micromatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
@@ -3126,17 +3751,20 @@
"picomatch": "^2.0.5"
}
},
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+ },
"mime-db": {
"version": "1.40.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
- "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
- "dev": true
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
},
"mime-types": {
"version": "2.1.24",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
- "dev": true,
"requires": {
"mime-db": "1.40.0"
}
@@ -3266,11 +3894,51 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
+ "msgpack-js": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/msgpack-js/-/msgpack-js-0.3.0.tgz",
+ "integrity": "sha1-Aw7AjFlW+cp9F9QKVy1Tlv7BCSM=",
+ "requires": {
+ "bops": "~0.0.6"
+ },
+ "dependencies": {
+ "base64-js": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.2.tgz",
+ "integrity": "sha1-Ak8Pcq+iW3X5wO5zzU9V7Bvtl4Q="
+ },
+ "bops": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/bops/-/bops-0.0.7.tgz",
+ "integrity": "sha1-tKClqDmkBkVK8P4FqLkaenZqVOI=",
+ "requires": {
+ "base64-js": "0.0.2",
+ "to-utf8": "0.0.1"
+ }
+ }
+ }
+ },
+ "msgpack-stream": {
+ "version": "0.0.13",
+ "resolved": "https://registry.npmjs.org/msgpack-stream/-/msgpack-stream-0.0.13.tgz",
+ "integrity": "sha1-UKZzrE6uyl43cBkk0JPUM1DB5Sw=",
+ "requires": {
+ "bops": "1.0.0",
+ "msgpack-js": "0.3.0",
+ "through": "2.3.4"
+ },
+ "dependencies": {
+ "through": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.4.tgz",
+ "integrity": "sha1-SV5A6Nio6uvHwnXqiMK4/BTFZFU="
+ }
+ }
+ },
"msgpack5": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-4.2.1.tgz",
"integrity": "sha512-Xo7nE9ZfBVonQi1rSopNAqPdts/QHyuSEUwIEzAkB+V2FtmkkLUbP6MyVqVVQxsZYI65FpvW3Bb8Z9ZWEjbgHQ==",
- "dev": true,
"requires": {
"bl": "^2.0.1",
"inherits": "^2.0.3",
@@ -3295,11 +3963,36 @@
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
},
+ "mux-demux": {
+ "version": "3.7.9",
+ "resolved": "https://registry.npmjs.org/mux-demux/-/mux-demux-3.7.9.tgz",
+ "integrity": "sha1-NTZ3GP02AcgLzi63YlMVdtekrO8=",
+ "requires": {
+ "duplex": "~1.0.0",
+ "json-buffer": "~2.0.4",
+ "msgpack-stream": "~0.0.10",
+ "stream-combiner": "0.0.2",
+ "stream-serializer": "~1.1.1",
+ "through": "~2.3.1",
+ "xtend": "~1.0.3"
+ },
+ "dependencies": {
+ "json-buffer": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-2.0.11.tgz",
+ "integrity": "sha1-PkQf2jCYvo0eMXGtWRvGKjPi1V8="
+ },
+ "xtend": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-1.0.3.tgz",
+ "integrity": "sha1-P12Tc1PM7Y4IU5mlY/2yJUHClgo="
+ }
+ }
+ },
"nanoid": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.1.tgz",
- "integrity": "sha512-0YbJdaL4JFoejIOoawgLcYValFGJ2iyUuVDIWL3g8Es87SSOWFbWdRUMV3VMSiyPs3SQ3QxCIxFX00q5DLkMCw==",
- "dev": true
+ "integrity": "sha512-0YbJdaL4JFoejIOoawgLcYValFGJ2iyUuVDIWL3g8Es87SSOWFbWdRUMV3VMSiyPs3SQ3QxCIxFX00q5DLkMCw=="
},
"nanomatch": {
"version": "1.2.13",
@@ -3324,6 +4017,11 @@
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
},
+ "negotiator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
+ },
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@@ -3383,6 +4081,38 @@
}
}
},
+ "nodemailer": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-4.7.0.tgz",
+ "integrity": "sha512-IludxDypFpYw4xpzKdMAozBSkzKHmNBvGanUREjJItgJ2NYcK/s8+PggVhj7c2yGFQykKsnnmv1+Aqo0ZfjHmw=="
+ },
+ "nodemailer-direct-transport": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-3.3.2.tgz",
+ "integrity": "sha1-6W+vuQNYVglH5WkBfZfmBzilCoY=",
+ "requires": {
+ "nodemailer-shared": "1.1.0",
+ "smtp-connection": "2.12.0"
+ }
+ },
+ "nodemailer-fetch": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz",
+ "integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q="
+ },
+ "nodemailer-shared": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz",
+ "integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=",
+ "requires": {
+ "nodemailer-fetch": "1.6.0"
+ }
+ },
+ "nodemailer-stub-transport": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/nodemailer-stub-transport/-/nodemailer-stub-transport-1.1.0.tgz",
+ "integrity": "sha1-EUIdLWa07m9AU1T5FMH0ZB6ySw0="
+ },
"normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@@ -3562,8 +4292,7 @@
"oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
- "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
- "dev": true
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
},
"object-copy": {
"version": "0.1.0",
@@ -3593,6 +4322,16 @@
}
}
},
+ "object-inspect": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz",
+ "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ=="
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
+ },
"object-visit": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
@@ -3601,6 +4340,15 @@
"isobject": "^3.0.0"
}
},
+ "object.getownpropertydescriptors": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
+ "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
+ "requires": {
+ "define-properties": "^1.1.2",
+ "es-abstract": "^1.5.1"
+ }
+ },
"object.pick": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
@@ -3609,6 +4357,14 @@
"isobject": "^3.0.1"
}
},
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -3640,6 +4396,11 @@
"resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-1.3.5.tgz",
"integrity": "sha512-11oi4zYorsgvg5yBarZplAqbpev5HkuVNPlZaPTknPDzAynq+lnJdXAmruGWP0s+dNYZS7bjM+xrTpJw7184Fg=="
},
+ "options": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
+ "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
+ },
"os-homedir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
@@ -3679,6 +4440,24 @@
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
"integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww="
},
+ "p-event": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.1.0.tgz",
+ "integrity": "sha512-4vAd06GCsgflX4wHN1JqrMzBh/8QZ4j+rzp0cd2scXRwuBEv+QR3wrVA5aLhWDLw4y2WgDKvzWF3CCLmVM1UgA==",
+ "requires": {
+ "p-timeout": "^2.0.1"
+ },
+ "dependencies": {
+ "p-timeout": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz",
+ "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==",
+ "requires": {
+ "p-finally": "^1.0.0"
+ }
+ }
+ }
+ },
"p-finally": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
@@ -3810,6 +4589,11 @@
"lines-and-columns": "^1.1.6"
}
},
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
+ },
"pascal-case": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz",
@@ -3887,8 +4671,7 @@
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
- "dev": true
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"picomatch": {
"version": "2.0.7",
@@ -3960,6 +4743,15 @@
"genfun": "^5.0.0"
}
},
+ "proxy-addr": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
+ "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
+ "requires": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.9.0"
+ }
+ },
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
@@ -3968,8 +4760,7 @@
"psl": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz",
- "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==",
- "dev": true
+ "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw=="
},
"pump": {
"version": "3.0.0",
@@ -4004,20 +4795,34 @@
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
- "dev": true
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"qs": {
"version": "6.9.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.0.tgz",
- "integrity": "sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA==",
- "dev": true
+ "integrity": "sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA=="
},
"quick-lru": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
"integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g=="
},
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
+ },
+ "raw-body": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+ "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "requires": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
"rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@@ -4166,7 +4971,6 @@
"version": "2.88.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
- "dev": true,
"requires": {
"aws-sign2": "~0.7.0",
"aws4": "^1.8.0",
@@ -4193,8 +4997,7 @@
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
- "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
- "dev": true
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
}
}
},
@@ -4334,6 +5137,11 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+ },
"scoped-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/scoped-regex/-/scoped-regex-1.0.0.tgz",
@@ -4359,6 +5167,53 @@
}
}
},
+ "send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+ "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ }
+ }
+ },
"sentence-case": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz",
@@ -4368,6 +5223,41 @@
"upper-case-first": "^1.1.2"
}
},
+ "serve-favicon": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz",
+ "integrity": "sha1-k10kDN/g9YBTB/3+ln2IlCosvPA=",
+ "requires": {
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "ms": "2.1.1",
+ "parseurl": "~1.3.2",
+ "safe-buffer": "5.1.1"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+ "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ }
+ },
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
@@ -4394,6 +5284,11 @@
}
}
},
+ "setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
+ },
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -4421,7 +5316,6 @@
"version": "2.2.15",
"resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.15.tgz",
"integrity": "sha512-5EaCy2mx2Jgc/Fdn9uuDuNIIfWBpzY4XIlhoqtXF6qsf+/+SGZ+FxDdX/ZsMZiWupIWNqAEmiNY4RC+LSmCeOw==",
- "dev": true,
"requires": {
"nanoid": "^2.1.0"
}
@@ -4504,6 +5398,15 @@
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz",
"integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw=="
},
+ "smtp-connection": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz",
+ "integrity": "sha1-1275EnyyPCJZ7bHoNJwujV4tdME=",
+ "requires": {
+ "httpntlm": "1.6.1",
+ "nodemailer-shared": "1.1.0"
+ }
+ },
"snake-case": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz",
@@ -4713,11 +5616,18 @@
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
+ "sse": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/sse/-/sse-0.0.8.tgz",
+ "integrity": "sha512-cviG7JH31TUhZeaEVhac3zTzA+2FwA7qvHziAHpb7mC7RNVJ/RbHN+6LIGsS2ugP4o2H15DWmrSMK+91CboIcg==",
+ "requires": {
+ "options": "0.0.6"
+ }
+ },
"sshpk": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
- "dev": true,
"requires": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
@@ -4741,8 +5651,7 @@
"stable": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
- "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
- "dev": true
+ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w=="
},
"static-extend": {
"version": "0.1.2",
@@ -4763,12 +5672,25 @@
}
}
},
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
+ },
"stealthy-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
"dev": true
},
+ "stream-combiner": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.2.tgz",
+ "integrity": "sha1-3+DnRnV0JWXnbGBWeI6lwjvZfbQ=",
+ "requires": {
+ "duplexer": "~0.0.3"
+ }
+ },
"stream-each": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
@@ -4778,6 +5700,11 @@
"stream-shift": "^1.0.0"
}
},
+ "stream-serializer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/stream-serializer/-/stream-serializer-1.1.2.tgz",
+ "integrity": "sha1-wfl9FdolH1lK4n1B7IraCahG408="
+ },
"stream-shift": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
@@ -4798,6 +5725,24 @@
"strip-ansi": "^5.2.0"
}
},
+ "string.prototype.trimleft": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz",
+ "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "function-bind": "^1.1.1"
+ }
+ },
+ "string.prototype.trimright": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz",
+ "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==",
+ "requires": {
+ "define-properties": "^1.1.3",
+ "function-bind": "^1.1.1"
+ }
+ },
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -4858,11 +5803,34 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
},
+ "strong-error-handler": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/strong-error-handler/-/strong-error-handler-3.2.0.tgz",
+ "integrity": "sha512-WBU5itMkVPoEPf1W3ptb0AjtPvRWabDzVO4Lcy8MbJQUbo8vdWngLAcNQptQovdFoMGLgQAgJzZkelm6FRADuQ==",
+ "requires": {
+ "@types/express": "^4.16.0",
+ "accepts": "^1.3.3",
+ "debug": "^3.1.0",
+ "ejs": "^2.6.1",
+ "http-status": "^1.1.2",
+ "js2xmlparser": "^3.0.0",
+ "strong-globalize": "^4.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
"strong-globalize": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/strong-globalize/-/strong-globalize-4.1.3.tgz",
"integrity": "sha512-SJegV7w5D4AodEspZJtJ7rls3fmi+Zc0PdyJCqBsg4RN9B8TC80/uAI2fikC+s1Jp9FLvr2vDX8f0Fqc62M4OA==",
- "dev": true,
"requires": {
"accept-language": "^3.0.18",
"debug": "^4.1.1",
@@ -4874,6 +5842,48 @@
"yamljs": "^0.3.0"
}
},
+ "strong-remoting": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/strong-remoting/-/strong-remoting-3.14.0.tgz",
+ "integrity": "sha512-kBOVMBIGW8fCv37G8uyvxBLO+ed0mF9z+gulAgOZfdIXWa0AgXhndpjTqAWvde+2iXt/n6odiyYvCUbXCrfBsQ==",
+ "requires": {
+ "async": "^2.0.1",
+ "body-parser": "^1.12.4",
+ "debug": "^3.1.0",
+ "depd": "^1.1.0",
+ "escape-string-regexp": "^1.0.5",
+ "eventemitter2": "^5.0.1",
+ "express": "4.x",
+ "inflection": "^1.7.1",
+ "jayson": "^2.0.5",
+ "js2xmlparser": "^3.0.0",
+ "loopback-datatype-geopoint": "^1.0.0",
+ "loopback-phase": "^3.1.0",
+ "mux-demux": "^3.7.9",
+ "qs": "^6.2.1",
+ "request": "^2.83.0",
+ "sse": "0.0.8",
+ "strong-error-handler": "^3.0.0",
+ "strong-globalize": "^4.1.0",
+ "traverse": "^0.6.6",
+ "xml2js": "^0.4.8"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ }
+ }
+ },
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -5088,11 +6098,20 @@
"is-number": "^7.0.0"
}
},
+ "to-utf8": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/to-utf8/-/to-utf8-0.0.1.tgz",
+ "integrity": "sha1-0Xrqcv8vujm55DYBvns/9y4ImFI="
+ },
+ "toidentifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
+ },
"tough-cookie": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
- "dev": true,
"requires": {
"psl": "^1.1.24",
"punycode": "^1.4.1"
@@ -5101,16 +6120,14 @@
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
- "dev": true
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
}
}
},
"traverse": {
"version": "0.6.6",
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
- "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=",
- "dev": true
+ "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc="
},
"ts-morph": {
"version": "4.0.1",
@@ -5136,7 +6153,6 @@
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
- "dev": true,
"requires": {
"safe-buffer": "^5.0.1"
}
@@ -5144,8 +6160,7 @@
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
- "dev": true
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"type-detect": {
"version": "4.0.8",
@@ -5158,6 +6173,15 @@
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz",
"integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw=="
},
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ }
+ },
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
@@ -5176,11 +6200,30 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.3.tgz",
"integrity": "sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw=="
},
+ "uid2": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz",
+ "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I="
+ },
"unc-path-regex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
"integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo="
},
+ "underscore": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
+ "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk="
+ },
+ "underscore.string": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz",
+ "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==",
+ "requires": {
+ "sprintf-js": "^1.0.3",
+ "util-deprecate": "^1.0.2"
+ }
+ },
"unicode-10.0.0": {
"version": "0.7.5",
"resolved": "https://registry.npmjs.org/unicode-10.0.0/-/unicode-10.0.0-0.7.5.tgz",
@@ -5231,6 +6274,11 @@
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
},
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
"unset-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
@@ -5313,7 +6361,6 @@
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
- "dev": true,
"requires": {
"punycode": "^2.1.0"
}
@@ -5355,11 +6402,24 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
+ "util.promisify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
+ "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
+ "requires": {
+ "define-properties": "^1.1.2",
+ "object.getownpropertydescriptors": "^2.0.3"
+ }
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+ },
"uuid": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
- "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==",
- "dev": true
+ "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ=="
},
"validate-npm-package-license": {
"version": "3.0.4",
@@ -5383,11 +6443,15 @@
"resolved": "https://registry.npmjs.org/validator/-/validator-11.1.0.tgz",
"integrity": "sha512-qiQ5ktdO7CD6C/5/mYV4jku/7qnqzjrxb3C/Q5wR3vGGinHTgJZN/TdFT3ZX4vXhX2R1PXx42fB1cn5W+uJ4lg=="
},
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ },
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
- "dev": true,
"requires": {
"assert-plus": "^1.0.0",
"core-util-is": "1.0.2",
@@ -5582,6 +6646,26 @@
"resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
"integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ="
},
+ "xml2js": {
+ "version": "0.4.22",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.22.tgz",
+ "integrity": "sha512-MWTbxAQqclRSTnehWWe5nMKzI3VmJ8ltiJEco8akcC6j3miOhjjfzKum5sId+CWhfxdOs/1xauYr8/ZDBtQiRw==",
+ "requires": {
+ "sax": ">=0.6.0",
+ "util.promisify": "~1.0.0",
+ "xmlbuilder": "~11.0.0"
+ }
+ },
+ "xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
+ },
+ "xmlcreate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-1.0.2.tgz",
+ "integrity": "sha1-+mv3YqYKQT+z3Y9LA8WyaSONMI8="
+ },
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@@ -5609,7 +6693,6 @@
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz",
"integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==",
- "dev": true,
"requires": {
"argparse": "^1.0.7",
"glob": "^7.0.5"
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 5196ce34ac9f..100c566e340e 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -50,9 +50,11 @@
"inquirer": "~7.0.0",
"json5": "^2.1.0",
"lodash": "^4.17.15",
+ "loopback": "^3.26.0",
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
+ "p-event": "^4.1.0",
"pacote": "^9.5.8",
"pluralize": "^8.0.0",
"regenerate": "^1.4.0",
diff --git a/packages/cli/snapshots/integration/cli/cli.integration.snapshots.js b/packages/cli/snapshots/integration/cli/cli.integration.snapshots.js
index 1e1289db5be7..c02ee82dc3de 100644
--- a/packages/cli/snapshots/integration/cli/cli.integration.snapshots.js
+++ b/packages/cli/snapshots/integration/cli/cli.integration.snapshots.js
@@ -13,6 +13,7 @@ Available commands:
lb4 extension
lb4 controller
lb4 datasource
+ lb4 import-lb3-models
lb4 model
lb4 repository
lb4 service
@@ -31,6 +32,7 @@ Available commands:
lb4 extension
lb4 controller
lb4 datasource
+ lb4 import-lb3-models
lb4 model
lb4 repository
lb4 service
diff --git a/packages/cli/snapshots/integration/generators/import-lb3-models.integration.snapshots.js b/packages/cli/snapshots/integration/generators/import-lb3-models.integration.snapshots.js
new file mode 100644
index 000000000000..7b852937c5f2
--- /dev/null
+++ b/packages/cli/snapshots/integration/generators/import-lb3-models.integration.snapshots.js
@@ -0,0 +1,64 @@
+// IMPORTANT
+// This snapshot file is auto-generated, but designed for humans.
+// It should be checked into source control and tracked carefully.
+// Re-generate by setting UPDATE_SNAPSHOTS=1 and running tests.
+// Make sure to inspect the changes in the snapshots below.
+// Do not ignore changes!
+
+'use strict';
+
+exports[`lb4 import-lb3-models imports CoffeeShop model from lb3-example app 1`] = `
+import {Entity, model, property} from '@loopback/repository';
+
+@model({
+ settings: {
+ strict: false,
+ forceId: false,
+ replaceOnPUT: true,
+ validateUpsert: true,
+ idInjection: true
+ }
+})
+export class CoffeeShop extends Entity {
+ @property({
+ type: 'number',
+ id: 1,
+ generated: true,
+ })
+ id?: number;
+
+ @property({
+ type: 'string',
+ required: true,
+ })
+ name: string;
+
+ @property({
+ type: 'string',
+ })
+ city?: string;
+
+ // Define well-known properties here
+
+ // Indexer property to allow additional data
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ [prop: string]: any;
+
+ constructor(data?: Partial) {
+ super(data);
+ }
+}
+
+export interface CoffeeShopRelations {
+ // describe navigational properties here
+}
+
+export type CoffeeShopWithRelations = CoffeeShop & CoffeeShopRelations;
+
+`;
+
+
+exports[`lb4 import-lb3-models imports CoffeeShop model from lb3-example app 2`] = `
+export * from './coffee-shop.model';
+
+`;
diff --git a/packages/cli/test/integration/generators/import-lb3-models.integration.js b/packages/cli/test/integration/generators/import-lb3-models.integration.js
new file mode 100644
index 000000000000..a468c5b689c7
--- /dev/null
+++ b/packages/cli/test/integration/generators/import-lb3-models.integration.js
@@ -0,0 +1,94 @@
+// Copyright IBM Corp. 2019. All Rights Reserved.
+// Node module: @loopback/cli
+// This file is licensed under the MIT License.
+// License text available at https://opensource.org/licenses/MIT
+
+'use strict';
+
+const assert = require('yeoman-assert');
+const {expect, TestSandbox} = require('@loopback/testlab');
+const path = require('path');
+const generator = path.join(__dirname, '../../../generators/import-lb3-models');
+const {expectFileToMatchSnapshot} = require('../../snapshots');
+const testUtils = require('../../test-utils');
+
+const SANDBOX_PATH = path.resolve(__dirname, '../.sandbox');
+const sandbox = new TestSandbox(SANDBOX_PATH);
+
+// In this test suite we invoke the full generator with mocked prompts
+// and inspect the generated model file(s).
+// Such tests are slow to run, we strive to keep only few of them.
+// Use unit tests to verify the conversion from LB3 to LB4 model definition,
+// see tests/unit/import-lb3-models/migrate-model.test.ts
+
+const {
+ loadLb3App,
+} = require('../../../generators/import-lb3-models/lb3app-loader');
+
+const COFFEE_SHOP_EXAMPLE = require.resolve(
+ '../../../../../examples/lb3-application/lb3app/server/server',
+);
+
+describe('lb4 import-lb3-models', function() {
+ require('../lib/base-generator')(generator, {args: ['path-to-lb3-app']})();
+
+ before(function preloadCoffeeShopExampleApp() {
+ // The CoffeeShop example app takes some time to load :(
+ // eslint-disable-next-line no-invalid-this
+ this.timeout(10000);
+ return loadLb3App(COFFEE_SHOP_EXAMPLE);
+ });
+
+ beforeEach('reset sandbox', () => sandbox.reset());
+
+ it('imports CoffeeShop model from lb3-example app', async () => {
+ await testUtils
+ .executeGenerator(generator)
+ .inDir(SANDBOX_PATH, () => testUtils.givenLBProject(SANDBOX_PATH))
+ .withArguments(COFFEE_SHOP_EXAMPLE)
+ .withPrompts({
+ modelNames: ['CoffeeShop'],
+ });
+
+ // The default outDir is "src/models"
+ const outDir = path.join(SANDBOX_PATH, 'src/models');
+
+ // Verify the source code generated for the model
+ expectFileToMatchSnapshot(`${outDir}/coffee-shop.model.ts`);
+
+ // Verify that the index file was updated
+ expectFileToMatchSnapshot(`${outDir}/index.ts`);
+ });
+
+ it('honours `outDir` option', async () => {
+ const outDir = path.join(SANDBOX_PATH, 'my-models');
+
+ await testUtils
+ .executeGenerator(generator)
+ .inDir(SANDBOX_PATH, () => testUtils.givenLBProject(SANDBOX_PATH))
+ .withArguments(COFFEE_SHOP_EXAMPLE)
+ .withPrompts({
+ modelNames: ['CoffeeShop'],
+ })
+ .withOptions({
+ outDir,
+ });
+
+ assert.file([`${outDir}/coffee-shop.model.ts`, `${outDir}/index.ts`]);
+ });
+
+ it('reports a helpful error when the selected model does not exist', () => {
+ return expect(
+ testUtils
+ .executeGenerator(generator)
+ .inDir(SANDBOX_PATH, () => testUtils.givenLBProject(SANDBOX_PATH))
+ .withArguments(COFFEE_SHOP_EXAMPLE)
+ .withPrompts({
+ modelNames: ['ModelDoesNotExist'],
+ }),
+ ).to.be.rejectedWith(
+ 'Unknown model name ModelDoesNotExist. Available models: Application, ' +
+ 'AccessToken, User, RoleMapping, Role, ACL, Scope, CoffeeShop.',
+ );
+ });
+});
diff --git a/packages/cli/test/unit/import-lb3-model/migrate-model.test.js b/packages/cli/test/unit/import-lb3-model/migrate-model.test.js
new file mode 100644
index 000000000000..16710f007318
--- /dev/null
+++ b/packages/cli/test/unit/import-lb3-model/migrate-model.test.js
@@ -0,0 +1,377 @@
+// Copyright IBM Corp. 2019. All Rights Reserved.
+// Node module: @loopback/cli
+// This file is licensed under the MIT License.
+// License text available at https://opensource.org/licenses/MIT
+
+'use strict';
+
+const loopback = require('loopback');
+const {expect, sinon, toJSON} = require('@loopback/testlab');
+const {
+ importLb3ModelDefinition,
+} = require('../../../generators/import-lb3-models/migrate-model');
+
+describe('importLb3ModelDefinition', () => {
+ let log;
+ beforeEach(function setupLogSpy() {
+ log = sinon.spy();
+ });
+
+ afterEach(function verifyNoExtraLogs() {
+ sinon.assert.notCalled(log);
+ });
+
+ context('bare-bone model attached to memory', () => {
+ let modelData;
+
+ before(function setupLb3AppWithMemoryAndModel() {
+ const MyModel = givenLb3Model('MyModel', {name: 'string'});
+ modelData = importLb3ModelDefinition(MyModel, log);
+ });
+
+ it('normalizes model settings', () => {
+ expect(toJSON(modelData.settings)).to.deepEqual({
+ // By default, LB3 models are not strict
+ strict: false,
+ replaceOnPUT: true,
+ });
+ });
+
+ it('imports all properties', () => {
+ expect(Object.keys(modelData.properties)).to.deepEqual(['id', 'name']);
+ });
+
+ it('normalizes custom property', () => {
+ expect(modelData.properties)
+ .to.have.property('name')
+ .deepEqual({
+ type: `'string'`,
+ tsType: 'string',
+ });
+ });
+
+ it('handles id property injected by the connector', () => {
+ expect(modelData.properties)
+ .to.have.property('id')
+ .deepEqual({
+ type: `'number'`,
+ tsType: 'number',
+ id: 1,
+ generated: true,
+ updateOnly: true,
+ });
+ });
+
+ it('adds other data for the model template', () => {
+ const options = getModelTemplateOptions(modelData);
+
+ expect(options).to.deepEqual({
+ name: 'MyModel',
+ className: 'MyModel',
+
+ modelBaseClass: 'Entity',
+ isModelBaseBuiltin: true,
+
+ allowAdditionalProperties: true,
+ });
+ });
+ });
+
+ context('array properties', () => {
+ it('correctly converts short-hand definition', () => {
+ const MyModel = givenLb3Model('MyModel', {
+ tags: ['string'],
+ });
+ const modelData = importLb3ModelDefinition(MyModel, log);
+
+ expect(modelData.properties)
+ .to.have.property('tags')
+ .deepEqual({
+ type: "'array'",
+ itemType: "'string'",
+ tsType: 'string[]',
+ });
+ });
+
+ it('correctly converts long-style definition', () => {
+ const MyModel = givenLb3Model('MyModel', {
+ counts: {
+ type: ['number'],
+ required: true,
+ },
+ });
+ const modelData = importLb3ModelDefinition(MyModel, log);
+
+ expect(modelData.properties)
+ .to.have.property('counts')
+ .deepEqual({
+ type: "'array'",
+ itemType: "'number'",
+ tsType: 'number[]',
+ required: true,
+ });
+ });
+ });
+
+ context('base classes', () => {
+ it('recognizes "Model" base', () => {
+ const MyModel = givenLb3Model('MyModel', {}, {base: 'Model'});
+ const modelData = importLb3ModelDefinition(MyModel, log);
+
+ const options = getModelTemplateOptions(modelData);
+ expect(options).to.containDeep({
+ modelBaseClass: 'Model',
+ isModelBaseBuiltin: true,
+ });
+ });
+
+ it('recognizes "PersistedModel" base', () => {
+ const MyModel = givenLb3Model('MyModel', {}, {base: 'PersistedModel'});
+ const modelData = importLb3ModelDefinition(MyModel, log);
+
+ const options = getModelTemplateOptions(modelData);
+ expect(options).to.containDeep({
+ modelBaseClass: 'Entity',
+ isModelBaseBuiltin: true,
+ });
+ });
+
+ it('recognizes "KeyValueModel" base', () => {
+ const MyModel = givenLb3Model(
+ 'MyModel',
+ {},
+ {base: 'KeyValueModel'},
+ {connector: 'kv-memory'},
+ );
+ const modelData = importLb3ModelDefinition(MyModel, log);
+
+ const options = getModelTemplateOptions(modelData);
+ expect(options).to.containDeep({
+ modelBaseClass: 'KeyValueModel',
+ isModelBaseBuiltin: true,
+ });
+ });
+
+ it('refuses to import model extending a non-LB4-built-in (for now)', () => {
+ // Note: User is a built-in model in LB3
+ const MyModel = givenLb3Model('MyModel', {}, {base: 'User'});
+ expect(() => importLb3ModelDefinition(MyModel, log)).to.throw(
+ 'Models inheriting from app-specific models cannot be migrated yet. ' +
+ 'Base model configured: User',
+ );
+ });
+ });
+
+ context('strict mode', () => {
+ it('correctly handles "strict: true"', () => {
+ const MyModel = givenLb3Model('MyModel', {}, {strict: true});
+
+ const modelData = importLb3ModelDefinition(MyModel, log);
+
+ const options = getModelTemplateOptions(modelData);
+ expect(options).to.have.property('allowAdditionalProperties', false);
+ expect(modelData.settings).to.have.property('strict', true);
+ });
+
+ it('correctly handles "strict: false"', () => {
+ const MyModel = givenLb3Model('MyModel', {}, {strict: false});
+
+ const modelData = importLb3ModelDefinition(MyModel, log);
+
+ const options = getModelTemplateOptions(modelData);
+ expect(options).to.have.property('allowAdditionalProperties', true);
+ expect(modelData.settings).to.have.property('strict', false);
+ });
+
+ it('interprets "strict: undefined" as "strict: false"', () => {
+ const MyModel = givenLb3Model('MyModel', {}, {strict: undefined});
+
+ const modelData = importLb3ModelDefinition(MyModel, log);
+
+ const options = getModelTemplateOptions(modelData);
+ expect(options).to.have.property('allowAdditionalProperties', true);
+ expect(modelData.settings).to.have.property('strict', false);
+ });
+ });
+
+ context('forceId', () => {
+ it('honors "forceId: true"', () => {
+ const MyModel = givenLb3Model('MyModel', {}, {forceId: true});
+
+ const modelData = importLb3ModelDefinition(MyModel, log);
+
+ // "forceId: true" is converted by juggler to "auto" and then removed
+ // during import, we want the runtime to decide based on PK definition
+ expect(modelData.settings).to.not.have.property('forceId');
+
+ expect(modelData.properties.id).to.containDeep({
+ updateOnly: true,
+ });
+ });
+
+ it('honors "forceId: false"', () => {
+ const MyModel = givenLb3Model('MyModel', {}, {forceId: false});
+
+ const modelData = importLb3ModelDefinition(MyModel, log);
+
+ expect(modelData.settings).to.have.property('forceId', false);
+ expect(modelData.properties.id).to.not.have.property('updateOnly');
+ });
+ });
+
+ context('connector settings at model level', () => {
+ it('is migrated as-is', () => {
+ const MyModel = givenLb3Model(
+ 'MyModel',
+ {},
+ {
+ strictObjectIDCoercion: true,
+ mongodb: {
+ collection: 'CustomCollectionName',
+ },
+ },
+ );
+ const modelData = importLb3ModelDefinition(MyModel, log);
+ expect(modelData.settings).to.containDeep({
+ strictObjectIDCoercion: true,
+ mongodb: {
+ collection: 'CustomCollectionName',
+ },
+ });
+ });
+ });
+
+ context('relations', () => {
+ it('reports a warning', () => {
+ const app = givenLb3App();
+ app.dataSource('ds', {connector: 'memory'});
+
+ const Product = app.registry.createModel('Product');
+ app.model(Product, {dataSource: 'ds'});
+
+ const Category = Product.app.registry.createModel(
+ 'Category',
+ {},
+ {
+ relations: {
+ products: {
+ type: 'hasMany',
+ model: 'Product',
+ },
+ },
+ },
+ );
+ app.model(Category, {dataSource: 'ds'});
+
+ importLb3ModelDefinition(Category, log);
+
+ sinon.assert.calledOnce(log);
+ sinon.assert.calledWithMatch(
+ log,
+ /Import of model relations is not supported yet. Skipping the following relations: products/,
+ );
+ log.resetHistory(); // disable assertion in afterEach hook
+ });
+ });
+
+ context('acls', () => {
+ it('reports a warning', () => {
+ const DUMMY_ACL = {
+ principalType: 'ROLE',
+ principalId: '$everyone',
+ permission: 'DENY',
+ };
+ const MyModel = givenLb3Model('MyModel', {}, {acls: [DUMMY_ACL]});
+
+ importLb3ModelDefinition(MyModel, log);
+
+ sinon.assert.calledOnce(log);
+ sinon.assert.calledWithMatch(
+ log,
+ /Ignoring the following unsupported settings: acls/,
+ );
+ log.resetHistory(); // disable assertion in afterEach hook
+ });
+ });
+
+ context('methods', () => {
+ it('reports a warning', () => {
+ const DUMMY_METHODS = {
+ find: {
+ accepts: [],
+ returns: [],
+ },
+ };
+
+ const MyModel = givenLb3Model('MyModel', {}, {methods: DUMMY_METHODS});
+
+ importLb3ModelDefinition(MyModel, log);
+
+ sinon.assert.calledOnce(log);
+ sinon.assert.calledWithMatch(
+ log,
+ /Ignoring the following unsupported settings: methods/,
+ );
+ log.resetHistory(); // disable assertion in afterEach hook
+ });
+ });
+
+ context('mixins', () => {
+ it('reports a warning', () => {
+ const app = givenLb3App();
+ app.dataSource('ds', {connector: 'memory'});
+
+ // Register a dummy mixin
+ app.registry.modelBuilder.mixins.define('timestamp', function(ctor) {});
+
+ // Create a model using that mixin
+ const DUMMY_MIXINS = {
+ timestamp: true,
+ };
+ const MyModel = app.registry.createModel(
+ 'MyModel',
+ {},
+ {mixins: DUMMY_MIXINS},
+ );
+ app.model(MyModel, {dataSource: 'ds'});
+
+ importLb3ModelDefinition(MyModel, log);
+
+ sinon.assert.calledOnce(log);
+ sinon.assert.calledWithMatch(
+ log,
+ /Ignoring the following unsupported settings: mixins/,
+ );
+ log.resetHistory(); // disable assertion in afterEach hook
+ });
+ });
+});
+
+function givenLb3App() {
+ return loopback({localRegistry: true, loadBuiltinModels: true});
+}
+
+function givenLb3Model(
+ name,
+ properties = {},
+ settings = {},
+ dataSourceConfig = {connector: 'memory'},
+) {
+ const app = givenLb3App();
+ app.dataSource('ds', dataSourceConfig);
+ const ModelCtor = app.registry.createModel(name, properties, settings);
+ app.model(ModelCtor, {dataSource: 'ds'});
+ return ModelCtor;
+}
+
+function getModelTemplateOptions(templateData) {
+ const options = {...templateData};
+
+ // Settings & properties have been already tested (see above)
+ delete options.settings;
+ delete options.properties;
+ // We don't care about stringified settings as they are auto-generated
+ delete options.modelSettings;
+
+ return options;
+}
diff --git a/packages/cli/test/unit/import-lb3-model/model-names.test.js b/packages/cli/test/unit/import-lb3-model/model-names.test.js
new file mode 100644
index 000000000000..f695d58cba3d
--- /dev/null
+++ b/packages/cli/test/unit/import-lb3-model/model-names.test.js
@@ -0,0 +1,53 @@
+// Copyright IBM Corp. 2019. All Rights Reserved.
+// Node module: @loopback/cli
+// This file is licensed under the MIT License.
+// License text available at https://opensource.org/licenses/MIT
+
+'use strict';
+
+const {
+ canImportModelName,
+} = require('../../../generators/import-lb3-models/model-names');
+const {expect} = require('@loopback/testlab');
+
+describe('canImportModelName', () => {
+ ['Model', 'PersistedModel', 'KeyValueModel'].forEach(name => {
+ it(`rejects base model ${name}`, () => {
+ expect(canImportModelName(name)).to.equal(false);
+ });
+ });
+
+ ['Change', 'Checkpoint'].forEach(name => {
+ it(`rejects change-tracking model ${name}`, () => {
+ expect(canImportModelName(name)).to.equal(false);
+ });
+ });
+
+ it('rejects model Email', () => {
+ expect(canImportModelName('Email')).to.equal(false);
+ });
+
+ it('rejects anonymous models', () => {
+ expect(canImportModelName('AnonymousModel_0')).to.equal(false);
+ });
+
+ [
+ 'ACL',
+ 'AccessToken',
+ 'Application',
+ 'Role',
+ 'RoleMapping',
+ 'Scope',
+ 'User',
+ ].forEach(name => {
+ it(`allows built-in model ${name}`, () => {
+ expect(canImportModelName(name)).to.equal(true);
+ });
+ });
+
+ ['Product', 'Category', 'CoffeeShop', 'Customer'].forEach(name => {
+ it(`allows application-specific model name ${name}`, () => {
+ expect(canImportModelName('Product')).to.equal(true);
+ });
+ });
+});