angular-typed-router 0.1.1-1 → 0.1.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.
Files changed (39) hide show
  1. package/README.md +42 -23
  2. package/index.d.ts +4 -4
  3. package/package.json +12 -3
  4. package/schematics/collection.json +15 -0
  5. package/schematics/index.d.ts +1 -0
  6. package/schematics/index.js +5 -0
  7. package/schematics/index.js.map +1 -0
  8. package/schematics/migrate/index.d.ts +3 -0
  9. package/schematics/migrate/index.js +10 -0
  10. package/schematics/migrate/index.js.map +1 -0
  11. package/schematics/migrate/schema.d.ts +16 -0
  12. package/schematics/migrate/schema.js +4 -0
  13. package/schematics/migrate/schema.js.map +1 -0
  14. package/schematics/migrate/schema.json +26 -0
  15. package/schematics/migrate/steps/replace-usages.d.ts +3 -0
  16. package/schematics/migrate/steps/replace-usages.js +208 -0
  17. package/schematics/migrate/steps/replace-usages.js.map +1 -0
  18. package/schematics/ng-add/index.d.ts +3 -0
  19. package/schematics/ng-add/index.js +22 -0
  20. package/schematics/ng-add/index.js.map +1 -0
  21. package/schematics/ng-add/schema.d.ts +18 -0
  22. package/schematics/ng-add/schema.js +5 -0
  23. package/schematics/ng-add/schema.js.map +1 -0
  24. package/schematics/ng-add/schema.json +26 -0
  25. package/schematics/ng-add/steps/add-declaration-file.d.ts +3 -0
  26. package/schematics/ng-add/steps/add-declaration-file.js +64 -0
  27. package/schematics/ng-add/steps/add-declaration-file.js.map +1 -0
  28. package/schematics/ng-add/steps/inform-user.d.ts +2 -0
  29. package/schematics/ng-add/steps/inform-user.js +14 -0
  30. package/schematics/ng-add/steps/inform-user.js.map +1 -0
  31. package/schematics/ng-add/steps/run-migrate.d.ts +3 -0
  32. package/schematics/ng-add/steps/run-migrate.js +16 -0
  33. package/schematics/ng-add/steps/run-migrate.js.map +1 -0
  34. package/schematics/ng-add/steps/update-route-declarations.d.ts +3 -0
  35. package/schematics/ng-add/steps/update-route-declarations.js +79 -0
  36. package/schematics/ng-add/steps/update-route-declarations.js.map +1 -0
  37. package/schematics/utils/handle-uncommitted-changes.d.ts +3 -0
  38. package/schematics/utils/handle-uncommitted-changes.js +41 -0
  39. package/schematics/utils/handle-uncommitted-changes.js.map +1 -0
package/README.md CHANGED
@@ -7,6 +7,7 @@ Type-safe ergonomic primitives on top of Angular's standalone router. Automatica
7
7
  ## Why
8
8
 
9
9
  Angular's router is powerful but untyped for URL literals – a misspelled path or an outdated segment only fails at runtime. This library lets your application declare routes once, then:
10
+
10
11
  - Navigate with `TypedRouter.navigateByUrl(path)` where `path` is validated at compile time.
11
12
  - Use `<a routerLink="...">` with type checking via an augmented `TypedRouterLink` directive.
12
13
  - Build command tuples with correct literal segments (`Commands` type).
@@ -15,6 +16,10 @@ No decorators, no custom builders, no code generation – just TypeScript type i
15
16
 
16
17
  ## Installation
17
18
 
19
+ `ng add angular-ryped-router` will set up the package and create a declaration file for you.
20
+
21
+ Or install manually:
22
+
18
23
  ```bash
19
24
  npm install angular-typed-router
20
25
  # or
@@ -34,24 +39,24 @@ import { DashboardComponent } from './dashboard.component';
34
39
 
35
40
  export const appRoutes = [
36
41
  { path: 'dashboard', component: DashboardComponent },
37
- { path: 'projects/:id', loadComponent: () => import('./project.component').then(m => m.ProjectComponent) },
38
- { path: '**', redirectTo: 'dashboard' }
42
+ { path: 'projects/:id', loadComponent: () => import('./project.component').then((m) => m.ProjectComponent) },
43
+ { path: '**', redirectTo: 'dashboard' },
39
44
  ] as const satisfies Routes;
40
45
  ```
41
46
 
42
47
  2. Create the augmentation file so the library can “see” your routes:
43
48
 
44
49
  ```ts
45
- // angular-typed-router.d.ts (sibling to main.ts or inside src/ root)
50
+ // typed-router.d.ts (sibling to main.ts or inside src/ root)
46
51
  import type { appRoutes } from './app/app.routes';
47
52
 
48
53
  declare module 'angular-typed-router' {
49
54
  interface UserTypedRoutes {
50
55
  routes: typeof appRoutes;
51
56
  }
52
- // Customize route param types here
53
- interface AllowedRouteParamValues {
54
- ids: `${number}`;
57
+ // Customize route param types here, the keys of this interface match your route param names
58
+ interface RouteParamTypes {
59
+ id: `${number}`;
55
60
  // other params...
56
61
  }
57
62
  }
@@ -63,13 +68,14 @@ declare module 'angular-typed-router' {
63
68
  // tsconfig.app.json
64
69
  {
65
70
  "extends": "./tsconfig.json",
66
- "compilerOptions": { },
71
+ "compilerOptions": {},
67
72
  "include": [
68
73
  "src/**/*.ts",
69
- "angular-typed-router.d.ts" // <— add this line
74
+ "typed-router.d.ts" // <— add this line
70
75
  ]
71
76
  }
72
77
  ```
78
+
73
79
  If you have multiple tsconfigs, ensure the specific app tsconfig that drives the build/test includes the file.
74
80
 
75
81
  4. Use the typed router & link:
@@ -83,12 +89,13 @@ import { TypedRouter, Path } from 'angular-typed-router';
83
89
  template: `
84
90
  <a routerLink="dashboard">Dashboard</a>
85
91
  <a routerLink="projects/123">Project 123</a>
86
- `
92
+ `,
87
93
  })
88
94
  export class NavComponent {
89
95
  private readonly router = inject(TypedRouter);
90
96
 
91
- go(p: Path) { // p must be one of the inferred paths
97
+ go(p: Path) {
98
+ // p must be one of the inferred paths
92
99
  this.router.navigateByUrl(p);
93
100
  }
94
101
 
@@ -104,7 +111,7 @@ If you try `this.router.navigateByUrl('projcts/123')` (typo) or `<a routerLink="
104
111
  ## Exports
105
112
 
106
113
  ```ts
107
- import { TypedRouter, TypedRouterLink, Path, Commands, UserTypedRoutes } from 'angular-typed-router';
114
+ import { TypedRouter, TypedRouterLink, Path, Commands, UserTypedRoutes, RouteParamTypes } from 'angular-typed-router';
108
115
  ```
109
116
 
110
117
  - `TypedRouter` – Extends Angular `Router`, overrides `navigateByUrl` & `navigate` signatures to accept `Path` / `Commands`.
@@ -113,6 +120,7 @@ import { TypedRouter, TypedRouterLink, Path, Commands, UserTypedRoutes } from 'a
113
120
  - `Commands` – Union of tuple command arrays representing valid `Router.navigate()` inputs (each static segment as a literal, each parameter position as `string`).
114
121
  - `UserTypedRoutes` – Empty interface you augment with your `routes` reference.
115
122
  - `ExtractPathsFromRoutes<Routes>` – Utility type if you need to compute from an arbitrary `Routes` array manually.
123
+ - `RouteParamTypes` – Interface you can augment to specify types for route parameters by name (e.g. `id: ${number}`).
116
124
 
117
125
  ## How It Works
118
126
 
@@ -127,6 +135,7 @@ All compile-time only; nothing ships to runtime.
127
135
  ## Lazy Routes
128
136
 
129
137
  Works with any lazy route whose `loadChildren` resolves to:
138
+
130
139
  - `Promise<Route[]>`
131
140
  - `Promise<{ routes: Route[] }>` (Angular v17+ pattern)
132
141
 
@@ -141,59 +150,68 @@ Those child paths get prefixed (`admin/...`) in `Path` & `Commands`.
141
150
  ## Parameter Segments
142
151
 
143
152
  A pattern `projects/:id/details/:section` produces a `Path` variant like:
153
+
144
154
  ```
145
- 'projects/' + string + '/details/' + string
155
+ 'projects/' + IdParamType + '/details/' + SectionParamType
146
156
  ```
157
+
147
158
  and a `Commands` tuple like:
159
+
148
160
  ```
149
- ['projects', string, 'details', string]
161
+ ['projects', IdParamType, 'details', SectionParamType]
150
162
  ```
151
- You pass real runtime values for the `string` positions. Empty string values and values like 'param/still-param' cannot currently be prevented at the type level without hurting DX (see Limitations).
163
+
164
+ You pass real runtime values for the `IdParamType` and `SectionParamType` positions. Empty string values and values like 'param/still-param' cannot currently be prevented at the type level without hurting DX (see Limitations).
152
165
 
153
166
  ## Usage Patterns
154
167
 
155
168
  Navigate by full path (typed):
169
+
156
170
  ```ts
157
171
  router.navigateByUrl('/dashboard');
158
172
  ```
173
+
159
174
  Navigate with commands array:
175
+
160
176
  ```ts
161
177
  router.navigate(['/', 'projects', someId]);
162
178
  ```
179
+
163
180
  Generate a `UrlTree`:
181
+
164
182
  ```ts
165
183
  router.createUrlTree(['/', 'projects', id]);
166
184
  ```
185
+
167
186
  Template links:
187
+
168
188
  ```html
169
- <a routerLink="/projects/42">Project 42</a>
170
- <a [routerLink]="['/', 'projects', projectId]"></a>
189
+ <a routerLink="/projects/42">Project 42</a> <a [routerLink]="['/', 'projects', projectId]"></a>
171
190
  ```
172
191
 
173
-
174
192
  ## Augmentation Placement
175
193
 
176
194
  Keep the augmentation in a `.d.ts` that is included by `tsconfig.app.json` (`include` array). If you see `Path` still as `never`, ensure:
195
+
177
196
  - The augmentation file is included.
178
197
  - The `routes` constant is `as const satisfies Routes`.
179
198
  - No circular import (augmentation file should only import the routes, nothing else runtime-heavy).
180
199
 
181
200
  ## Limitations & Tradeoffs
182
201
 
183
- | Concern | Status / Rationale |
184
- |---------|---------------------------------------------------------------------------------------|
202
+ | Concern | Status / Rationale |
203
+ | ---------------------------------- | ------------------------------------------------------------------------------------- |
185
204
  | `relativeTo` (relative navigation) | Not supported – all inferred `Path` / `Commands` are absolute. Use absolute commands. |
186
205
 
187
-
188
206
  ## ESLint Recommendation (Optional)
189
207
 
190
208
  You can use `angular-typed-router-eslint` plugin to forbid untyped navigation calls.
191
209
 
192
210
  ## Troubleshooting
193
211
 
194
- | Symptom | Fix |
195
- |---------|-----|
196
- | `Path` is `never` | Check augmentation file is included in tsconfig. |
212
+ | Symptom | Fix |
213
+ | --------------------- | -------------------------------------------------------------- |
214
+ | `Path` is `never` | Check augmentation file is included in tsconfig. |
197
215
  | Lazy children missing | Ensure promise resolves to `Route[]` or `{ routes: Route[] }`. |
198
216
 
199
217
  ## Contributing
@@ -205,4 +223,5 @@ PRs welcome.
205
223
  MIT
206
224
 
207
225
  ---
226
+
208
227
  Happy routing.
package/index.d.ts CHANGED
@@ -16,10 +16,10 @@ declare const __rootCatchAll: unique symbol;
16
16
  type RootCatchAll = string & {
17
17
  readonly [__rootCatchAll]: true;
18
18
  };
19
- interface AllowedRouteParamValues {
19
+ interface RouteParamTypes {
20
20
  }
21
- type AllowedRouteParamValue = AllowedRouteParamValues[keyof AllowedRouteParamValues];
22
- type _ReplaceParams<S extends string> = S extends `${infer Start}:${string}/${infer Rest}` ? `${Start}${AllowedRouteParamValue}/${_ReplaceParams<Rest>}` : S extends `${infer Start}:${string}` ? `${Start}${AllowedRouteParamValue}` : S extends `${infer Start}**/${infer Rest}` ? `${Start}${string}/${_ReplaceParams<Rest>}` : S extends `${infer Start}**` ? Start extends '' ? RootCatchAll : `${Start}${string}` : S;
21
+ type ParamValueType<Name extends string> = Name extends keyof RouteParamTypes ? RouteParamTypes[Name] : never;
22
+ type _ReplaceParams<S extends string> = S extends `${infer Start}:${infer Param}/${infer Rest}` ? `${Start}${ParamValueType<Param>}/${_ReplaceParams<Rest>}` : S extends `${infer Start}:${infer Param}` ? `${Start}${ParamValueType<Param>}` : S extends `${infer Start}**/${infer Rest}` ? `${Start}${string}/${_ReplaceParams<Rest>}` : S extends `${infer Start}**` ? Start extends '' ? RootCatchAll : `${Start}${string}` : S;
23
23
  type ReplaceParams<S extends string> = _ReplaceParams<S>;
24
24
 
25
25
  type PathOrEmptyString<R extends Route> = R['path'] extends string ? R['path'] : '';
@@ -65,4 +65,4 @@ declare class TypedRouterLink extends RouterLink {
65
65
  }
66
66
 
67
67
  export { TypedRouter, TypedRouterLink };
68
- export type { AllowedRouteParamValues, Commands, ExtractPathsFromRoutes, Path, UserTypedRoutes };
68
+ export type { Commands, ExtractPathsFromRoutes, Path, RouteParamTypes, UserTypedRoutes };
package/package.json CHANGED
@@ -1,11 +1,20 @@
1
1
  {
2
2
  "name": "angular-typed-router",
3
- "version": "0.1.1-1",
3
+ "version": "0.1.1-3",
4
4
  "peerDependencies": {
5
- "@angular/common": "^20.2.0",
6
- "@angular/core": "^20.2.0"
5
+ "@angular/common": "^20.0.0",
6
+ "@angular/core": "^20.0.0"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/dominicbachmann/angular-typed-router.git",
11
+ "directory": "libs/typed-router"
7
12
  },
8
13
  "sideEffects": false,
14
+ "schematics": "./schematics/collection.json",
15
+ "ng-add": {
16
+ "save": "dependencies"
17
+ },
9
18
  "module": "fesm2022/angular-typed-router.mjs",
10
19
  "typings": "index.d.ts",
11
20
  "exports": {
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
3
+ "schematics": {
4
+ "ng-add": {
5
+ "description": "Add angular-typed-router to the project.",
6
+ "factory": "./ng-add/index#ngAdd",
7
+ "schema": "./ng-add/schema.json"
8
+ },
9
+ "migrate": {
10
+ "description": "Migrate from @angular/router to angular-typed-router",
11
+ "factory": "./migrate/index#migrate",
12
+ "schema": "./migrate/schema.json"
13
+ }
14
+ }
15
+ }
@@ -0,0 +1 @@
1
+ import './collection.json';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // This import only ensures that the collection is included in the build
4
+ require("./collection.json");
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/typed-router/schematics/index.ts"],"names":[],"mappings":";;AAAA,wEAAwE;AACxE,6BAA2B"}
@@ -0,0 +1,3 @@
1
+ import { Rule } from '@angular-devkit/schematics';
2
+ import { Schema } from './schema';
3
+ export declare function migrate(options: Schema): Rule;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrate = migrate;
4
+ const schematics_1 = require("@angular-devkit/schematics");
5
+ const handle_uncommitted_changes_1 = require("../utils/handle-uncommitted-changes");
6
+ const replace_usages_1 = require("./steps/replace-usages");
7
+ function migrate(options) {
8
+ return (0, schematics_1.chain)([(0, handle_uncommitted_changes_1.handleUncommittedChanges)(options), (0, replace_usages_1.replaceUsages)(options)]);
9
+ }
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/typed-router/schematics/migrate/index.ts"],"names":[],"mappings":";;AAKA,0BAEC;AAPD,2DAAyD;AAEzD,oFAA+E;AAC/E,2DAAuD;AAEvD,SAAgB,OAAO,CAAC,OAAe;IACrC,OAAO,IAAA,kBAAK,EAAC,CAAC,IAAA,qDAAwB,EAAC,OAAO,CAAC,EAAE,IAAA,8BAAa,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,16 @@
1
+ import './schema.json';
2
+ export interface Schema {
3
+ /**
4
+ * The name of the project to migrate.
5
+ */
6
+ project: string;
7
+ /**
8
+ * Path to the project source files.
9
+ * If not specified, the project source root will be used.
10
+ */
11
+ path?: string;
12
+ /**
13
+ * Whether to allow the migration to run even if there are uncommitted Git changes.
14
+ */
15
+ allowDirty?: boolean;
16
+ }
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("./schema.json");
4
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../../libs/typed-router/schematics/migrate/schema.ts"],"names":[],"mappings":";;AAAA,yBAAuB"}
@@ -0,0 +1,26 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "migrate-to-angular-typed-router",
4
+ "title": "Angular Typed Router Migration",
5
+ "type": "object",
6
+ "properties": {
7
+ "project": {
8
+ "type": "string",
9
+ "description": "The name of the project to migrate.",
10
+ "$default": {
11
+ "$source": "projectName"
12
+ }
13
+ },
14
+ "path": {
15
+ "type": "string",
16
+ "description": "Path to the project source files. If not specified, the project source root will be used.",
17
+ "format": "path"
18
+ },
19
+ "allowDirty": {
20
+ "type": "boolean",
21
+ "description": "Whether to allow the migration to run even if there are uncommitted Git changes.",
22
+ "default": false
23
+ }
24
+ },
25
+ "required": ["project"]
26
+ }
@@ -0,0 +1,3 @@
1
+ import { Schema } from '../schema';
2
+ import { SchematicContext, Tree } from '@angular-devkit/schematics';
3
+ export declare const replaceUsages: (options: Schema) => (tree: Tree, context: SchematicContext) => Promise<import("@angular-devkit/schematics/src/tree/interface").Tree>;
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.replaceUsages = void 0;
13
+ const schematics_1 = require("@angular-devkit/schematics");
14
+ const utility_1 = require("@schematics/angular/utility");
15
+ const ts = require("typescript");
16
+ const replaceUsages = (options) => (tree, context) => __awaiter(void 0, void 0, void 0, function* () {
17
+ const workspace = yield (0, utility_1.readWorkspace)(tree);
18
+ const project = workspace.projects.get(options.project);
19
+ if (!project) {
20
+ throw new schematics_1.SchematicsException(`Project "${options.project}" not found.`);
21
+ }
22
+ const sourceRoot = options.path || project.sourceRoot;
23
+ if (!sourceRoot) {
24
+ throw new schematics_1.SchematicsException(`Could not determine source root for project "${options.project}".`);
25
+ }
26
+ context.logger.info(`Migrating Angular Router imports in ${sourceRoot}...`);
27
+ const importMappings = [
28
+ {
29
+ oldImport: 'Router',
30
+ newImport: 'TypedRouter',
31
+ fromModule: '@angular/router',
32
+ toModule: 'angular-typed-router',
33
+ },
34
+ {
35
+ oldImport: 'RouterLink',
36
+ newImport: 'TypedRouterLink',
37
+ fromModule: '@angular/router',
38
+ toModule: 'angular-typed-router',
39
+ },
40
+ ];
41
+ const tsFiles = getTypeScriptFiles(tree, sourceRoot);
42
+ for (const filePath of tsFiles) {
43
+ migrateFile(tree, filePath, importMappings);
44
+ }
45
+ context.logger.info('Migration complete!');
46
+ return tree;
47
+ });
48
+ exports.replaceUsages = replaceUsages;
49
+ function getTypeScriptFiles(tree, rootPath) {
50
+ const files = [];
51
+ function getFilesRecursively(path) {
52
+ const dir = tree.getDir(path);
53
+ const entries = dir.subfiles;
54
+ for (const entry of entries) {
55
+ if (entry.endsWith('.ts') &&
56
+ !entry.endsWith('.d.ts') &&
57
+ !entry.endsWith('.spec.ts')) {
58
+ files.push(`${path}/${entry}`);
59
+ }
60
+ }
61
+ const directories = dir.subdirs;
62
+ for (const directory of directories) {
63
+ getFilesRecursively(`${path}/${directory}`);
64
+ }
65
+ }
66
+ getFilesRecursively(rootPath);
67
+ return files;
68
+ }
69
+ function migrateFile(tree, filePath, mappings) {
70
+ const content = tree.read(filePath);
71
+ if (!content) {
72
+ return;
73
+ }
74
+ const sourceText = content.toString('utf-8');
75
+ const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true);
76
+ let updatedSourceText = sourceText;
77
+ let hasChanged = false;
78
+ const importsToAdd = new Map();
79
+ const importsToRemove = new Set();
80
+ const componentImportsToReplace = new Map();
81
+ sourceFile.forEachChild((node) => {
82
+ if (ts.isImportDeclaration(node)) {
83
+ const moduleSpecifier = node.moduleSpecifier;
84
+ if (ts.isStringLiteral(moduleSpecifier)) {
85
+ const moduleName = moduleSpecifier.text;
86
+ if (moduleName === '@angular/router') {
87
+ if (node.importClause && node.importClause.namedBindings) {
88
+ const namedBindings = node.importClause.namedBindings;
89
+ if (ts.isNamedImports(namedBindings)) {
90
+ const importSpecifiers = namedBindings.elements;
91
+ for (const specifier of importSpecifiers) {
92
+ const importName = specifier.name.text;
93
+ const mapping = mappings.find((m) => m.oldImport === importName);
94
+ if (mapping) {
95
+ if (!importsToAdd.has(mapping.toModule)) {
96
+ importsToAdd.set(mapping.toModule, new Set());
97
+ }
98
+ importsToAdd.get(mapping.toModule).add(mapping.newImport);
99
+ importsToRemove.add(importName);
100
+ hasChanged = true;
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+ }
108
+ });
109
+ if (hasChanged || componentImportsToReplace.size > 0) {
110
+ updatedSourceText = processImports(sourceFile, updatedSourceText, importsToRemove);
111
+ updatedSourceText = addNewImports(updatedSourceText, importsToAdd);
112
+ const updatedSourceFile = ts.createSourceFile(filePath, updatedSourceText, ts.ScriptTarget.Latest, true);
113
+ updatedSourceText = replaceAllClassReferences(updatedSourceFile, updatedSourceText, mappings);
114
+ tree.overwrite(filePath, updatedSourceText);
115
+ }
116
+ }
117
+ function processImports(sourceFile, sourceText, importsToRemove) {
118
+ let updatedText = sourceText;
119
+ sourceFile.forEachChild((node) => {
120
+ if (ts.isImportDeclaration(node)) {
121
+ const moduleSpecifier = node.moduleSpecifier;
122
+ if (ts.isStringLiteral(moduleSpecifier) &&
123
+ moduleSpecifier.text === '@angular/router') {
124
+ if (node.importClause && node.importClause.namedBindings) {
125
+ const namedBindings = node.importClause.namedBindings;
126
+ if (ts.isNamedImports(namedBindings)) {
127
+ const importSpecifiers = namedBindings.elements;
128
+ const remainingImports = importSpecifiers.filter((specifier) => !importsToRemove.has(specifier.name.text));
129
+ if (remainingImports.length !== importSpecifiers.length) {
130
+ if (remainingImports.length === 0) {
131
+ updatedText =
132
+ updatedText.substring(0, node.getStart()) +
133
+ updatedText.substring(node.getEnd());
134
+ }
135
+ else {
136
+ const namedBindingsStart = namedBindings.getStart();
137
+ const namedBindingsEnd = namedBindings.getEnd();
138
+ const newNamedBindings = '{ ' +
139
+ remainingImports
140
+ .map((specifier) => specifier.getText())
141
+ .join(', ') +
142
+ ' }';
143
+ updatedText =
144
+ updatedText.substring(0, namedBindingsStart) +
145
+ newNamedBindings +
146
+ updatedText.substring(namedBindingsEnd);
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+ }
153
+ });
154
+ return updatedText;
155
+ }
156
+ function addNewImports(sourceText, importsToAdd) {
157
+ let updatedText = sourceText;
158
+ for (const [moduleName, importNames] of Array.from(importsToAdd.entries())) {
159
+ const importStatement = `import { ${Array.from(importNames).join(', ')} } from '${moduleName}';\n`;
160
+ let insertPosition = 0;
161
+ const importRegex = /^import .* from .*;$/gm;
162
+ let match;
163
+ while ((match = importRegex.exec(updatedText)) !== null) {
164
+ insertPosition = match.index + match[0].length;
165
+ }
166
+ updatedText =
167
+ updatedText.substring(0, insertPosition) +
168
+ '\n' +
169
+ importStatement +
170
+ updatedText.substring(insertPosition);
171
+ }
172
+ return updatedText;
173
+ }
174
+ function replaceAllClassReferences(sourceFile, sourceText, mappings) {
175
+ const replacementMap = new Map(mappings.map((m) => [m.oldImport, m.newImport]));
176
+ const replacements = [];
177
+ function visitNode(node) {
178
+ if (ts.isIdentifier(node)) {
179
+ const replacement = replacementMap.get(node.text);
180
+ if (replacement) {
181
+ let parent = node.parent;
182
+ let isPartOfImport = false;
183
+ while (parent) {
184
+ if (ts.isImportDeclaration(parent) || ts.isImportSpecifier(parent)) {
185
+ isPartOfImport = true;
186
+ break;
187
+ }
188
+ parent = parent.parent;
189
+ }
190
+ if (!isPartOfImport) {
191
+ replacements.push({
192
+ start: node.getStart(sourceFile),
193
+ end: node.getEnd(),
194
+ newText: replacement,
195
+ });
196
+ }
197
+ }
198
+ }
199
+ ts.forEachChild(node, visitNode);
200
+ }
201
+ visitNode(sourceFile);
202
+ let result = sourceText;
203
+ for (const { start, end, newText } of replacements.sort((a, b) => b.start - a.start)) {
204
+ result = result.substring(0, start) + newText + result.substring(end);
205
+ }
206
+ return result;
207
+ }
208
+ //# sourceMappingURL=replace-usages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replace-usages.js","sourceRoot":"","sources":["../../../../../../libs/typed-router/schematics/migrate/steps/replace-usages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Rule } from '@angular-devkit/schematics';
2
+ import { Schema } from './schema';
3
+ export declare function ngAdd(options: Schema): Rule;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ngAdd = ngAdd;
4
+ const schematics_1 = require("@angular-devkit/schematics");
5
+ const update_route_declarations_1 = require("./steps/update-route-declarations");
6
+ const run_migrate_1 = require("./steps/run-migrate");
7
+ const add_declaration_file_1 = require("./steps/add-declaration-file");
8
+ const handle_uncommitted_changes_1 = require("../utils/handle-uncommitted-changes");
9
+ const inform_user_1 = require("./steps/inform-user");
10
+ function ngAdd(options) {
11
+ if (!options.project) {
12
+ throw new Error('Project name is required.');
13
+ }
14
+ return (0, schematics_1.chain)([
15
+ (0, handle_uncommitted_changes_1.handleUncommittedChanges)(options),
16
+ (0, add_declaration_file_1.addDeclarationFile)(options),
17
+ (0, update_route_declarations_1.updateRouteDeclarations)(options),
18
+ (0, run_migrate_1.runMigrate)(options),
19
+ (0, inform_user_1.informUser)(),
20
+ ]);
21
+ }
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/typed-router/schematics/ng-add/index.ts"],"names":[],"mappings":";;AAQA,sBAYC;AApBD,2DAAyD;AAEzD,iFAA4E;AAC5E,qDAAiD;AACjD,uEAAkE;AAClE,oFAA+E;AAC/E,qDAAiD;AAEjD,SAAgB,KAAK,CAAC,OAAe;IACnC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,IAAA,kBAAK,EAAC;QACX,IAAA,qDAAwB,EAAC,OAAO,CAAC;QACjC,IAAA,yCAAkB,EAAC,OAAO,CAAC;QAC3B,IAAA,mDAAuB,EAAC,OAAO,CAAC;QAChC,IAAA,wBAAU,EAAC,OAAO,CAAC;QACnB,IAAA,wBAAU,GAAE;KACb,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,18 @@
1
+ import './schema.json';
2
+ /**
3
+ * Options available to the ng-add schematic.
4
+ */
5
+ export interface Schema {
6
+ /**
7
+ * The name of the project to add angular-typed-router to.
8
+ */
9
+ project?: string;
10
+ /**
11
+ * Whether to allow the migration to run even if there are uncommitted Git changes.
12
+ */
13
+ allowDirty?: boolean;
14
+ /**
15
+ * Whether to run the migration to update existing imports from @angular/router to angular-typed-router.
16
+ */
17
+ migrate?: boolean;
18
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // This import only ensures that the schema is included in the build
4
+ require("./schema.json");
5
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../../libs/typed-router/schematics/ng-add/schema.ts"],"names":[],"mappings":";;AAAA,oEAAoE;AACpE,yBAAuB"}
@@ -0,0 +1,26 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "add-angular-typed-router",
4
+ "title": "Add angular-typed-router to an existing workspace",
5
+ "type": "object",
6
+ "properties": {
7
+ "project": {
8
+ "type": "string",
9
+ "description": "The name of the project to add angular-typed-router to.",
10
+ "$default": {
11
+ "$source": "projectName"
12
+ }
13
+ },
14
+ "allowDirty": {
15
+ "type": "boolean",
16
+ "description": "Whether to allow to run even if there are uncommitted Git changes.",
17
+ "default": false
18
+ },
19
+ "migrate": {
20
+ "type": "boolean",
21
+ "description": "Run migration to replace usages of RouterLink and Router with TypedRouterLink and TypedRouter.",
22
+ "default": false,
23
+ "x-prompt": "Would you like to replace usages of RouterLink and Router with TypedRouterLink and TypedRouter?"
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,3 @@
1
+ import { Schema } from '../schema';
2
+ import { SchematicContext, Tree } from '@angular-devkit/schematics';
3
+ export declare const addDeclarationFile: (options: Schema) => (host: Tree, context: SchematicContext) => Promise<void>;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.addDeclarationFile = void 0;
13
+ const utility_1 = require("@schematics/angular/utility");
14
+ const workspace_models_1 = require("@schematics/angular/utility/workspace-models");
15
+ const path_1 = require("path");
16
+ const json_file_1 = require("@schematics/angular/utility/json-file");
17
+ const addDeclarationFile = (options) => (host, context) => __awaiter(void 0, void 0, void 0, function* () {
18
+ var _a, _b, _c, _d;
19
+ const workspace = yield (0, utility_1.readWorkspace)(host);
20
+ const project = workspace.projects.get(options.project);
21
+ if (project &&
22
+ project.extensions['projectType'] === workspace_models_1.ProjectType.Application) {
23
+ const projectRoot = project.root;
24
+ const augmentationFileName = 'typed-router.d.ts';
25
+ const declarationFilePath = (0, path_1.join)(projectRoot, augmentationFileName);
26
+ // TODO: Check if app.routes.ts exists and if it has the correct export
27
+ const augmentationFileContent = `import type { routes } from './src/app/app.routes';
28
+
29
+ declare module 'angular-typed-router' {
30
+ interface UserTypedRoutes {
31
+ routes: typeof routes;
32
+ }
33
+ interface RouteParamTypes {
34
+
35
+ }
36
+ }
37
+ `;
38
+ host.create(declarationFilePath, augmentationFileContent);
39
+ const buildTsConfig = (_b = (_a = project === null || project === void 0 ? void 0 : project.targets.get('build')) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.tsConfig;
40
+ const testTsConfig = (_d = (_c = project === null || project === void 0 ? void 0 : project.targets.get('test')) === null || _c === void 0 ? void 0 : _c.options) === null || _d === void 0 ? void 0 : _d.tsConfig;
41
+ if (buildTsConfig && typeof buildTsConfig === 'string') {
42
+ addDeclarationFileToTsConfig(host, buildTsConfig, declarationFilePath);
43
+ }
44
+ if (testTsConfig && typeof testTsConfig === 'string') {
45
+ addDeclarationFileToTsConfig(host, testTsConfig, declarationFilePath);
46
+ }
47
+ }
48
+ else {
49
+ context.logger.warn(`Project "${options.project}" not found or is not an application.`);
50
+ }
51
+ });
52
+ exports.addDeclarationFile = addDeclarationFile;
53
+ function addDeclarationFileToTsConfig(host, tsConfigPath, declarationFilePath) {
54
+ if (host.exists(tsConfigPath)) {
55
+ const json = new json_file_1.JSONFile(host, tsConfigPath);
56
+ const includeArray = json.get(['include']) || [];
57
+ const relativePath = (0, path_1.relative)((0, path_1.dirname)(tsConfigPath), declarationFilePath);
58
+ if (!includeArray.includes(relativePath)) {
59
+ includeArray.push(relativePath);
60
+ json.modify(['include'], includeArray);
61
+ }
62
+ }
63
+ }
64
+ //# sourceMappingURL=add-declaration-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-declaration-file.js","sourceRoot":"","sources":["../../../../../../libs/typed-router/schematics/ng-add/steps/add-declaration-file.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,yDAA4D;AAC5D,mFAA2E;AAC3E,+BAA+C;AAC/C,qEAAiE;AAE1D,MAAM,kBAAkB,GAC7B,CAAC,OAAe,EAAE,EAAE,CAAC,CAAO,IAAU,EAAE,OAAyB,EAAE,EAAE;;IACnE,MAAM,SAAS,GAAG,MAAM,IAAA,uBAAa,EAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAQ,CAAC,CAAC;IACzD,IACE,OAAO;QACP,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK,8BAAW,CAAC,WAAW,EAC7D,CAAC;QACD,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;QACjC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;QACjD,MAAM,mBAAmB,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;QACpE,uEAAuE;QACvE,MAAM,uBAAuB,GAAG;;;;;;;;;;CAUrC,CAAC;QACI,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,uBAAuB,CAAC,CAAC;QAE1D,MAAM,aAAa,GAAG,MAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,0CAAE,OAAO,0CAAE,QAAQ,CAAC;QACvE,MAAM,YAAY,GAAG,MAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,0CAAE,OAAO,0CAAE,QAAQ,CAAC;QAErE,IAAI,aAAa,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;YACvD,4BAA4B,CAAC,IAAI,EAAE,aAAa,EAAE,mBAAmB,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;YACrD,4BAA4B,CAAC,IAAI,EAAE,YAAY,EAAE,mBAAmB,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,IAAI,CACjB,YAAY,OAAO,CAAC,OAAO,uCAAuC,CACnE,CAAC;IACJ,CAAC;AACH,CAAC,CAAA,CAAC;AAvCS,QAAA,kBAAkB,sBAuC3B;AAEJ,SAAS,4BAA4B,CACnC,IAAU,EACV,YAAoB,EACpB,mBAA2B;IAE3B,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,oBAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QAE9C,MAAM,YAAY,GAAI,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAc,IAAI,EAAE,CAAC;QAE/D,MAAM,YAAY,GAAG,IAAA,eAAQ,EAAC,IAAA,cAAO,EAAC,YAAY,CAAC,EAAE,mBAAmB,CAAC,CAAC;QAE1E,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACzC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,EAAE,YAAY,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { SchematicContext, Tree } from '@angular-devkit/schematics';
2
+ export declare const informUser: () => (host: Tree, context: SchematicContext) => import("@angular-devkit/schematics/src/tree/interface").Tree;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.informUser = void 0;
4
+ const informUser = () => (host, context) => {
5
+ context.logger.info('\n⚠️ IMPORTANT: Route Declaration Change Required ⚠️');
6
+ context.logger.info('We attempted to automatically update your route declarations.');
7
+ context.logger.info('Please verify that all route files now use the correct format:');
8
+ context.logger.info('FROM: export const routes: Routes = [];');
9
+ context.logger.info('TO: export const routes = [] as const satisfies Routes;');
10
+ context.logger.info('\nThis change is necessary for proper type inference of your routes.\n');
11
+ return host;
12
+ };
13
+ exports.informUser = informUser;
14
+ //# sourceMappingURL=inform-user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inform-user.js","sourceRoot":"","sources":["../../../../../../libs/typed-router/schematics/ng-add/steps/inform-user.ts"],"names":[],"mappings":";;;AAEO,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,CAAC,IAAU,EAAE,OAAyB,EAAE,EAAE;IACxE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;IAC5E,OAAO,CAAC,MAAM,CAAC,IAAI,CACjB,+DAA+D,CAChE,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,IAAI,CACjB,gEAAgE,CACjE,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IAC/D,OAAO,CAAC,MAAM,CAAC,IAAI,CACjB,2DAA2D,CAC5D,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,IAAI,CACjB,wEAAwE,CACzE,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAhBW,QAAA,UAAU,cAgBrB"}
@@ -0,0 +1,3 @@
1
+ import { SchematicContext, Tree } from '@angular-devkit/schematics';
2
+ import { Schema } from '../schema';
3
+ export declare const runMigrate: (options: Schema) => (host: Tree, context: SchematicContext) => import("@angular-devkit/schematics/src/tree/interface").Tree | import("@angular-devkit/schematics").Rule;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runMigrate = void 0;
4
+ const schematics_1 = require("@angular-devkit/schematics");
5
+ const runMigrate = (options) => (host, context) => {
6
+ if (options.migrate) {
7
+ context.logger.info('Running migration to angular-typed-router...');
8
+ return (0, schematics_1.schematic)('migrate', {
9
+ project: options.project,
10
+ allowDirty: options.allowDirty,
11
+ });
12
+ }
13
+ return host;
14
+ };
15
+ exports.runMigrate = runMigrate;
16
+ //# sourceMappingURL=run-migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-migrate.js","sourceRoot":"","sources":["../../../../../../libs/typed-router/schematics/ng-add/steps/run-migrate.ts"],"names":[],"mappings":";;;AAAA,2DAA+E;AAGxE,MAAM,UAAU,GACrB,CAAC,OAAe,EAAE,EAAE,CAAC,CAAC,IAAU,EAAE,OAAyB,EAAE,EAAE;IAC7D,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;QACpE,OAAO,IAAA,sBAAS,EAAC,SAAS,EAAE;YAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAVS,QAAA,UAAU,cAUnB"}
@@ -0,0 +1,3 @@
1
+ import { Rule } from '@angular-devkit/schematics';
2
+ import { Schema } from '../schema';
3
+ export declare const updateRouteDeclarations: (options: Schema) => Rule;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.updateRouteDeclarations = void 0;
13
+ const ts = require("typescript");
14
+ const path_1 = require("path");
15
+ const utility_1 = require("@schematics/angular/utility");
16
+ const updateRouteDeclarations = (options) => (tree, context) => __awaiter(void 0, void 0, void 0, function* () {
17
+ var _a;
18
+ const workspace = yield (0, utility_1.readWorkspace)(tree);
19
+ const project = workspace.projects.get(options.project);
20
+ if (!project)
21
+ return tree;
22
+ const routeFiles = findRouteFiles(tree, project.sourceRoot || (0, path_1.join)(project.root, 'src'));
23
+ for (const filePath of routeFiles) {
24
+ if (!tree.exists(filePath))
25
+ continue;
26
+ const sourceText = (_a = tree.read(filePath)) === null || _a === void 0 ? void 0 : _a.toString();
27
+ if (!sourceText)
28
+ continue;
29
+ const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true);
30
+ const result = transformRouteDeclarations(sourceFile, sourceText);
31
+ if (result.changed) {
32
+ context.logger.info(`Updated route declaration in ${filePath}`);
33
+ tree.overwrite(filePath, result.content);
34
+ }
35
+ }
36
+ return tree;
37
+ });
38
+ exports.updateRouteDeclarations = updateRouteDeclarations;
39
+ function findRouteFiles(tree, sourceRoot) {
40
+ const result = [];
41
+ // Look for common route file patterns
42
+ tree.getDir(sourceRoot).visit((filePath) => {
43
+ if (filePath.endsWith('.routes.ts') ||
44
+ (filePath.includes('routes') && filePath.endsWith('.ts'))) {
45
+ result.push(filePath);
46
+ }
47
+ });
48
+ return result;
49
+ }
50
+ function transformRouteDeclarations(sourceFile, sourceText) {
51
+ let changed = false;
52
+ const replacements = [];
53
+ function visit(node) {
54
+ // Look for variable declarations like "routes: Routes = [...]"
55
+ if (ts.isVariableDeclaration(node) &&
56
+ node.type &&
57
+ ts.isTypeReferenceNode(node.type) &&
58
+ node.type.typeName.getText() === 'Routes' &&
59
+ node.initializer &&
60
+ ts.isArrayLiteralExpression(node.initializer)) {
61
+ const variableName = node.name.getText();
62
+ const arrayText = node.initializer.getText();
63
+ replacements.push({
64
+ start: node.getStart(),
65
+ end: node.getEnd(),
66
+ newText: `${variableName} = ${arrayText} as const satisfies Routes`,
67
+ });
68
+ changed = true;
69
+ }
70
+ ts.forEachChild(node, visit);
71
+ }
72
+ visit(sourceFile);
73
+ let result = sourceText;
74
+ for (const { start, end, newText } of replacements.sort((a, b) => b.start - a.start)) {
75
+ result = result.substring(0, start) + newText + result.substring(end);
76
+ }
77
+ return { changed, content: result };
78
+ }
79
+ //# sourceMappingURL=update-route-declarations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-route-declarations.js","sourceRoot":"","sources":["../../../../../../libs/typed-router/schematics/ng-add/steps/update-route-declarations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const handleUncommittedChanges: (options: {
2
+ allowDirty?: boolean | undefined;
3
+ }) => () => void;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleUncommittedChanges = void 0;
4
+ const schematics_1 = require("@angular-devkit/schematics");
5
+ const child_process_1 = require("child_process");
6
+ const hasUncommittedChanges = () => {
7
+ try {
8
+ const gitVersionResult = (0, child_process_1.spawnSync)('git', ['--version']);
9
+ if (gitVersionResult.status !== 0) {
10
+ return false;
11
+ }
12
+ const gitRevParseResult = (0, child_process_1.spawnSync)('git', [
13
+ 'rev-parse',
14
+ '--is-inside-work-tree',
15
+ ]);
16
+ if (gitRevParseResult.status !== 0) {
17
+ return false;
18
+ }
19
+ const result = (0, child_process_1.spawnSync)('git', ['status', '--porcelain']);
20
+ if (result.status !== 0) {
21
+ throw new schematics_1.SchematicsException(`Failed to execute git status: ${result.stderr.toString()}`);
22
+ }
23
+ // If output is not empty, there are uncommitted changes
24
+ return result.stdout.toString().trim() !== '';
25
+ }
26
+ catch (error) {
27
+ throw new schematics_1.SchematicsException('Error checking Git status: ' + error.message);
28
+ }
29
+ };
30
+ const handleUncommittedChanges = (options) => {
31
+ return () => {
32
+ if (hasUncommittedChanges()) {
33
+ if (!options.allowDirty) {
34
+ throw new schematics_1.SchematicsException('Operation aborted due to uncommitted changes. ' +
35
+ 'Use --allow-dirty flag to bypass this check.');
36
+ }
37
+ }
38
+ };
39
+ };
40
+ exports.handleUncommittedChanges = handleUncommittedChanges;
41
+ //# sourceMappingURL=handle-uncommitted-changes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle-uncommitted-changes.js","sourceRoot":"","sources":["../../../../../libs/typed-router/schematics/utils/handle-uncommitted-changes.ts"],"names":[],"mappings":";;;AAAA,2DAAiE;AACjE,iDAA0C;AAE1C,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACjC,IAAI,CAAC;QACH,MAAM,gBAAgB,GAAG,IAAA,yBAAS,EAAC,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;QACzD,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,iBAAiB,GAAG,IAAA,yBAAS,EAAC,KAAK,EAAE;YACzC,WAAW;YACX,uBAAuB;SACxB,CAAC,CAAC;QACH,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,yBAAS,EAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;QAC3D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,gCAAmB,CAC3B,iCAAiC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAC5D,CAAC;QACJ,CAAC;QAED,wDAAwD;QACxD,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,gCAAmB,CAC3B,6BAA6B,GAAI,KAAe,CAAC,OAAO,CACzD,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEK,MAAM,wBAAwB,GAAG,CAAC,OAExC,EAAE,EAAE;IACH,OAAO,GAAG,EAAE;QACV,IAAI,qBAAqB,EAAE,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;gBACxB,MAAM,IAAI,gCAAmB,CAC3B,gDAAgD;oBAC9C,8CAA8C,CACjD,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAbW,QAAA,wBAAwB,4BAanC"}