@angular-devkit/core 14.0.0-next.9 → 14.0.0-rc.2

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/node/host.js CHANGED
@@ -111,21 +111,21 @@ class NodeJsAsyncHost {
111
111
  obs.next({
112
112
  path: (0, src_1.normalize)(path),
113
113
  time: new Date(),
114
- type: 0 /* Changed */,
114
+ type: 0 /* virtualFs.HostWatchEventType.Changed */,
115
115
  });
116
116
  })
117
117
  .on('add', (path) => {
118
118
  obs.next({
119
119
  path: (0, src_1.normalize)(path),
120
120
  time: new Date(),
121
- type: 1 /* Created */,
121
+ type: 1 /* virtualFs.HostWatchEventType.Created */,
122
122
  });
123
123
  })
124
124
  .on('unlink', (path) => {
125
125
  obs.next({
126
126
  path: (0, src_1.normalize)(path),
127
127
  time: new Date(),
128
- type: 2 /* Deleted */,
128
+ type: 2 /* virtualFs.HostWatchEventType.Deleted */,
129
129
  });
130
130
  });
131
131
  return () => watcher.close();
@@ -209,21 +209,21 @@ class NodeJsSyncHost {
209
209
  obs.next({
210
210
  path: (0, src_1.normalize)(path),
211
211
  time: new Date(),
212
- type: 0 /* Changed */,
212
+ type: 0 /* virtualFs.HostWatchEventType.Changed */,
213
213
  });
214
214
  })
215
215
  .on('add', (path) => {
216
216
  obs.next({
217
217
  path: (0, src_1.normalize)(path),
218
218
  time: new Date(),
219
- type: 1 /* Created */,
219
+ type: 1 /* virtualFs.HostWatchEventType.Created */,
220
220
  });
221
221
  })
222
222
  .on('unlink', (path) => {
223
223
  obs.next({
224
224
  path: (0, src_1.normalize)(path),
225
225
  time: new Date(),
226
- type: 2 /* Deleted */,
226
+ type: 2 /* virtualFs.HostWatchEventType.Deleted */,
227
227
  });
228
228
  });
229
229
  return () => watcher.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular-devkit/core",
3
- "version": "14.0.0-next.9",
3
+ "version": "14.0.0-rc.2",
4
4
  "description": "Angular DevKit - Core Utility Library",
5
5
  "main": "src/index.js",
6
6
  "typings": "src/index.d.ts",
@@ -15,8 +15,7 @@
15
15
  "dependencies": {
16
16
  "ajv-formats": "2.1.1",
17
17
  "ajv": "8.11.0",
18
- "fast-json-stable-stringify": "2.1.0",
19
- "magic-string": "0.26.1",
18
+ "jsonc-parser": "3.0.0",
20
19
  "rxjs": "6.6.7",
21
20
  "source-map": "0.7.3"
22
21
  },
@@ -27,7 +27,7 @@ function deepCopy(value) {
27
27
  for (const key of Object.getOwnPropertyNames(valueCasted)) {
28
28
  copy[key] = deepCopy(valueCasted[key]);
29
29
  }
30
- valueCasted[copySymbol] = undefined;
30
+ delete valueCasted[copySymbol];
31
31
  return copy;
32
32
  }
33
33
  else {
@@ -71,7 +71,7 @@ class SimpleMemoryHost {
71
71
  maybeWatcher.forEach((watcher) => {
72
72
  const [options, subject] = watcher;
73
73
  subject.next({ path, time, type });
74
- if (!options.persistent && type == 2 /* Deleted */) {
74
+ if (!options.persistent && type == 2 /* HostWatchEventType.Deleted */) {
75
75
  subject.complete();
76
76
  this._watchers.delete(currentPath);
77
77
  }
@@ -88,7 +88,7 @@ class SimpleMemoryHost {
88
88
  return;
89
89
  }
90
90
  subject.next({ path, time, type });
91
- if (!options.persistent && type == 2 /* Deleted */) {
91
+ if (!options.persistent && type == 2 /* HostWatchEventType.Deleted */) {
92
92
  subject.complete();
93
93
  this._watchers.delete(currentPath);
94
94
  }
@@ -127,7 +127,7 @@ class SimpleMemoryHost {
127
127
  // Create the stats.
128
128
  const stats = this._newFileStats(content, old);
129
129
  this._cache.set(path, stats);
130
- this._updateWatchers(path, old ? 0 /* Changed */ : 1 /* Created */);
130
+ this._updateWatchers(path, old ? 0 /* HostWatchEventType.Changed */ : 1 /* HostWatchEventType.Created */);
131
131
  }
132
132
  _read(path) {
133
133
  path = this._toAbsolute(path);
@@ -157,7 +157,7 @@ class SimpleMemoryHost {
157
157
  else {
158
158
  this._cache.delete(path);
159
159
  }
160
- this._updateWatchers(path, 2 /* Deleted */);
160
+ this._updateWatchers(path, 2 /* HostWatchEventType.Deleted */);
161
161
  }
162
162
  _rename(from, to) {
163
163
  from = this._toAbsolute(from);
@@ -204,7 +204,7 @@ class SimpleMemoryHost {
204
204
  this._cache.set(to, content);
205
205
  }
206
206
  }
207
- this._updateWatchers(from, 3 /* Renamed */);
207
+ this._updateWatchers(from, 3 /* HostWatchEventType.Renamed */);
208
208
  }
209
209
  _list(path) {
210
210
  path = this._toAbsolute(path);
@@ -23,7 +23,7 @@ export interface TargetDefinition {
23
23
  defaultConfiguration?: string;
24
24
  builder: string;
25
25
  }
26
- export declare type DefinitionCollectionListener<V extends object> = (name: string, action: 'add' | 'remove' | 'replace', newValue: V | undefined, oldValue: V | undefined, collection: DefinitionCollection<V>) => void;
26
+ export declare type DefinitionCollectionListener<V extends object> = (name: string, newValue: V | undefined, collection: DefinitionCollection<V>) => void;
27
27
  declare class DefinitionCollection<V extends object> implements ReadonlyMap<string, V> {
28
28
  private _listener?;
29
29
  private _map;
@@ -14,18 +14,19 @@ class DefinitionCollection {
14
14
  this._map = new Map(initial && Object.entries(initial));
15
15
  }
16
16
  delete(key) {
17
- const value = this._map.get(key);
17
+ var _a;
18
18
  const result = this._map.delete(key);
19
- if (result && value !== undefined && this._listener) {
20
- this._listener(key, 'remove', undefined, value, this);
19
+ if (result) {
20
+ (_a = this._listener) === null || _a === void 0 ? void 0 : _a.call(this, key, undefined, this);
21
21
  }
22
22
  return result;
23
23
  }
24
24
  set(key, value) {
25
- const existing = this.get(key);
26
- this._map.set(key, value);
27
- if (this._listener) {
28
- this._listener(key, existing !== undefined ? 'replace' : 'add', value, existing, this);
25
+ var _a;
26
+ const updatedValue = value !== this.get(key);
27
+ if (updatedValue) {
28
+ this._map.set(key, value);
29
+ (_a = this._listener) === null || _a === void 0 ? void 0 : _a.call(this, key, value, this);
29
30
  }
30
31
  return this;
31
32
  }
@@ -5,8 +5,8 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
+ import { JSONPath, Node } from 'jsonc-parser';
8
9
  import { JsonValue } from '../../json';
9
- import { JsonAstArray, JsonAstKeyValue, JsonAstNode, JsonAstObject } from '../../json/parser_ast';
10
10
  import { ProjectDefinition, TargetDefinition, WorkspaceDefinition } from '../definitions';
11
11
  export declare const JsonWorkspaceSymbol: unique symbol;
12
12
  export interface JsonWorkspaceDefinition extends WorkspaceDefinition {
@@ -19,23 +19,22 @@ interface ChangeValues {
19
19
  projectcollection: Iterable<[string, ProjectDefinition]>;
20
20
  targetcollection: Iterable<[string, TargetDefinition]>;
21
21
  }
22
- export interface JsonChange<T extends keyof ChangeValues = keyof ChangeValues> {
23
- op: T extends 'json' | 'project' | 'target' ? 'add' | 'remove' | 'replace' : 'add';
24
- path: string;
25
- node: JsonAstNode | JsonAstKeyValue;
26
- value?: ChangeValues[T];
27
- type: T;
22
+ export interface JsonChange {
23
+ value?: unknown;
24
+ type?: keyof ChangeValues;
25
+ jsonPath: string[];
28
26
  }
29
27
  export declare class JsonWorkspaceMetadata {
30
28
  readonly filePath: string;
31
- readonly ast: JsonAstObject;
29
+ private readonly ast;
32
30
  readonly raw: string;
33
- readonly changes: JsonChange[];
34
- constructor(filePath: string, ast: JsonAstObject, raw: string);
31
+ readonly changes: Map<string, JsonChange>;
32
+ hasLegacyTargetsName: boolean;
33
+ constructor(filePath: string, ast: Node, raw: string);
35
34
  get hasChanges(): boolean;
36
35
  get changeCount(): number;
37
- findChangesForPath(path: string): JsonChange[];
38
- addChange<T extends keyof ChangeValues = keyof ChangeValues>(op: 'add' | 'remove' | 'replace', path: string, node: JsonAstArray | JsonAstObject | JsonAstKeyValue, value?: ChangeValues[T], type?: T): void;
39
- reset(): void;
36
+ getNodeValueFromAst(path: JSONPath): unknown;
37
+ findChangesForPath(path: string): JsonChange | undefined;
38
+ addChange<T extends keyof ChangeValues = keyof ChangeValues>(jsonPath: string[], value: ChangeValues[T] | undefined, type?: T): void;
40
39
  }
41
40
  export {};
@@ -8,40 +8,49 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.JsonWorkspaceMetadata = exports.JsonWorkspaceSymbol = void 0;
11
+ const jsonc_parser_1 = require("jsonc-parser");
11
12
  exports.JsonWorkspaceSymbol = Symbol.for('@angular/core:workspace-json');
13
+ function escapeKey(key) {
14
+ return key.replace('~', '~0').replace('/', '~1');
15
+ }
12
16
  class JsonWorkspaceMetadata {
13
17
  constructor(filePath, ast, raw) {
14
18
  this.filePath = filePath;
15
19
  this.ast = ast;
16
20
  this.raw = raw;
17
- this.changes = [];
21
+ this.changes = new Map();
22
+ this.hasLegacyTargetsName = true;
18
23
  }
19
24
  get hasChanges() {
20
- return this.changes.length > 0;
25
+ return this.changes.size > 0;
21
26
  }
22
27
  get changeCount() {
23
- return this.changes.length;
28
+ return this.changes.size;
29
+ }
30
+ getNodeValueFromAst(path) {
31
+ const node = (0, jsonc_parser_1.findNodeAtLocation)(this.ast, path);
32
+ return node && (0, jsonc_parser_1.getNodeValue)(node);
24
33
  }
25
34
  findChangesForPath(path) {
26
- return this.changes.filter((c) => c.path === path);
35
+ return this.changes.get(path);
27
36
  }
28
- addChange(op, path, node, value, type) {
29
- // Remove redundant operations
30
- if (op === 'remove' || op === 'replace') {
31
- for (let i = this.changes.length - 1; i >= 0; --i) {
32
- const currentPath = this.changes[i].path;
33
- if (currentPath === path || currentPath.startsWith(path + '/')) {
34
- if (op === 'replace' && currentPath === path && this.changes[i].op === 'add') {
35
- op = 'add';
36
- }
37
- this.changes.splice(i, 1);
38
- }
37
+ addChange(jsonPath, value, type) {
38
+ let currentPath = '';
39
+ for (let index = 0; index < jsonPath.length - 1; index++) {
40
+ currentPath = currentPath + '/' + escapeKey(jsonPath[index]);
41
+ if (this.changes.has(currentPath)) {
42
+ // Ignore changes on children as parent is updated.
43
+ return;
39
44
  }
40
45
  }
41
- this.changes.push({ op, path, node, value, type: op === 'remove' || !type ? 'json' : type });
42
- }
43
- reset() {
44
- this.changes.length = 0;
46
+ const pathKey = '/' + jsonPath.map((k) => escapeKey(k)).join('/');
47
+ for (const key of this.changes.keys()) {
48
+ if (key.startsWith(pathKey + '/')) {
49
+ // changes on the same or child paths are redundant.
50
+ this.changes.delete(key);
51
+ }
52
+ }
53
+ this.changes.set(pathKey, { jsonPath, type, value });
45
54
  }
46
55
  }
47
56
  exports.JsonWorkspaceMetadata = JsonWorkspaceMetadata;
@@ -8,7 +8,8 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.readJsonWorkspace = void 0;
11
- const parser_1 = require("../../json/parser");
11
+ const jsonc_parser_1 = require("jsonc-parser");
12
+ const utils_1 = require("../../json/utils");
12
13
  const definitions_1 = require("../definitions");
13
14
  const metadata_1 = require("./metadata");
14
15
  const utilities_1 = require("./utilities");
@@ -17,18 +18,18 @@ async function readJsonWorkspace(path, host) {
17
18
  if (raw === undefined) {
18
19
  throw new Error('Unable to read workspace file.');
19
20
  }
20
- const ast = (0, parser_1.parseJsonAst)(raw, parser_1.JsonParseMode.Loose);
21
- if (ast.kind !== 'object') {
21
+ const ast = (0, jsonc_parser_1.parseTree)(raw, undefined, { allowTrailingComma: true, disallowComments: false });
22
+ if ((ast === null || ast === void 0 ? void 0 : ast.type) !== 'object' || !ast.children) {
22
23
  throw new Error('Invalid workspace file - expected JSON object.');
23
24
  }
24
25
  // Version check
25
- const versionNode = ast.properties.find((pair) => pair.key.value === 'version');
26
+ const versionNode = (0, jsonc_parser_1.findNodeAtLocation)(ast, ['version']);
26
27
  if (!versionNode) {
27
28
  throw new Error('Unknown format - version specifier not found.');
28
29
  }
29
- const formatVersion = versionNode.value.value;
30
- if (formatVersion !== 1) {
31
- throw new Error(`Invalid format version detected - Expected:[ 1 ] Found: [ ${formatVersion} ]`);
30
+ const version = versionNode.value;
31
+ if (version !== 1) {
32
+ throw new Error(`Invalid format version detected - Expected:[ 1 ] Found: [ ${version} ]`);
32
33
  }
33
34
  const context = {
34
35
  host,
@@ -51,38 +52,38 @@ const specialProjectExtensions = ['cli', 'schematics', 'projectType'];
51
52
  function parseWorkspace(workspaceNode, context) {
52
53
  const jsonMetadata = context.metadata;
53
54
  let projects;
54
- let projectsNode;
55
55
  let extensions;
56
56
  if (!context.trackChanges) {
57
57
  extensions = Object.create(null);
58
58
  }
59
- for (const { key, value } of workspaceNode.properties) {
60
- const name = key.value;
59
+ // TODO: `getNodeValue` - looks potentially expensive since it walks the whole tree and instantiates the full object structure each time.
60
+ // Might be something to look at moving forward to optimize.
61
+ const workspaceNodeValue = (0, jsonc_parser_1.getNodeValue)(workspaceNode);
62
+ for (const [name, value] of Object.entries(workspaceNodeValue)) {
61
63
  if (name === '$schema' || name === 'version') {
62
64
  // skip
63
65
  }
64
66
  else if (name === 'projects') {
65
- if (value.kind !== 'object') {
67
+ const nodes = (0, jsonc_parser_1.findNodeAtLocation)(workspaceNode, ['projects']);
68
+ if (!(0, utils_1.isJsonObject)(value) || !nodes) {
66
69
  context.error('Invalid "projects" field found; expected an object.', value);
67
70
  continue;
68
71
  }
69
- projectsNode = value;
70
- projects = parseProjectsObject(value, context);
72
+ projects = parseProjectsObject(nodes, context);
71
73
  }
72
74
  else {
73
75
  if (!specialWorkspaceExtensions.includes(name) && !/^[a-z]{1,3}-.*/.test(name)) {
74
- context.warn(`Project extension with invalid name found.`, key);
76
+ context.warn(`Project extension with invalid name found.`, name);
75
77
  }
76
78
  if (extensions) {
77
- extensions[name] = value.value;
79
+ extensions[name] = value;
78
80
  }
79
81
  }
80
82
  }
81
83
  let collectionListener;
82
- if (context.trackChanges && projectsNode) {
83
- const parentNode = projectsNode;
84
- collectionListener = (name, action, newValue) => {
85
- jsonMetadata.addChange(action, `/projects/${(0, utilities_1.escapeKey)(name)}`, parentNode, newValue, 'project');
84
+ if (context.trackChanges) {
85
+ collectionListener = (name, newValue) => {
86
+ jsonMetadata.addChange(['projects', name], newValue, 'project');
86
87
  };
87
88
  }
88
89
  const projectCollection = new definitions_1.ProjectDefinitionCollection(projects, collectionListener);
@@ -91,31 +92,30 @@ function parseWorkspace(workspaceNode, context) {
91
92
  projects: projectCollection,
92
93
  // If not tracking changes the `extensions` variable will contain the parsed
93
94
  // values. Otherwise the extensions are tracked via a virtual AST object.
94
- extensions: extensions ||
95
- (0, utilities_1.createVirtualAstObject)(workspaceNode, {
96
- exclude: ['$schema', 'version', 'projects'],
97
- listener(op, path, node, value) {
98
- jsonMetadata.addChange(op, path, node, value);
99
- },
100
- }),
95
+ extensions: extensions !== null && extensions !== void 0 ? extensions : (0, utilities_1.createVirtualAstObject)(workspaceNodeValue, {
96
+ exclude: ['$schema', 'version', 'projects'],
97
+ listener(path, value) {
98
+ jsonMetadata.addChange(path, value);
99
+ },
100
+ }),
101
101
  };
102
102
  }
103
103
  function parseProjectsObject(projectsNode, context) {
104
104
  const projects = Object.create(null);
105
- for (const { key, value } of projectsNode.properties) {
106
- if (value.kind !== 'object') {
105
+ for (const [name, value] of Object.entries((0, jsonc_parser_1.getNodeValue)(projectsNode))) {
106
+ const nodes = (0, jsonc_parser_1.findNodeAtLocation)(projectsNode, [name]);
107
+ if (!(0, utils_1.isJsonObject)(value) || !nodes) {
107
108
  context.warn('Skipping invalid project value; expected an object.', value);
108
109
  continue;
109
110
  }
110
- const name = key.value;
111
- projects[name] = parseProject(name, value, context);
111
+ projects[name] = parseProject(name, nodes, context);
112
112
  }
113
113
  return projects;
114
114
  }
115
115
  function parseProject(projectName, projectNode, context) {
116
116
  const jsonMetadata = context.metadata;
117
117
  let targets;
118
- let targetsNode;
118
+ let hasTargets = false;
119
119
  let extensions;
120
120
  let properties;
121
121
  if (!context.trackChanges) {
@@ -123,106 +123,91 @@ function parseProject(projectName, projectNode, context) {
123
123
  extensions = Object.create(null);
124
124
  properties = Object.create(null);
125
125
  }
126
- for (const { key, value } of projectNode.properties) {
127
- const name = key.value;
126
+ const projectNodeValue = (0, jsonc_parser_1.getNodeValue)(projectNode);
127
+ for (const [name, value] of Object.entries(projectNodeValue)) {
128
128
  switch (name) {
129
129
  case 'targets':
130
130
  case 'architect':
131
- if (value.kind !== 'object') {
131
+ const nodes = (0, jsonc_parser_1.findNodeAtLocation)(projectNode, [name]);
132
+ if (!(0, utils_1.isJsonObject)(value) || !nodes) {
132
133
  context.error(`Invalid "${name}" field found; expected an object.`, value);
133
134
  break;
134
135
  }
135
- targetsNode = value;
136
- targets = parseTargetsObject(projectName, value, context);
136
+ hasTargets = true;
137
+ targets = parseTargetsObject(projectName, nodes, context);
138
+ jsonMetadata.hasLegacyTargetsName = name === 'architect';
137
139
  break;
138
140
  case 'prefix':
139
141
  case 'root':
140
142
  case 'sourceRoot':
141
- if (value.kind !== 'string') {
143
+ if (typeof value !== 'string') {
142
144
  context.warn(`Project property "${name}" should be a string.`, value);
143
145
  }
144
146
  if (properties) {
145
- properties[name] = value.value;
147
+ properties[name] = value;
146
148
  }
147
149
  break;
148
150
  default:
149
151
  if (!specialProjectExtensions.includes(name) && !/^[a-z]{1,3}-.*/.test(name)) {
150
- context.warn(`Project extension with invalid name found.`, key);
152
+ context.warn(`Project extension with invalid name found.`, name);
151
153
  }
152
154
  if (extensions) {
153
- extensions[name] = value.value;
155
+ extensions[name] = value;
154
156
  }
155
157
  break;
156
158
  }
157
159
  }
158
160
  let collectionListener;
159
161
  if (context.trackChanges) {
160
- if (targetsNode) {
161
- const parentNode = targetsNode;
162
- collectionListener = (name, action, newValue) => {
163
- jsonMetadata.addChange(action, `/projects/${projectName}/targets/${(0, utilities_1.escapeKey)(name)}`, parentNode, newValue, 'target');
164
- };
165
- }
166
- else {
167
- let added = false;
168
- collectionListener = (_name, action, _new, _old, collection) => {
169
- if (added || action !== 'add') {
170
- return;
171
- }
172
- jsonMetadata.addChange('add', `/projects/${projectName}/targets`, projectNode, collection, 'targetcollection');
173
- added = true;
174
- };
175
- }
162
+ collectionListener = (name, newValue, collection) => {
163
+ if (hasTargets) {
164
+ jsonMetadata.addChange(['projects', projectName, 'targets', name], newValue, 'target');
165
+ }
166
+ else {
167
+ jsonMetadata.addChange(['projects', projectName, 'targets'], collection, 'targetcollection');
168
+ }
169
+ };
176
170
  }
177
171
  const base = {
178
172
  targets: new definitions_1.TargetDefinitionCollection(targets, collectionListener),
179
173
  // If not tracking changes the `extensions` variable will contain the parsed
180
174
  // values. Otherwise the extensions are tracked via a virtual AST object.
181
- extensions: extensions ||
182
- (0, utilities_1.createVirtualAstObject)(projectNode, {
183
- exclude: ['architect', 'prefix', 'root', 'sourceRoot', 'targets'],
184
- listener(op, path, node, value) {
185
- jsonMetadata.addChange(op, `/projects/${projectName}${path}`, node, value);
186
- },
187
- }),
188
- };
189
- let project;
190
- if (context.trackChanges) {
191
- project = (0, utilities_1.createVirtualAstObject)(projectNode, {
192
- base,
193
- include: ['prefix', 'root', 'sourceRoot'],
194
- listener(op, path, node, value) {
195
- jsonMetadata.addChange(op, `/projects/${projectName}${path}`, node, value);
175
+ extensions: extensions !== null && extensions !== void 0 ? extensions : (0, utilities_1.createVirtualAstObject)(projectNodeValue, {
176
+ exclude: ['architect', 'prefix', 'root', 'sourceRoot', 'targets'],
177
+ listener(path, value) {
178
+ jsonMetadata.addChange(['projects', projectName, ...path], value);
196
179
  },
197
- });
198
- }
199
- else {
200
- project = {
201
- ...base,
202
- ...properties,
203
- };
204
- }
205
- return project;
180
+ }),
181
+ };
182
+ const baseKeys = new Set(Object.keys(base));
183
+ const project = properties !== null && properties !== void 0 ? properties : (0, utilities_1.createVirtualAstObject)(projectNodeValue, {
184
+ include: ['prefix', 'root', 'sourceRoot', ...baseKeys],
185
+ listener(path, value) {
186
+ if (!baseKeys.has(path[0])) {
187
+ jsonMetadata.addChange(['projects', projectName, ...path], value);
188
+ }
189
+ },
190
+ });
191
+ return Object.assign(project, base);
206
192
  }
207
193
  function parseTargetsObject(projectName, targetsNode, context) {
208
194
  const jsonMetadata = context.metadata;
209
195
  const targets = Object.create(null);
210
- for (const { key, value } of targetsNode.properties) {
211
- if (value.kind !== 'object') {
196
+ for (const [name, value] of Object.entries((0, jsonc_parser_1.getNodeValue)(targetsNode))) {
197
+ if (!(0, utils_1.isJsonObject)(value)) {
212
198
  context.warn('Skipping invalid target value; expected an object.', value);
213
199
  continue;
214
200
  }
215
- const name = key.value;
216
201
  if (context.trackChanges) {
217
202
  targets[name] = (0, utilities_1.createVirtualAstObject)(value, {
218
203
  include: ['builder', 'options', 'configurations', 'defaultConfiguration'],
219
- listener(op, path, node, value) {
220
- jsonMetadata.addChange(op, `/projects/${projectName}/targets/${name}${path}`, node, value);
204
+ listener(path, value) {
205
+ jsonMetadata.addChange(['projects', projectName, 'targets', name, ...path], value);
221
206
  },
222
207
  });
223
208
  }
224
209
  else {
225
- targets[name] = value.value;
210
+ targets[name] = value;
226
211
  }
227
212
  }
228
213
  return targets;
@@ -5,14 +5,10 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
- import { JsonObject, JsonValue } from '../../json';
9
- import { JsonAstArray, JsonAstKeyValue, JsonAstObject } from '../../json/parser_ast';
10
- export declare type ChangeListener = (op: 'add' | 'remove' | 'replace', path: string, node: JsonAstArray | JsonAstObject | JsonAstKeyValue, value?: JsonValue) => void;
11
- export declare function escapeKey(key: string | number): string | number;
12
- export declare function unescapeKey(key: string | number): string | number;
13
- export declare function createVirtualAstObject<T extends object = JsonObject>(root: JsonAstObject, options?: {
8
+ import { JsonArray, JsonObject, JsonValue } from '../../json';
9
+ export declare type ChangeListener = (path: string[], newValue: JsonValue | undefined) => void;
10
+ export declare function createVirtualAstObject<T extends object = JsonObject>(root: JsonObject | JsonArray, options?: {
14
11
  exclude?: string[];
15
12
  include?: string[];
16
13
  listener?: ChangeListener;
17
- base?: object;
18
14
  }): T;