@abgov/nx-adsp 13.1.2 → 13.1.3
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 +3 -4
- package/package.json +1 -1
- package/src/utils/quality.js +5 -1
- package/src/utils/quality.js.map +1 -1
- package/src/utils/quality.spec.ts +67 -0
package/README.md
CHANGED
|
@@ -44,9 +44,8 @@ npx nx g @abgov/nx-adsp:express-service my-service --env dev --tenant my-tenant
|
|
|
44
44
|
## Full-stack quickstart (PEVN → sandbox)
|
|
45
45
|
|
|
46
46
|
This is the end-to-end path a coding agent can follow from an empty folder to a
|
|
47
|
-
running full-stack app in an OpenShift sandbox.
|
|
48
|
-
|
|
49
|
-
`latest`.
|
|
47
|
+
running full-stack app in an OpenShift sandbox. The plugins require **Nx 23**,
|
|
48
|
+
which `create-nx-workspace@latest` produces by default.
|
|
50
49
|
|
|
51
50
|
Prerequisites for the sandbox deploy (steps 4–5): `podman` (machine started on
|
|
52
51
|
macOS), `oc` logged in to the sandbox cluster, and the GitHub CLI (`gh`)
|
|
@@ -66,7 +65,7 @@ cd my-solution
|
|
|
66
65
|
|
|
67
66
|
# 2. Install the plugins + stack peers (match @nx/* to the workspace nx version)
|
|
68
67
|
NXV=$(node -p "require('./node_modules/nx/package.json').version")
|
|
69
|
-
npm i -D @abgov/nx-oc
|
|
68
|
+
npm i -D @abgov/nx-oc @abgov/nx-adsp "@nx/express@$NXV" "@nx/vue@$NXV" "@nx/node@$NXV" "@nx/js@$NXV" "@nx/eslint@$NXV"
|
|
70
69
|
|
|
71
70
|
# 3. Scaffold a Postgres + Express + Vue + Node solution (opens a browser for the ADSP tenant login)
|
|
72
71
|
npx nx g @abgov/nx-adsp:pevn acme --env=dev --tenant=my-tenant --no-interactive
|
package/package.json
CHANGED
package/src/utils/quality.js
CHANGED
|
@@ -57,7 +57,11 @@ function addJestCoverageConfig(host, projectRoot) {
|
|
|
57
57
|
if (!host.exists(jestPath))
|
|
58
58
|
return;
|
|
59
59
|
const existing = host.read(jestPath).toString();
|
|
60
|
-
|
|
60
|
+
// Capture the coverageDirectory line WITHOUT its trailing comma, then re-emit
|
|
61
|
+
// it with one before the inserted properties. @nx/jest may leave
|
|
62
|
+
// coverageDirectory as the last property (no trailing comma), so appending
|
|
63
|
+
// properties after it verbatim would produce an invalid object literal.
|
|
64
|
+
const modified = existing.replace(/([ \t]*coverageDirectory:[^\n]*?),?\n/, `$1,\n collectCoverage: true,\n coverageThreshold: {\n global: {\n lines: 60,\n },\n },\n`);
|
|
61
65
|
if (modified !== existing) {
|
|
62
66
|
host.write(jestPath, modified);
|
|
63
67
|
}
|
package/src/utils/quality.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quality.js","sourceRoot":"","sources":["../../../../../packages/nx-adsp/src/utils/quality.ts"],"names":[],"mappings":";;AAUA,sDAoCC;AAOD,
|
|
1
|
+
{"version":3,"file":"quality.js","sourceRoot":"","sources":["../../../../../packages/nx-adsp/src/utils/quality.ts"],"names":[],"mappings":";;AAUA,sDAoCC;AAOD,sDAgBC;AAOD,4CAeC;AAED,8CAeC;AA5GD,uCAA+G;AAE/G;;;;;;;GAOG;AACH,SAAgB,qBAAqB,CAAC,IAAU,EAAE,WAAmB,EAAE,aAAuB;;IAC5F,MAAM,UAAU,GAAG,GAAG,WAAW,oBAAoB,CAAC;IACtD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;QAAE,OAAO;IAErC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;IAClD,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACtF,MAAM,cAAc,GAAG,MAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAG,CAAC,CAAC,mCAAI,yBAAyB,CAAC;IACzE,MAAM,YAAY,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEnE,IAAI,CAAC,KAAK,CACR,UAAU,EACV,2BAA2B,cAAc;;;;;;;;;;;;;;;cAe/B,YAAY;;;;;;;;CAQzB,CACE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,qBAAqB,CAAC,IAAU,EAAE,WAAmB;IACnE,MAAM,QAAQ,GAAG,GAAG,WAAW,kBAAkB,CAAC;IAClD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAAE,OAAO;IAEnC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;IAChD,8EAA8E;IAC9E,iEAAiE;IACjE,2EAA2E;IAC3E,wEAAwE;IACxE,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAC/B,uCAAuC,EACvC,wGAAwG,CACzG,CAAC;IACF,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,IAAU,EAAE,WAAmB;IAC9D,MAAM,MAAM,GAAG,IAAA,iCAAwB,EAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC3D,MAAM,CAAC,OAAO,mCACT,MAAM,CAAC,OAAO,KACjB,OAAO,EAAE;YACP,QAAQ,EAAE,iBAAiB;YAC3B,MAAM,EAAE,CAAC,SAAS,CAAC;YACnB,KAAK,EAAE,IAAI;YACX,OAAO,EAAE;gBACP,OAAO,EAAE,iDAAiD;gBAC1D,GAAG,EAAE,eAAe;aACrB;SACF,GACF,CAAC;IACF,IAAA,mCAA0B,EAAC,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;AACxD,CAAC;AAED,SAAgB,iBAAiB,CAAC,IAAU;IAC1C,MAAM,YAAY,GAAG,uBAAuB,CAAC;IAC7C,MAAM,QAAQ,GAAG;QACf,qBAAqB,EAAE,IAAI;QAC3B,yBAAyB,EAAE,wBAAwB;QACnD,0BAA0B,EAAE;YAC1B,sBAAsB,EAAE,UAAU;SACnC;KACF,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,IAAA,mBAAU,EAAC,IAAI,EAAE,YAAY,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,iCAAM,QAAQ,GAAK,QAAQ,EAAG,CAAC,CAAC;IAC/E,CAAC;SAAM,CAAC;QACN,IAAA,kBAAS,EAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Tree } from '@nx/devkit';
|
|
2
|
+
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
3
|
+
import { addJestCoverageConfig } from './quality';
|
|
4
|
+
|
|
5
|
+
function makeConfig(coverageDirectoryLine: string): string {
|
|
6
|
+
return [
|
|
7
|
+
'module.exports = {',
|
|
8
|
+
" displayName: 'svc',",
|
|
9
|
+
" preset: '../../jest.preset.js',",
|
|
10
|
+
` ${coverageDirectoryLine}`,
|
|
11
|
+
'};',
|
|
12
|
+
'',
|
|
13
|
+
].join('\n');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Parse the exported object literal; throws SyntaxError if the config is invalid
|
|
17
|
+
// (e.g. a property with no separating comma).
|
|
18
|
+
function evalConfigObject(src: string): Record<string, unknown> {
|
|
19
|
+
const body = src.slice(src.indexOf('{'), src.lastIndexOf('}') + 1);
|
|
20
|
+
return new Function(`return (${body})`)() as Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe('addJestCoverageConfig', () => {
|
|
24
|
+
let tree: Tree;
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('inserts a comma when coverageDirectory is the last property (no trailing comma)', () => {
|
|
30
|
+
// The @nx/jest (Nx 23) template leaves coverageDirectory without a trailing comma.
|
|
31
|
+
tree.write(
|
|
32
|
+
'apps/svc/jest.config.cts',
|
|
33
|
+
makeConfig("coverageDirectory: 'test-output/jest/coverage'")
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
addJestCoverageConfig(tree, 'apps/svc');
|
|
37
|
+
const out = tree.read('apps/svc/jest.config.cts').toString();
|
|
38
|
+
|
|
39
|
+
expect(out).toContain("coverageDirectory: 'test-output/jest/coverage',");
|
|
40
|
+
expect(out).toContain('collectCoverage: true,');
|
|
41
|
+
expect(out).toContain('lines: 60,');
|
|
42
|
+
expect(out).not.toContain(',,');
|
|
43
|
+
// The result must be a valid object literal.
|
|
44
|
+
const cfg = evalConfigObject(out);
|
|
45
|
+
expect(cfg.collectCoverage).toBe(true);
|
|
46
|
+
expect((cfg.coverageThreshold as { global: { lines: number } }).global.lines).toBe(60);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('does not double the comma when coverageDirectory already has one', () => {
|
|
50
|
+
tree.write(
|
|
51
|
+
'apps/svc/jest.config.cts',
|
|
52
|
+
makeConfig("coverageDirectory: '../../coverage/svc',")
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
addJestCoverageConfig(tree, 'apps/svc');
|
|
56
|
+
const out = tree.read('apps/svc/jest.config.cts').toString();
|
|
57
|
+
|
|
58
|
+
expect(out).toContain("coverageDirectory: '../../coverage/svc',");
|
|
59
|
+
expect(out).not.toContain(',,');
|
|
60
|
+
expect(() => evalConfigObject(out)).not.toThrow();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('is a no-op when there is no jest config', () => {
|
|
64
|
+
expect(() => addJestCoverageConfig(tree, 'apps/none')).not.toThrow();
|
|
65
|
+
expect(tree.exists('apps/none/jest.config.cts')).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
});
|