@loopback/cli 4.0.0-alpha.9 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.yo-rc.json +1719 -0
- package/{generators/project/templates/LICENSE → LICENSE} +2 -1
- package/README.md +44 -43
- package/bin/cli-main.js +61 -0
- package/generators/app/index.js +109 -15
- package/generators/app/templates/.dockerignore +5 -0
- package/generators/app/templates/Dockerfile +28 -0
- package/generators/app/templates/README.md.ejs +130 -0
- package/generators/app/templates/public/index.html.ejs +88 -0
- package/generators/app/templates/{test → src/__tests__}/README.md +0 -1
- package/generators/app/templates/src/__tests__/acceptance/home-page.acceptance.ts.ejs +31 -0
- package/generators/app/templates/src/__tests__/acceptance/ping.controller.acceptance.ts.ejs +21 -0
- package/generators/app/templates/src/__tests__/acceptance/test-helper.ts.ejs +32 -0
- package/generators/app/templates/src/application.ts.ejs +70 -0
- package/generators/app/templates/src/controllers/README.md +6 -0
- package/generators/app/templates/src/controllers/index.ts.ejs +1 -0
- package/generators/app/templates/src/controllers/ping.controller.ts.ejs +55 -0
- package/generators/app/templates/src/datasources/README.md +3 -0
- package/generators/app/templates/src/index.ts.ejs +39 -0
- package/generators/app/templates/src/migrate.ts.ejs +20 -0
- package/generators/app/templates/src/models/README.md +3 -0
- package/generators/app/templates/src/openapi-spec.ts.ejs +23 -0
- package/generators/app/templates/src/sequence.ts.ejs +3 -0
- package/generators/controller/index.js +240 -23
- package/generators/controller/templates/src/controllers/controller-rest-template.ts.ejs +150 -0
- package/generators/controller/templates/src/controllers/{controller-template.ts → controller-template.ts.ejs} +2 -2
- package/generators/copyright/fs.js +46 -0
- package/generators/copyright/git.js +78 -0
- package/generators/copyright/header.js +306 -0
- package/generators/copyright/index.js +230 -0
- package/generators/copyright/license.js +105 -0
- package/generators/datasource/index.js +341 -0
- package/generators/datasource/templates/datasource.ts.ejs +22 -0
- package/generators/discover/import-discovered-model.js +70 -0
- package/generators/discover/index.js +411 -0
- package/generators/example/downloader.js +16 -0
- package/generators/example/index.js +176 -0
- package/generators/extension/index.js +34 -5
- package/generators/extension/templates/README.md.ejs +32 -0
- package/generators/extension/templates/{test → src/__tests__}/acceptance/README.md +0 -0
- package/generators/extension/templates/{test → src/__tests__}/integration/README.md +0 -0
- package/generators/extension/templates/{test → src/__tests__}/unit/README.md +0 -0
- package/generators/extension/templates/src/component.ts.ejs +22 -0
- package/generators/extension/templates/src/controllers/README.md +3 -2
- package/generators/extension/templates/src/decorators/README.md +10 -4
- package/generators/extension/templates/src/index.ts.ejs +3 -0
- package/generators/extension/templates/src/keys.ts.ejs +11 -0
- package/generators/extension/templates/src/mixins/README.md +77 -21
- package/generators/extension/templates/src/providers/README.md +51 -25
- package/generators/extension/templates/src/repositories/README.md +1 -1
- package/generators/extension/templates/src/types.ts.ejs +15 -0
- package/generators/import-lb3-models/index.js +197 -0
- package/generators/import-lb3-models/lb3app-loader.js +31 -0
- package/generators/import-lb3-models/migrate-model.js +249 -0
- package/generators/import-lb3-models/model-names.js +32 -0
- package/generators/interceptor/index.js +178 -0
- package/generators/interceptor/templates/interceptor-template.ts.ejs +62 -0
- package/generators/model/index.js +536 -0
- package/generators/model/property-definition.js +85 -0
- package/generators/model/templates/model.ts.ejs +49 -0
- package/generators/observer/index.js +132 -0
- package/generators/observer/templates/observer-template.ts.ejs +40 -0
- package/generators/openapi/README.md +211 -0
- package/generators/openapi/index.js +535 -0
- package/generators/openapi/schema-helper.js +447 -0
- package/generators/openapi/spec-helper.js +484 -0
- package/generators/openapi/spec-loader.js +75 -0
- package/generators/openapi/templates/src/controllers/controller-template.ts.ejs +43 -0
- package/generators/openapi/templates/src/datasources/datasource.ts.ejs +42 -0
- package/generators/openapi/templates/src/models/model-template.ts.ejs +71 -0
- package/generators/openapi/templates/src/models/type-template.ts.ejs +13 -0
- package/generators/openapi/templates/src/services/service-proxy-template.ts.ejs +55 -0
- package/generators/openapi/utils.js +322 -0
- package/generators/project/templates/.eslintignore +4 -0
- package/generators/project/templates/.eslintrc.js.ejs +3 -0
- package/generators/project/templates/.mocharc.json +5 -0
- package/generators/project/templates/.prettierignore +0 -2
- package/generators/project/templates/.prettierrc +2 -1
- package/generators/project/templates/.vscode/launch.json +38 -0
- package/generators/project/templates/.vscode/settings.json +32 -0
- package/generators/project/templates/.vscode/tasks.json +29 -0
- package/generators/project/templates/DEVELOPING.md +36 -0
- package/generators/project/templates/_.gitignore +3 -5
- package/generators/project/templates/package.json.ejs +175 -0
- package/generators/project/templates/package.plain.json.ejs +176 -0
- package/generators/project/templates/tsconfig.json.ejs +39 -0
- package/generators/relation/base-relation.generator.js +220 -0
- package/generators/relation/belongs-to-relation.generator.js +196 -0
- package/generators/relation/has-many-relation.generator.js +200 -0
- package/generators/relation/has-many-through-relation.generator.js +331 -0
- package/generators/relation/has-one-relation.generator.js +200 -0
- package/generators/relation/index.js +795 -0
- package/generators/relation/references-many-relation.generator.js +142 -0
- package/generators/relation/templates/controller-relation-template-belongs-to.ts.ejs +38 -0
- package/generators/relation/templates/controller-relation-template-has-many-through.ts.ejs +110 -0
- package/generators/relation/templates/controller-relation-template-has-many.ts.ejs +110 -0
- package/generators/relation/templates/controller-relation-template-has-one.ts.ejs +110 -0
- package/generators/relation/utils.generator.js +260 -0
- package/generators/repository/index.js +576 -0
- package/generators/repository/templates/src/repositories/repository-crud-default-template.ts.ejs +21 -0
- package/generators/repository/templates/src/repositories/repository-kv-template.ts.ejs +19 -0
- package/generators/rest-crud/crud-rest-component.js +63 -0
- package/generators/rest-crud/index.js +423 -0
- package/generators/rest-crud/templates/src/model-endpoints/model.rest-config-template.ts.ejs +11 -0
- package/generators/service/index.js +351 -0
- package/generators/service/templates/local-service-class-template.ts.ejs +10 -0
- package/generators/service/templates/local-service-provider-template.ts.ejs +19 -0
- package/generators/service/templates/remote-service-proxy-template.ts.ejs +21 -0
- package/generators/update/index.js +55 -0
- package/intl/cs/messages.json +204 -0
- package/intl/de/messages.json +204 -0
- package/intl/en/messages.json +204 -0
- package/intl/es/messages.json +204 -0
- package/intl/fr/messages.json +204 -0
- package/intl/it/messages.json +204 -0
- package/intl/ja/messages.json +204 -0
- package/intl/ko/messages.json +204 -0
- package/intl/nl/messages.json +204 -0
- package/intl/pl/messages.json +204 -0
- package/intl/pt/messages.json +204 -0
- package/intl/ru/messages.json +204 -0
- package/intl/tr/messages.json +204 -0
- package/intl/zh-Hans/messages.json +204 -0
- package/intl/zh-Hant/messages.json +204 -0
- package/lib/artifact-generator.js +138 -39
- package/lib/ast-helper.js +214 -0
- package/lib/base-generator.js +509 -0
- package/lib/cli.js +233 -0
- package/lib/connectors.json +894 -0
- package/lib/debug.js +16 -0
- package/lib/globalize.js +12 -0
- package/lib/model-discoverer.js +118 -0
- package/lib/project-generator.js +154 -57
- package/lib/tab-completion.js +127 -0
- package/lib/update-index.js +44 -0
- package/lib/utils.js +689 -20
- package/lib/version-helper.js +299 -0
- package/package.json +183 -39
- package/CHANGELOG.md +0 -86
- package/bin/cli.js +0 -66
- package/generators/app/templates/index.js +0 -14
- package/generators/app/templates/src/application.ts +0 -27
- package/generators/app/templates/src/controllers/ping-controller.ts +0 -25
- package/generators/app/templates/src/index.ts +0 -25
- package/generators/app/templates/test/ping-controller.test.ts +0 -46
- package/generators/extension/templates/index.js +0 -8
- package/generators/extension/templates/src/component.ts +0 -14
- package/generators/extension/templates/src/index.ts +0 -6
- package/generators/project/templates/.npmrc +0 -1
- package/generators/project/templates/.yo-rc.json +0 -1
- package/generators/project/templates/README.md +0 -4
- package/generators/project/templates/index.d.ts +0 -6
- package/generators/project/templates/index.ts +0 -11
- package/generators/project/templates/package.json +0 -79
- package/generators/project/templates/package.plain.json +0 -82
- package/generators/project/templates/test/mocha.opts +0 -1
- package/generators/project/templates/tsconfig.json +0 -29
- package/generators/project/templates/tslint.build.json +0 -17
- package/generators/project/templates/tslint.json +0 -33
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<%_
|
|
2
|
+
const _properties = locals.properties || [];
|
|
3
|
+
if (importProperty && baseModel) {
|
|
4
|
+
-%>
|
|
5
|
+
import {model, property, <%- baseModel %>} from '@loopback/repository';
|
|
6
|
+
<%_
|
|
7
|
+
} else if (importProperty) {
|
|
8
|
+
-%>
|
|
9
|
+
import {model, property} from '@loopback/repository';
|
|
10
|
+
<%_
|
|
11
|
+
} else {
|
|
12
|
+
-%>
|
|
13
|
+
import {model} from '@loopback/repository';
|
|
14
|
+
<%_
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
imports.forEach(i => {
|
|
18
|
+
-%>
|
|
19
|
+
<%- i %>
|
|
20
|
+
<%_
|
|
21
|
+
});
|
|
22
|
+
-%>
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The model class is generated from OpenAPI schema - <%- name %>
|
|
26
|
+
* <%- escapeComment(description) %>
|
|
27
|
+
*/
|
|
28
|
+
@model({name: '<%- name %>'})
|
|
29
|
+
<%_ if (baseModel) { -%>
|
|
30
|
+
export class <%- className %> extends <%- baseModel %> {
|
|
31
|
+
constructor(data?: Partial<<%- className %>>) {
|
|
32
|
+
super(data);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
<%_ } else { -%>
|
|
36
|
+
export class <%- className %> {
|
|
37
|
+
constructor(data?: Partial<<%- className %>>) {
|
|
38
|
+
if (data != null && typeof data === 'object') {
|
|
39
|
+
Object.assign(this, data);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
<%_ } -%>
|
|
44
|
+
<%_ for (const p of _properties) { -%>
|
|
45
|
+
/**
|
|
46
|
+
<%_ const _comment = escapeComment(p.description);
|
|
47
|
+
if (_comment) {
|
|
48
|
+
-%>
|
|
49
|
+
* <%- _comment %>
|
|
50
|
+
<%_ } else { -%>
|
|
51
|
+
*
|
|
52
|
+
<%_ } -%>
|
|
53
|
+
*/
|
|
54
|
+
<%_ if (p.comment) { -%>
|
|
55
|
+
// <%- p.comment %>
|
|
56
|
+
<%_ } -%>
|
|
57
|
+
<%_ if (p.decoration) { -%>
|
|
58
|
+
<%- p.decoration %>
|
|
59
|
+
<%_ } -%>
|
|
60
|
+
<%- p.signature %>
|
|
61
|
+
|
|
62
|
+
<%_ } -%>
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface <%- className %>Relations {
|
|
66
|
+
// describe navigational properties here
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type <%- className %>WithRelations = <%- className %> & <%- className %>Relations;
|
|
70
|
+
|
|
71
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {inject, Provider} from '@loopback/core';
|
|
2
|
+
import {getService} from '@loopback/service-proxy';
|
|
3
|
+
import {<%- dataSourceClassName %>} from '../datasources';
|
|
4
|
+
|
|
5
|
+
<%_
|
|
6
|
+
imports.forEach(i => {
|
|
7
|
+
-%>
|
|
8
|
+
<%- i %>
|
|
9
|
+
<%_
|
|
10
|
+
});
|
|
11
|
+
-%>
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The service interface is generated from OpenAPI spec with operations tagged
|
|
15
|
+
* by <%- tag || '<no-tag>' %>.
|
|
16
|
+
<%_ const _comment = escapeComment(description);
|
|
17
|
+
if (_comment) {
|
|
18
|
+
-%>
|
|
19
|
+
* <%- _comment %>
|
|
20
|
+
<%_ } -%>
|
|
21
|
+
*/
|
|
22
|
+
export interface <%- serviceClassName %> {
|
|
23
|
+
<%_ for (const m of methods) { -%>
|
|
24
|
+
/**
|
|
25
|
+
<%_ for (const c of m.comments) {
|
|
26
|
+
const _comment = escapeComment(c);
|
|
27
|
+
if (_comment) {
|
|
28
|
+
-%>
|
|
29
|
+
* <%- _comment %>
|
|
30
|
+
<%_ }
|
|
31
|
+
} -%>
|
|
32
|
+
*/
|
|
33
|
+
<%_ if (usePositionalParams !== false) { -%>
|
|
34
|
+
<%- m.signatureForInterface %>;
|
|
35
|
+
<%_ } else { -%>
|
|
36
|
+
<%- m.signatureForNamedParams %>;
|
|
37
|
+
<%_ } -%>
|
|
38
|
+
|
|
39
|
+
<%_ } -%>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class <%- serviceClassName %>Provider implements Provider<<%- serviceClassName %>> {
|
|
43
|
+
constructor(
|
|
44
|
+
// <%- dataSourceName %> must match the name property in the datasource json file
|
|
45
|
+
@inject('datasources.<%- dataSourceName %>')
|
|
46
|
+
protected dataSource: <%- dataSourceClassName %> = new <%- dataSourceClassName %>(),
|
|
47
|
+
) {}
|
|
48
|
+
|
|
49
|
+
async value(): Promise<<%- serviceClassName %>> {
|
|
50
|
+
const service = await getService<{apis: {'<%- tag || 'default' %>': <%- serviceClassName %>}}>(
|
|
51
|
+
this.dataSource,
|
|
52
|
+
);
|
|
53
|
+
return service.apis['<%- tag || 'default' %>'];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
// Copyright IBM Corp. and LoopBack contributors 2018,2020. All Rights Reserved.
|
|
2
|
+
// Node module: @loopback/cli
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const util = require('util');
|
|
9
|
+
const _ = require('lodash');
|
|
10
|
+
const json5 = require('json5');
|
|
11
|
+
const url = require('url');
|
|
12
|
+
|
|
13
|
+
const utils = require('../../lib/utils');
|
|
14
|
+
const debug = require('../../lib/debug')('openapi-generator');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Convert OpenAPI schema to JSON schema draft 4
|
|
18
|
+
*/
|
|
19
|
+
const oasToJsonSchema4 = require('@openapi-contrib/openapi-schema-to-json-schema');
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Convert a string to title case
|
|
23
|
+
* @param {string} str
|
|
24
|
+
*/
|
|
25
|
+
function titleCase(str) {
|
|
26
|
+
return _.startCase(_.camelCase(str)).replace(/\s/g, '');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Check if a given key is openapi extension (x-)
|
|
31
|
+
* @param {string} key
|
|
32
|
+
*/
|
|
33
|
+
function isExtension(key) {
|
|
34
|
+
return typeof key === 'string' && key.startsWith('x-');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Dump the json object for debugging
|
|
39
|
+
* @param {string} msg Message
|
|
40
|
+
* @param {object} obj The json object
|
|
41
|
+
*/
|
|
42
|
+
function debugJson(msg, obj) {
|
|
43
|
+
if (debug.enabled) {
|
|
44
|
+
debug('%s: %s', msg, util.inspect(obj, {depth: 10}));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Validate a url or file path for the open api spec
|
|
50
|
+
* @param {string} specUrlStr
|
|
51
|
+
*/
|
|
52
|
+
function validateUrlOrFile(specUrlStr) {
|
|
53
|
+
if (!specUrlStr) {
|
|
54
|
+
return 'API spec url or file path is required.';
|
|
55
|
+
}
|
|
56
|
+
const specUrl = url.parse(specUrlStr);
|
|
57
|
+
if (specUrl.protocol === 'http:' || specUrl.protocol === 'https:') {
|
|
58
|
+
return true;
|
|
59
|
+
} else {
|
|
60
|
+
const stat = fs.existsSync(specUrlStr) && fs.statSync(specUrlStr);
|
|
61
|
+
if (stat && stat.isFile()) {
|
|
62
|
+
return true;
|
|
63
|
+
} else {
|
|
64
|
+
return util.format('Path %s is not a file.', specUrlStr);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* JavaScript keywords
|
|
71
|
+
*/
|
|
72
|
+
const JS_KEYWORDS = [
|
|
73
|
+
'break',
|
|
74
|
+
'case',
|
|
75
|
+
'catch',
|
|
76
|
+
'class',
|
|
77
|
+
'const',
|
|
78
|
+
'continue',
|
|
79
|
+
'debugger',
|
|
80
|
+
'default',
|
|
81
|
+
'delete',
|
|
82
|
+
'do',
|
|
83
|
+
'else',
|
|
84
|
+
'export',
|
|
85
|
+
'extends',
|
|
86
|
+
'finally',
|
|
87
|
+
'for',
|
|
88
|
+
'function',
|
|
89
|
+
'if',
|
|
90
|
+
'import',
|
|
91
|
+
'in',
|
|
92
|
+
'instanceof',
|
|
93
|
+
'new',
|
|
94
|
+
'return',
|
|
95
|
+
'super',
|
|
96
|
+
'switch',
|
|
97
|
+
'this',
|
|
98
|
+
'throw',
|
|
99
|
+
'try',
|
|
100
|
+
'typeof',
|
|
101
|
+
'var',
|
|
102
|
+
'void',
|
|
103
|
+
'while',
|
|
104
|
+
'with',
|
|
105
|
+
'yield',
|
|
106
|
+
'enum',
|
|
107
|
+
'implements',
|
|
108
|
+
'interface',
|
|
109
|
+
'let',
|
|
110
|
+
'package',
|
|
111
|
+
'private',
|
|
112
|
+
'protected',
|
|
113
|
+
'public',
|
|
114
|
+
'static',
|
|
115
|
+
'await',
|
|
116
|
+
'abstract',
|
|
117
|
+
'boolean',
|
|
118
|
+
'byte',
|
|
119
|
+
'char',
|
|
120
|
+
'double',
|
|
121
|
+
'final',
|
|
122
|
+
'float',
|
|
123
|
+
'goto',
|
|
124
|
+
'int',
|
|
125
|
+
'long',
|
|
126
|
+
'native',
|
|
127
|
+
'short',
|
|
128
|
+
'synchronized',
|
|
129
|
+
'throws',
|
|
130
|
+
'transient',
|
|
131
|
+
'volatile',
|
|
132
|
+
'null',
|
|
133
|
+
'true',
|
|
134
|
+
'false',
|
|
135
|
+
];
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Avoid tslint error - Shadowed name: 'requestBody'
|
|
139
|
+
*/
|
|
140
|
+
const DECORATOR_NAMES = ['operation', 'param', 'requestBody'];
|
|
141
|
+
|
|
142
|
+
const SAFE_IDENTIFER = /^[a-zA-Z_$][0-9a-zA-Z_$]*$/;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Escape the name to be a JavaScript identifier. If the name happens to be one
|
|
146
|
+
* of the JavaScript keywords, a `_` prefix will be added. Otherwise, it will
|
|
147
|
+
* be converted using camelCase.
|
|
148
|
+
*
|
|
149
|
+
* For example,
|
|
150
|
+
* - `default` -> `_default`
|
|
151
|
+
* - `my-name` -> 'myName'
|
|
152
|
+
*
|
|
153
|
+
* @param {string} name
|
|
154
|
+
*/
|
|
155
|
+
function escapeIdentifier(name) {
|
|
156
|
+
if (JS_KEYWORDS.includes(name)) {
|
|
157
|
+
return '_' + name;
|
|
158
|
+
}
|
|
159
|
+
if (!name.match(SAFE_IDENTIFER)) {
|
|
160
|
+
name = _.camelCase(name);
|
|
161
|
+
}
|
|
162
|
+
if (DECORATOR_NAMES.includes(name)) {
|
|
163
|
+
return '_' + name;
|
|
164
|
+
}
|
|
165
|
+
return name;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Escape the property if it's not a valid JavaScript identifer
|
|
170
|
+
* @param {string} name
|
|
171
|
+
*/
|
|
172
|
+
function escapePropertyName(name) {
|
|
173
|
+
if (JS_KEYWORDS.includes(name) || !name.match(SAFE_IDENTIFER)) {
|
|
174
|
+
return printSpecObject(name);
|
|
175
|
+
}
|
|
176
|
+
return name;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Escape a string to be used as a block comment
|
|
181
|
+
*
|
|
182
|
+
* @param {string} comment
|
|
183
|
+
*/
|
|
184
|
+
function escapeComment(comment) {
|
|
185
|
+
comment = comment || '';
|
|
186
|
+
comment = comment.replace(/\/\*/g, '\\/*').replace(/\*\//g, '*\\/');
|
|
187
|
+
return utils.wrapText(comment, 76);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Clone an OpenAPI spec. When a `$ref` is encountered, we store it as `x-$ref`
|
|
192
|
+
* and keep the stringified original value as `x-$original-value`. These
|
|
193
|
+
* metadata allows us to access the original object after `$ref` is resolved
|
|
194
|
+
* and dereferenced by the parser.
|
|
195
|
+
*
|
|
196
|
+
* @param {*} spec An OpenAPI spec object
|
|
197
|
+
*/
|
|
198
|
+
function cloneSpecObject(spec) {
|
|
199
|
+
return _.cloneDeepWith(spec, item => {
|
|
200
|
+
/**
|
|
201
|
+
* A yaml object below produces `null` for `servers.url`
|
|
202
|
+
* ```yaml
|
|
203
|
+
* servers:
|
|
204
|
+
* - url:
|
|
205
|
+
* description: null url for testing
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
if (item != null && item.$ref) {
|
|
209
|
+
const copy = _.cloneDeep(item);
|
|
210
|
+
return {
|
|
211
|
+
...copy,
|
|
212
|
+
// Store the original item in `x-$original`
|
|
213
|
+
'x-$original-value': json5.stringify(item, null, 2),
|
|
214
|
+
// Keep `$ref` as `x-$ref` as `$ref` will be removed during dereferencing
|
|
215
|
+
'x-$ref': item.$ref,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Print an OpenAPI spec object as JavaScript object literal. The original value
|
|
223
|
+
* is used if `$ref` is resolved.
|
|
224
|
+
* @param {*} specObject - An OpenAPI spec object such as `Parameter` or `Operation`.
|
|
225
|
+
*/
|
|
226
|
+
function printSpecObject(specObject) {
|
|
227
|
+
return json5.stringify(
|
|
228
|
+
specObject,
|
|
229
|
+
(key, value) => {
|
|
230
|
+
// Restore the original value from `x-$original-value`
|
|
231
|
+
if (value != null && value['x-$ref']) {
|
|
232
|
+
return json5.parse(value['x-$original-value']);
|
|
233
|
+
}
|
|
234
|
+
return value;
|
|
235
|
+
},
|
|
236
|
+
2,
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Restore the OpenAPI spec object to its original value
|
|
242
|
+
* @param {object} specObject - OpenAPI spec object
|
|
243
|
+
*/
|
|
244
|
+
function restoreSpecObject(specObject) {
|
|
245
|
+
return _.cloneDeepWith(specObject, value => {
|
|
246
|
+
// Restore the original value from `x-$original-value`
|
|
247
|
+
if (value != null && value['x-$ref']) {
|
|
248
|
+
return json5.parse(value['x-$original-value']);
|
|
249
|
+
}
|
|
250
|
+
// Return `undefined` so that child items are cloned too
|
|
251
|
+
return undefined;
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Convert OpenAPI schema to JSON Schema Draft 7
|
|
257
|
+
* @param {object} oasSchema - OpenAPI schema
|
|
258
|
+
*/
|
|
259
|
+
function toJsonSchema(oasSchema) {
|
|
260
|
+
oasSchema = restoreSpecObject(oasSchema);
|
|
261
|
+
let jsonSchema = oasToJsonSchema4(oasSchema);
|
|
262
|
+
delete jsonSchema['$schema'];
|
|
263
|
+
// See https://json-schema.org/draft-06/json-schema-release-notes.html
|
|
264
|
+
if (jsonSchema.id) {
|
|
265
|
+
// id => $id
|
|
266
|
+
jsonSchema.$id = jsonSchema.id;
|
|
267
|
+
delete jsonSchema.id;
|
|
268
|
+
}
|
|
269
|
+
jsonSchema = _.cloneDeepWith(jsonSchema, value => {
|
|
270
|
+
if (value == null) return value;
|
|
271
|
+
let changed = false;
|
|
272
|
+
if (typeof value.exclusiveMinimum === 'boolean') {
|
|
273
|
+
// exclusiveMinimum + minimum (boolean + number) => exclusiveMinimum (number)
|
|
274
|
+
if (value.exclusiveMinimum) {
|
|
275
|
+
value.exclusiveMinimum = value.minimum;
|
|
276
|
+
delete value.minimum;
|
|
277
|
+
} else {
|
|
278
|
+
delete value.exclusiveMinimum;
|
|
279
|
+
}
|
|
280
|
+
changed = true;
|
|
281
|
+
}
|
|
282
|
+
if (typeof value.exclusiveMaximum === 'boolean') {
|
|
283
|
+
// exclusiveMaximum + maximum (boolean + number) => exclusiveMaximum (number)
|
|
284
|
+
if (value.exclusiveMaximum) {
|
|
285
|
+
value.exclusiveMaximum = value.maximum;
|
|
286
|
+
delete value.maximum;
|
|
287
|
+
} else {
|
|
288
|
+
delete value.exclusiveMaximum;
|
|
289
|
+
}
|
|
290
|
+
changed = true;
|
|
291
|
+
}
|
|
292
|
+
return changed ? value : undefined;
|
|
293
|
+
});
|
|
294
|
+
return jsonSchema;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Convert OpenAPI schema to JSON schema draft 7 and print it as a JavaScript
|
|
299
|
+
* object literal
|
|
300
|
+
* @param {object} oasSchema - OpenAPI schema
|
|
301
|
+
*/
|
|
302
|
+
function printJsonSchema(oasSchema) {
|
|
303
|
+
const jsonSchema = toJsonSchema(oasSchema);
|
|
304
|
+
return printSpecObject(jsonSchema);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
module.exports = {
|
|
308
|
+
isExtension,
|
|
309
|
+
titleCase,
|
|
310
|
+
debug,
|
|
311
|
+
debugJson,
|
|
312
|
+
toFileName: utils.toFileName,
|
|
313
|
+
camelCase: utils.camelCase,
|
|
314
|
+
escapeIdentifier,
|
|
315
|
+
escapePropertyName,
|
|
316
|
+
escapeComment,
|
|
317
|
+
printSpecObject,
|
|
318
|
+
cloneSpecObject,
|
|
319
|
+
toJsonSchema,
|
|
320
|
+
printJsonSchema,
|
|
321
|
+
validateUrlOrFile,
|
|
322
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"configurations": [
|
|
3
|
+
{
|
|
4
|
+
"type": "node",
|
|
5
|
+
"request": "launch",
|
|
6
|
+
"name": "Launch Program",
|
|
7
|
+
"skipFiles": [
|
|
8
|
+
"<node_internals>/**"
|
|
9
|
+
],
|
|
10
|
+
"program": "${workspaceFolder}/dist/index.js",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "node",
|
|
14
|
+
"request": "launch",
|
|
15
|
+
"name": "Run Mocha tests",
|
|
16
|
+
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
|
|
17
|
+
"runtimeArgs": [
|
|
18
|
+
"-r",
|
|
19
|
+
"${workspaceRoot}/node_modules/source-map-support/register"
|
|
20
|
+
],
|
|
21
|
+
"cwd": "${workspaceRoot}",
|
|
22
|
+
"autoAttachChildProcesses": true,
|
|
23
|
+
"args": [
|
|
24
|
+
"--config",
|
|
25
|
+
"${workspaceRoot}/.mocharc.json",
|
|
26
|
+
"${workspaceRoot}/dist/__tests__/**/*.js",
|
|
27
|
+
"-t",
|
|
28
|
+
"0"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "node",
|
|
33
|
+
"request": "attach",
|
|
34
|
+
"name": "Attach to Process",
|
|
35
|
+
"port": 5858
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"editor.rulers": [80],
|
|
3
|
+
"editor.tabCompletion": "on",
|
|
4
|
+
"editor.tabSize": 2,
|
|
5
|
+
"editor.trimAutoWhitespace": true,
|
|
6
|
+
"editor.formatOnSave": true,
|
|
7
|
+
"editor.codeActionsOnSave": {
|
|
8
|
+
"source.organizeImports": true,
|
|
9
|
+
"source.fixAll.eslint": true
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
"files.exclude": {
|
|
13
|
+
"**/.DS_Store": true,
|
|
14
|
+
"**/.git": true,
|
|
15
|
+
"**/.hg": true,
|
|
16
|
+
"**/.svn": true,
|
|
17
|
+
"**/CVS": true,
|
|
18
|
+
"dist": true,
|
|
19
|
+
},
|
|
20
|
+
"files.insertFinalNewline": true,
|
|
21
|
+
"files.trimTrailingWhitespace": true,
|
|
22
|
+
|
|
23
|
+
"typescript.tsdk": "./node_modules/typescript/lib",
|
|
24
|
+
"typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false,
|
|
25
|
+
"typescript.preferences.quoteStyle": "single",
|
|
26
|
+
"eslint.run": "onSave",
|
|
27
|
+
"eslint.nodePath": "./node_modules",
|
|
28
|
+
"eslint.validate": [
|
|
29
|
+
"javascript",
|
|
30
|
+
"typescript"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
|
3
|
+
// for the documentation about the tasks.json format
|
|
4
|
+
"version": "2.0.0",
|
|
5
|
+
"tasks": [
|
|
6
|
+
{
|
|
7
|
+
"label": "Watch and Compile Project",
|
|
8
|
+
"type": "shell",
|
|
9
|
+
"command": "npm",
|
|
10
|
+
"args": ["--silent", "run", "build:watch"],
|
|
11
|
+
"group": {
|
|
12
|
+
"kind": "build",
|
|
13
|
+
"isDefault": true
|
|
14
|
+
},
|
|
15
|
+
"problemMatcher": "$tsc-watch"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"label": "Build, Test and Lint",
|
|
19
|
+
"type": "shell",
|
|
20
|
+
"command": "npm",
|
|
21
|
+
"args": ["--silent", "run", "test:dev"],
|
|
22
|
+
"group": {
|
|
23
|
+
"kind": "test",
|
|
24
|
+
"isDefault": true
|
|
25
|
+
},
|
|
26
|
+
"problemMatcher": ["$tsc", "$eslint-compact", "$eslint-stylish"]
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Developer's Guide
|
|
2
|
+
|
|
3
|
+
We use Visual Studio Code for developing LoopBack and recommend the same to our
|
|
4
|
+
users.
|
|
5
|
+
|
|
6
|
+
## VSCode setup
|
|
7
|
+
|
|
8
|
+
Install the following extensions:
|
|
9
|
+
|
|
10
|
+
- [eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
|
|
11
|
+
- [prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
|
|
12
|
+
|
|
13
|
+
## Development workflow
|
|
14
|
+
|
|
15
|
+
### Visual Studio Code
|
|
16
|
+
|
|
17
|
+
1. Start the build task (Cmd+Shift+B) to run TypeScript compiler in the
|
|
18
|
+
background, watching and recompiling files as you change them. Compilation
|
|
19
|
+
errors will be shown in the VSCode's "PROBLEMS" window.
|
|
20
|
+
|
|
21
|
+
2. Execute "Run Rest Task" from the Command Palette (Cmd+Shift+P) to re-run the
|
|
22
|
+
test suite and lint the code for both programming and style errors. Linting
|
|
23
|
+
errors will be shown in VSCode's "PROBLEMS" window. Failed tests are printed
|
|
24
|
+
to terminal output only.
|
|
25
|
+
|
|
26
|
+
### Other editors/IDEs
|
|
27
|
+
|
|
28
|
+
1. Open a new terminal window/tab and start the continuous build process via
|
|
29
|
+
`npm run build:watch`. It will run TypeScript compiler in watch mode,
|
|
30
|
+
recompiling files as you change them. Any compilation errors will be printed
|
|
31
|
+
to the terminal.
|
|
32
|
+
|
|
33
|
+
2. In your main terminal window/tab, run `npm run test:dev` to re-run the test
|
|
34
|
+
suite and lint the code for both programming and style errors. You should run
|
|
35
|
+
this command manually whenever you have new changes to test. Test failures
|
|
36
|
+
and linter errors will be printed to the terminal.
|