@nx/angular 23.0.0-beta.8 → 23.0.0-beta.9
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/generators.d.ts +0 -1
- package/generators.d.ts.map +1 -1
- package/generators.js +0 -1
- package/generators.json +0 -6
- package/migrations.json +5 -0
- package/package.json +8 -8
- package/src/migrations/update-23-0-0/migrate-ngrx-generator-defaults.d.ts +3 -0
- package/src/migrations/update-23-0-0/migrate-ngrx-generator-defaults.d.ts.map +1 -0
- package/src/migrations/update-23-0-0/migrate-ngrx-generator-defaults.js +120 -0
- package/src/utils/backward-compatible-versions.js +2 -2
- package/src/utils/versions.d.ts +1 -1
- package/src/utils/versions.js +1 -1
- package/src/generators/ngrx/files/__directory__/__fileName__.actions.ts__tmpl__ +0 -16
- package/src/generators/ngrx/files/__directory__/__fileName__.effects.spec.ts__tmpl__ +0 -37
- package/src/generators/ngrx/files/__directory__/__fileName__.effects.ts__tmpl__ +0 -22
- package/src/generators/ngrx/files/__directory__/__fileName__.facade.spec.ts__tmpl__ +0 -103
- package/src/generators/ngrx/files/__directory__/__fileName__.facade.ts__tmpl__ +0 -27
- package/src/generators/ngrx/files/__directory__/__fileName__.models.ts__tmpl__ +0 -7
- package/src/generators/ngrx/files/__directory__/__fileName__.reducer.spec.ts__tmpl__ +0 -37
- package/src/generators/ngrx/files/__directory__/__fileName__.reducer.ts__tmpl__ +0 -41
- package/src/generators/ngrx/files/__directory__/__fileName__.selectors.spec.ts__tmpl__ +0 -58
- package/src/generators/ngrx/files/__directory__/__fileName__.selectors.ts__tmpl__ +0 -38
- package/src/generators/ngrx/lib/add-exports-barrel.d.ts +0 -7
- package/src/generators/ngrx/lib/add-exports-barrel.d.ts.map +0 -1
- package/src/generators/ngrx/lib/add-exports-barrel.js +0 -44
- package/src/generators/ngrx/lib/add-imports-to-module.d.ts +0 -4
- package/src/generators/ngrx/lib/add-imports-to-module.d.ts.map +0 -1
- package/src/generators/ngrx/lib/add-imports-to-module.js +0 -181
- package/src/generators/ngrx/lib/add-ngrx-to-package-json.d.ts +0 -4
- package/src/generators/ngrx/lib/add-ngrx-to-package-json.d.ts.map +0 -1
- package/src/generators/ngrx/lib/add-ngrx-to-package-json.js +0 -23
- package/src/generators/ngrx/lib/generate-files.d.ts +0 -7
- package/src/generators/ngrx/lib/generate-files.d.ts.map +0 -1
- package/src/generators/ngrx/lib/generate-files.js +0 -23
- package/src/generators/ngrx/lib/index.d.ts +0 -7
- package/src/generators/ngrx/lib/index.d.ts.map +0 -1
- package/src/generators/ngrx/lib/index.js +0 -15
- package/src/generators/ngrx/lib/normalize-options.d.ts +0 -9
- package/src/generators/ngrx/lib/normalize-options.d.ts.map +0 -1
- package/src/generators/ngrx/lib/normalize-options.js +0 -30
- package/src/generators/ngrx/lib/validate-options.d.ts +0 -4
- package/src/generators/ngrx/lib/validate-options.d.ts.map +0 -1
- package/src/generators/ngrx/lib/validate-options.js +0 -14
- package/src/generators/ngrx/ngrx.d.ts +0 -8
- package/src/generators/ngrx/ngrx.d.ts.map +0 -1
- package/src/generators/ngrx/ngrx.js +0 -28
- package/src/generators/ngrx/schema.d.ts +0 -14
- package/src/generators/ngrx/schema.json +0 -102
package/generators.d.ts
CHANGED
|
@@ -8,7 +8,6 @@ export * from './src/generators/host/host';
|
|
|
8
8
|
export * from './src/generators/init/init';
|
|
9
9
|
export * from './src/generators/library-secondary-entry-point/library-secondary-entry-point';
|
|
10
10
|
export * from './src/generators/library/library';
|
|
11
|
-
export * from './src/generators/ngrx/ngrx';
|
|
12
11
|
export * from './src/generators/ngrx-feature-store/ngrx-feature-store';
|
|
13
12
|
export * from './src/generators/ngrx-root-store/ngrx-root-store';
|
|
14
13
|
export * from './src/generators/pipe/pipe';
|
package/generators.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../../packages/angular/generators.ts"],"names":[],"mappings":"AAAA,cAAc,0CAA0C,CAAC;AACzD,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,kDAAkD,CAAC;AACjE,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8EAA8E,CAAC;AAC7F,cAAc,kCAAkC,CAAC;AACjD,cAAc,
|
|
1
|
+
{"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../../packages/angular/generators.ts"],"names":[],"mappings":"AAAA,cAAc,0CAA0C,CAAC;AACzD,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,kDAAkD,CAAC;AACjE,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8EAA8E,CAAC;AAC7F,cAAc,kCAAkC,CAAC;AACjD,cAAc,wDAAwD,CAAC;AACvE,cAAc,kDAAkD,CAAC;AACjE,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gDAAgD,CAAC;AAC/D,cAAc,sCAAsC,CAAC;AACrD,cAAc,wDAAwD,CAAC;AACvE,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AACnD,cAAc,sCAAsC,CAAC;AACrD,cAAc,kCAAkC,CAAC;AACjD,cAAc,kEAAkE,CAAC;AACjF,cAAc,wCAAwC,CAAC;AACvD,OAAO,EAAE,6BAA6B,EAAE,MAAM,kFAAkF,CAAC;AACjI,cAAc,gDAAgD,CAAC;AAC/D,cAAc,0BAA0B,CAAC"}
|
package/generators.js
CHANGED
|
@@ -12,7 +12,6 @@ tslib_1.__exportStar(require("./src/generators/host/host"), exports);
|
|
|
12
12
|
tslib_1.__exportStar(require("./src/generators/init/init"), exports);
|
|
13
13
|
tslib_1.__exportStar(require("./src/generators/library-secondary-entry-point/library-secondary-entry-point"), exports);
|
|
14
14
|
tslib_1.__exportStar(require("./src/generators/library/library"), exports);
|
|
15
|
-
tslib_1.__exportStar(require("./src/generators/ngrx/ngrx"), exports);
|
|
16
15
|
tslib_1.__exportStar(require("./src/generators/ngrx-feature-store/ngrx-feature-store"), exports);
|
|
17
16
|
tslib_1.__exportStar(require("./src/generators/ngrx-root-store/ngrx-root-store"), exports);
|
|
18
17
|
tslib_1.__exportStar(require("./src/generators/pipe/pipe"), exports);
|
package/generators.json
CHANGED
|
@@ -99,12 +99,6 @@
|
|
|
99
99
|
"description": "Migrates an Angular CLI workspace to Nx or adds the Angular plugin to an Nx workspace.",
|
|
100
100
|
"hidden": true
|
|
101
101
|
},
|
|
102
|
-
"ngrx": {
|
|
103
|
-
"factory": "./src/generators/ngrx/ngrx",
|
|
104
|
-
"schema": "./src/generators/ngrx/schema.json",
|
|
105
|
-
"description": "Adds NgRx support to an application or library.",
|
|
106
|
-
"x-deprecated": "Use the 'ngrx-root-store' and 'ngrx-feature-store' generators instead. It will be removed in Nx v22."
|
|
107
|
-
},
|
|
108
102
|
"ngrx-feature-store": {
|
|
109
103
|
"factory": "./src/generators/ngrx-feature-store/ngrx-feature-store",
|
|
110
104
|
"schema": "./src/generators/ngrx-feature-store/schema.json",
|
package/migrations.json
CHANGED
|
@@ -394,6 +394,11 @@
|
|
|
394
394
|
"version": "23.0.0-beta.0",
|
|
395
395
|
"description": "Update the @nx/angular/module-federation import to use @nx/module-federation/angular.",
|
|
396
396
|
"factory": "./src/migrations/update-23-0-0/migrate-with-mf-import-to-new-package"
|
|
397
|
+
},
|
|
398
|
+
"update-23-0-0-migrate-ngrx-generator-defaults": {
|
|
399
|
+
"version": "23.0.0-beta.7",
|
|
400
|
+
"description": "Split @nx/angular:ngrx generator defaults in nx.json across the @nx/angular:ngrx-root-store and @nx/angular:ngrx-feature-store generators.",
|
|
401
|
+
"factory": "./src/migrations/update-23-0-0/migrate-ngrx-generator-defaults"
|
|
397
402
|
}
|
|
398
403
|
},
|
|
399
404
|
"packageJsonUpdates": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/angular",
|
|
3
|
-
"version": "23.0.0-beta.
|
|
3
|
+
"version": "23.0.0-beta.9",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The Nx Plugin for Angular contains executors, generators, and utilities for managing Angular applications and libraries within an Nx workspace. It provides: \n\n- Integration with libraries such as Storybook, Jest, ESLint, Playwright and Cypress. \n\n- Generators to help scaffold code quickly (like: Micro Frontends, Libraries, both internal to your codebase and publishable to npm) \n\n- Single Component Application Modules (SCAMs) \n\n- NgRx helpers. \n\n- Utilities for automatic workspace refactoring.",
|
|
6
6
|
"repository": {
|
|
@@ -61,13 +61,13 @@
|
|
|
61
61
|
"migrations": "./migrations.json"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@nx/devkit": "23.0.0-beta.
|
|
65
|
-
"@nx/eslint": "23.0.0-beta.
|
|
66
|
-
"@nx/js": "23.0.0-beta.
|
|
67
|
-
"@nx/module-federation": "23.0.0-beta.
|
|
68
|
-
"@nx/rspack": "23.0.0-beta.
|
|
69
|
-
"@nx/web": "23.0.0-beta.
|
|
70
|
-
"@nx/webpack": "23.0.0-beta.
|
|
64
|
+
"@nx/devkit": "23.0.0-beta.9",
|
|
65
|
+
"@nx/eslint": "23.0.0-beta.9",
|
|
66
|
+
"@nx/js": "23.0.0-beta.9",
|
|
67
|
+
"@nx/module-federation": "23.0.0-beta.9",
|
|
68
|
+
"@nx/rspack": "23.0.0-beta.9",
|
|
69
|
+
"@nx/web": "23.0.0-beta.9",
|
|
70
|
+
"@nx/webpack": "23.0.0-beta.9",
|
|
71
71
|
"@phenomnomnominal/tsquery": "~6.2.0",
|
|
72
72
|
"@typescript-eslint/type-utils": "^8.0.0",
|
|
73
73
|
"enquirer": "~2.3.6",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate-ngrx-generator-defaults.d.ts","sourceRoot":"","sources":["../../../../../../packages/angular/src/migrations/update-23-0-0/migrate-ngrx-generator-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,IAAI,EACV,MAAM,YAAY,CAAC;AAsCpB,yBAA+B,IAAI,EAAE,IAAI,iBAcxC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = default_1;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const COLLECTION = '@nx/angular';
|
|
6
|
+
const OLD_GENERATOR = 'ngrx';
|
|
7
|
+
const OLD_KEY = `${COLLECTION}:${OLD_GENERATOR}`;
|
|
8
|
+
const ROOT_STORE = 'ngrx-root-store';
|
|
9
|
+
const FEATURE_STORE = 'ngrx-feature-store';
|
|
10
|
+
// Options supported by ngrx-root-store. The `minimal` option is included here
|
|
11
|
+
// because its semantics match the old generator (skip generating root feature
|
|
12
|
+
// state files).
|
|
13
|
+
const ROOT_STORE_OPTIONS = [
|
|
14
|
+
'name',
|
|
15
|
+
'route',
|
|
16
|
+
'directory',
|
|
17
|
+
'facade',
|
|
18
|
+
'minimal',
|
|
19
|
+
'skipImport',
|
|
20
|
+
'skipPackageJson',
|
|
21
|
+
'skipFormat',
|
|
22
|
+
];
|
|
23
|
+
// Options supported by ngrx-feature-store. `minimal` is intentionally excluded:
|
|
24
|
+
// in the old generator it was a no-op for feature usage, but in
|
|
25
|
+
// ngrx-feature-store it skips template generation while still wiring imports,
|
|
26
|
+
// which would produce broken modules.
|
|
27
|
+
const FEATURE_STORE_OPTIONS = [
|
|
28
|
+
'name',
|
|
29
|
+
'parent',
|
|
30
|
+
'route',
|
|
31
|
+
'directory',
|
|
32
|
+
'facade',
|
|
33
|
+
'barrels',
|
|
34
|
+
'skipImport',
|
|
35
|
+
'skipPackageJson',
|
|
36
|
+
'skipFormat',
|
|
37
|
+
];
|
|
38
|
+
async function default_1(tree) {
|
|
39
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
40
|
+
if (nxJson?.generators && migrateGenerators(nxJson.generators)) {
|
|
41
|
+
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
42
|
+
}
|
|
43
|
+
const projects = (0, devkit_1.getProjects)(tree);
|
|
44
|
+
for (const [projectName, project] of projects) {
|
|
45
|
+
if (project.generators && migrateGenerators(project.generators)) {
|
|
46
|
+
(0, devkit_1.updateProjectConfiguration)(tree, projectName, project);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
50
|
+
}
|
|
51
|
+
function migrateGenerators(generators) {
|
|
52
|
+
const flatDefaults = generators[OLD_KEY];
|
|
53
|
+
const nestedDefaults = generators[COLLECTION]?.[OLD_GENERATOR];
|
|
54
|
+
if (!flatDefaults && !nestedDefaults) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
// Match Nx's runtime merge: nested first, then flat overrides.
|
|
58
|
+
// See `getGeneratorDefaults` in packages/nx/src/utils/params.ts.
|
|
59
|
+
const oldDefaults = {
|
|
60
|
+
...(nestedDefaults ?? {}),
|
|
61
|
+
...(flatDefaults ?? {}),
|
|
62
|
+
};
|
|
63
|
+
// Prefer flat when both shapes exist (it's the dominant runtime shape).
|
|
64
|
+
const useNestedFormat = !flatDefaults && !!nestedDefaults;
|
|
65
|
+
// The deprecated `module` option was an alias for `parent`. The old
|
|
66
|
+
// generator resolved `options.module ?? options.parent`, so `module` won
|
|
67
|
+
// when both were set — preserve that precedence here.
|
|
68
|
+
if (oldDefaults.module !== undefined) {
|
|
69
|
+
oldDefaults.parent = oldDefaults.module;
|
|
70
|
+
}
|
|
71
|
+
const rootStoreDefaults = pick(oldDefaults, ROOT_STORE_OPTIONS);
|
|
72
|
+
const featureStoreDefaults = pick(oldDefaults, FEATURE_STORE_OPTIONS);
|
|
73
|
+
if (Object.keys(rootStoreDefaults).length > 0) {
|
|
74
|
+
setNewDefaults(generators, ROOT_STORE, rootStoreDefaults, useNestedFormat);
|
|
75
|
+
}
|
|
76
|
+
if (Object.keys(featureStoreDefaults).length > 0) {
|
|
77
|
+
setNewDefaults(generators, FEATURE_STORE, featureStoreDefaults, useNestedFormat);
|
|
78
|
+
}
|
|
79
|
+
delete generators[OLD_KEY];
|
|
80
|
+
if (generators[COLLECTION]?.[OLD_GENERATOR] !== undefined) {
|
|
81
|
+
delete generators[COLLECTION][OLD_GENERATOR];
|
|
82
|
+
if (Object.keys(generators[COLLECTION]).length === 0) {
|
|
83
|
+
delete generators[COLLECTION];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
function pick(obj, keys) {
|
|
89
|
+
const result = {};
|
|
90
|
+
for (const key of keys) {
|
|
91
|
+
if (obj[key] !== undefined) {
|
|
92
|
+
result[key] = obj[key];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
function setNewDefaults(generators, generator, newDefaults, preferNestedFormat) {
|
|
98
|
+
const flatKey = `${COLLECTION}:${generator}`;
|
|
99
|
+
const existingFlat = generators[flatKey];
|
|
100
|
+
const existingNested = generators[COLLECTION]?.[generator];
|
|
101
|
+
// Per-generator destination: prefer whichever shape the user already uses
|
|
102
|
+
// for the replacement key, so the migrated defaults layer correctly under
|
|
103
|
+
// their existing values. Fall back to the input shape when neither exists.
|
|
104
|
+
const writeNested = existingNested !== undefined
|
|
105
|
+
? true
|
|
106
|
+
: existingFlat !== undefined
|
|
107
|
+
? false
|
|
108
|
+
: preferNestedFormat;
|
|
109
|
+
if (writeNested) {
|
|
110
|
+
generators[COLLECTION] ??= {};
|
|
111
|
+
// Existing user-set defaults take precedence over the migrated ones.
|
|
112
|
+
generators[COLLECTION][generator] = {
|
|
113
|
+
...newDefaults,
|
|
114
|
+
...(existingNested ?? {}),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
generators[flatKey] = { ...newDefaults, ...(existingFlat ?? {}) };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -29,7 +29,7 @@ exports.backwardCompatibleVersions = {
|
|
|
29
29
|
tsNodeVersion: '10.9.1',
|
|
30
30
|
lessVersion: '^4.3.0',
|
|
31
31
|
jestPresetAngularVersion: '~14.6.1',
|
|
32
|
-
typesNodeVersion: '
|
|
32
|
+
typesNodeVersion: '^22.0.0',
|
|
33
33
|
jasmineMarblesVersion: '^0.9.2',
|
|
34
34
|
jsoncEslintParserVersion: '^2.1.0',
|
|
35
35
|
webpackMergeVersion: '^5.8.0',
|
|
@@ -61,7 +61,7 @@ exports.backwardCompatibleVersions = {
|
|
|
61
61
|
tsNodeVersion: '10.9.1',
|
|
62
62
|
lessVersion: '^4.3.0',
|
|
63
63
|
jestPresetAngularVersion: '~14.4.0',
|
|
64
|
-
typesNodeVersion: '
|
|
64
|
+
typesNodeVersion: '^22.0.0',
|
|
65
65
|
jasmineMarblesVersion: '^0.9.2',
|
|
66
66
|
jsoncEslintParserVersion: '^2.1.0',
|
|
67
67
|
webpackMergeVersion: '^5.8.0',
|
package/src/utils/versions.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export declare const autoprefixerVersion = "^10.4.0";
|
|
|
22
22
|
export declare const tsNodeVersion = "10.9.1";
|
|
23
23
|
export declare const lessVersion = "^4.3.0";
|
|
24
24
|
export declare const jestPresetAngularVersion = "~16.0.0";
|
|
25
|
-
export declare const typesNodeVersion = "
|
|
25
|
+
export declare const typesNodeVersion = "^22.0.0";
|
|
26
26
|
export declare const jasmineMarblesVersion = "^0.9.2";
|
|
27
27
|
export declare const vitestVersion = "^4.0.8";
|
|
28
28
|
export declare const jsdomVersion = "^27.1.0";
|
package/src/utils/versions.js
CHANGED
|
@@ -25,7 +25,7 @@ exports.autoprefixerVersion = '^10.4.0';
|
|
|
25
25
|
exports.tsNodeVersion = '10.9.1';
|
|
26
26
|
exports.lessVersion = '^4.3.0';
|
|
27
27
|
exports.jestPresetAngularVersion = '~16.0.0';
|
|
28
|
-
exports.typesNodeVersion = '
|
|
28
|
+
exports.typesNodeVersion = '^22.0.0';
|
|
29
29
|
exports.jasmineMarblesVersion = '^0.9.2';
|
|
30
30
|
exports.vitestVersion = '^4.0.8';
|
|
31
31
|
exports.jsdomVersion = '^27.1.0';
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { createAction, props } from '@ngrx/store';
|
|
2
|
-
import { <%= className %>Entity } from './<%= fileName %>.models';
|
|
3
|
-
|
|
4
|
-
export const init<%= className %> = createAction(
|
|
5
|
-
'[<%= className %> Page] Init'
|
|
6
|
-
);
|
|
7
|
-
|
|
8
|
-
export const load<%= className %>Success = createAction(
|
|
9
|
-
'[<%= className %>/API] Load <%= className %> Success',
|
|
10
|
-
props<{ <%= propertyName %>: <%= className %>Entity[] }>()
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
export const load<%= className %>Failure = createAction(
|
|
14
|
-
'[<%= className %>/API] Load <%= className %> Failure',
|
|
15
|
-
props<{ error: any }>()
|
|
16
|
-
);
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { TestBed } from '@angular/core/testing';
|
|
2
|
-
import { provideMockActions } from '@ngrx/effects/testing';
|
|
3
|
-
import { Action } from '@ngrx/store';
|
|
4
|
-
import { provideMockStore } from '@ngrx/store/testing';
|
|
5
|
-
import { hot } from 'jasmine-marbles';
|
|
6
|
-
import { Observable } from 'rxjs';
|
|
7
|
-
|
|
8
|
-
import * as <%= className %>Actions from './<%= fileName %>.actions';
|
|
9
|
-
import { <%= className %>Effects } from './<%= fileName %>.effects';
|
|
10
|
-
|
|
11
|
-
describe('<%= className %>Effects', () => {
|
|
12
|
-
let actions: Observable<Action>;
|
|
13
|
-
let effects: <%= className %>Effects;
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
TestBed.configureTestingModule({
|
|
17
|
-
imports: [],
|
|
18
|
-
providers: [
|
|
19
|
-
<%= className %>Effects,
|
|
20
|
-
provideMockActions(() => actions),
|
|
21
|
-
provideMockStore()
|
|
22
|
-
],
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
effects = TestBed.inject(<%= className %>Effects);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
describe('init$', () => {
|
|
29
|
-
it('should work', () => {
|
|
30
|
-
actions = hot('-a-|', { a: <%= className %>Actions.init<%= className %>() });
|
|
31
|
-
|
|
32
|
-
const expected = hot('-a-|', { a: <%= className %>Actions.load<%= className %>Success({ <%= propertyName %>: [] }) });
|
|
33
|
-
|
|
34
|
-
expect(effects.init$).toBeObservable(expected);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
});
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Injectable, inject } from '@angular/core';
|
|
2
|
-
import { createEffect, Actions, ofType } from '@ngrx/effects';<% if (!importFromOperators) { %>
|
|
3
|
-
import { switchMap, catchError, of } from 'rxjs';<% } else { %>
|
|
4
|
-
import { of } from 'rxjs';
|
|
5
|
-
import { switchMap, catchError } from 'rxjs/operators';<% } %>
|
|
6
|
-
import * as <%= className %>Actions from './<%= fileName %>.actions';
|
|
7
|
-
import * as <%= className %>Feature from './<%= fileName %>.reducer';
|
|
8
|
-
|
|
9
|
-
@Injectable()
|
|
10
|
-
export class <%= className %>Effects {
|
|
11
|
-
private actions$ = inject(Actions);
|
|
12
|
-
|
|
13
|
-
init$ = createEffect(() => this.actions$.pipe(
|
|
14
|
-
ofType(<%= className %>Actions.init<%= className %>),
|
|
15
|
-
switchMap(() => of(<%= className %>Actions.load<%= className %>Success({ <%= propertyName %>: [] }))),
|
|
16
|
-
catchError((error) => {
|
|
17
|
-
console.error('Error', error);
|
|
18
|
-
return of(<%= className %>Actions.load<%= className %>Failure({ error }));
|
|
19
|
-
}
|
|
20
|
-
)
|
|
21
|
-
));
|
|
22
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { NgModule } from '@angular/core';
|
|
2
|
-
import { TestBed } from '@angular/core/testing';
|
|
3
|
-
import { EffectsModule } from '@ngrx/effects';
|
|
4
|
-
import { StoreModule, Store } from '@ngrx/store';
|
|
5
|
-
<%_ if (isRxJs7) { _%>
|
|
6
|
-
import { firstValueFrom } from 'rxjs';
|
|
7
|
-
<%_ } else { _%>
|
|
8
|
-
import { first } from 'rxjs/operators';
|
|
9
|
-
<%_ } _%>
|
|
10
|
-
|
|
11
|
-
import * as <%= className %>Actions from './<%= fileName %>.actions';
|
|
12
|
-
import { <%= className %>Effects } from './<%= fileName %>.effects';
|
|
13
|
-
import { <%= className %>Facade } from './<%= fileName %>.facade';
|
|
14
|
-
import { <%= className %>Entity } from './<%= fileName %>.models';
|
|
15
|
-
import {
|
|
16
|
-
<%= constantName %>_FEATURE_KEY,
|
|
17
|
-
<%= className %>State,
|
|
18
|
-
initial<%= className %>State,
|
|
19
|
-
<%= propertyName %>Reducer
|
|
20
|
-
} from './<%= fileName %>.reducer';
|
|
21
|
-
import * as <%= className %>Selectors from './<%= fileName %>.selectors';
|
|
22
|
-
|
|
23
|
-
interface TestSchema {
|
|
24
|
-
<%= propertyName %>: <%= className %>State;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
describe('<%= className %>Facade', () => {
|
|
28
|
-
let facade: <%= className %>Facade;
|
|
29
|
-
let store: Store<TestSchema>;
|
|
30
|
-
const create<%= className %>Entity = (id: string, name = ''): <%= className %>Entity => ({
|
|
31
|
-
id,
|
|
32
|
-
name: name || `name-${id}`
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe('used in NgModule', () => {
|
|
36
|
-
beforeEach(() => {
|
|
37
|
-
@NgModule({
|
|
38
|
-
imports: [
|
|
39
|
-
StoreModule.forFeature(<%= constantName %>_FEATURE_KEY, <%= propertyName %>Reducer),
|
|
40
|
-
EffectsModule.forFeature([<%= className %>Effects])
|
|
41
|
-
],
|
|
42
|
-
providers: [<%= className %>Facade]
|
|
43
|
-
})
|
|
44
|
-
class CustomFeatureModule {}
|
|
45
|
-
|
|
46
|
-
@NgModule({
|
|
47
|
-
imports: [
|
|
48
|
-
StoreModule.forRoot({}),
|
|
49
|
-
EffectsModule.forRoot([]),
|
|
50
|
-
CustomFeatureModule,
|
|
51
|
-
]
|
|
52
|
-
})
|
|
53
|
-
class RootModule {}
|
|
54
|
-
TestBed.configureTestingModule({ imports: [RootModule] });
|
|
55
|
-
|
|
56
|
-
store = TestBed.inject(Store);
|
|
57
|
-
facade = TestBed.inject(<%= className %>Facade);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* The initially generated facade::loadAll() returns empty array
|
|
62
|
-
*/
|
|
63
|
-
it('loadAll() should return empty list with loaded == true', async () => {
|
|
64
|
-
let list = await <% if (isRxJs7) { %>firstValueFrom(facade.all<%= className %>$)<% } else { %>facade.all<%= className %>$.pipe(first()).toPromise()<% } %>;
|
|
65
|
-
let isLoaded = await <% if (isRxJs7) { %>firstValueFrom(facade.loaded$)<% } else { %>facade.loaded$.pipe(first()).toPromise()<% } %>;
|
|
66
|
-
|
|
67
|
-
expect(list.length).toBe(0);
|
|
68
|
-
expect(isLoaded).toBe(false);
|
|
69
|
-
|
|
70
|
-
facade.init();
|
|
71
|
-
|
|
72
|
-
list = await <% if (isRxJs7) { %>firstValueFrom(facade.all<%= className %>$)<% } else { %>facade.all<%= className %>$.pipe(first()).toPromise()<% } %>;
|
|
73
|
-
isLoaded = await <% if (isRxJs7) { %>firstValueFrom(facade.loaded$)<% } else { %>facade.loaded$.pipe(first()).toPromise()<% } %>;
|
|
74
|
-
|
|
75
|
-
expect(list.length).toBe(0);
|
|
76
|
-
expect(isLoaded).toBe(true);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Use `load<%= className %>Success` to manually update list
|
|
81
|
-
*/
|
|
82
|
-
it('all<%= className %>$ should return the loaded list; and loaded flag == true', async () => {
|
|
83
|
-
let list = await <% if (isRxJs7) { %>firstValueFrom(facade.all<%= className %>$)<% } else { %>facade.all<%= className %>$.pipe(first()).toPromise()<% } %>;
|
|
84
|
-
let isLoaded = await <% if (isRxJs7) { %>firstValueFrom(facade.loaded$)<% } else { %>facade.loaded$.pipe(first()).toPromise()<% } %>;
|
|
85
|
-
|
|
86
|
-
expect(list.length).toBe(0);
|
|
87
|
-
expect(isLoaded).toBe(false);
|
|
88
|
-
|
|
89
|
-
store.dispatch(<%= className %>Actions.load<%= className %>Success({
|
|
90
|
-
<%= propertyName %>: [
|
|
91
|
-
create<%= className %>Entity('AAA'),
|
|
92
|
-
create<%= className %>Entity('BBB')
|
|
93
|
-
]})
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
list = await <% if (isRxJs7) { %>firstValueFrom(facade.all<%= className %>$)<% } else { %>facade.all<%= className %>$.pipe(first()).toPromise()<% } %>;
|
|
97
|
-
isLoaded = await <% if (isRxJs7) { %>firstValueFrom(facade.loaded$)<% } else { %>facade.loaded$.pipe(first()).toPromise()<% } %>;
|
|
98
|
-
|
|
99
|
-
expect(list.length).toBe(2);
|
|
100
|
-
expect(isLoaded).toBe(true);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { Injectable, inject } from '@angular/core';
|
|
2
|
-
import { select, Store, Action } from '@ngrx/store';
|
|
3
|
-
|
|
4
|
-
import * as <%= className %>Actions from './<%= fileName %>.actions';
|
|
5
|
-
import * as <%= className %>Feature from './<%= fileName %>.reducer';
|
|
6
|
-
import * as <%= className %>Selectors from './<%= fileName %>.selectors';
|
|
7
|
-
|
|
8
|
-
@Injectable()
|
|
9
|
-
export class <%= className %>Facade {
|
|
10
|
-
private readonly store = inject(Store);
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Combine pieces of state using createSelector,
|
|
14
|
-
* and expose them as observables through the facade.
|
|
15
|
-
*/
|
|
16
|
-
loaded$ = this.store.pipe(select(<%= className %>Selectors.select<%= className %>Loaded));
|
|
17
|
-
all<%= className %>$ = this.store.pipe(select(<%= className %>Selectors.selectAll<%= className %>));
|
|
18
|
-
selected<%= className %>$ = this.store.pipe(select(<%= className %>Selectors.selectEntity));
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Use the initialization action to perform one
|
|
22
|
-
* or more tasks in your Effects.
|
|
23
|
-
*/
|
|
24
|
-
init() {
|
|
25
|
-
this.store.dispatch(<%= className %>Actions.init<%= className %>());
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { Action } from '@ngrx/store';
|
|
2
|
-
|
|
3
|
-
import * as <%= className %>Actions from './<%= fileName %>.actions';
|
|
4
|
-
import { <%= className %>Entity } from './<%= fileName %>.models';
|
|
5
|
-
import { <%= className %>State, initial<%= className %>State, <%= propertyName %>Reducer } from './<%= fileName %>.reducer';
|
|
6
|
-
|
|
7
|
-
describe('<%= className %> Reducer', () => {
|
|
8
|
-
const create<%= className %>Entity = (id: string, name = ''): <%= className %>Entity => ({
|
|
9
|
-
id,
|
|
10
|
-
name: name || `name-${id}`
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
describe('valid <%= className %> actions', () => {
|
|
14
|
-
it('load<%= className %>Success should return the list of known <%= className %>', () => {
|
|
15
|
-
const <%= propertyName %> = [
|
|
16
|
-
create<%= className %>Entity('PRODUCT-AAA'),
|
|
17
|
-
create<%= className %>Entity('PRODUCT-zzz')
|
|
18
|
-
];
|
|
19
|
-
const action = <%= className %>Actions.load<%= className %>Success({ <%= propertyName %> });
|
|
20
|
-
|
|
21
|
-
const result: <%= className %>State = <%= propertyName %>Reducer(initial<%= className %>State, action);
|
|
22
|
-
|
|
23
|
-
expect(result.loaded).toBe(true);
|
|
24
|
-
expect(result.ids.length).toBe(2);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
describe('unknown action', () => {
|
|
29
|
-
it('should return the previous state', () => {
|
|
30
|
-
const action = {} as Action;
|
|
31
|
-
|
|
32
|
-
const result = <%= propertyName %>Reducer(initial<%= className %>State, action);
|
|
33
|
-
|
|
34
|
-
expect(result).toBe(initial<%= className %>State);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
});
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity';
|
|
2
|
-
import { createReducer, on, Action } from '@ngrx/store';
|
|
3
|
-
|
|
4
|
-
import * as <%= className %>Actions from './<%= fileName %>.actions';
|
|
5
|
-
import { <%= className %>Entity } from './<%= fileName %>.models';
|
|
6
|
-
|
|
7
|
-
export const <%= constantName %>_FEATURE_KEY = '<%= propertyName %>';
|
|
8
|
-
|
|
9
|
-
export interface <%= className %>State extends EntityState<<%= className %>Entity> {
|
|
10
|
-
selectedId?: string | number; // which <%= className %> record has been selected
|
|
11
|
-
loaded: boolean; // has the <%= className %> list been loaded
|
|
12
|
-
error?: string | null; // last known error (if any)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface <%= className %>PartialState {
|
|
16
|
-
readonly [<%= constantName %>_FEATURE_KEY]: <%= className %>State;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const <%= propertyName %>Adapter: EntityAdapter<<%= className %>Entity> = createEntityAdapter<<%= className %>Entity>();
|
|
20
|
-
|
|
21
|
-
export const initial<%= className %>State: <%= className %>State = <%= propertyName %>Adapter.getInitialState({
|
|
22
|
-
// set initial required properties
|
|
23
|
-
loaded: false
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const reducer = createReducer(
|
|
27
|
-
initial<%= className %>State,
|
|
28
|
-
on(<%= className %>Actions.init<%= className %>,
|
|
29
|
-
state => ({ ...state, loaded: false, error: null })
|
|
30
|
-
),
|
|
31
|
-
on(<%= className %>Actions.load<%= className %>Success,
|
|
32
|
-
(state, { <%= propertyName %> }) => <%= propertyName %>Adapter.setAll(<%= propertyName %>, { ...state, loaded: true })
|
|
33
|
-
),
|
|
34
|
-
on(<%= className %>Actions.load<%= className %>Failure,
|
|
35
|
-
(state, { error }) => ({ ...state, error })
|
|
36
|
-
),
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
export function <%= propertyName %>Reducer(state: <%= className %>State | undefined, action: Action) {
|
|
40
|
-
return reducer(state, action);
|
|
41
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { <%= className %>Entity } from './<%= fileName %>.models';
|
|
2
|
-
import { <%= propertyName %>Adapter, <%= className %>PartialState, initial<%= className %>State } from './<%= fileName %>.reducer';
|
|
3
|
-
import * as <%= className %>Selectors from './<%= fileName %>.selectors';
|
|
4
|
-
|
|
5
|
-
describe('<%= className %> Selectors', () => {
|
|
6
|
-
const ERROR_MSG = 'No Error Available';
|
|
7
|
-
const get<%= className %>Id = (it: <%= className %>Entity) => it.id;
|
|
8
|
-
const create<%= className %>Entity = (id: string, name = '') => ({
|
|
9
|
-
id,
|
|
10
|
-
name: name || `name-${id}`
|
|
11
|
-
}) as <%= className %>Entity;
|
|
12
|
-
|
|
13
|
-
let state: <%= className %>PartialState;
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
state = {
|
|
17
|
-
<%= propertyName %>: <%= propertyName %>Adapter.setAll([
|
|
18
|
-
create<%= className %>Entity('PRODUCT-AAA'),
|
|
19
|
-
create<%= className %>Entity('PRODUCT-BBB'),
|
|
20
|
-
create<%= className %>Entity('PRODUCT-CCC')
|
|
21
|
-
], {
|
|
22
|
-
...initial<%= className %>State,
|
|
23
|
-
selectedId: 'PRODUCT-BBB',
|
|
24
|
-
error: ERROR_MSG,
|
|
25
|
-
loaded: true
|
|
26
|
-
})
|
|
27
|
-
};
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe('<%= className %> Selectors', () => {
|
|
31
|
-
it('selectAll<%= className %>() should return the list of <%= className %>', () => {
|
|
32
|
-
const results = <%= className %>Selectors.selectAll<%= className %>(state);
|
|
33
|
-
const selId = get<%= className %>Id(results[1]);
|
|
34
|
-
|
|
35
|
-
expect(results.length).toBe(3);
|
|
36
|
-
expect(selId).toBe('PRODUCT-BBB');
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('selectEntity() should return the selected Entity', () => {
|
|
40
|
-
const result = <%= className %>Selectors.selectEntity(state) as <%= className %>Entity;
|
|
41
|
-
const selId = get<%= className %>Id(result);
|
|
42
|
-
|
|
43
|
-
expect(selId).toBe('PRODUCT-BBB');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('select<%= className %>Loaded() should return the current "loaded" status', () => {
|
|
47
|
-
const result = <%= className %>Selectors.select<%= className %>Loaded(state);
|
|
48
|
-
|
|
49
|
-
expect(result).toBe(true);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('select<%= className %>Error() should return the current "error" state', () => {
|
|
53
|
-
const result = <%= className %>Selectors.select<%= className %>Error(state);
|
|
54
|
-
|
|
55
|
-
expect(result).toBe(ERROR_MSG);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { createFeatureSelector, createSelector } from '@ngrx/store';
|
|
2
|
-
import { <%= constantName %>_FEATURE_KEY, <%= className %>State, <%= propertyName %>Adapter } from './<%= fileName %>.reducer';
|
|
3
|
-
|
|
4
|
-
// Lookup the '<%= className %>' feature state managed by NgRx
|
|
5
|
-
export const select<%= className %>State = createFeatureSelector<<%= className %>State>(<%= constantName %>_FEATURE_KEY);
|
|
6
|
-
|
|
7
|
-
const { selectAll, selectEntities } = <%= propertyName %>Adapter.getSelectors();
|
|
8
|
-
|
|
9
|
-
export const select<%= className %>Loaded = createSelector(
|
|
10
|
-
select<%= className %>State,
|
|
11
|
-
(state: <%= className %>State) => state.loaded
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
export const select<%= className %>Error = createSelector(
|
|
15
|
-
select<%= className %>State,
|
|
16
|
-
(state: <%= className %>State) => state.error
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
export const selectAll<%= className %> = createSelector(
|
|
20
|
-
select<%= className %>State,
|
|
21
|
-
(state: <%= className %>State) => selectAll(state)
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
export const select<%= className %>Entities = createSelector(
|
|
25
|
-
select<%= className %>State,
|
|
26
|
-
(state: <%= className %>State) => selectEntities(state)
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
export const selectSelectedId = createSelector(
|
|
30
|
-
select<%= className %>State,
|
|
31
|
-
(state: <%= className %>State) => state.selectedId
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
export const selectEntity = createSelector(
|
|
35
|
-
select<%= className %>Entities,
|
|
36
|
-
selectSelectedId,
|
|
37
|
-
(entities, selectedId) => (selectedId ? entities[selectedId] : undefined)
|
|
38
|
-
);
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Tree } from '@nx/devkit';
|
|
2
|
-
import type { NormalizedNgRxGeneratorOptions } from './normalize-options';
|
|
3
|
-
/**
|
|
4
|
-
* Add ngrx feature exports to the public barrel in the feature library
|
|
5
|
-
*/
|
|
6
|
-
export declare function addExportsToBarrel(tree: Tree, options: NormalizedNgRxGeneratorOptions): void;
|
|
7
|
-
//# sourceMappingURL=add-exports-barrel.d.ts.map
|