@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.
Files changed (159) hide show
  1. package/.yo-rc.json +1719 -0
  2. package/{generators/project/templates/LICENSE → LICENSE} +2 -1
  3. package/README.md +44 -43
  4. package/bin/cli-main.js +61 -0
  5. package/generators/app/index.js +109 -15
  6. package/generators/app/templates/.dockerignore +5 -0
  7. package/generators/app/templates/Dockerfile +28 -0
  8. package/generators/app/templates/README.md.ejs +130 -0
  9. package/generators/app/templates/public/index.html.ejs +88 -0
  10. package/generators/app/templates/{test → src/__tests__}/README.md +0 -1
  11. package/generators/app/templates/src/__tests__/acceptance/home-page.acceptance.ts.ejs +31 -0
  12. package/generators/app/templates/src/__tests__/acceptance/ping.controller.acceptance.ts.ejs +21 -0
  13. package/generators/app/templates/src/__tests__/acceptance/test-helper.ts.ejs +32 -0
  14. package/generators/app/templates/src/application.ts.ejs +70 -0
  15. package/generators/app/templates/src/controllers/README.md +6 -0
  16. package/generators/app/templates/src/controllers/index.ts.ejs +1 -0
  17. package/generators/app/templates/src/controllers/ping.controller.ts.ejs +55 -0
  18. package/generators/app/templates/src/datasources/README.md +3 -0
  19. package/generators/app/templates/src/index.ts.ejs +39 -0
  20. package/generators/app/templates/src/migrate.ts.ejs +20 -0
  21. package/generators/app/templates/src/models/README.md +3 -0
  22. package/generators/app/templates/src/openapi-spec.ts.ejs +23 -0
  23. package/generators/app/templates/src/sequence.ts.ejs +3 -0
  24. package/generators/controller/index.js +240 -23
  25. package/generators/controller/templates/src/controllers/controller-rest-template.ts.ejs +150 -0
  26. package/generators/controller/templates/src/controllers/{controller-template.ts → controller-template.ts.ejs} +2 -2
  27. package/generators/copyright/fs.js +46 -0
  28. package/generators/copyright/git.js +78 -0
  29. package/generators/copyright/header.js +306 -0
  30. package/generators/copyright/index.js +230 -0
  31. package/generators/copyright/license.js +105 -0
  32. package/generators/datasource/index.js +341 -0
  33. package/generators/datasource/templates/datasource.ts.ejs +22 -0
  34. package/generators/discover/import-discovered-model.js +70 -0
  35. package/generators/discover/index.js +411 -0
  36. package/generators/example/downloader.js +16 -0
  37. package/generators/example/index.js +176 -0
  38. package/generators/extension/index.js +34 -5
  39. package/generators/extension/templates/README.md.ejs +32 -0
  40. package/generators/extension/templates/{test → src/__tests__}/acceptance/README.md +0 -0
  41. package/generators/extension/templates/{test → src/__tests__}/integration/README.md +0 -0
  42. package/generators/extension/templates/{test → src/__tests__}/unit/README.md +0 -0
  43. package/generators/extension/templates/src/component.ts.ejs +22 -0
  44. package/generators/extension/templates/src/controllers/README.md +3 -2
  45. package/generators/extension/templates/src/decorators/README.md +10 -4
  46. package/generators/extension/templates/src/index.ts.ejs +3 -0
  47. package/generators/extension/templates/src/keys.ts.ejs +11 -0
  48. package/generators/extension/templates/src/mixins/README.md +77 -21
  49. package/generators/extension/templates/src/providers/README.md +51 -25
  50. package/generators/extension/templates/src/repositories/README.md +1 -1
  51. package/generators/extension/templates/src/types.ts.ejs +15 -0
  52. package/generators/import-lb3-models/index.js +197 -0
  53. package/generators/import-lb3-models/lb3app-loader.js +31 -0
  54. package/generators/import-lb3-models/migrate-model.js +249 -0
  55. package/generators/import-lb3-models/model-names.js +32 -0
  56. package/generators/interceptor/index.js +178 -0
  57. package/generators/interceptor/templates/interceptor-template.ts.ejs +62 -0
  58. package/generators/model/index.js +536 -0
  59. package/generators/model/property-definition.js +85 -0
  60. package/generators/model/templates/model.ts.ejs +49 -0
  61. package/generators/observer/index.js +132 -0
  62. package/generators/observer/templates/observer-template.ts.ejs +40 -0
  63. package/generators/openapi/README.md +211 -0
  64. package/generators/openapi/index.js +535 -0
  65. package/generators/openapi/schema-helper.js +447 -0
  66. package/generators/openapi/spec-helper.js +484 -0
  67. package/generators/openapi/spec-loader.js +75 -0
  68. package/generators/openapi/templates/src/controllers/controller-template.ts.ejs +43 -0
  69. package/generators/openapi/templates/src/datasources/datasource.ts.ejs +42 -0
  70. package/generators/openapi/templates/src/models/model-template.ts.ejs +71 -0
  71. package/generators/openapi/templates/src/models/type-template.ts.ejs +13 -0
  72. package/generators/openapi/templates/src/services/service-proxy-template.ts.ejs +55 -0
  73. package/generators/openapi/utils.js +322 -0
  74. package/generators/project/templates/.eslintignore +4 -0
  75. package/generators/project/templates/.eslintrc.js.ejs +3 -0
  76. package/generators/project/templates/.mocharc.json +5 -0
  77. package/generators/project/templates/.prettierignore +0 -2
  78. package/generators/project/templates/.prettierrc +2 -1
  79. package/generators/project/templates/.vscode/launch.json +38 -0
  80. package/generators/project/templates/.vscode/settings.json +32 -0
  81. package/generators/project/templates/.vscode/tasks.json +29 -0
  82. package/generators/project/templates/DEVELOPING.md +36 -0
  83. package/generators/project/templates/_.gitignore +3 -5
  84. package/generators/project/templates/package.json.ejs +175 -0
  85. package/generators/project/templates/package.plain.json.ejs +176 -0
  86. package/generators/project/templates/tsconfig.json.ejs +39 -0
  87. package/generators/relation/base-relation.generator.js +220 -0
  88. package/generators/relation/belongs-to-relation.generator.js +196 -0
  89. package/generators/relation/has-many-relation.generator.js +200 -0
  90. package/generators/relation/has-many-through-relation.generator.js +331 -0
  91. package/generators/relation/has-one-relation.generator.js +200 -0
  92. package/generators/relation/index.js +795 -0
  93. package/generators/relation/references-many-relation.generator.js +142 -0
  94. package/generators/relation/templates/controller-relation-template-belongs-to.ts.ejs +38 -0
  95. package/generators/relation/templates/controller-relation-template-has-many-through.ts.ejs +110 -0
  96. package/generators/relation/templates/controller-relation-template-has-many.ts.ejs +110 -0
  97. package/generators/relation/templates/controller-relation-template-has-one.ts.ejs +110 -0
  98. package/generators/relation/utils.generator.js +260 -0
  99. package/generators/repository/index.js +576 -0
  100. package/generators/repository/templates/src/repositories/repository-crud-default-template.ts.ejs +21 -0
  101. package/generators/repository/templates/src/repositories/repository-kv-template.ts.ejs +19 -0
  102. package/generators/rest-crud/crud-rest-component.js +63 -0
  103. package/generators/rest-crud/index.js +423 -0
  104. package/generators/rest-crud/templates/src/model-endpoints/model.rest-config-template.ts.ejs +11 -0
  105. package/generators/service/index.js +351 -0
  106. package/generators/service/templates/local-service-class-template.ts.ejs +10 -0
  107. package/generators/service/templates/local-service-provider-template.ts.ejs +19 -0
  108. package/generators/service/templates/remote-service-proxy-template.ts.ejs +21 -0
  109. package/generators/update/index.js +55 -0
  110. package/intl/cs/messages.json +204 -0
  111. package/intl/de/messages.json +204 -0
  112. package/intl/en/messages.json +204 -0
  113. package/intl/es/messages.json +204 -0
  114. package/intl/fr/messages.json +204 -0
  115. package/intl/it/messages.json +204 -0
  116. package/intl/ja/messages.json +204 -0
  117. package/intl/ko/messages.json +204 -0
  118. package/intl/nl/messages.json +204 -0
  119. package/intl/pl/messages.json +204 -0
  120. package/intl/pt/messages.json +204 -0
  121. package/intl/ru/messages.json +204 -0
  122. package/intl/tr/messages.json +204 -0
  123. package/intl/zh-Hans/messages.json +204 -0
  124. package/intl/zh-Hant/messages.json +204 -0
  125. package/lib/artifact-generator.js +138 -39
  126. package/lib/ast-helper.js +214 -0
  127. package/lib/base-generator.js +509 -0
  128. package/lib/cli.js +233 -0
  129. package/lib/connectors.json +894 -0
  130. package/lib/debug.js +16 -0
  131. package/lib/globalize.js +12 -0
  132. package/lib/model-discoverer.js +118 -0
  133. package/lib/project-generator.js +154 -57
  134. package/lib/tab-completion.js +127 -0
  135. package/lib/update-index.js +44 -0
  136. package/lib/utils.js +689 -20
  137. package/lib/version-helper.js +299 -0
  138. package/package.json +183 -39
  139. package/CHANGELOG.md +0 -86
  140. package/bin/cli.js +0 -66
  141. package/generators/app/templates/index.js +0 -14
  142. package/generators/app/templates/src/application.ts +0 -27
  143. package/generators/app/templates/src/controllers/ping-controller.ts +0 -25
  144. package/generators/app/templates/src/index.ts +0 -25
  145. package/generators/app/templates/test/ping-controller.test.ts +0 -46
  146. package/generators/extension/templates/index.js +0 -8
  147. package/generators/extension/templates/src/component.ts +0 -14
  148. package/generators/extension/templates/src/index.ts +0 -6
  149. package/generators/project/templates/.npmrc +0 -1
  150. package/generators/project/templates/.yo-rc.json +0 -1
  151. package/generators/project/templates/README.md +0 -4
  152. package/generators/project/templates/index.d.ts +0 -6
  153. package/generators/project/templates/index.ts +0 -11
  154. package/generators/project/templates/package.json +0 -79
  155. package/generators/project/templates/package.plain.json +0 -82
  156. package/generators/project/templates/test/mocha.opts +0 -1
  157. package/generators/project/templates/tsconfig.json +0 -29
  158. package/generators/project/templates/tslint.build.json +0 -17
  159. package/generators/project/templates/tslint.json +0 -33
@@ -1,4 +1,5 @@
1
- Node module: <%= project.name %>
1
+ Copyright (c) IBM Corp. and LoopBack contributors 2017,2019.
2
+ Node module: @loopback/cli
2
3
  This project is licensed under the MIT License, full text below.
3
4
 
4
5
  --------
package/README.md CHANGED
@@ -1,69 +1,70 @@
1
1
  # @loopback/cli
2
2
 
3
- This module contains the experimental CLI for LoopBack 4.
3
+ This module contains the official CLI for LoopBack 4.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  Run the following command to install the CLI.
8
8
 
9
- `npm install -g @loopback/cli`
10
-
11
- ## Usage
9
+ ```
10
+ $ npm install -g @loopback/cli
11
+ ```
12
12
 
13
- 1. To scaffold a LoopBack 4 application
13
+ ## Basic Use
14
14
 
15
- `lb4 app`
15
+ Run `lb4 --commands` or `lb4 -l` to list all available commands:
16
16
 
17
17
  ```
18
- Usage:
19
- lb4 app [options] [<name>]
20
-
21
- Options:
22
- -h, --help # Print the generator's options and usage
23
- --skip-cache # Do not remember prompt answers Default: false
24
- --skip-install # Do not automatically install dependencies Default: false
25
- --applicationName # Application name
26
- --description # Description for the application
27
- --outdir # Project root directory for the application
28
- --tslint # Enable tslint
29
- --prettier # Enable prettier
30
- --mocha # Enable mocha
31
- --loopbackBuild # Use @loopback/build
32
-
33
- Arguments:
34
- name # Project name for the application Type: String Required: false
18
+ $ lb4 -l
35
19
  ```
36
20
 
37
- 2. To scaffold a LoopBack 4 extension
21
+ Use the option `--help` to learn more about any specific command:
22
+
23
+ ```
24
+ $ lb4 model --help
25
+ ```
38
26
 
39
- `lb4 extension`
27
+ Run `lb4` or `lb4 app` to scaffold a new LoopBack 4 project.
40
28
 
41
29
  ```
42
- Usage:
43
- lb4 extension [options] [<name>]
44
-
45
- Options:
46
- -h, --help # Print the generator's options and usage
47
- --skip-cache # Do not remember prompt answers Default: false
48
- --skip-install # Do not automatically install dependencies Default: false
49
- --description # Description for the extension
50
- --outdir # Project root directory for the extension
51
- --tslint # Enable tslint
52
- --prettier # Enable prettier
53
- --mocha # Enable mocha
54
- --loopbackBuild # Use @loopback/build
55
- --componentName # Component name
30
+ $ lb4 app
31
+ ? Project name: my-awesome-app
32
+ (etc.)
33
+ ```
34
+
35
+ Use `lb4 --version` (or `lb4 -v`) to print out version information to include in
36
+ bug reports, for example:
56
37
 
57
38
  ```
39
+ $ lb4 -v
40
+ @loopback/cli version: 1.8.1
41
+
42
+ @loopback/* dependencies:
43
+ - @loopback/authentication: ^1.0.14
44
+ - @loopback/boot: ^1.0.14
45
+ - @loopback/build: ^1.3.1
46
+ - @loopback/context: ^1.6.0
47
+ - @loopback/core: ^1.1.7
48
+ - (etc.)
49
+ ```
50
+
51
+ See [CLI reference](https://loopback.io/doc/en/lb4/Command-line-interface.html)
52
+ for a detailed documentation.
53
+
54
+ ## Contributions
55
+
56
+ - [Guidelines](https://github.com/loopbackio/loopback-next/blob/master/docs/CONTRIBUTING.md)
57
+ - [Join the team](https://github.com/loopbackio/loopback-next/issues/110)
58
58
 
59
- # Tests
59
+ ## Tests
60
60
 
61
61
  run `npm test` from the root folder.
62
62
 
63
- # Contributors
63
+ ## Contributors
64
64
 
65
- See [all contributors](https://github.com/strongloop/loopback-next/graphs/contributors).
65
+ See
66
+ [all contributors](https://github.com/loopbackio/loopback-next/graphs/contributors).
66
67
 
67
- # License
68
+ ## License
68
69
 
69
70
  MIT
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env node
2
+ // Copyright IBM Corp. and LoopBack contributors 2018,2020. All Rights Reserved.
3
+ // Node module: @loopback/cli
4
+ // This file is licensed under the MIT License.
5
+ // License text available at https://opensource.org/licenses/MIT
6
+
7
+ 'use strict';
8
+
9
+ const pkg = require('../package.json');
10
+ const semver = require('semver');
11
+ const fs = require('fs-extra');
12
+ const path = require('path');
13
+ const chalk = require('chalk');
14
+
15
+ const {
16
+ tabCompletionCommands,
17
+ runTabCompletionCommand,
18
+ } = require('../lib/tab-completion');
19
+
20
+ // Make sure node version meets the requirement. This code intentionally only
21
+ // uses ES5 features so that it can be run with lower versions of Node
22
+ // to report the version requirement.
23
+ const nodeVer = process.versions.node;
24
+ const requiredVer = pkg.engines.node;
25
+ const ok = semver.satisfies(nodeVer, requiredVer);
26
+ if (!ok) {
27
+ const format =
28
+ 'Node.js "%s" is not supported. Please use a version that satisfies "%s".';
29
+ console.warn(chalk.red(format), nodeVer, requiredVer);
30
+ }
31
+
32
+ // Intentionally have a separate `main.js` which can use JS features
33
+ // supported by required version of Node
34
+ const minimist = require('minimist');
35
+ const opts = minimist(process.argv.slice(2), {
36
+ alias: {
37
+ version: 'v', // --version or -v: print versions
38
+ commands: 'l', // --commands or -l: print commands
39
+ help: 'h', // --help or -h: help
40
+ },
41
+ });
42
+
43
+ const args = opts._;
44
+
45
+ const originalCommand = args[0];
46
+ if (tabCompletionCommands.includes(originalCommand)) {
47
+ const yoJsonFile = path.join(__dirname, '../.yo-rc.json');
48
+ const config = fs.readJsonSync(yoJsonFile);
49
+ return runTabCompletionCommand(config.commands, originalCommand, console.log);
50
+ }
51
+
52
+ const main = require('../lib/cli');
53
+ const updateNotifier = require('update-notifier');
54
+ // Force version check with `lb4 --version`
55
+ const interval = opts.version ? 0 : undefined;
56
+ updateNotifier({
57
+ pkg: pkg,
58
+ updateCheckInterval: interval,
59
+ }).notify({isGlobal: true});
60
+
61
+ main(opts);
@@ -1,4 +1,4 @@
1
- // Copyright IBM Corp. 2017. All Rights Reserved.
1
+ // Copyright IBM Corp. and LoopBack contributors 2017,2020. All Rights Reserved.
2
2
  // Node module: @loopback/cli
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
@@ -6,73 +6,167 @@
6
6
  'use strict';
7
7
  const ProjectGenerator = require('../../lib/project-generator');
8
8
  const utils = require('../../lib/utils');
9
+ const g = require('../../lib/globalize');
9
10
 
10
- module.exports = class extends ProjectGenerator {
11
+ module.exports = class AppGenerator extends ProjectGenerator {
11
12
  // Note: arguments and options should be defined in the constructor.
12
13
  constructor(args, opts) {
13
14
  super(args, opts);
15
+ this.buildOptions.push({
16
+ name: 'docker',
17
+ description: g.f('include Dockerfile and .dockerignore'),
18
+ });
19
+ this.buildOptions.push({
20
+ name: 'repositories',
21
+ description: g.f('include repository imports and RepositoryMixin'),
22
+ });
23
+ this.buildOptions.push({
24
+ name: 'services',
25
+ description: g.f('include service-proxy imports and ServiceMixin'),
26
+ });
14
27
  }
15
28
 
16
29
  _setupGenerator() {
17
30
  this.projectType = 'application';
31
+
18
32
  this.option('applicationName', {
19
33
  type: String,
20
- description: 'Application name',
34
+ description: g.f('Application class name'),
35
+ });
36
+
37
+ this.option('docker', {
38
+ type: Boolean,
39
+ description: g.f('Include Dockerfile and .dockerignore'),
21
40
  });
41
+
42
+ this.option('repositories', {
43
+ type: Boolean,
44
+ description: g.f('Include repository imports and RepositoryMixin'),
45
+ });
46
+
47
+ this.option('services', {
48
+ type: Boolean,
49
+ description: g.f('Include service-proxy imports and ServiceMixin'),
50
+ });
51
+
52
+ this.option('apiconnect', {
53
+ type: Boolean,
54
+ description: g.f('Include ApiConnectComponent'),
55
+ });
56
+
22
57
  return super._setupGenerator();
23
58
  }
24
59
 
25
- setOptions() {
26
- return super.setOptions();
60
+ async setOptions() {
61
+ await super.setOptions();
62
+ if (this.shouldExit()) return;
63
+ if (this.options.applicationName) {
64
+ const clsName = utils.toClassName(this.options.applicationName);
65
+ if (typeof clsName === 'string') {
66
+ this.projectInfo.applicationName = clsName;
67
+ } else if (clsName instanceof Error) {
68
+ throw clsName;
69
+ }
70
+ const msg = utils.validateClassName(clsName);
71
+ if (msg !== true) {
72
+ throw new Error(msg);
73
+ }
74
+ }
27
75
  }
28
76
 
29
77
  promptProjectName() {
78
+ if (this.shouldExit()) return;
30
79
  return super.promptProjectName();
31
80
  }
32
81
 
33
82
  promptProjectDir() {
83
+ if (this.shouldExit()) return;
34
84
  return super.promptProjectDir();
35
85
  }
36
86
 
37
87
  promptApplication() {
88
+ if (this.shouldExit()) return;
38
89
  const prompts = [
39
90
  {
40
91
  type: 'input',
41
92
  name: 'applicationName',
42
- message: 'Application class name:',
43
- default: utils.toClassName(this.projectInfo.name) + 'Application',
93
+ message: g.f('Application class name:'),
94
+ default: utils.pascalCase(this.projectInfo.name) + 'Application',
95
+ validate: utils.validateClassName,
96
+ when: this.projectInfo.applicationName == null,
44
97
  },
45
98
  ];
46
99
 
47
100
  return this.prompt(prompts).then(props => {
48
- Object.assign(this.projectInfo, props);
101
+ props.applicationName = utils.toClassName(props.applicationName);
102
+ if (typeof props.applicationName === 'string') {
103
+ this.projectInfo.applicationName = props.applicationName;
104
+ }
49
105
  });
50
106
  }
51
107
 
52
108
  promptOptions() {
109
+ if (this.shouldExit()) return;
53
110
  return super.promptOptions();
54
111
  }
55
112
 
113
+ promptYarnInstall() {
114
+ if (this.shouldExit()) return;
115
+ return super.promptYarnInstall();
116
+ }
117
+
118
+ buildAppClassMixins() {
119
+ if (this.shouldExit()) return;
120
+ const {repositories, services} = this.projectInfo || {};
121
+ if (!repositories && !services) return;
122
+
123
+ let appClassWithMixins = 'RestApplication';
124
+ if (repositories) {
125
+ appClassWithMixins = `RepositoryMixin(${appClassWithMixins})`;
126
+ }
127
+ if (services) {
128
+ appClassWithMixins = `ServiceMixin(${appClassWithMixins})`;
129
+ }
130
+
131
+ this.projectInfo.appClassWithMixins = appClassWithMixins;
132
+ }
133
+
56
134
  scaffold() {
57
- return super.scaffold();
135
+ const result = super.scaffold();
136
+ if (this.shouldExit()) return result;
137
+
138
+ const {docker, repositories} = this.projectInfo || {};
139
+ if (!docker) {
140
+ this.fs.delete(this.destinationPath('Dockerfile'));
141
+ this.fs.delete(this.destinationPath('.dockerignore'));
142
+ }
143
+ if (!repositories) {
144
+ this.fs.delete(this.destinationPath('src/migrate.ts.ejs'));
145
+ }
146
+
147
+ return result;
58
148
  }
59
149
 
60
150
  install() {
61
151
  return super.install();
62
152
  }
63
153
 
64
- end() {
154
+ async end() {
155
+ await super.end();
156
+ if (this.shouldExit()) return;
65
157
  this.log();
66
158
  this.log(
67
- 'Application %s is now created in %s.',
68
- this.projectInfo.name,
69
- this.projectInfo.outdir
159
+ g.f(
160
+ 'Application %s was created in %s.',
161
+ this.projectInfo.name,
162
+ this.projectInfo.outdir,
163
+ ),
70
164
  );
71
165
  this.log();
72
- this.log('Next steps:');
166
+ this.log(g.f('Next steps:'));
73
167
  this.log();
74
168
  this.log('$ cd ' + this.projectInfo.outdir);
75
- this.log('$ npm start');
169
+ this.log(`$ ${this.options.packageManager || 'npm'} start`);
76
170
  this.log();
77
171
  }
78
172
  };
@@ -0,0 +1,5 @@
1
+ node_modules
2
+ npm-debug.log
3
+ /dist
4
+ # Cache used by TypeScript's incremental build
5
+ *.tsbuildinfo
@@ -0,0 +1,28 @@
1
+ # Check out https://hub.docker.com/_/node to select a new base image
2
+ FROM node:16-slim
3
+
4
+ # Set to a non-root built-in user `node`
5
+ USER node
6
+
7
+ # Create app directory (with user `node`)
8
+ RUN mkdir -p /home/node/app
9
+
10
+ WORKDIR /home/node/app
11
+
12
+ # Install app dependencies
13
+ # A wildcard is used to ensure both package.json AND package-lock.json are copied
14
+ # where available (npm@5+)
15
+ COPY --chown=node package*.json ./
16
+
17
+ RUN npm install
18
+
19
+ # Bundle app source code
20
+ COPY --chown=node . .
21
+
22
+ RUN npm run build
23
+
24
+ # Bind to all network interfaces so that it can be mapped to the host OS
25
+ ENV HOST=0.0.0.0 PORT=3000
26
+
27
+ EXPOSE ${PORT}
28
+ CMD [ "node", "." ]
@@ -0,0 +1,130 @@
1
+ # <%= project.name %>
2
+
3
+ This application is generated using [LoopBack 4 CLI](https://loopback.io/doc/en/lb4/Command-line-interface.html) with the
4
+ [initial project layout](https://loopback.io/doc/en/lb4/Loopback-application-layout.html).
5
+
6
+ ## Install dependencies
7
+
8
+ By default, dependencies were installed when this application was generated.
9
+ Whenever dependencies in `package.json` are changed, run the following command:
10
+
11
+ <% if (packageManager === 'yarn') { -%>
12
+ ```sh
13
+ yarn install
14
+ ```
15
+ <% } else { -%>
16
+ ```sh
17
+ npm install
18
+ ```
19
+
20
+ To only install resolved dependencies in `package-lock.json`:
21
+
22
+ ```sh
23
+ npm ci
24
+ ```
25
+ <% } -%>
26
+
27
+ ## Run the application
28
+
29
+ <% if (packageManager === 'yarn') { -%>
30
+ ```sh
31
+ yarn start
32
+ ```
33
+ <% } else { -%>
34
+ ```sh
35
+ npm start
36
+ ```
37
+ <% } -%>
38
+
39
+ You can also run `node .` to skip the build step.
40
+
41
+ Open http://127.0.0.1:3000 in your browser.
42
+
43
+ ## Rebuild the project
44
+
45
+ To incrementally build the project:
46
+
47
+ <% if (packageManager === 'yarn') { -%>
48
+ ```sh
49
+ yarn run build
50
+ ```
51
+ <% } else { -%>
52
+ ```sh
53
+ npm run build
54
+ ```
55
+ <% } -%>
56
+
57
+ To force a full build by cleaning up cached artifacts:
58
+
59
+ <% if (packageManager === 'yarn') { -%>
60
+ ```sh
61
+ yarn run rebuild
62
+ ```
63
+ <% } else { -%>
64
+ ```sh
65
+ npm run rebuild
66
+ ```
67
+ <% } -%>
68
+
69
+ <% if (project.prettier || project.eslint) { -%>
70
+ ## Fix code style and formatting issues
71
+
72
+ <% if (packageManager === 'yarn') { -%>
73
+ ```sh
74
+ yarn run lint
75
+ ```
76
+ <% } else { -%>
77
+ ```sh
78
+ npm run lint
79
+ ```
80
+ <% } -%>
81
+
82
+ To automatically fix such issues:
83
+
84
+ <% if (packageManager === 'yarn') { -%>
85
+ ```sh
86
+ yarn run lint:fix
87
+ ```
88
+ <% } else { -%>
89
+ ```sh
90
+ npm run lint:fix
91
+ ```
92
+ <% } -%>
93
+ <% } -%>
94
+
95
+ ## Other useful commands
96
+
97
+ <% if (packageManager === 'yarn') { -%>
98
+ - `yarn run migrate`: Migrate database schemas for models
99
+ - `yarn run openapi-spec`: Generate OpenAPI spec into a file
100
+ <% if (project.docker) { -%>
101
+ - `yarn run docker:build`: Build a Docker image for this application
102
+ - `yarn run docker:run`: Run this application inside a Docker container
103
+ <% } -%>
104
+ <% } else { -%>
105
+ - `npm run migrate`: Migrate database schemas for models
106
+ - `npm run openapi-spec`: Generate OpenAPI spec into a file
107
+ <% if (project.docker) { -%>
108
+ - `npm run docker:build`: Build a Docker image for this application
109
+ - `npm run docker:run`: Run this application inside a Docker container
110
+ <% } -%>
111
+ <% } -%>
112
+
113
+ ## Tests
114
+
115
+ <% if (packageManager === 'yarn') { -%>
116
+ ```sh
117
+ yarn test
118
+ ```
119
+ <% } else { -%>
120
+ ```sh
121
+ npm test
122
+ ```
123
+ <% } -%>
124
+
125
+ ## What's next
126
+
127
+ Please check out [LoopBack 4 documentation](https://loopback.io/doc/en/lb4/) to
128
+ understand how you can continue to add features to this application.
129
+
130
+ [![LoopBack](https://github.com/loopbackio/loopback-next/raw/master/docs/site/imgs/branding/Powered-by-LoopBack-Badge-(blue)-@2x.png)](http://loopback.io/)
@@ -0,0 +1,88 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <title><%= project.description %></title>
6
+
7
+ <meta charset="utf-8">
8
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
9
+ <meta name="viewport" content="width=device-width, initial-scale=1">
10
+ <link rel="shortcut icon" type="image/x-icon" href="https://loopback.io/favicon.ico">
11
+
12
+ <style>
13
+ h3 {
14
+ margin-left: 25px;
15
+ text-align: center;
16
+ }
17
+
18
+ a, a:visited {
19
+ color: #3f5dff;
20
+ }
21
+
22
+ h3 a {
23
+ margin-left: 10px;
24
+ }
25
+
26
+ a:hover, a:focus, a:active {
27
+ color: #001956;
28
+ }
29
+
30
+ .power {
31
+ position: absolute;
32
+ bottom: 25px;
33
+ left: 50%;
34
+ transform: translateX(-50%);
35
+ }
36
+
37
+ .info {
38
+ position: absolute;
39
+ top: 50%;
40
+ left: 50%;
41
+ transform: translate(-50%, -50%)
42
+ }
43
+
44
+ .info h1 {
45
+ text-align: center;
46
+ margin-bottom: 0;
47
+ }
48
+
49
+ .info p {
50
+ text-align: center;
51
+ margin-bottom: 3em;
52
+ margin-top: 1em;
53
+ }
54
+
55
+ @media (prefers-color-scheme: dark) {
56
+ body {
57
+ background-color: rgb(29, 30, 32);
58
+ color: white;
59
+ }
60
+
61
+ a, a:visited {
62
+ color: #4990e2;
63
+ }
64
+
65
+ a:hover, a:focus, a:active {
66
+ color: #2b78ff;
67
+ }
68
+ }
69
+ </style>
70
+ </head>
71
+
72
+ <body>
73
+ <div class="info">
74
+ <h1><%= project.name %></h1>
75
+ <p>Version <%= project.version || '1.0.0' %></p>
76
+
77
+ <h3>OpenAPI spec: <a href="./openapi.json">/openapi.json</a></h3>
78
+ <h3>API Explorer: <a href="./explorer">/explorer</a></h3>
79
+ </div>
80
+
81
+ <footer class="power">
82
+ <a href="https://loopback.io" target="_blank">
83
+ <img src="https://loopback.io/images/branding/powered-by-loopback/blue/powered-by-loopback-sm.png" />
84
+ </a>
85
+ </footer>
86
+ </body>
87
+
88
+ </html>
@@ -1,4 +1,3 @@
1
1
  # Tests
2
2
 
3
3
  Please place your tests in this folder.
4
-
@@ -0,0 +1,31 @@
1
+ import {Client} from '@loopback/testlab';
2
+ import {<%= project.applicationName %>} from '../..';
3
+ import {setupApplication} from './test-helper';
4
+
5
+ describe('HomePage', () => {
6
+ let app: <%= project.applicationName %>;
7
+ let client: Client;
8
+
9
+ before('setupApplication', async () => {
10
+ ({app, client} = await setupApplication());
11
+ });
12
+
13
+ after(async () => {
14
+ await app.stop();
15
+ });
16
+
17
+ it('exposes a default home page', async () => {
18
+ await client
19
+ .get('/')
20
+ .expect(200)
21
+ .expect('Content-Type', /text\/html/);
22
+ });
23
+
24
+ it('exposes self-hosted explorer', async () => {
25
+ await client
26
+ .get('/explorer/')
27
+ .expect(200)
28
+ .expect('Content-Type', /text\/html/)
29
+ .expect(/<title>LoopBack API Explorer/);
30
+ });
31
+ });
@@ -0,0 +1,21 @@
1
+ import {Client, expect} from '@loopback/testlab';
2
+ import {<%= project.applicationName %>} from '../..';
3
+ import {setupApplication} from './test-helper';
4
+
5
+ describe('PingController', () => {
6
+ let app: <%= project.applicationName %>;
7
+ let client: Client;
8
+
9
+ before('setupApplication', async () => {
10
+ ({app, client} = await setupApplication());
11
+ });
12
+
13
+ after(async () => {
14
+ await app.stop();
15
+ });
16
+
17
+ it('invokes GET /ping', async () => {
18
+ const res = await client.get('/ping?msg=world').expect(200);
19
+ expect(res.body).to.containEql({greeting: 'Hello from LoopBack'});
20
+ });
21
+ });