@uniformdev/transformer 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +858 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +64 -1
- package/dist/index.js +472 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -109,6 +109,25 @@ interface RenameSlotOptions extends GlobalOptions {
|
|
|
109
109
|
newSlotId: string;
|
|
110
110
|
newSlotName?: string;
|
|
111
111
|
}
|
|
112
|
+
interface AddComponentOptions extends GlobalOptions {
|
|
113
|
+
parentComponentType: string;
|
|
114
|
+
slot: string;
|
|
115
|
+
newComponentType: string;
|
|
116
|
+
parameters?: string;
|
|
117
|
+
}
|
|
118
|
+
interface AddComponentPatternOptions extends GlobalOptions {
|
|
119
|
+
parentComponentType: string;
|
|
120
|
+
slot: string;
|
|
121
|
+
componentPatternId: string;
|
|
122
|
+
parameters?: string;
|
|
123
|
+
}
|
|
124
|
+
interface PropagateRootComponentSlotOptions extends GlobalOptions {
|
|
125
|
+
compositionType: string;
|
|
126
|
+
slot: string;
|
|
127
|
+
targetComponentType: string;
|
|
128
|
+
targetSlot: string;
|
|
129
|
+
deleteSourceSlot?: boolean;
|
|
130
|
+
}
|
|
112
131
|
|
|
113
132
|
declare class TransformError extends Error {
|
|
114
133
|
constructor(message: string);
|
|
@@ -179,6 +198,10 @@ declare class ComponentService {
|
|
|
179
198
|
addParameterToGroup(component: ComponentDefinition, groupId: string, parameterId: string, options?: FindOptions$1): ComponentDefinition;
|
|
180
199
|
removeParameter(component: ComponentDefinition, parameterId: string, options?: FindOptions$1): ComponentDefinition;
|
|
181
200
|
removeEmptyGroups(component: ComponentDefinition): ComponentDefinition;
|
|
201
|
+
findSlot(component: ComponentDefinition, slotId: string, options?: FindOptions$1): SlotDefinition | undefined;
|
|
202
|
+
addSlot(component: ComponentDefinition, slot: SlotDefinition): ComponentDefinition;
|
|
203
|
+
updateSlotAllowedComponents(component: ComponentDefinition, slotId: string, allowedComponents: string[], options?: FindOptions$1): ComponentDefinition;
|
|
204
|
+
removeSlot(component: ComponentDefinition, slotId: string, options?: FindOptions$1): ComponentDefinition;
|
|
182
205
|
}
|
|
183
206
|
|
|
184
207
|
interface FindOptions {
|
|
@@ -317,4 +340,44 @@ declare class ComponentRenamerService {
|
|
|
317
340
|
private renameTypeInTree;
|
|
318
341
|
}
|
|
319
342
|
|
|
320
|
-
|
|
343
|
+
interface AddComponentInternalOptions {
|
|
344
|
+
rootDir: string;
|
|
345
|
+
componentsDir: string;
|
|
346
|
+
compositionsDir: string;
|
|
347
|
+
compositionPatternsDir: string;
|
|
348
|
+
componentPatternsDir: string;
|
|
349
|
+
parentComponentType: string;
|
|
350
|
+
slot: string;
|
|
351
|
+
newComponentType?: string;
|
|
352
|
+
componentPatternId?: string;
|
|
353
|
+
parameters?: string;
|
|
354
|
+
whatIf: boolean;
|
|
355
|
+
strict: boolean;
|
|
356
|
+
}
|
|
357
|
+
interface AddComponentResult {
|
|
358
|
+
allowedComponentsUpdated: boolean;
|
|
359
|
+
compositionsModified: number;
|
|
360
|
+
compositionPatternsModified: number;
|
|
361
|
+
componentPatternsModified: number;
|
|
362
|
+
instancesAdded: number;
|
|
363
|
+
}
|
|
364
|
+
declare class ComponentAdderService {
|
|
365
|
+
private fileSystem;
|
|
366
|
+
private componentService;
|
|
367
|
+
private logger;
|
|
368
|
+
constructor(fileSystem: FileSystemService, componentService: ComponentService, logger: Logger);
|
|
369
|
+
private compareIds;
|
|
370
|
+
private parseParameters;
|
|
371
|
+
private generateId;
|
|
372
|
+
private cloneComponentInstance;
|
|
373
|
+
private regenerateInstanceIds;
|
|
374
|
+
private createComponentInstance;
|
|
375
|
+
private addComponentToSlot;
|
|
376
|
+
addComponent(options: AddComponentInternalOptions): Promise<AddComponentResult>;
|
|
377
|
+
addComponentPattern(options: AddComponentInternalOptions): Promise<AddComponentResult>;
|
|
378
|
+
private loadComponentPattern;
|
|
379
|
+
private addComponentToDirectory;
|
|
380
|
+
private addComponentToNestedSlots;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export { type AddComponentOptions, type AddComponentPatternOptions, ComponentAdderService, ComponentAlreadyExistsError, type ComponentDefinition, type ComponentInstance, ComponentNotFoundError, ComponentRenamerService, ComponentService, type Composition, type CompositionOverrides, type CompositionPatternCandidatesOptions, type CompositionRoot, CompositionService, DuplicateIdError, FileNotFoundError, FileSystemService, type GlobalOptions, InvalidYamlError, Logger, type PackSerializationOptions, type Parameter, type ParameterValue, type PropagateRootComponentPropertyOptions, type PropagateRootComponentSlotOptions, PropertyNotFoundError, PropertyPropagatorService, type RenameComponentOptions, type RenameSlotOptions, SlotAlreadyExistsError, type SlotDefinition, SlotNotFoundError, SlotRenamerService, TransformError, type UnpackSerializationOptions };
|
package/dist/index.js
CHANGED
|
@@ -314,6 +314,34 @@ var ComponentService = class {
|
|
|
314
314
|
});
|
|
315
315
|
return component;
|
|
316
316
|
}
|
|
317
|
+
// Slot methods
|
|
318
|
+
findSlot(component, slotId, options = {}) {
|
|
319
|
+
const { strict = false } = options;
|
|
320
|
+
return component.slots?.find((s) => this.compareIds(s.id, slotId, strict));
|
|
321
|
+
}
|
|
322
|
+
addSlot(component, slot) {
|
|
323
|
+
if (!component.slots) {
|
|
324
|
+
component.slots = [];
|
|
325
|
+
}
|
|
326
|
+
component.slots.push({ ...slot });
|
|
327
|
+
return component;
|
|
328
|
+
}
|
|
329
|
+
updateSlotAllowedComponents(component, slotId, allowedComponents, options = {}) {
|
|
330
|
+
const { strict = false } = options;
|
|
331
|
+
const slot = component.slots?.find((s) => this.compareIds(s.id, slotId, strict));
|
|
332
|
+
if (slot) {
|
|
333
|
+
slot.allowedComponents = allowedComponents;
|
|
334
|
+
}
|
|
335
|
+
return component;
|
|
336
|
+
}
|
|
337
|
+
removeSlot(component, slotId, options = {}) {
|
|
338
|
+
const { strict = false } = options;
|
|
339
|
+
if (!component.slots) {
|
|
340
|
+
return component;
|
|
341
|
+
}
|
|
342
|
+
component.slots = component.slots.filter((s) => !this.compareIds(s.id, slotId, strict));
|
|
343
|
+
return component;
|
|
344
|
+
}
|
|
317
345
|
};
|
|
318
346
|
|
|
319
347
|
// src/core/services/composition.service.ts
|
|
@@ -1072,6 +1100,449 @@ var ComponentRenamerService = class {
|
|
|
1072
1100
|
}
|
|
1073
1101
|
};
|
|
1074
1102
|
|
|
1103
|
+
// src/core/services/component-adder.service.ts
|
|
1104
|
+
import { randomUUID } from "crypto";
|
|
1105
|
+
var ComponentAdderService = class {
|
|
1106
|
+
constructor(fileSystem, componentService, logger) {
|
|
1107
|
+
this.fileSystem = fileSystem;
|
|
1108
|
+
this.componentService = componentService;
|
|
1109
|
+
this.logger = logger;
|
|
1110
|
+
}
|
|
1111
|
+
compareIds(id1, id2, strict) {
|
|
1112
|
+
if (strict) {
|
|
1113
|
+
return id1 === id2;
|
|
1114
|
+
}
|
|
1115
|
+
return id1.toLowerCase() === id2.toLowerCase();
|
|
1116
|
+
}
|
|
1117
|
+
parseParameters(parameterString) {
|
|
1118
|
+
const result = {};
|
|
1119
|
+
if (!parameterString) return result;
|
|
1120
|
+
const pairs = parameterString.split("|");
|
|
1121
|
+
for (const pair of pairs) {
|
|
1122
|
+
const [key, ...valueParts] = pair.split(":");
|
|
1123
|
+
if (key && valueParts.length > 0) {
|
|
1124
|
+
result[key.trim()] = valueParts.join(":").trim();
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
return result;
|
|
1128
|
+
}
|
|
1129
|
+
generateId(baseName) {
|
|
1130
|
+
return `${baseName}-${randomUUID().slice(0, 8)}`;
|
|
1131
|
+
}
|
|
1132
|
+
cloneComponentInstance(instance) {
|
|
1133
|
+
const clone = JSON.parse(JSON.stringify(instance));
|
|
1134
|
+
if (clone._id) {
|
|
1135
|
+
clone._id = this.generateId(clone.type);
|
|
1136
|
+
}
|
|
1137
|
+
if (clone.slots) {
|
|
1138
|
+
for (const slotInstances of Object.values(clone.slots)) {
|
|
1139
|
+
if (Array.isArray(slotInstances)) {
|
|
1140
|
+
for (const nestedInstance of slotInstances) {
|
|
1141
|
+
this.regenerateInstanceIds(nestedInstance);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
return clone;
|
|
1147
|
+
}
|
|
1148
|
+
regenerateInstanceIds(instance) {
|
|
1149
|
+
if (instance._id) {
|
|
1150
|
+
instance._id = this.generateId(instance.type);
|
|
1151
|
+
}
|
|
1152
|
+
if (instance.slots) {
|
|
1153
|
+
for (const slotInstances of Object.values(instance.slots)) {
|
|
1154
|
+
if (Array.isArray(slotInstances)) {
|
|
1155
|
+
for (const nestedInstance of slotInstances) {
|
|
1156
|
+
this.regenerateInstanceIds(nestedInstance);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
createComponentInstance(componentType, parameters) {
|
|
1163
|
+
const instance = {
|
|
1164
|
+
type: componentType,
|
|
1165
|
+
_id: this.generateId(componentType)
|
|
1166
|
+
};
|
|
1167
|
+
if (Object.keys(parameters).length > 0) {
|
|
1168
|
+
instance.parameters = {};
|
|
1169
|
+
for (const [key, value] of Object.entries(parameters)) {
|
|
1170
|
+
instance.parameters[key] = {
|
|
1171
|
+
type: "text",
|
|
1172
|
+
value
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
return instance;
|
|
1177
|
+
}
|
|
1178
|
+
addComponentToSlot(slots, slotId, instance) {
|
|
1179
|
+
if (!slots[slotId]) {
|
|
1180
|
+
slots[slotId] = [];
|
|
1181
|
+
}
|
|
1182
|
+
slots[slotId].push(instance);
|
|
1183
|
+
}
|
|
1184
|
+
async addComponent(options) {
|
|
1185
|
+
const {
|
|
1186
|
+
rootDir,
|
|
1187
|
+
componentsDir,
|
|
1188
|
+
compositionsDir,
|
|
1189
|
+
compositionPatternsDir,
|
|
1190
|
+
componentPatternsDir,
|
|
1191
|
+
parentComponentType,
|
|
1192
|
+
slot,
|
|
1193
|
+
newComponentType,
|
|
1194
|
+
parameters: paramString,
|
|
1195
|
+
whatIf,
|
|
1196
|
+
strict
|
|
1197
|
+
} = options;
|
|
1198
|
+
if (!newComponentType) {
|
|
1199
|
+
throw new TransformError("newComponentType is required for add-component");
|
|
1200
|
+
}
|
|
1201
|
+
const fullComponentsDir = this.fileSystem.resolvePath(rootDir, componentsDir);
|
|
1202
|
+
const fullCompositionsDir = this.fileSystem.resolvePath(rootDir, compositionsDir);
|
|
1203
|
+
const fullCompositionPatternsDir = this.fileSystem.resolvePath(rootDir, compositionPatternsDir);
|
|
1204
|
+
const fullComponentPatternsDir = this.fileSystem.resolvePath(rootDir, componentPatternsDir);
|
|
1205
|
+
const findOptions = { strict };
|
|
1206
|
+
this.logger.info(`Loading parent component: ${parentComponentType}`);
|
|
1207
|
+
const { component: parentComponent, filePath: parentComponentFilePath } = await this.componentService.loadComponent(fullComponentsDir, parentComponentType, findOptions);
|
|
1208
|
+
if (!parentComponent.slots) {
|
|
1209
|
+
parentComponent.slots = [];
|
|
1210
|
+
}
|
|
1211
|
+
let slotDef = parentComponent.slots.find(
|
|
1212
|
+
(s) => this.compareIds(s.id, slot, strict)
|
|
1213
|
+
);
|
|
1214
|
+
if (!slotDef) {
|
|
1215
|
+
this.logger.info(`Slot "${slot}" not found on component "${parentComponentType}", creating it`);
|
|
1216
|
+
slotDef = { id: slot, name: slot, allowedComponents: [] };
|
|
1217
|
+
parentComponent.slots.push(slotDef);
|
|
1218
|
+
}
|
|
1219
|
+
this.logger.info(`Validating new component: ${newComponentType}`);
|
|
1220
|
+
try {
|
|
1221
|
+
await this.componentService.loadComponent(fullComponentsDir, newComponentType, findOptions);
|
|
1222
|
+
} catch (error) {
|
|
1223
|
+
if (error instanceof ComponentNotFoundError) {
|
|
1224
|
+
throw new TransformError(
|
|
1225
|
+
`Component type "${newComponentType}" not found in ${fullComponentsDir}`
|
|
1226
|
+
);
|
|
1227
|
+
}
|
|
1228
|
+
throw error;
|
|
1229
|
+
}
|
|
1230
|
+
let allowedComponentsUpdated = false;
|
|
1231
|
+
const slotIndex = parentComponent.slots?.findIndex(
|
|
1232
|
+
(s) => this.compareIds(s.id, slotDef.id, strict)
|
|
1233
|
+
);
|
|
1234
|
+
if (slotIndex !== void 0 && slotIndex >= 0) {
|
|
1235
|
+
const actualSlot = parentComponent.slots[slotIndex];
|
|
1236
|
+
if (!actualSlot.allowedComponents) {
|
|
1237
|
+
actualSlot.allowedComponents = [];
|
|
1238
|
+
}
|
|
1239
|
+
const isAlreadyAllowed = actualSlot.allowedComponents.some(
|
|
1240
|
+
(c) => this.compareIds(c, newComponentType, strict)
|
|
1241
|
+
);
|
|
1242
|
+
if (!isAlreadyAllowed) {
|
|
1243
|
+
this.logger.action(
|
|
1244
|
+
whatIf,
|
|
1245
|
+
"UPDATE",
|
|
1246
|
+
`Adding "${newComponentType}" to allowedComponents for slot "${slot}" on component "${parentComponentType}"`
|
|
1247
|
+
);
|
|
1248
|
+
actualSlot.allowedComponents.push(newComponentType);
|
|
1249
|
+
if (!whatIf) {
|
|
1250
|
+
await this.componentService.saveComponent(parentComponentFilePath, parentComponent);
|
|
1251
|
+
}
|
|
1252
|
+
allowedComponentsUpdated = true;
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
const parsedParams = this.parseParameters(paramString);
|
|
1256
|
+
const newInstance = this.createComponentInstance(newComponentType, parsedParams);
|
|
1257
|
+
const compositionsResult = await this.addComponentToDirectory(
|
|
1258
|
+
fullCompositionsDir,
|
|
1259
|
+
parentComponentType,
|
|
1260
|
+
slot,
|
|
1261
|
+
newInstance,
|
|
1262
|
+
whatIf,
|
|
1263
|
+
strict,
|
|
1264
|
+
"composition"
|
|
1265
|
+
);
|
|
1266
|
+
const compositionPatternsResult = await this.addComponentToDirectory(
|
|
1267
|
+
fullCompositionPatternsDir,
|
|
1268
|
+
parentComponentType,
|
|
1269
|
+
slot,
|
|
1270
|
+
newInstance,
|
|
1271
|
+
whatIf,
|
|
1272
|
+
strict,
|
|
1273
|
+
"compositionPattern"
|
|
1274
|
+
);
|
|
1275
|
+
const componentPatternsResult = await this.addComponentToDirectory(
|
|
1276
|
+
fullComponentPatternsDir,
|
|
1277
|
+
parentComponentType,
|
|
1278
|
+
slot,
|
|
1279
|
+
newInstance,
|
|
1280
|
+
whatIf,
|
|
1281
|
+
strict,
|
|
1282
|
+
"componentPattern"
|
|
1283
|
+
);
|
|
1284
|
+
this.logger.info("");
|
|
1285
|
+
this.logger.info(
|
|
1286
|
+
`Summary: ${allowedComponentsUpdated ? "1 component definition updated, " : ""}${compositionsResult} composition(s), ${compositionPatternsResult} composition pattern(s), ${componentPatternsResult} component pattern(s) updated. ${compositionsResult + compositionPatternsResult + componentPatternsResult} instance(s) added.`
|
|
1287
|
+
);
|
|
1288
|
+
return {
|
|
1289
|
+
allowedComponentsUpdated,
|
|
1290
|
+
compositionsModified: compositionsResult,
|
|
1291
|
+
compositionPatternsModified: compositionPatternsResult,
|
|
1292
|
+
componentPatternsModified: componentPatternsResult,
|
|
1293
|
+
instancesAdded: compositionsResult + compositionPatternsResult + componentPatternsResult
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
async addComponentPattern(options) {
|
|
1297
|
+
const {
|
|
1298
|
+
rootDir,
|
|
1299
|
+
componentsDir,
|
|
1300
|
+
compositionsDir,
|
|
1301
|
+
compositionPatternsDir,
|
|
1302
|
+
componentPatternsDir,
|
|
1303
|
+
parentComponentType,
|
|
1304
|
+
slot,
|
|
1305
|
+
componentPatternId,
|
|
1306
|
+
whatIf,
|
|
1307
|
+
strict
|
|
1308
|
+
} = options;
|
|
1309
|
+
if (!componentPatternId) {
|
|
1310
|
+
throw new TransformError("componentPatternId is required for add-component-pattern");
|
|
1311
|
+
}
|
|
1312
|
+
const fullComponentsDir = this.fileSystem.resolvePath(rootDir, componentsDir);
|
|
1313
|
+
const fullCompositionsDir = this.fileSystem.resolvePath(rootDir, compositionsDir);
|
|
1314
|
+
const fullCompositionPatternsDir = this.fileSystem.resolvePath(rootDir, compositionPatternsDir);
|
|
1315
|
+
const fullComponentPatternsDir = this.fileSystem.resolvePath(rootDir, componentPatternsDir);
|
|
1316
|
+
const findOptions = { strict };
|
|
1317
|
+
this.logger.info(`Loading parent component: ${parentComponentType}`);
|
|
1318
|
+
const { component: parentComponent } = await this.componentService.loadComponent(fullComponentsDir, parentComponentType, findOptions);
|
|
1319
|
+
if (!parentComponent.slots) {
|
|
1320
|
+
parentComponent.slots = [];
|
|
1321
|
+
}
|
|
1322
|
+
let slotDef = parentComponent.slots.find(
|
|
1323
|
+
(s) => this.compareIds(s.id, slot, strict)
|
|
1324
|
+
);
|
|
1325
|
+
if (!slotDef) {
|
|
1326
|
+
this.logger.info(`Slot "${slot}" not found on component "${parentComponentType}", creating it`);
|
|
1327
|
+
slotDef = { id: slot, name: slot, allowedComponents: [] };
|
|
1328
|
+
parentComponent.slots.push(slotDef);
|
|
1329
|
+
}
|
|
1330
|
+
this.logger.info(`Loading component pattern: ${componentPatternId}`);
|
|
1331
|
+
const pattern = await this.loadComponentPattern(
|
|
1332
|
+
fullComponentPatternsDir,
|
|
1333
|
+
componentPatternId,
|
|
1334
|
+
strict
|
|
1335
|
+
);
|
|
1336
|
+
const patternDefinition = pattern.definition;
|
|
1337
|
+
if (!patternDefinition || !patternDefinition.type) {
|
|
1338
|
+
throw new TransformError(
|
|
1339
|
+
`Component pattern "${componentPatternId}" has no valid definition or missing type`
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1342
|
+
let allowedComponentsUpdated = false;
|
|
1343
|
+
const componentTypeInPattern = patternDefinition.type;
|
|
1344
|
+
const slotIndex = parentComponent.slots?.findIndex(
|
|
1345
|
+
(s) => this.compareIds(s.id, slotDef.id, strict)
|
|
1346
|
+
);
|
|
1347
|
+
if (slotIndex !== void 0 && slotIndex >= 0) {
|
|
1348
|
+
const actualSlot = parentComponent.slots[slotIndex];
|
|
1349
|
+
if (!actualSlot.allowedComponents) {
|
|
1350
|
+
actualSlot.allowedComponents = [];
|
|
1351
|
+
}
|
|
1352
|
+
const isAlreadyAllowed = actualSlot.allowedComponents.some(
|
|
1353
|
+
(c) => this.compareIds(c, componentTypeInPattern, strict)
|
|
1354
|
+
);
|
|
1355
|
+
if (!isAlreadyAllowed) {
|
|
1356
|
+
this.logger.action(
|
|
1357
|
+
whatIf,
|
|
1358
|
+
"UPDATE",
|
|
1359
|
+
`Adding "${componentTypeInPattern}" to allowedComponents for slot "${slot}" on component "${parentComponentType}"`
|
|
1360
|
+
);
|
|
1361
|
+
actualSlot.allowedComponents.push(componentTypeInPattern);
|
|
1362
|
+
if (!whatIf) {
|
|
1363
|
+
await this.componentService.loadComponent(fullComponentsDir, parentComponentType, findOptions).then(
|
|
1364
|
+
({ filePath }) => this.componentService.saveComponent(filePath, parentComponent)
|
|
1365
|
+
);
|
|
1366
|
+
}
|
|
1367
|
+
allowedComponentsUpdated = true;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
const newInstance = this.cloneComponentInstance(patternDefinition);
|
|
1371
|
+
const compositionsResult = await this.addComponentToDirectory(
|
|
1372
|
+
fullCompositionsDir,
|
|
1373
|
+
parentComponentType,
|
|
1374
|
+
slot,
|
|
1375
|
+
newInstance,
|
|
1376
|
+
whatIf,
|
|
1377
|
+
strict,
|
|
1378
|
+
"composition"
|
|
1379
|
+
);
|
|
1380
|
+
const compositionPatternsResult = await this.addComponentToDirectory(
|
|
1381
|
+
fullCompositionPatternsDir,
|
|
1382
|
+
parentComponentType,
|
|
1383
|
+
slot,
|
|
1384
|
+
newInstance,
|
|
1385
|
+
whatIf,
|
|
1386
|
+
strict,
|
|
1387
|
+
"compositionPattern"
|
|
1388
|
+
);
|
|
1389
|
+
const componentPatternsResult = await this.addComponentToDirectory(
|
|
1390
|
+
fullComponentPatternsDir,
|
|
1391
|
+
parentComponentType,
|
|
1392
|
+
slot,
|
|
1393
|
+
newInstance,
|
|
1394
|
+
whatIf,
|
|
1395
|
+
strict,
|
|
1396
|
+
"componentPattern"
|
|
1397
|
+
);
|
|
1398
|
+
this.logger.info("");
|
|
1399
|
+
this.logger.info(
|
|
1400
|
+
`Summary: ${allowedComponentsUpdated ? "1 component definition updated, " : ""}${compositionsResult} composition(s), ${compositionPatternsResult} composition pattern(s), ${componentPatternsResult} component pattern(s) updated. ${compositionsResult + compositionPatternsResult + componentPatternsResult} instance(s) added.`
|
|
1401
|
+
);
|
|
1402
|
+
return {
|
|
1403
|
+
allowedComponentsUpdated,
|
|
1404
|
+
compositionsModified: compositionsResult,
|
|
1405
|
+
compositionPatternsModified: compositionPatternsResult,
|
|
1406
|
+
componentPatternsModified: componentPatternsResult,
|
|
1407
|
+
instancesAdded: compositionsResult + compositionPatternsResult + componentPatternsResult
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
async loadComponentPattern(componentPatternsDir, patternId, strict) {
|
|
1411
|
+
const jsonPath = this.fileSystem.joinPath(componentPatternsDir, `${patternId}.json`);
|
|
1412
|
+
const yamlPath = this.fileSystem.joinPath(componentPatternsDir, `${patternId}.yaml`);
|
|
1413
|
+
const ymlPath = this.fileSystem.joinPath(componentPatternsDir, `${patternId}.yml`);
|
|
1414
|
+
if (await this.fileSystem.fileExists(jsonPath)) {
|
|
1415
|
+
return this.fileSystem.readFile(jsonPath);
|
|
1416
|
+
}
|
|
1417
|
+
if (await this.fileSystem.fileExists(yamlPath)) {
|
|
1418
|
+
return this.fileSystem.readFile(yamlPath);
|
|
1419
|
+
}
|
|
1420
|
+
if (await this.fileSystem.fileExists(ymlPath)) {
|
|
1421
|
+
return this.fileSystem.readFile(ymlPath);
|
|
1422
|
+
}
|
|
1423
|
+
if (!strict) {
|
|
1424
|
+
const files = await this.fileSystem.findFiles(componentPatternsDir, "*.{json,yaml,yml}");
|
|
1425
|
+
for (const filePath of files) {
|
|
1426
|
+
const basename2 = this.fileSystem.getBasename(filePath);
|
|
1427
|
+
const nameWithoutExt = basename2.replace(/\.(json|yaml|yml)$/i, "");
|
|
1428
|
+
if (nameWithoutExt.toLowerCase() === patternId.toLowerCase()) {
|
|
1429
|
+
return this.fileSystem.readFile(filePath);
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
throw new TransformError(`Component pattern "${patternId}" not found in ${componentPatternsDir}`);
|
|
1434
|
+
}
|
|
1435
|
+
async addComponentToDirectory(directory, parentComponentType, slot, newInstance, whatIf, strict, dirType) {
|
|
1436
|
+
const exists = await this.fileSystem.fileExists(directory);
|
|
1437
|
+
if (!exists) {
|
|
1438
|
+
this.logger.detail(`${dirType} directory does not exist, skipping`);
|
|
1439
|
+
return 0;
|
|
1440
|
+
}
|
|
1441
|
+
const files = await this.fileSystem.findFiles(directory, "**/*.{json,yaml,yml}");
|
|
1442
|
+
let filesModified = 0;
|
|
1443
|
+
for (const filePath of files) {
|
|
1444
|
+
try {
|
|
1445
|
+
const content = await this.fileSystem.readFile(filePath);
|
|
1446
|
+
let composition = null;
|
|
1447
|
+
let isComponentPattern = false;
|
|
1448
|
+
if (dirType === "componentPattern" && content && typeof content === "object" && "definition" in content) {
|
|
1449
|
+
isComponentPattern = true;
|
|
1450
|
+
const pattern = content;
|
|
1451
|
+
if (pattern.definition && pattern.definition.slots) {
|
|
1452
|
+
composition = {
|
|
1453
|
+
composition: {
|
|
1454
|
+
_id: "pattern-root",
|
|
1455
|
+
type: pattern.definition.type,
|
|
1456
|
+
slots: pattern.definition.slots
|
|
1457
|
+
}
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
} else {
|
|
1461
|
+
composition = content;
|
|
1462
|
+
}
|
|
1463
|
+
if (!composition?.composition) {
|
|
1464
|
+
continue;
|
|
1465
|
+
}
|
|
1466
|
+
const rootInstance = composition.composition;
|
|
1467
|
+
let modified = false;
|
|
1468
|
+
if (this.compareIds(rootInstance.type, parentComponentType, strict)) {
|
|
1469
|
+
if (!rootInstance.slots) {
|
|
1470
|
+
rootInstance.slots = {};
|
|
1471
|
+
}
|
|
1472
|
+
const instanceCopy = JSON.parse(JSON.stringify(newInstance));
|
|
1473
|
+
this.regenerateInstanceIds(instanceCopy);
|
|
1474
|
+
this.addComponentToSlot(rootInstance.slots, slot, instanceCopy);
|
|
1475
|
+
modified = true;
|
|
1476
|
+
}
|
|
1477
|
+
if (rootInstance.slots) {
|
|
1478
|
+
const nestedModified = this.addComponentToNestedSlots(
|
|
1479
|
+
rootInstance.slots,
|
|
1480
|
+
parentComponentType,
|
|
1481
|
+
slot,
|
|
1482
|
+
newInstance,
|
|
1483
|
+
strict
|
|
1484
|
+
);
|
|
1485
|
+
if (nestedModified) {
|
|
1486
|
+
modified = true;
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
if (modified) {
|
|
1490
|
+
this.logger.action(
|
|
1491
|
+
whatIf,
|
|
1492
|
+
"UPDATE",
|
|
1493
|
+
`Adding "${newInstance.type}" to slot "${slot}" in ${dirType}/${this.fileSystem.getBasename(filePath)}`
|
|
1494
|
+
);
|
|
1495
|
+
if (!whatIf) {
|
|
1496
|
+
if (isComponentPattern && content && typeof content === "object" && "definition" in content) {
|
|
1497
|
+
const pattern = content;
|
|
1498
|
+
if (rootInstance.slots) {
|
|
1499
|
+
pattern.definition.slots = rootInstance.slots;
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
await this.fileSystem.writeFile(filePath, content);
|
|
1503
|
+
}
|
|
1504
|
+
filesModified++;
|
|
1505
|
+
}
|
|
1506
|
+
} catch (error) {
|
|
1507
|
+
if (error instanceof Error && !error.message.includes("skipping")) {
|
|
1508
|
+
this.logger.detail(`Skipping ${filePath}: ${error.message}`);
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
return filesModified;
|
|
1513
|
+
}
|
|
1514
|
+
addComponentToNestedSlots(slots, parentComponentType, slot, newInstance, strict) {
|
|
1515
|
+
let modified = false;
|
|
1516
|
+
for (const slotInstances of Object.values(slots)) {
|
|
1517
|
+
if (!Array.isArray(slotInstances)) continue;
|
|
1518
|
+
for (const instance of slotInstances) {
|
|
1519
|
+
if (this.compareIds(instance.type, parentComponentType, strict)) {
|
|
1520
|
+
if (!instance.slots) {
|
|
1521
|
+
instance.slots = {};
|
|
1522
|
+
}
|
|
1523
|
+
const instanceCopy = JSON.parse(JSON.stringify(newInstance));
|
|
1524
|
+
this.regenerateInstanceIds(instanceCopy);
|
|
1525
|
+
this.addComponentToSlot(instance.slots, slot, instanceCopy);
|
|
1526
|
+
modified = true;
|
|
1527
|
+
}
|
|
1528
|
+
if (instance.slots) {
|
|
1529
|
+
const nestedModified = this.addComponentToNestedSlots(
|
|
1530
|
+
instance.slots,
|
|
1531
|
+
parentComponentType,
|
|
1532
|
+
slot,
|
|
1533
|
+
newInstance,
|
|
1534
|
+
strict
|
|
1535
|
+
);
|
|
1536
|
+
if (nestedModified) {
|
|
1537
|
+
modified = true;
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
return modified;
|
|
1543
|
+
}
|
|
1544
|
+
};
|
|
1545
|
+
|
|
1075
1546
|
// src/cli/logger.ts
|
|
1076
1547
|
import chalk from "chalk";
|
|
1077
1548
|
var Logger = class {
|
|
@@ -1096,6 +1567,7 @@ var Logger = class {
|
|
|
1096
1567
|
}
|
|
1097
1568
|
};
|
|
1098
1569
|
export {
|
|
1570
|
+
ComponentAdderService,
|
|
1099
1571
|
ComponentAlreadyExistsError,
|
|
1100
1572
|
ComponentNotFoundError,
|
|
1101
1573
|
ComponentRenamerService,
|