@abgov/nx-adsp 13.8.0 → 13.9.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/README.md +48 -42
- package/package.json +1 -1
- package/src/build-assets.spec.ts +3 -3
- package/src/generators/angular-app/angular-app.js +29 -10
- package/src/generators/angular-app/angular-app.js.map +1 -1
- package/src/generators/angular-app/angular-app.spec.ts +12 -4
- package/src/generators/dotnet-service/dotnet-service.spec.ts +1 -1
- package/src/generators/express-service/express-service.js +29 -47
- package/src/generators/express-service/express-service.js.map +1 -1
- package/src/generators/express-service/express-service.spec.ts +76 -14
- package/src/generators/express-service/files/AGENTS.md__tmpl__ +31 -0
- package/src/generators/express-service/files/src/main.ts__tmpl__ +23 -0
- package/src/generators/express-service/files/src/openapi.ts__tmpl__ +19 -0
- package/src/generators/express-service/files/src/routes/example.ts__tmpl__ +73 -0
- package/src/generators/mean/mean.js +3 -2
- package/src/generators/mean/mean.js.map +1 -1
- package/src/generators/mean/mean.spec.ts +9 -1
- package/src/generators/mern/mern.js +3 -2
- package/src/generators/mern/mern.js.map +1 -1
- package/src/generators/mern/mern.spec.ts +9 -1
- package/src/generators/mevn/mevn.js +3 -2
- package/src/generators/mevn/mevn.js.map +1 -1
- package/src/generators/mevn/mevn.spec.ts +9 -1
- package/src/generators/pean/pean.js +3 -2
- package/src/generators/pean/pean.js.map +1 -1
- package/src/generators/pean/pean.spec.ts +9 -1
- package/src/generators/pern/pern.js +3 -2
- package/src/generators/pern/pern.js.map +1 -1
- package/src/generators/pern/pern.spec.ts +9 -1
- package/src/generators/pevn/pevn.js +3 -2
- package/src/generators/pevn/pevn.js.map +1 -1
- package/src/generators/pevn/pevn.spec.ts +9 -1
- package/src/generators/react-app/react-app.js +20 -9
- package/src/generators/react-app/react-app.js.map +1 -1
- package/src/generators/react-app/react-app.spec.ts +8 -3
- package/src/generators/react-dotnet/react-dotnet.spec.ts +5 -0
- package/src/generators/react-form/react-form.js.map +1 -1
- package/src/generators/react-form/react-forms.spec.ts +3 -3
- package/src/generators/react-task-list/react-task-list.js.map +1 -1
- package/src/generators/react-task-list/react-task-list.spec.ts +2 -2
- package/src/generators/vue-app/vue-app.js +22 -10
- package/src/generators/vue-app/vue-app.js.map +1 -1
- package/src/generators/vue-app/vue-app.spec.ts +35 -8
- package/src/generators/vue-components/vue-components.js +7 -2
- package/src/generators/vue-components/vue-components.js.map +1 -1
- package/src/generators/vue-components/vue-components.spec.ts +41 -13
- package/src/types/nx-angular-generators.d.ts +1 -1
- package/src/utils/agent.js +23 -9
- package/src/utils/agent.js.map +1 -1
- package/src/utils/agent.spec.ts +74 -17
- package/src/utils/keycloak-admin.js +16 -5
- package/src/utils/keycloak-admin.js.map +1 -1
- package/src/utils/quality.js.map +1 -1
- package/src/utils/quality.spec.ts +5 -3
|
@@ -15,6 +15,11 @@ utilsMock.getAdspConfiguration.mockResolvedValue({
|
|
|
15
15
|
accessServiceUrl: environments.test.accessServiceUrl,
|
|
16
16
|
directoryServiceUrl: environments.test.directoryServiceUrl,
|
|
17
17
|
});
|
|
18
|
+
// jest.mock('@abgov/nx-oc') automocks adspProjectTags too — restore the real
|
|
19
|
+
// (pure, no I/O) implementation so tag-writing behavior is actually exercised.
|
|
20
|
+
utilsMock.adspProjectTags.mockImplementation(
|
|
21
|
+
jest.requireActual('@abgov/nx-oc').adspProjectTags,
|
|
22
|
+
);
|
|
18
23
|
utilsMock.deploymentGenerator.mockResolvedValue(undefined);
|
|
19
24
|
utilsMock.ensureAdspToken.mockResolvedValue('test-token');
|
|
20
25
|
|
|
@@ -36,7 +41,45 @@ describe('Express Service Generator', () => {
|
|
|
36
41
|
|
|
37
42
|
expect(host.exists('apps/test/src/main.ts')).toBeTruthy();
|
|
38
43
|
expect(host.exists('apps/test/src/environment.ts')).toBeTruthy();
|
|
39
|
-
expect(
|
|
44
|
+
expect(
|
|
45
|
+
host.exists('apps/test/src/environments/environment.ts'),
|
|
46
|
+
).toBeFalsy();
|
|
47
|
+
}, 60000);
|
|
48
|
+
|
|
49
|
+
it('serves generated OpenAPI docs, discoverable via the root _links convention', async () => {
|
|
50
|
+
const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
51
|
+
await generator(host, options);
|
|
52
|
+
|
|
53
|
+
// Shared registry module: extends Zod once, exports the registry every
|
|
54
|
+
// router registers its paths into.
|
|
55
|
+
expect(host.exists('apps/test/src/openapi.ts')).toBeTruthy();
|
|
56
|
+
const openapiTs = host.read('apps/test/src/openapi.ts').toString();
|
|
57
|
+
expect(openapiTs).toContain('extendZodWithOpenApi');
|
|
58
|
+
expect(openapiTs).toContain('export const registry');
|
|
59
|
+
|
|
60
|
+
// main.ts builds the doc from the registry once at startup and serves it
|
|
61
|
+
// at the conventional path; the root endpoint's _links gains a docs entry
|
|
62
|
+
// pointing at it — this is what ADSP's directory service polls for.
|
|
63
|
+
const mainTs = host.read('apps/test/src/main.ts').toString();
|
|
64
|
+
expect(mainTs).toContain('OpenApiGeneratorV3');
|
|
65
|
+
expect(mainTs).toContain('/swagger/docs/v1');
|
|
66
|
+
expect(mainTs).toContain(
|
|
67
|
+
"docs: { href: new URL('/swagger/docs/v1', rootUrl).href }",
|
|
68
|
+
);
|
|
69
|
+
// Document-level default security — without it, routes with no explicit
|
|
70
|
+
// `security` override (e.g. /private) would inherit nothing at all,
|
|
71
|
+
// rather than the accessToken requirement they actually enforce.
|
|
72
|
+
expect(mainTs).toContain('security: [{ accessToken: [] }]');
|
|
73
|
+
|
|
74
|
+
// The shipped example router documents its own routes, reusing the same
|
|
75
|
+
// schema already passed to createValidationHandler (no separate spec).
|
|
76
|
+
const routerTs = host.read('apps/test/src/routes/example.ts').toString();
|
|
77
|
+
expect(routerTs).toContain('registry.registerPath');
|
|
78
|
+
expect(routerTs).toContain("import { registry } from '../openapi'");
|
|
79
|
+
|
|
80
|
+
// Runtime dependency (built at app startup), not a devDependency.
|
|
81
|
+
const pkgJson = readJson(host, 'package.json');
|
|
82
|
+
expect(pkgJson.dependencies['@asteasolutions/zod-to-openapi']).toBeTruthy();
|
|
40
83
|
}, 60000);
|
|
41
84
|
|
|
42
85
|
it('wires the ADSP SDK MCP server into the workspace .mcp.json', async () => {
|
|
@@ -70,7 +113,10 @@ describe('Express Service Generator', () => {
|
|
|
70
113
|
// Unrelated server preserved.
|
|
71
114
|
expect(mcp.mcpServers.other).toEqual({ command: 'other-cmd', args: [] });
|
|
72
115
|
// A team's customized adsp-sdk entry is not overwritten.
|
|
73
|
-
expect(mcp.mcpServers['adsp-sdk']).toEqual({
|
|
116
|
+
expect(mcp.mcpServers['adsp-sdk']).toEqual({
|
|
117
|
+
command: 'node',
|
|
118
|
+
args: ['/local/build/main.js'],
|
|
119
|
+
});
|
|
74
120
|
}, 60000);
|
|
75
121
|
|
|
76
122
|
it('factors routes into a router module mounted in main.ts (not inlined)', async () => {
|
|
@@ -80,7 +126,9 @@ describe('Express Service Generator', () => {
|
|
|
80
126
|
// main.ts holds infra + the mount, not route handlers.
|
|
81
127
|
const mainTs = host.read('apps/test/src/main.ts').toString();
|
|
82
128
|
expect(mainTs).toContain('createErrorHandler');
|
|
83
|
-
expect(mainTs).toContain(
|
|
129
|
+
expect(mainTs).toContain(
|
|
130
|
+
"import { exampleRouter } from './routes/example'",
|
|
131
|
+
);
|
|
84
132
|
expect(mainTs).toContain('exampleRouter(eventService)');
|
|
85
133
|
// The handler internals moved out of main.ts.
|
|
86
134
|
expect(mainTs).not.toContain('authorize');
|
|
@@ -89,7 +137,9 @@ describe('Express Service Generator', () => {
|
|
|
89
137
|
// The router module carries the handlers, capabilities passed in as args.
|
|
90
138
|
expect(host.exists('apps/test/src/routes/example.ts')).toBeTruthy();
|
|
91
139
|
const routerTs = host.read('apps/test/src/routes/example.ts').toString();
|
|
92
|
-
expect(routerTs).toContain(
|
|
140
|
+
expect(routerTs).toContain(
|
|
141
|
+
'export function exampleRouter(eventService: EventService)',
|
|
142
|
+
);
|
|
93
143
|
expect(routerTs).toContain('authorize');
|
|
94
144
|
expect(routerTs).toContain('createValidationHandler');
|
|
95
145
|
expect(routerTs).toContain('eventService.send');
|
|
@@ -131,14 +181,17 @@ describe('Express Service Generator', () => {
|
|
|
131
181
|
expect(config.targets['serve'].dependsOn).toContain('dev-db');
|
|
132
182
|
|
|
133
183
|
// Drizzle has no client codegen, so build must NOT depend on db:generate.
|
|
134
|
-
expect(config.targets['build'].dependsOn ?? []).not.toContain(
|
|
184
|
+
expect(config.targets['build'].dependsOn ?? []).not.toContain(
|
|
185
|
+
'db:generate',
|
|
186
|
+
);
|
|
135
187
|
// The SQL migrations are shipped as a build asset.
|
|
136
188
|
const assets = config.targets['build'].options.assets ?? [];
|
|
137
189
|
expect(
|
|
138
190
|
assets.some(
|
|
139
191
|
(a: unknown) =>
|
|
140
|
-
typeof a === 'object' &&
|
|
141
|
-
|
|
192
|
+
typeof a === 'object' &&
|
|
193
|
+
(a as { output?: string }).output === 'drizzle',
|
|
194
|
+
),
|
|
142
195
|
).toBe(true);
|
|
143
196
|
|
|
144
197
|
// Tagged so the sandbox generator wires the DB without a --database flag.
|
|
@@ -173,9 +226,9 @@ describe('Express Service Generator', () => {
|
|
|
173
226
|
|
|
174
227
|
const config = readProjectConfiguration(host, 'test');
|
|
175
228
|
expect(config.targets['dev-db']).toBeFalsy();
|
|
176
|
-
expect(
|
|
177
|
-
|
|
178
|
-
);
|
|
229
|
+
expect(
|
|
230
|
+
(config.tags ?? []).some((t) => t.startsWith('adsp:database:')),
|
|
231
|
+
).toBe(false);
|
|
179
232
|
}, 60000);
|
|
180
233
|
|
|
181
234
|
it('writes a provisioned CLIENT_SECRET to .env.local, not .env', async () => {
|
|
@@ -183,7 +236,9 @@ describe('Express Service Generator', () => {
|
|
|
183
236
|
const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
184
237
|
await generator(host, { ...options, accessToken: 'test-token' });
|
|
185
238
|
|
|
186
|
-
expect(host.read('apps/test/.env.local').toString()).toContain(
|
|
239
|
+
expect(host.read('apps/test/.env.local').toString()).toContain(
|
|
240
|
+
'CLIENT_SECRET=super-secret',
|
|
241
|
+
);
|
|
187
242
|
expect(host.exists('apps/test/.env')).toBeFalsy();
|
|
188
243
|
}, 60000);
|
|
189
244
|
|
|
@@ -197,7 +252,9 @@ describe('Express Service Generator', () => {
|
|
|
197
252
|
}, 60000);
|
|
198
253
|
|
|
199
254
|
it('does not overwrite or duplicate an existing CLIENT_SECRET in .env.local', async () => {
|
|
200
|
-
keycloakAdminMock.ensureServiceClient.mockResolvedValueOnce(
|
|
255
|
+
keycloakAdminMock.ensureServiceClient.mockResolvedValueOnce(
|
|
256
|
+
'freshly-provisioned-secret',
|
|
257
|
+
);
|
|
201
258
|
const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
202
259
|
// express-service is a one-shot scaffolder (re-running it against an
|
|
203
260
|
// existing project throws in @nx/express), so this exercises the guard
|
|
@@ -215,11 +272,16 @@ describe('Express Service Generator', () => {
|
|
|
215
272
|
it('preserves an existing .env.local value (e.g. a prior dev-db run) alongside CLIENT_SECRET', async () => {
|
|
216
273
|
keycloakAdminMock.ensureServiceClient.mockResolvedValueOnce('super-secret');
|
|
217
274
|
const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
218
|
-
host.write(
|
|
275
|
+
host.write(
|
|
276
|
+
'apps/test/.env.local',
|
|
277
|
+
'DATABASE_URL=postgresql://test:test@localhost:5432/test_dev\n',
|
|
278
|
+
);
|
|
219
279
|
await generator(host, { ...options, accessToken: 'test-token' });
|
|
220
280
|
|
|
221
281
|
const envLocal = host.read('apps/test/.env.local').toString();
|
|
222
|
-
expect(envLocal).toContain(
|
|
282
|
+
expect(envLocal).toContain(
|
|
283
|
+
'DATABASE_URL=postgresql://test:test@localhost:5432/test_dev',
|
|
284
|
+
);
|
|
223
285
|
expect(envLocal).toContain('CLIENT_SECRET=super-secret');
|
|
224
286
|
}, 60000);
|
|
225
287
|
|
|
@@ -156,8 +156,28 @@ import { Router } from 'express';
|
|
|
156
156
|
import { authorize, createValidationHandler } from '@abgov/adsp-service-sdk';
|
|
157
157
|
import { z } from 'zod';
|
|
158
158
|
import * as items from '../services/items';
|
|
159
|
+
import { registry } from '../openapi';
|
|
159
160
|
|
|
160
161
|
const CreateItem = z.object({ name: z.string().trim().min(1) });
|
|
162
|
+
const BASE = '/<%= projectName %>/v1/items';
|
|
163
|
+
|
|
164
|
+
// Reuses CreateItem — the same schema passed to createValidationHandler below
|
|
165
|
+
// — so the served OpenAPI doc can't drift from what's actually validated. See
|
|
166
|
+
// "Why this matters for ADSP" below.
|
|
167
|
+
registry.registerPath({
|
|
168
|
+
method: 'get',
|
|
169
|
+
path: BASE,
|
|
170
|
+
summary: 'List items.',
|
|
171
|
+
security: [], // anonymous is allowed on the /v1 prefix — see the router below
|
|
172
|
+
responses: { 200: { description: 'The items.', content: { 'application/json': { schema: z.array(CreateItem) } } } },
|
|
173
|
+
});
|
|
174
|
+
registry.registerPath({
|
|
175
|
+
method: 'post',
|
|
176
|
+
path: BASE,
|
|
177
|
+
summary: 'Create an item.',
|
|
178
|
+
request: { body: { content: { 'application/json': { schema: CreateItem } } } },
|
|
179
|
+
responses: { 201: { description: 'The created item.', content: { 'application/json': { schema: CreateItem } } } },
|
|
180
|
+
});
|
|
161
181
|
|
|
162
182
|
export function itemsRouter(): Router {
|
|
163
183
|
const router = Router();
|
|
@@ -212,6 +232,17 @@ app.use('/<%= projectName %>/v1/items', itemsRouter());
|
|
|
212
232
|
z.infer<typeof Schema>`) — that's the raw, unparsed body, not the validated
|
|
213
233
|
one; parse it again with the same schema instead, as above.
|
|
214
234
|
|
|
235
|
+
### Why this matters for ADSP
|
|
236
|
+
|
|
237
|
+
`main.ts`'s root `/` handler returns a `docs` link pointing at `/swagger/docs/v1`, which serves an
|
|
238
|
+
OpenAPI document built at startup from every `registry.registerPath()` call across all mounted
|
|
239
|
+
routers (see `src/openapi.ts`). ADSP's directory service polls each registered service's root
|
|
240
|
+
endpoint and, when it finds that `docs` link, aggregates the spec into
|
|
241
|
+
`https://api.adsp.alberta.ca/{tenant}` — so every route added here (following the pattern above)
|
|
242
|
+
becomes part of the platform's aggregated API docs automatically, with no separate file to update.
|
|
243
|
+
This requires the service to already have a directory entry — a one-time setup step outside this
|
|
244
|
+
generator, done via the Tenant Management Webapp's directory admin UI.
|
|
245
|
+
|
|
215
246
|
## Recipe: add a resource end to end
|
|
216
247
|
|
|
217
248
|
Build a feature the conventional way — persistence, a service, a router, wiring,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AdspId, createErrorHandler, initializeService } from '@abgov/adsp-service-sdk';
|
|
2
|
+
import { OpenApiGeneratorV3 } from '@asteasolutions/zod-to-openapi';
|
|
2
3
|
import compression from 'compression';
|
|
3
4
|
import cors from 'cors';
|
|
4
5
|
import express from 'express';
|
|
@@ -12,6 +13,7 @@ import { connectDatabase, disconnectDatabase } from './database';
|
|
|
12
13
|
<% } %>
|
|
13
14
|
import { environment } from './environment';
|
|
14
15
|
import { exampleEventDefinition } from './events';
|
|
16
|
+
import { registry } from './openapi';
|
|
15
17
|
import { exampleRouter } from './routes/example';
|
|
16
18
|
|
|
17
19
|
async function initializeApp() {
|
|
@@ -57,6 +59,26 @@ async function initializeApp() {
|
|
|
57
59
|
res.json({ ...platform });
|
|
58
60
|
});
|
|
59
61
|
|
|
62
|
+
// Generated once from the routers' registry.registerPath() calls (see
|
|
63
|
+
// routes/example.ts) — every router imported above has already registered
|
|
64
|
+
// its paths by the time this runs. Served statically; ADSP's directory
|
|
65
|
+
// service polls the `docs` link below to aggregate this into
|
|
66
|
+
// https://api.adsp.alberta.ca/{tenant} (see AGENTS.md's "Why this matters
|
|
67
|
+
// for ADSP" — requires the service to have a directory entry, set up
|
|
68
|
+
// separately from this generator).
|
|
69
|
+
const openApiDoc = new OpenApiGeneratorV3(registry.definitions).generateDocument({
|
|
70
|
+
openapi: '3.0.0',
|
|
71
|
+
info: { title: '<%= projectName %>', version: '0.0.0' },
|
|
72
|
+
// Document-level default — an operation with no security override (e.g.
|
|
73
|
+
// /private, /example in routes/example.ts) inherits this; a route that's
|
|
74
|
+
// actually anonymous-accessible must set `security: []` explicitly, as
|
|
75
|
+
// the shipped example's index and /public routes do.
|
|
76
|
+
security: [{ accessToken: [] }],
|
|
77
|
+
});
|
|
78
|
+
app.get('/swagger/docs/v1', (_req, res) => {
|
|
79
|
+
res.json(openApiDoc);
|
|
80
|
+
});
|
|
81
|
+
|
|
60
82
|
app.get('/', (req, res) => {
|
|
61
83
|
const rootUrl = new URL(`${req.protocol}://${req.get('host')}`);
|
|
62
84
|
res.json({
|
|
@@ -64,6 +86,7 @@ async function initializeApp() {
|
|
|
64
86
|
self: { href: new URL(req.originalUrl, rootUrl).href },
|
|
65
87
|
health: { href: new URL('/health', rootUrl).href },
|
|
66
88
|
api: { href: new URL('/<%= projectName %>/v1', rootUrl).href },
|
|
89
|
+
docs: { href: new URL('/swagger/docs/v1', rootUrl).href },
|
|
67
90
|
},
|
|
68
91
|
});
|
|
69
92
|
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { extendZodWithOpenApi, OpenAPIRegistry } from '@asteasolutions/zod-to-openapi';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
// Extends Zod schemas with a .openapi() method — must run before any schema
|
|
5
|
+
// calls it, which route modules importing `registry` from here already
|
|
6
|
+
// guarantee (Node evaluates this module's body once, on first import).
|
|
7
|
+
extendZodWithOpenApi(z);
|
|
8
|
+
|
|
9
|
+
// Shared across every route module: each router registers its own paths here,
|
|
10
|
+
// re-using the same Zod schemas already passed to createValidationHandler —
|
|
11
|
+
// one source of truth for validation and API docs, no separate spec to
|
|
12
|
+
// hand-maintain. main.ts generates the served document from this registry.
|
|
13
|
+
export const registry = new OpenAPIRegistry();
|
|
14
|
+
|
|
15
|
+
registry.registerComponent('securitySchemes', 'accessToken', {
|
|
16
|
+
type: 'http',
|
|
17
|
+
scheme: 'bearer',
|
|
18
|
+
bearerFormat: 'JWT',
|
|
19
|
+
});
|
|
@@ -3,11 +3,84 @@ import { Router } from 'express';
|
|
|
3
3
|
import passport from 'passport';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { createExampleEvent } from '../events';
|
|
6
|
+
import { registry } from '../openapi';
|
|
6
7
|
|
|
7
8
|
const ExampleRequestSchema = z.object({
|
|
8
9
|
id: z.string().min(1),
|
|
9
10
|
});
|
|
10
11
|
|
|
12
|
+
const IndexResponseSchema = z.object({
|
|
13
|
+
_links: z.object({
|
|
14
|
+
self: z.object({ href: z.string() }),
|
|
15
|
+
public: z.object({ href: z.string() }),
|
|
16
|
+
private: z.object({ href: z.string() }),
|
|
17
|
+
}),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const MessageResponseSchema = z.object({ message: z.string() });
|
|
21
|
+
|
|
22
|
+
const BASE = '/<%= projectName %>/v1';
|
|
23
|
+
|
|
24
|
+
// One registry.registerPath() per route, reusing the same schemas passed to
|
|
25
|
+
// createValidationHandler below — this keeps the served OpenAPI doc (see
|
|
26
|
+
// AGENTS.md's "Why this matters for ADSP") in sync with actual validation
|
|
27
|
+
// automatically. The mount in main.ts applies tenant-or-anonymous auth to
|
|
28
|
+
// every route here; /private and /example additionally require a real
|
|
29
|
+
// tenant user, so only the index and /public get an explicit `security: []`
|
|
30
|
+
// override.
|
|
31
|
+
registry.registerPath({
|
|
32
|
+
method: 'get',
|
|
33
|
+
path: BASE,
|
|
34
|
+
summary: 'Resource index for the example API.',
|
|
35
|
+
security: [],
|
|
36
|
+
responses: {
|
|
37
|
+
200: {
|
|
38
|
+
description: 'Hypermedia links to this resource\'s routes.',
|
|
39
|
+
content: { 'application/json': { schema: IndexResponseSchema } },
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
registry.registerPath({
|
|
45
|
+
method: 'get',
|
|
46
|
+
path: `${BASE}/public`,
|
|
47
|
+
summary: 'Public endpoint — no authentication required.',
|
|
48
|
+
security: [],
|
|
49
|
+
responses: {
|
|
50
|
+
200: {
|
|
51
|
+
description: 'A greeting message.',
|
|
52
|
+
content: { 'application/json': { schema: MessageResponseSchema } },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
registry.registerPath({
|
|
58
|
+
method: 'get',
|
|
59
|
+
path: `${BASE}/private`,
|
|
60
|
+
summary: 'Private endpoint — requires an authenticated tenant user.',
|
|
61
|
+
responses: {
|
|
62
|
+
200: {
|
|
63
|
+
description: 'A greeting message with the caller\'s name.',
|
|
64
|
+
content: { 'application/json': { schema: MessageResponseSchema } },
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
registry.registerPath({
|
|
70
|
+
method: 'post',
|
|
71
|
+
path: `${BASE}/example`,
|
|
72
|
+
summary: 'Protected route demonstrating authorize, validation, and a domain event.',
|
|
73
|
+
request: {
|
|
74
|
+
body: { content: { 'application/json': { schema: ExampleRequestSchema } } },
|
|
75
|
+
},
|
|
76
|
+
responses: {
|
|
77
|
+
200: {
|
|
78
|
+
description: 'The submitted id, echoed back.',
|
|
79
|
+
content: { 'application/json': { schema: ExampleRequestSchema } },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
11
84
|
// Thin HTTP handlers for the example resource, grouped in an express.Router().
|
|
12
85
|
// Capabilities from initializeService() are passed in (not imported) so the router
|
|
13
86
|
// stays testable — mount it with supertest and pass a mock eventService (see the
|
|
@@ -65,9 +65,10 @@ function default_1(host, options) {
|
|
|
65
65
|
'app/src/app/app.component.html': (_o = (_m = host.read(`${appRoot}/src/app/app.component.html`)) === null || _m === void 0 ? void 0 : _m.toString()) !== null && _o !== void 0 ? _o : '',
|
|
66
66
|
'app/src/app/app.config.ts': (_q = (_p = host.read(`${appRoot}/src/app/app.config.ts`)) === null || _p === void 0 ? void 0 : _p.toString()) !== null && _q !== void 0 ? _q : '',
|
|
67
67
|
'app/src/app/app.routes.ts': (_s = (_r = host.read(`${appRoot}/src/app/app.routes.ts`)) === null || _r === void 0 ? void 0 : _r.toString()) !== null && _s !== void 0 ? _s : '',
|
|
68
|
-
'app/src/environments/environment.ts': (_u = (_t = host
|
|
68
|
+
'app/src/environments/environment.ts': (_u = (_t = host
|
|
69
|
+
.read(`${appRoot}/src/environments/environment.ts`)) === null || _t === void 0 ? void 0 : _t.toString()) !== null && _u !== void 0 ? _u : '',
|
|
69
70
|
},
|
|
70
|
-
}, host, serviceRoot, { additionalRoots: {
|
|
71
|
+
}, host, serviceRoot, { additionalRoots: { app: appRoot } }));
|
|
71
72
|
}
|
|
72
73
|
yield (0, devkit_1.formatFiles)(host);
|
|
73
74
|
return () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mean.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/mean/mean.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"mean.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/mean/mean.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,10 @@ import { environments } from '@abgov/nx-oc';
|
|
|
5
5
|
import { Schema } from './schema';
|
|
6
6
|
import generator from './mean';
|
|
7
7
|
|
|
8
|
-
jest.mock('@nx/devkit', () => ({
|
|
8
|
+
jest.mock('@nx/devkit', () => ({
|
|
9
|
+
...jest.requireActual('@nx/devkit'),
|
|
10
|
+
formatFiles: jest.fn().mockResolvedValue(undefined),
|
|
11
|
+
}));
|
|
9
12
|
jest.mock('@abgov/nx-oc');
|
|
10
13
|
jest.mock('../../utils/agent', () => ({
|
|
11
14
|
consultAgent: jest.fn().mockResolvedValue(null),
|
|
@@ -18,6 +21,11 @@ utilsMock.getAdspConfiguration.mockResolvedValue({
|
|
|
18
21
|
accessServiceUrl: environments.test.accessServiceUrl,
|
|
19
22
|
directoryServiceUrl: environments.test.directoryServiceUrl,
|
|
20
23
|
});
|
|
24
|
+
// jest.mock('@abgov/nx-oc') automocks adspProjectTags too — restore the real
|
|
25
|
+
// (pure, no I/O) implementation so tag-writing behavior is actually exercised.
|
|
26
|
+
utilsMock.adspProjectTags.mockImplementation(
|
|
27
|
+
jest.requireActual('@abgov/nx-oc').adspProjectTags,
|
|
28
|
+
);
|
|
21
29
|
utilsMock.deploymentGenerator.mockResolvedValue(undefined);
|
|
22
30
|
utilsMock.ensureAdspToken.mockResolvedValue('test-token');
|
|
23
31
|
|
|
@@ -63,11 +63,12 @@ function default_1(host, options) {
|
|
|
63
63
|
'service/src/events.ts': (_j = (_h = host.read(`${serviceRoot}/src/events.ts`)) === null || _h === void 0 ? void 0 : _h.toString()) !== null && _j !== void 0 ? _j : '',
|
|
64
64
|
'app/src/app/app.tsx': (_l = (_k = host.read(`${appRoot}/src/app/app.tsx`)) === null || _k === void 0 ? void 0 : _k.toString()) !== null && _l !== void 0 ? _l : '',
|
|
65
65
|
'app/src/store.ts': (_o = (_m = host.read(`${appRoot}/src/store.ts`)) === null || _m === void 0 ? void 0 : _m.toString()) !== null && _o !== void 0 ? _o : '',
|
|
66
|
-
'app/src/environments/environment.ts': (_q = (_p = host
|
|
66
|
+
'app/src/environments/environment.ts': (_q = (_p = host
|
|
67
|
+
.read(`${appRoot}/src/environments/environment.ts`)) === null || _p === void 0 ? void 0 : _p.toString()) !== null && _q !== void 0 ? _q : '',
|
|
67
68
|
'app/src/app/config.slice.ts': (_s = (_r = host.read(`${appRoot}/src/app/config.slice.ts`)) === null || _r === void 0 ? void 0 : _r.toString()) !== null && _s !== void 0 ? _s : '',
|
|
68
69
|
'app/src/app/intake.slice.ts': (_u = (_t = host.read(`${appRoot}/src/app/intake.slice.ts`)) === null || _t === void 0 ? void 0 : _t.toString()) !== null && _u !== void 0 ? _u : '',
|
|
69
70
|
},
|
|
70
|
-
}, host, serviceRoot, { additionalRoots: {
|
|
71
|
+
}, host, serviceRoot, { additionalRoots: { app: appRoot } }));
|
|
71
72
|
}
|
|
72
73
|
yield (0, devkit_1.formatFiles)(host);
|
|
73
74
|
return () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mern.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/mern/mern.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"mern.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/mern/mern.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,10 @@ import { environments } from '@abgov/nx-oc';
|
|
|
6
6
|
import { Schema } from './schema';
|
|
7
7
|
import generator from './mern';
|
|
8
8
|
|
|
9
|
-
jest.mock('@nx/devkit', () => ({
|
|
9
|
+
jest.mock('@nx/devkit', () => ({
|
|
10
|
+
...jest.requireActual('@nx/devkit'),
|
|
11
|
+
formatFiles: jest.fn().mockResolvedValue(undefined),
|
|
12
|
+
}));
|
|
10
13
|
jest.mock('@abgov/nx-oc');
|
|
11
14
|
jest.mock('../../utils/agent', () => ({
|
|
12
15
|
consultAgent: jest.fn().mockResolvedValue(null),
|
|
@@ -19,6 +22,11 @@ utilsMock.getAdspConfiguration.mockResolvedValue({
|
|
|
19
22
|
accessServiceUrl: environments.test.accessServiceUrl,
|
|
20
23
|
directoryServiceUrl: environments.test.directoryServiceUrl,
|
|
21
24
|
});
|
|
25
|
+
// jest.mock('@abgov/nx-oc') automocks adspProjectTags too — restore the real
|
|
26
|
+
// (pure, no I/O) implementation so tag-writing behavior is actually exercised.
|
|
27
|
+
utilsMock.adspProjectTags.mockImplementation(
|
|
28
|
+
jest.requireActual('@abgov/nx-oc').adspProjectTags,
|
|
29
|
+
);
|
|
22
30
|
utilsMock.ensureAdspToken.mockResolvedValue('test-token');
|
|
23
31
|
|
|
24
32
|
describe('MERN Generator', () => {
|
|
@@ -55,9 +55,10 @@ function default_1(host, options) {
|
|
|
55
55
|
'app/src/App.vue': (_l = (_k = host.read(`${appRoot}/src/App.vue`)) === null || _k === void 0 ? void 0 : _k.toString()) !== null && _l !== void 0 ? _l : '',
|
|
56
56
|
'app/src/main.ts': (_o = (_m = host.read(`${appRoot}/src/main.ts`)) === null || _m === void 0 ? void 0 : _m.toString()) !== null && _o !== void 0 ? _o : '',
|
|
57
57
|
'app/src/router/index.ts': (_q = (_p = host.read(`${appRoot}/src/router/index.ts`)) === null || _p === void 0 ? void 0 : _p.toString()) !== null && _q !== void 0 ? _q : '',
|
|
58
|
-
'app/src/environments/environment.ts': (_s = (_r = host
|
|
58
|
+
'app/src/environments/environment.ts': (_s = (_r = host
|
|
59
|
+
.read(`${appRoot}/src/environments/environment.ts`)) === null || _r === void 0 ? void 0 : _r.toString()) !== null && _s !== void 0 ? _s : '',
|
|
59
60
|
},
|
|
60
|
-
}, host, serviceRoot, { additionalRoots: {
|
|
61
|
+
}, host, serviceRoot, { additionalRoots: { app: appRoot } }));
|
|
61
62
|
}
|
|
62
63
|
yield (0, devkit_1.formatFiles)(host);
|
|
63
64
|
return () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mevn.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/mevn/mevn.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"mevn.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/mevn/mevn.ts"],"names":[],"mappings":";;AA8BA,4BA6FC;;AA3HD,uCAMoB;AACpB,wCAAoD;AACpD,wEAAoE;AACpE,gDAA4C;AAE5C,6CAA6E;AAC7E,+DAGoC;AACpC,+DAA4D;AAE5D,SAAe,gBAAgB,CAC7B,IAAU,EACV,OAAe;;;QAEf,MAAM,IAAI,GAAG,MAAM,IAAA,4BAAoB,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvD,uCACK,OAAO,KACV,WAAW,EAAE,MAAA,IAAI,CAAC,WAAW,mCAAI,OAAO,CAAC,WAAW,EACpD,IAAI,IACJ;IACJ,CAAC;CAAA;AAED,mBAA+B,IAAU,EAAE,OAAe;;;QACxD,MAAM,iBAAiB,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAChE,MAAM,WAAW,GAAG,IAAA,cAAK,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;QACjD,MAAM,WAAW,GAAG,GAAG,WAAW,UAAU,CAAC;QAC7C,MAAM,OAAO,GAAG,GAAG,WAAW,MAAM,CAAC;QACrC,MAAM,OAAO,GAAG,IAAA,2BAAkB,EAAC,IAAI,CAAC,CAAC,OAAO,CAAC;QACjD,MAAM,WAAW,GAAG,GAAG,OAAO,IAAI,WAAW,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,GAAG,OAAO,IAAI,OAAO,EAAE,CAAC;QAExC,MAAM,IAAA,yBAAkB,EAAC,IAAI,kCACxB,iBAAiB,KACpB,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,IAAI,EACf,QAAQ,EAAE,OAAO,IACjB,CAAC;QACH,MAAM,IAAA,iBAAU,EAAC,IAAI,kCAChB,iBAAiB,KACpB,IAAI,EAAE,OAAO,EACb,KAAK,EAAE;gBACL,QAAQ,EAAE,OAAO;gBACjB,SAAS,EAAE,UAAU,WAAW,SAAS,WAAW,GAAG;aACxD,EACD,SAAS,EAAE,IAAI,IACf,CAAC;QAEH,IAAI,iBAAiB,CAAC,IAAI,EAAE,CAAC;YAC3B,MAAM,WAAW,GACf,MAAA,iBAAiB,CAAC,IAAI,CAAC,WAAW,mCAAI,iBAAiB,CAAC,WAAW,CAAC;YACtE,MAAM,eAAe,GAAG,WAAW,iBAAiB,CAAC,IAAI,CAAC,MAAM,IAAI,WAAW,EAAE,CAAC;YAClF,MAAM,WAAW,GAAG,WAAW,iBAAiB,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,EAAE,CAAC;YAC1E,MAAM,IAAA,qCAAoB,EACxB,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,EACvC,iBAAiB,CAAC,IAAI,CAAC,WAAW,EAClC,WAAW,EACX,eAAe,EACf,WAAW,CACZ,CAAC;YACF,MAAM,IAAA,sCAAqB,EACzB,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,EACvC,iBAAiB,CAAC,IAAI,CAAC,WAAW,EAClC,WAAW,EACX,eAAe,EACf,cAAc,EACd,WAAW,CACZ,CAAC;QACJ,CAAC;QAED,IAAI,iBAAiB,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,CAAC;YAC3D,8EAA8E;YAC9E,6DAA6D;YAC7D,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC;YACvD,MAAM,IAAA,kCAA0B,EAC9B,MAAM,IAAA,oBAAY,EAChB,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,EAC1C,WAAW,EACX;gBACE,WAAW;gBACX,WAAW,EAAE,MAAM;gBACnB,MAAM,EAAE,iBAAiB,CAAC,IAAI,CAAC,MAAM;gBACrC,aAAa,EAAE,+BAAc;gBAC7B,aAAa,EAAE;oBACb,qBAAqB,EACnB,MAAA,MAAA,IAAI,CAAC,IAAI,CAAC,GAAG,WAAW,cAAc,CAAC,0CAAE,QAAQ,EAAE,mCAAI,EAAE;oBAC3D,4BAA4B,EAC1B,MAAA,MAAA,IAAI,CAAC,IAAI,CAAC,GAAG,WAAW,qBAAqB,CAAC,0CAAE,QAAQ,EAAE,mCAAI,EAAE;oBAClE,yBAAyB,EACvB,MAAA,MAAA,IAAI,CAAC,IAAI,CAAC,GAAG,WAAW,kBAAkB,CAAC,0CAAE,QAAQ,EAAE,mCAAI,EAAE;oBAC/D,uBAAuB,EACrB,MAAA,MAAA,IAAI,CAAC,IAAI,CAAC,GAAG,WAAW,gBAAgB,CAAC,0CAAE,QAAQ,EAAE,mCAAI,EAAE;oBAC7D,iBAAiB,EACf,MAAA,MAAA,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,cAAc,CAAC,0CAAE,QAAQ,EAAE,mCAAI,EAAE;oBACvD,iBAAiB,EACf,MAAA,MAAA,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,cAAc,CAAC,0CAAE,QAAQ,EAAE,mCAAI,EAAE;oBACvD,yBAAyB,EACvB,MAAA,MAAA,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,sBAAsB,CAAC,0CAAE,QAAQ,EAAE,mCAAI,EAAE;oBAC/D,qCAAqC,EACnC,MAAA,MAAA,IAAI;yBACD,IAAI,CAAC,GAAG,OAAO,kCAAkC,CAAC,0CACjD,QAAQ,EAAE,mCAAI,EAAE;iBACvB;aACF,EACD,IAAI,EACJ,WAAW,EACX,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CACtC,CACF,CAAC;QACJ,CAAC;QAED,MAAM,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAC;QAExB,OAAO,GAAG,EAAE;YACV,IAAA,4BAAmB,EAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC;IACJ,CAAC;CAAA"}
|
|
@@ -6,7 +6,10 @@ import { environments } from '@abgov/nx-oc';
|
|
|
6
6
|
import { Schema } from './schema';
|
|
7
7
|
import generator from './mevn';
|
|
8
8
|
|
|
9
|
-
jest.mock('@nx/devkit', () => ({
|
|
9
|
+
jest.mock('@nx/devkit', () => ({
|
|
10
|
+
...jest.requireActual('@nx/devkit'),
|
|
11
|
+
formatFiles: jest.fn().mockResolvedValue(undefined),
|
|
12
|
+
}));
|
|
10
13
|
jest.mock('@abgov/nx-oc');
|
|
11
14
|
jest.mock('../../utils/agent', () => ({
|
|
12
15
|
consultAgent: jest.fn().mockResolvedValue(null),
|
|
@@ -19,6 +22,11 @@ utilsMock.getAdspConfiguration.mockResolvedValue({
|
|
|
19
22
|
accessServiceUrl: environments.test.accessServiceUrl,
|
|
20
23
|
directoryServiceUrl: environments.test.directoryServiceUrl,
|
|
21
24
|
});
|
|
25
|
+
// jest.mock('@abgov/nx-oc') automocks adspProjectTags too — restore the real
|
|
26
|
+
// (pure, no I/O) implementation so tag-writing behavior is actually exercised.
|
|
27
|
+
utilsMock.adspProjectTags.mockImplementation(
|
|
28
|
+
jest.requireActual('@abgov/nx-oc').adspProjectTags,
|
|
29
|
+
);
|
|
22
30
|
utilsMock.ensureAdspToken.mockResolvedValue('test-token');
|
|
23
31
|
|
|
24
32
|
describe('MEVN Generator', () => {
|
|
@@ -65,9 +65,10 @@ function default_1(host, options) {
|
|
|
65
65
|
'app/src/app/app.component.html': (_o = (_m = host.read(`${appRoot}/src/app/app.component.html`)) === null || _m === void 0 ? void 0 : _m.toString()) !== null && _o !== void 0 ? _o : '',
|
|
66
66
|
'app/src/app/app.config.ts': (_q = (_p = host.read(`${appRoot}/src/app/app.config.ts`)) === null || _p === void 0 ? void 0 : _p.toString()) !== null && _q !== void 0 ? _q : '',
|
|
67
67
|
'app/src/app/app.routes.ts': (_s = (_r = host.read(`${appRoot}/src/app/app.routes.ts`)) === null || _r === void 0 ? void 0 : _r.toString()) !== null && _s !== void 0 ? _s : '',
|
|
68
|
-
'app/src/environments/environment.ts': (_u = (_t = host
|
|
68
|
+
'app/src/environments/environment.ts': (_u = (_t = host
|
|
69
|
+
.read(`${appRoot}/src/environments/environment.ts`)) === null || _t === void 0 ? void 0 : _t.toString()) !== null && _u !== void 0 ? _u : '',
|
|
69
70
|
},
|
|
70
|
-
}, host, serviceRoot, { additionalRoots: {
|
|
71
|
+
}, host, serviceRoot, { additionalRoots: { app: appRoot } }));
|
|
71
72
|
}
|
|
72
73
|
yield (0, devkit_1.formatFiles)(host);
|
|
73
74
|
return () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pean.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/pean/pean.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"pean.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/pean/pean.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,10 @@ import { environments } from '@abgov/nx-oc';
|
|
|
6
6
|
import { Schema } from './schema';
|
|
7
7
|
import generator from './pean';
|
|
8
8
|
|
|
9
|
-
jest.mock('@nx/devkit', () => ({
|
|
9
|
+
jest.mock('@nx/devkit', () => ({
|
|
10
|
+
...jest.requireActual('@nx/devkit'),
|
|
11
|
+
formatFiles: jest.fn().mockResolvedValue(undefined),
|
|
12
|
+
}));
|
|
10
13
|
jest.mock('@abgov/nx-oc');
|
|
11
14
|
jest.mock('../../utils/agent', () => ({
|
|
12
15
|
consultAgent: jest.fn().mockResolvedValue(null),
|
|
@@ -19,6 +22,11 @@ utilsMock.getAdspConfiguration.mockResolvedValue({
|
|
|
19
22
|
accessServiceUrl: environments.test.accessServiceUrl,
|
|
20
23
|
directoryServiceUrl: environments.test.directoryServiceUrl,
|
|
21
24
|
});
|
|
25
|
+
// jest.mock('@abgov/nx-oc') automocks adspProjectTags too — restore the real
|
|
26
|
+
// (pure, no I/O) implementation so tag-writing behavior is actually exercised.
|
|
27
|
+
utilsMock.adspProjectTags.mockImplementation(
|
|
28
|
+
jest.requireActual('@abgov/nx-oc').adspProjectTags,
|
|
29
|
+
);
|
|
22
30
|
utilsMock.ensureAdspToken.mockResolvedValue('test-token');
|
|
23
31
|
|
|
24
32
|
describe('PEAN Generator', () => {
|
|
@@ -63,11 +63,12 @@ function default_1(host, options) {
|
|
|
63
63
|
'service/src/events.ts': (_j = (_h = host.read(`${serviceRoot}/src/events.ts`)) === null || _h === void 0 ? void 0 : _h.toString()) !== null && _j !== void 0 ? _j : '',
|
|
64
64
|
'app/src/app/app.tsx': (_l = (_k = host.read(`${appRoot}/src/app/app.tsx`)) === null || _k === void 0 ? void 0 : _k.toString()) !== null && _l !== void 0 ? _l : '',
|
|
65
65
|
'app/src/store.ts': (_o = (_m = host.read(`${appRoot}/src/store.ts`)) === null || _m === void 0 ? void 0 : _m.toString()) !== null && _o !== void 0 ? _o : '',
|
|
66
|
-
'app/src/environments/environment.ts': (_q = (_p = host
|
|
66
|
+
'app/src/environments/environment.ts': (_q = (_p = host
|
|
67
|
+
.read(`${appRoot}/src/environments/environment.ts`)) === null || _p === void 0 ? void 0 : _p.toString()) !== null && _q !== void 0 ? _q : '',
|
|
67
68
|
'app/src/app/config.slice.ts': (_s = (_r = host.read(`${appRoot}/src/app/config.slice.ts`)) === null || _r === void 0 ? void 0 : _r.toString()) !== null && _s !== void 0 ? _s : '',
|
|
68
69
|
'app/src/app/intake.slice.ts': (_u = (_t = host.read(`${appRoot}/src/app/intake.slice.ts`)) === null || _t === void 0 ? void 0 : _t.toString()) !== null && _u !== void 0 ? _u : '',
|
|
69
70
|
},
|
|
70
|
-
}, host, serviceRoot, { additionalRoots: {
|
|
71
|
+
}, host, serviceRoot, { additionalRoots: { app: appRoot } }));
|
|
71
72
|
}
|
|
72
73
|
yield (0, devkit_1.formatFiles)(host);
|
|
73
74
|
return () => {
|