@loopback/example-lb3-application 3.0.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/.prettierignore +2 -0
- package/.prettierrc +7 -0
- package/.vscode/settings.json +20 -0
- package/.vscode/tasks.json +29 -0
- package/CHANGELOG.md +626 -0
- package/LICENSE +25 -0
- package/README.md +560 -0
- package/dist/__tests__/acceptance/home-page.acceptance.d.ts +1 -0
- package/dist/__tests__/acceptance/home-page.acceptance.js +38 -0
- package/dist/__tests__/acceptance/home-page.acceptance.js.map +1 -0
- package/dist/__tests__/acceptance/lb3app.acceptance.d.ts +1 -0
- package/dist/__tests__/acceptance/lb3app.acceptance.js +200 -0
- package/dist/__tests__/acceptance/lb3app.acceptance.js.map +1 -0
- package/dist/__tests__/acceptance/test-helper.d.ts +11 -0
- package/dist/__tests__/acceptance/test-helper.js +33 -0
- package/dist/__tests__/acceptance/test-helper.js.map +1 -0
- package/dist/application.d.ts +187 -0
- package/dist/application.js +41 -0
- package/dist/application.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/migrate.d.ts +1 -0
- package/dist/migrate.js +25 -0
- package/dist/migrate.js.map +1 -0
- package/dist/openapi-spec.d.ts +1 -0
- package/dist/openapi-spec.js +28 -0
- package/dist/openapi-spec.js.map +1 -0
- package/dist/sequence.d.ts +3 -0
- package/dist/sequence.js +12 -0
- package/dist/sequence.js.map +1 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.js +58 -0
- package/dist/server.js.map +1 -0
- package/lb3app/common/models/coffee-shop.js +44 -0
- package/lb3app/common/models/coffee-shop.json +30 -0
- package/lb3app/server/boot/authentication.js +11 -0
- package/lb3app/server/boot/create-sample-models.js +28 -0
- package/lb3app/server/config.json +21 -0
- package/lb3app/server/datasources.json +6 -0
- package/lb3app/server/middleware.json +9 -0
- package/lb3app/server/model-config.json +39 -0
- package/lb3app/server/server.js +17 -0
- package/lb3app/test/acceptance.js +107 -0
- package/lb3app/test/authentication.js +135 -0
- package/lb3app/test/integration.js +75 -0
- package/package.json +78 -0
- package/public/index.html +74 -0
- package/public/lb3-index.html +5 -0
- package/src/__tests__/acceptance/home-page.acceptance.ts +44 -0
- package/src/__tests__/acceptance/lb3app.acceptance.ts +244 -0
- package/src/__tests__/acceptance/test-helper.ts +40 -0
- package/src/application.ts +44 -0
- package/src/index.ts +35 -0
- package/src/migrate.ts +25 -0
- package/src/openapi-spec.ts +28 -0
- package/src/sequence.ts +8 -0
- package/src/server.ts +71 -0
- package/tsconfig.json +36 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2019. All Rights Reserved.
|
|
2
|
+
// Node module: @loopback/example-lb3-application
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
|
|
6
|
+
import {Client} from '@loopback/testlab';
|
|
7
|
+
import {ExpressServer} from '../../server';
|
|
8
|
+
import {setupApplication} from './test-helper';
|
|
9
|
+
|
|
10
|
+
describe('HomePage', () => {
|
|
11
|
+
let app: ExpressServer;
|
|
12
|
+
let client: Client;
|
|
13
|
+
|
|
14
|
+
before('setupApplication', async () => {
|
|
15
|
+
({app, client} = await setupApplication());
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
after(async () => {
|
|
19
|
+
await app.stop();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('exposes a default home page', async () => {
|
|
23
|
+
await client
|
|
24
|
+
.get('/')
|
|
25
|
+
.expect(200)
|
|
26
|
+
.expect('Content-Type', /text\/html/);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('exposes self-hosted explorer', async () => {
|
|
30
|
+
await client
|
|
31
|
+
.get('/api/explorer/')
|
|
32
|
+
.expect(200)
|
|
33
|
+
.expect('Content-Type', /text\/html/)
|
|
34
|
+
.expect(/<title>LoopBack API Explorer/);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('exposes LoopBack 3 home page', async () => {
|
|
38
|
+
await client
|
|
39
|
+
.get('/lb3-index.html')
|
|
40
|
+
.expect(200)
|
|
41
|
+
.expect('Content-Type', /text\/html/)
|
|
42
|
+
.expect(/<h1>LoopBack Rocks!/);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2019,2020. All Rights Reserved.
|
|
2
|
+
// Node module: @loopback/example-lb3-application
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
|
|
6
|
+
import {OpenApiSpec} from '@loopback/rest';
|
|
7
|
+
import {Client, expect} from '@loopback/testlab';
|
|
8
|
+
import _ from 'lodash';
|
|
9
|
+
import {ExpressServer} from '../../server';
|
|
10
|
+
import {givenCoffeeShop, setupApplication} from './test-helper';
|
|
11
|
+
|
|
12
|
+
const lb3App = require('../../../lb3app/server/server');
|
|
13
|
+
|
|
14
|
+
describe('CoffeeShopApplication', () => {
|
|
15
|
+
let app: ExpressServer;
|
|
16
|
+
let client: Client;
|
|
17
|
+
|
|
18
|
+
before('setupApplication', async () => {
|
|
19
|
+
({app, client} = await setupApplication());
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
after('closes application', async () => {
|
|
23
|
+
if (app) await app.stop();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
context('basic REST calls for LoopBack 3 application', () => {
|
|
27
|
+
it('creates and finds a CoffeeShop', async () => {
|
|
28
|
+
const coffeeShop = givenCoffeeShop();
|
|
29
|
+
const response = await client
|
|
30
|
+
.post('/api/CoffeeShops')
|
|
31
|
+
.send(coffeeShop)
|
|
32
|
+
.expect(200);
|
|
33
|
+
|
|
34
|
+
expect(response.body).to.containDeep(
|
|
35
|
+
_.pick(coffeeShop, ['name', 'city']),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const result = await client.get(`/api/CoffeeShops/${response.body.id}`);
|
|
39
|
+
expect(result.body).to.containDeep(_.pick(coffeeShop, ['name', 'city']));
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("gets the CoffeeShop's status", async () => {
|
|
43
|
+
const response = await client.get('/api/CoffeeShops/status').expect(200);
|
|
44
|
+
|
|
45
|
+
expect(response.body.status).to.be.equalOneOf(
|
|
46
|
+
'We are open for business.',
|
|
47
|
+
'Sorry, we are closed. Open daily from 6am to 8pm.',
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('gets external route in application', async () => {
|
|
52
|
+
await client.get('/ping').expect(200, 'pong');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
context('LoopBack 3 authentication', () => {
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
58
|
+
let User: any;
|
|
59
|
+
|
|
60
|
+
before(() => {
|
|
61
|
+
User = lb3App.models.User;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('creates a User and logs them in and out', async () => {
|
|
65
|
+
const user = await User.create({
|
|
66
|
+
email: 'created@email.com',
|
|
67
|
+
password: 'L00pBack!',
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
expect(user.email).to.eql('created@email.com');
|
|
71
|
+
|
|
72
|
+
const token = await User.login({
|
|
73
|
+
email: 'created@email.com',
|
|
74
|
+
password: 'L00pBack!',
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
expect(token).to.have.properties('ttl', 'userId', 'created', 'id');
|
|
78
|
+
expect(token.userId).to.eql(user.id);
|
|
79
|
+
|
|
80
|
+
await User.logout(token.id);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('makes an authenticated request', async () => {
|
|
84
|
+
const token = await User.login({
|
|
85
|
+
email: 'created@email.com',
|
|
86
|
+
password: 'L00pBack!',
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const response = await client
|
|
90
|
+
.get(`/api/CoffeeShops/greet?access_token=${token.id}`)
|
|
91
|
+
.expect(200);
|
|
92
|
+
|
|
93
|
+
expect(response.body.greeting).to.eql('Hello from this Coffee Shop');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('rejects anonymous requests to protected endpoints', async () => {
|
|
97
|
+
await client.get('/api/CoffeeShops/greet').expect(401);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("denies request made by another user's access token", async () => {
|
|
101
|
+
const users = await User.create([
|
|
102
|
+
{
|
|
103
|
+
email: 'original@email.com',
|
|
104
|
+
password: 'L00pBack!',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
email: 'other@email.com',
|
|
108
|
+
password: 'L00pBack!',
|
|
109
|
+
},
|
|
110
|
+
]);
|
|
111
|
+
|
|
112
|
+
const token = await User.login({
|
|
113
|
+
email: users[0].email,
|
|
114
|
+
password: 'L00pBack!',
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const otherToken = await User.login({
|
|
118
|
+
email: users[1].email,
|
|
119
|
+
password: 'L00pBack!',
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const response = await client
|
|
123
|
+
.get(`/api/Users/${users[0].id}?access_token=${token.id}`)
|
|
124
|
+
.expect(200);
|
|
125
|
+
|
|
126
|
+
expect(response.body).to.containEql({
|
|
127
|
+
email: users[0].email,
|
|
128
|
+
id: users[0].id,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
await client
|
|
132
|
+
.get(`/api/Users/${users[0].id}?access_token=${otherToken.id}`)
|
|
133
|
+
.expect(401);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
context('OpenAPI spec', () => {
|
|
138
|
+
let apiSpec: OpenApiSpec;
|
|
139
|
+
|
|
140
|
+
before(async () => {
|
|
141
|
+
apiSpec = await app.lbApp.restServer.getApiSpec();
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('has the same properties in both the LB3 and LB4 specs', () => {
|
|
145
|
+
const lb4SpecProperties = Object.keys(apiSpec);
|
|
146
|
+
|
|
147
|
+
expect(lb4SpecProperties).to.eql([
|
|
148
|
+
'openapi',
|
|
149
|
+
'info',
|
|
150
|
+
'paths',
|
|
151
|
+
'servers',
|
|
152
|
+
'components',
|
|
153
|
+
'tags',
|
|
154
|
+
]);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('uses OpenApi version 3', () => {
|
|
158
|
+
expect(apiSpec.openapi).to.eql('3.0.0');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('transfers the tags from the LB3 spec to the LB4 spec', () => {
|
|
162
|
+
expect(apiSpec.tags).to.containDeep([
|
|
163
|
+
{name: 'User', description: undefined, externalDocs: undefined},
|
|
164
|
+
{name: 'CoffeeShop', description: undefined, externalDocs: undefined},
|
|
165
|
+
]);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('transfers the components from the LB3 spec to the LB4 spec', () => {
|
|
169
|
+
const components = apiSpec.components;
|
|
170
|
+
expect(components).to.have.properties('requestBodies', 'schemas');
|
|
171
|
+
|
|
172
|
+
expect(components!.requestBodies).to.containDeep({
|
|
173
|
+
CoffeeShop: {
|
|
174
|
+
content: {
|
|
175
|
+
'application/json': {
|
|
176
|
+
schema: {$ref: '#/components/schemas/CoffeeShop'},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
description: 'Model instance data',
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
expect(components!.schemas).to.containDeep({
|
|
185
|
+
CoffeeShop: {
|
|
186
|
+
description: undefined,
|
|
187
|
+
properties: {
|
|
188
|
+
name: {type: 'string'},
|
|
189
|
+
city: {type: 'string'},
|
|
190
|
+
id: {type: 'number', format: 'double'},
|
|
191
|
+
},
|
|
192
|
+
required: ['name'],
|
|
193
|
+
additionalProperties: false,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('appends the basePath and transfers the paths from the LB3 spec to the LB4 spec', () => {
|
|
199
|
+
const paths = Object.keys(apiSpec.paths);
|
|
200
|
+
expect(paths).to.have.length(32);
|
|
201
|
+
// some of the expected paths
|
|
202
|
+
expect(paths).to.containDeep([
|
|
203
|
+
'/Users/{id}/accessTokens/{fk}',
|
|
204
|
+
'/Users',
|
|
205
|
+
'/Users/{id}/exists',
|
|
206
|
+
'/Users/login',
|
|
207
|
+
'/CoffeeShops',
|
|
208
|
+
'/CoffeeShops/{id}',
|
|
209
|
+
'/CoffeeShops/greet',
|
|
210
|
+
]);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("transfers the path's details", () => {
|
|
214
|
+
const CoffeeShopsEndpoint = apiSpec.paths['/CoffeeShops'];
|
|
215
|
+
expect(CoffeeShopsEndpoint).to.have.properties([
|
|
216
|
+
'post',
|
|
217
|
+
'patch',
|
|
218
|
+
'put',
|
|
219
|
+
'get',
|
|
220
|
+
]);
|
|
221
|
+
|
|
222
|
+
expect(CoffeeShopsEndpoint['post']).to.containDeep({
|
|
223
|
+
tags: ['CoffeeShop'],
|
|
224
|
+
summary:
|
|
225
|
+
'Create a new instance of the model and persist it into the data source.',
|
|
226
|
+
operationId: 'CoffeeShop.create',
|
|
227
|
+
requestBody: {$ref: '#/components/requestBodies/CoffeeShop'},
|
|
228
|
+
responses: {
|
|
229
|
+
'200': {
|
|
230
|
+
description: 'Request was successful',
|
|
231
|
+
content: {
|
|
232
|
+
'application/json': {
|
|
233
|
+
schema: {
|
|
234
|
+
$ref: '#/components/schemas/CoffeeShop',
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
deprecated: false,
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2019. All Rights Reserved.
|
|
2
|
+
// Node module: @loopback/example-lb3-application
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
|
|
6
|
+
import {Client, givenHttpServerConfig, supertest} from '@loopback/testlab';
|
|
7
|
+
import {ExpressServer} from '../../server';
|
|
8
|
+
const lb3app = require('../../../lb3app/server/server');
|
|
9
|
+
|
|
10
|
+
export async function setupApplication(): Promise<AppWithClient> {
|
|
11
|
+
const app = new ExpressServer({
|
|
12
|
+
rest: givenHttpServerConfig(),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
await app.boot();
|
|
16
|
+
await app.start();
|
|
17
|
+
|
|
18
|
+
const client = supertest(app.url);
|
|
19
|
+
|
|
20
|
+
return {app, client};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface AppWithClient {
|
|
24
|
+
app: ExpressServer;
|
|
25
|
+
client: Client;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Generate a complete Coffee object for use with tests.
|
|
30
|
+
*/
|
|
31
|
+
export function givenCoffeeShop() {
|
|
32
|
+
const CoffeeShop = lb3app.models.CoffeeShop;
|
|
33
|
+
|
|
34
|
+
const data = {
|
|
35
|
+
name: 'Coffee Shop',
|
|
36
|
+
city: 'Toronto',
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return new CoffeeShop(data);
|
|
40
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2019. All Rights Reserved.
|
|
2
|
+
// Node module: @loopback/example-lb3-application
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
|
|
6
|
+
import {BootMixin} from '@loopback/boot';
|
|
7
|
+
import {Lb3AppBooterComponent} from '@loopback/booter-lb3app';
|
|
8
|
+
import {ApplicationConfig} from '@loopback/core';
|
|
9
|
+
import {RepositoryMixin} from '@loopback/repository';
|
|
10
|
+
import {RestApplication} from '@loopback/rest';
|
|
11
|
+
import {RestExplorerComponent} from '@loopback/rest-explorer';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
import {MySequence} from './sequence';
|
|
14
|
+
|
|
15
|
+
export class CoffeeShopApplication extends BootMixin(
|
|
16
|
+
RepositoryMixin(RestApplication),
|
|
17
|
+
) {
|
|
18
|
+
constructor(options: ApplicationConfig = {}) {
|
|
19
|
+
super(options);
|
|
20
|
+
|
|
21
|
+
// Set up the custom sequence
|
|
22
|
+
this.sequence(MySequence);
|
|
23
|
+
|
|
24
|
+
// Set up default home page
|
|
25
|
+
this.static('/', path.join(__dirname, '../public'));
|
|
26
|
+
|
|
27
|
+
this.component(RestExplorerComponent);
|
|
28
|
+
this.component(Lb3AppBooterComponent);
|
|
29
|
+
|
|
30
|
+
this.projectRoot = __dirname;
|
|
31
|
+
// Customize @loopback/boot Booter Conventions here
|
|
32
|
+
this.bootOptions = {
|
|
33
|
+
controllers: {
|
|
34
|
+
// Customize ControllerBooter Conventions here
|
|
35
|
+
dirs: ['controllers'],
|
|
36
|
+
extensions: ['.controller.js'],
|
|
37
|
+
nested: true,
|
|
38
|
+
},
|
|
39
|
+
lb3app: {
|
|
40
|
+
mode: 'fullApp',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2019,2020. All Rights Reserved.
|
|
2
|
+
// Node module: @loopback/example-lb3-application
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
|
|
6
|
+
import {ApplicationConfig, ExpressServer} from './server';
|
|
7
|
+
|
|
8
|
+
export * from './server';
|
|
9
|
+
|
|
10
|
+
export async function main(options: ApplicationConfig = {}) {
|
|
11
|
+
const server = new ExpressServer(options);
|
|
12
|
+
await server.boot();
|
|
13
|
+
await server.start();
|
|
14
|
+
console.log(`Server is running at ${server.url}`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (require.main === module) {
|
|
18
|
+
// Run the application
|
|
19
|
+
const config = {
|
|
20
|
+
rest: {
|
|
21
|
+
port: +(process.env.PORT ?? 3000),
|
|
22
|
+
host: process.env.HOST ?? 'localhost',
|
|
23
|
+
openApiSpec: {
|
|
24
|
+
// useful when used with OpenAPI-to-GraphQL to locate your application
|
|
25
|
+
setServersFromRequest: true,
|
|
26
|
+
},
|
|
27
|
+
// Use the LB4 application as a route. It should not be listening.
|
|
28
|
+
listenOnStart: false,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
main(config).catch(err => {
|
|
32
|
+
console.error('Cannot start the application.', err);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
});
|
|
35
|
+
}
|
package/src/migrate.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2019. All Rights Reserved.
|
|
2
|
+
// Node module: @loopback/example-lb3-application
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
|
|
6
|
+
import {ExpressServer} from './server';
|
|
7
|
+
|
|
8
|
+
export async function migrate(args: string[]) {
|
|
9
|
+
const existingSchema = args.includes('--rebuild') ? 'drop' : 'alter';
|
|
10
|
+
console.log('Migrating schemas (%s existing schema)', existingSchema);
|
|
11
|
+
|
|
12
|
+
const server = new ExpressServer();
|
|
13
|
+
await server.boot();
|
|
14
|
+
await server.lbApp.migrateSchema({existingSchema});
|
|
15
|
+
|
|
16
|
+
// Connectors usually keep a pool of opened connections,
|
|
17
|
+
// this keeps the process running even after all work is done.
|
|
18
|
+
// We need to exit explicitly.
|
|
19
|
+
process.exit(0);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
migrate(process.argv).catch(err => {
|
|
23
|
+
console.error('Cannot migrate database schema', err);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Copyright IBM Corp. 2020. All Rights Reserved.
|
|
2
|
+
// Node module: @loopback/example-lb3-application
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
|
|
6
|
+
import {ApplicationConfig} from '@loopback/core';
|
|
7
|
+
import {CoffeeShopApplication} from './application';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Export the OpenAPI spec from the application
|
|
11
|
+
*/
|
|
12
|
+
async function exportOpenApiSpec(): Promise<void> {
|
|
13
|
+
const config: ApplicationConfig = {
|
|
14
|
+
rest: {
|
|
15
|
+
port: +(process.env.PORT ?? 3000),
|
|
16
|
+
host: process.env.HOST ?? 'localhost',
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
const outFile = process.argv[2] ?? '';
|
|
20
|
+
const app = new CoffeeShopApplication(config);
|
|
21
|
+
await app.boot();
|
|
22
|
+
await app.exportOpenApiSpec(outFile);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
exportOpenApiSpec().catch(err => {
|
|
26
|
+
console.error('Fail to export OpenAPI spec from the application.', err);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
});
|