@contrail/cli 3.3.0-alpha → 3.3.0

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 (43) hide show
  1. package/README.md +1 -142
  2. package/dist/api/types.d.ts +0 -35
  3. package/dist/api/types.js +1 -47
  4. package/dist/basecommand.d.ts +1 -3
  5. package/dist/basecommand.js +1 -1
  6. package/dist/commands/app/create.js +15 -0
  7. package/dist/commands/app/init.js +14 -0
  8. package/dist/commands/app/upgrade.js +6 -6
  9. package/dist/common.d.ts +1 -1
  10. package/dist/helpers/app/app-deployer.js +16 -20
  11. package/dist/helpers/app/setup-template.d.ts +2 -0
  12. package/dist/helpers/app/setup-template.js +2 -1
  13. package/dist/helpers/file-helpers.d.ts +0 -1
  14. package/dist/helpers/file-helpers.js +1 -19
  15. package/dist/interfaces.d.ts +2 -9
  16. package/dist/interfaces.js +1 -8
  17. package/dist/templates/typescript/app.yml +1 -0
  18. package/oclif.manifest.json +1 -341
  19. package/package.json +4 -5
  20. package/dist/commands/entities/create.d.ts +0 -37
  21. package/dist/commands/entities/create.js +0 -532
  22. package/dist/commands/entities/create.spec.d.ts +0 -1
  23. package/dist/commands/entities/create.spec.js +0 -514
  24. package/dist/commands/entities/delete.d.ts +0 -16
  25. package/dist/commands/entities/delete.js +0 -103
  26. package/dist/commands/entities/get.d.ts +0 -19
  27. package/dist/commands/entities/get.js +0 -151
  28. package/dist/commands/entities/update.d.ts +0 -17
  29. package/dist/commands/entities/update.js +0 -86
  30. package/dist/helpers/entities/assortment-items.d.ts +0 -10
  31. package/dist/helpers/entities/assortment-items.js +0 -86
  32. package/dist/helpers/entities/batchFetch.d.ts +0 -8
  33. package/dist/helpers/entities/batchFetch.js +0 -41
  34. package/dist/helpers/entities/index.d.ts +0 -3
  35. package/dist/helpers/entities/index.js +0 -6
  36. package/dist/helpers/entities/items.d.ts +0 -10
  37. package/dist/helpers/entities/items.js +0 -84
  38. package/dist/helpers/entities/project-items.d.ts +0 -3
  39. package/dist/helpers/entities/project-items.js +0 -65
  40. package/dist/helpers/propertySpecifications/propertySpecifications.d.ts +0 -26
  41. package/dist/helpers/propertySpecifications/propertySpecifications.js +0 -58
  42. package/dist/helpers/propertySpecifications/propertySpecifications.spec.d.ts +0 -1
  43. package/dist/helpers/propertySpecifications/propertySpecifications.spec.js +0 -266
@@ -1,532 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.doesPropertyLevelMatchRole = exports.selectRandomObject = exports.buildObjectReferenceCache = exports.getReferencedObjectPaths = exports.pickRandomValueForProperty = void 0;
4
- const tslib_1 = require("tslib");
5
- const fs_1 = tslib_1.__importDefault(require("fs"));
6
- const unique_names_generator_1 = require("unique-names-generator");
7
- const p_limit_1 = tslib_1.__importDefault(require("p-limit"));
8
- const types_1 = require("@contrail/types");
9
- const types_2 = require("../../api/types");
10
- const core_1 = require("@oclif/core");
11
- const types_3 = require("../../api/types");
12
- const login_1 = require("../../auth/login");
13
- const basecommand_1 = require("../../basecommand");
14
- const sdk_1 = require("@contrail/sdk");
15
- const entities_1 = require("../../helpers/entities");
16
- const propertySpecifications_1 = require("../../helpers/propertySpecifications/propertySpecifications");
17
- const file_helpers_1 = require("../../helpers/file-helpers");
18
- let IS_DRY_RUN = false;
19
- let SHOULD_USE_READABLE_IDS = false;
20
- let SHOULD_SKIP_HYDRATE_RELATIONSHIPS = false;
21
- let SHOULD_ONLY_USE_SPECIFIED_PROPERTIES = false;
22
- const baseValidationMap = {
23
- assortmentId: async (_slug, assortmentId) => (0, entities_1.throwIfInvalidAssortmentId)(assortmentId),
24
- itemId: async (_slug, itemId) => (0, entities_1.throwIfInvalidItemId)(itemId),
25
- projectId: async (_slug, projectId) => (0, entities_1.throwIfInvalidProjectId)(projectId),
26
- };
27
- const throwIfInvalidPropertyLevelFn = async (_slug, maybeRoles) => maybeRoles.forEach((maybeRole) => (0, entities_1.throwIfInvalidItemLevel)(maybeRole));
28
- const throwIfInvalidUserOrgRoleFn = async (_slug, maybeRole) => {
29
- if (maybeRole !== 'MEMBER' && maybeRole !== 'ADMIN') {
30
- throw new Error(`${maybeRole} is not a valid User Org Role`); // TODO: get these roles from a shared library
31
- }
32
- };
33
- const SLUG_VALIDATION_BY_ROOT_MAP = {
34
- item: { ...baseValidationMap, roles: throwIfInvalidPropertyLevelFn },
35
- 'project-item': { ...baseValidationMap, roles: throwIfInvalidPropertyLevelFn },
36
- 'assortment-item': baseValidationMap,
37
- 'user-org': baseValidationMap,
38
- 'custom-entity': { ...baseValidationMap, role: throwIfInvalidUserOrgRoleFn },
39
- };
40
- const SLUGS_THAT_MUST_BE_SPECIFIED_BY_TYPE_PATH = {
41
- item: ['roles'],
42
- 'project-item': ['projectId'],
43
- 'assortment-item': ['assortmentId'],
44
- 'user-org': ['role'],
45
- };
46
- const FIND_VALID_VALUE_MAP = {
47
- assortment: [
48
- {
49
- slug: 'name',
50
- findValidValuesFn: async (assortments) => new Set(Array.from({ length: assortments.length }, () => generateRandomReadableString())),
51
- applyValueToEntityFn: (entity, validValues) => {
52
- entity.name = Array.from(validValues)[Math.floor(Math.random() * validValues.size)];
53
- validValues.delete(entity.name);
54
- },
55
- },
56
- ],
57
- 'assortment-item': [
58
- {
59
- slug: 'itemId',
60
- findValidValuesFn: async (assortmentItems) => new Set((await (0, entities_1.findItemsNotInAssortment)(assortmentItems[0].assortmentId)).map(({ id }) => id)),
61
- applyValueToEntityFn: (entity, validValues) => {
62
- entity.itemId = Array.from(validValues)[Math.floor(Math.random() * validValues.size)];
63
- validValues.delete(entity.itemId);
64
- },
65
- },
66
- ],
67
- 'project-item': [
68
- {
69
- slug: 'itemId',
70
- findValidValuesFn: async (projectItems) => new Set((await (0, entities_1.findItemsNotInProject)(projectItems[0].projectId)).map(({ id }) => id)),
71
- applyValueToEntityFn: (entity, validValues) => {
72
- entity.itemId = Array.from(validValues)[Math.floor(Math.random() * validValues.size)];
73
- validValues.delete(entity.itemId);
74
- },
75
- },
76
- ],
77
- item: [
78
- {
79
- slug: 'familyId',
80
- findValidValuesFn: async (_items) => new Set(await (0, entities_1.getItemFamilies)().then((families) => families === undefined ? undefined : families.map(({ id }) => id))),
81
- applyValueToEntityFn: (entity, validValues) => {
82
- if (entity.roles?.includes('option')) {
83
- entity.familyId = Array.from(validValues)[Math.floor(Math.random() * validValues.size)];
84
- // can reuse familyId for options
85
- }
86
- },
87
- },
88
- {
89
- slug: 'name',
90
- findValidValuesFn: async (items) => new Set(Array.from({ length: items.length }, () => generateRandomReadableString())),
91
- applyValueToEntityFn: (entity, validValues) => {
92
- entity.name = Array.from(validValues)[Math.floor(Math.random() * validValues.size)];
93
- validValues.delete(entity.name);
94
- },
95
- },
96
- {
97
- slug: 'optionName',
98
- findValidValuesFn: async (items) => new Set(Array.from({ length: items.length }, () => generateRandomReadableString())),
99
- applyValueToEntityFn: (entity, validValues) => {
100
- if (!entity.roles?.includes('option'))
101
- return; // only apply to options
102
- entity.optionName = Array.from(validValues)[Math.floor(Math.random() * validValues.size)];
103
- validValues.delete(entity.optionName);
104
- },
105
- },
106
- {
107
- slug: 'optionGroup',
108
- findValidValuesFn: async (_items) => new Set(),
109
- applyValueToEntityFn: (entity, _validValues) => {
110
- if (!entity.roles?.includes('option'))
111
- return; // only apply to options
112
- entity.optionGroup = 'color';
113
- },
114
- },
115
- ],
116
- workspace: [
117
- {
118
- slug: 'name',
119
- findValidValuesFn: async (items) => new Set(Array.from({ length: items.length }, () => generateRandomReadableString())),
120
- applyValueToEntityFn: (entity, validValues) => {
121
- entity.name = Array.from(validValues)[Math.floor(Math.random() * validValues.size)];
122
- validValues.delete(entity.name);
123
- },
124
- },
125
- ],
126
- };
127
- class CreateEntity extends basecommand_1.BaseCommand {
128
- static description = '(BETA) Create entities';
129
- static examples = [
130
- 'contrail entities create color -n=10 # creates 10 random colors',
131
- 'contrail entities create color # creates one item',
132
- 'contrail entities create custom-entities:franchise',
133
- 'contrail entities create project-item -n=1 -- projectId=abc # creates 10 project items within project ABC',
134
- 'contrail entities create color -r # creates a random color with a human readable ID',
135
- 'contrail entities create color -d # simulates the creation of a random color without actually creating it',
136
- 'contrail entities create custom-entity:franchise -s # creates a random color and the response does not contain hydrating relationships',
137
- 'contrail entities create color -p -- name=Electric\ Blue green=1 red=2 blue=3 # creates a color with specified properties',
138
- 'contrail entities create color -o /tmp/colors.json # creates a random color and saves the output to /tmp/colors.json',
139
- ];
140
- static flags = {
141
- ...basecommand_1.BaseCommand.baseFlags,
142
- count: core_1.Flags.integer({
143
- char: 'n',
144
- description: 'Number of random entities to create',
145
- required: false,
146
- }),
147
- dryRun: core_1.Flags.boolean({
148
- char: 'd',
149
- description: 'If true, does not create the entity but simulates the creation',
150
- required: false,
151
- default: false,
152
- }),
153
- input: core_1.Flags.string({
154
- char: 'i',
155
- description: 'A JSON array of objects where each object is one entity to create. Cannot be used with --count. Unless --precise is specified, any missing values will be populated with random values.',
156
- required: false,
157
- multiple: false,
158
- }),
159
- outputFile: core_1.Flags.string({
160
- char: 'o',
161
- description: 'File to save the output (optional)',
162
- required: false,
163
- multiple: false,
164
- }),
165
- preciseProperties: core_1.Flags.boolean({
166
- char: 'p',
167
- description: 'If true, does not generate random values for properties. All values must be specified.',
168
- required: false,
169
- default: false,
170
- }),
171
- readableIds: core_1.Flags.boolean({
172
- char: 'r',
173
- description: 'If true, uses readable IDs for the created entities',
174
- required: false,
175
- default: false,
176
- }),
177
- skipHydrateRelationships: core_1.Flags.boolean({
178
- char: 's',
179
- description: 'If true, does not hydrate relationships for the created entities',
180
- required: false,
181
- default: false,
182
- }),
183
- };
184
- static args = {
185
- path: core_1.Args.string({
186
- description: 'Path of the entity type to create',
187
- required: true,
188
- multiple: false,
189
- }),
190
- };
191
- static strict = false;
192
- async run() {
193
- this.log('🚨 This command is in BETA and may change or be removed at any time.');
194
- await (0, login_1.authUser)();
195
- const { flags, argv, args } = await this.parse(CreateEntity);
196
- const { count, dryRun: isDryRun, input: inputFilename, outputFile: outputFilename, preciseProperties: shouldOnlyUseSpecifiedProperties, readableIds: shouldUseReadableIds, skipHydrateRelationships, } = flags;
197
- const { path: entityTypePath } = args;
198
- // Global flags is a little hacky, but it was easier
199
- // and it doesn't see *that* bad because they are only valid
200
- // for the lifecycle of the command.
201
- IS_DRY_RUN = isDryRun;
202
- SHOULD_USE_READABLE_IDS = shouldUseReadableIds;
203
- SHOULD_SKIP_HYDRATE_RELATIONSHIPS = skipHydrateRelationships;
204
- SHOULD_ONLY_USE_SPECIFIED_PROPERTIES = shouldOnlyUseSpecifiedProperties;
205
- const propertySpecificationArgs = argv
206
- .slice(1, argv.length)
207
- .filter(propertySpecifications_1.isValidPropertySpecification);
208
- const propertySpecBySlug = (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(propertySpecificationArgs);
209
- // Validate args
210
- if (!entityTypePath) {
211
- this.error('You must specify an entity type path.');
212
- }
213
- if (inputFilename && count) {
214
- throw new Error('You cannot use --input and --count together. Please specify one or the other.');
215
- }
216
- if (count !== undefined && count <= 0) {
217
- this.error('Count must be a positive integer.');
218
- }
219
- const partialEntities = inputFilename
220
- ? (0, file_helpers_1.parseFileAsJsonArray)(inputFilename)
221
- : Array.from({ length: count || 1 }).fill({});
222
- // Ensure we have the required properties for the entity type
223
- if (SLUGS_THAT_MUST_BE_SPECIFIED_BY_TYPE_PATH[entityTypePath]) {
224
- const requiredSlugs = SLUGS_THAT_MUST_BE_SPECIFIED_BY_TYPE_PATH[entityTypePath];
225
- for (const slug of requiredSlugs) {
226
- if (!propertySpecBySlug.has(slug)) {
227
- this.error(`Property '${slug}' must be specified for entity type '${entityTypePath}'.`);
228
- }
229
- }
230
- }
231
- try {
232
- const entitiesToCreate = await buildEntitiesToCreate(entityTypePath, partialEntities, propertySpecBySlug);
233
- const { root: entityName } = (0, types_2.parseTypePath)(entityTypePath);
234
- const createdEntities = await createEntities(entityName, entitiesToCreate);
235
- if (outputFilename) {
236
- fs_1.default.writeFileSync(outputFilename, JSON.stringify(createdEntities, null, 2));
237
- this.log(`Output saved to ${outputFilename}`);
238
- }
239
- else {
240
- console.log(`Created ${entityTypePath}(s), Entity: ${JSON.stringify(createdEntities, null, 2)}`);
241
- }
242
- }
243
- catch (error) {
244
- this.error(`Failed to create random entities: ${error.message}, ${error.stack}`);
245
- }
246
- }
247
- }
248
- exports.default = CreateEntity;
249
- async function createEntities(entityName, entities) {
250
- const limit = (0, p_limit_1.default)(20);
251
- const createdEntities = IS_DRY_RUN
252
- ? entities
253
- : await Promise.all(entities.map(async (e) => limit(() => createEntity(entityName, e))));
254
- if (IS_DRY_RUN) {
255
- console.log(`Dry run mode: not creating entities, but simulating creation for ${entityName}`);
256
- }
257
- return createdEntities;
258
- }
259
- async function buildEntitiesToCreate(entityTypePath, entities, propertySpecificationBySlug) {
260
- const type = await (0, types_3.getTypeByPath)(entityTypePath);
261
- if (!type) {
262
- throw new Error(`Type not found for path: ${entityTypePath}`);
263
- }
264
- const [typesCache, objectReferencesCache] = await Promise.all([
265
- (0, types_2.buildLocalTypesCache)([...(0, types_2.getReferencedTypePaths)(type), entityTypePath]),
266
- buildLocalObjectReferencesCache(getReferencedObjectPaths(type)),
267
- ]);
268
- const populatedEntities = entities.map((entity) => ({
269
- ...createEntityWithPopulatedValues(type, typesCache, objectReferencesCache, propertySpecificationBySlug),
270
- ...entity,
271
- }));
272
- const limit = (0, p_limit_1.default)(30);
273
- await Promise.all(populatedEntities.map(async () => limit(() => throwIfEntityIsInvalid)));
274
- // Add system values if needed
275
- const { root } = (0, types_2.parseTypePath)(type.typePath);
276
- const valueFinderApplierForEntity = FIND_VALID_VALUE_MAP[root] || [];
277
- for (const { slug, findValidValuesFn, applyValueToEntityFn } of valueFinderApplierForEntity) {
278
- // If the property is already specified, skip it unless it is a role for an option or family
279
- if (propertySpecificationBySlug?.has(slug)) {
280
- console.log(`Skipping property ${slug} because it is already specified.`);
281
- continue;
282
- }
283
- const values = await findValidValuesFn(populatedEntities);
284
- if (values) {
285
- populatedEntities.forEach((e) => applyValueToEntityFn(e, values));
286
- }
287
- else {
288
- console.warn(`No valid values found for property ${slug}. Skipping.`);
289
- }
290
- }
291
- return populatedEntities;
292
- }
293
- function createEntityWithPopulatedValues(type, typeReferencesCache, objectReferencesCache, propertySpecificationBySlug) {
294
- const roles = propertySpecificationBySlug?.get('roles');
295
- const entity = SHOULD_ONLY_USE_SPECIFIED_PROPERTIES
296
- ? {}
297
- : pickRandomPropertyValues(type, objectReferencesCache, typeReferencesCache, roles);
298
- // Handle property specifications
299
- for (const [propertySlug, specifiedValue] of propertySpecificationBySlug.entries()) {
300
- const correspondingProperty = type.typeProperties.find((prop) => getPropertySlug(prop) === propertySlug);
301
- if (!specifiedValue) {
302
- throw new Error(`Value for property ${propertySlug} is required`);
303
- }
304
- entity[propertySlug] = castValueToPropertyType(specifiedValue, correspondingProperty?.propertyType || types_1.PropertyType.String);
305
- }
306
- // Give Readbable IDs if specified
307
- if (SHOULD_USE_READABLE_IDS) {
308
- entity.specifiedId = generateRandomReadableString();
309
- }
310
- // Support specifiedId
311
- if (propertySpecificationBySlug?.has('specifiedId')) {
312
- const specifiedId = propertySpecificationBySlug.get('specifiedId');
313
- entity.specifiedId = specifiedId;
314
- }
315
- // There are some required values for certain entity types
316
- const requiredValuesForType = requiredValues(type.typePath, typeReferencesCache);
317
- if (requiredValuesForType) {
318
- requiredValuesForType.forEach(({ slug, value }) => {
319
- entity[slug] = value;
320
- });
321
- }
322
- return entity;
323
- }
324
- function pickRandomPropertyValues(type, objectReferencesCache, typeReferencesCache, roles) {
325
- const entity = {};
326
- // Get values for properties
327
- for (const property of type.typeProperties) {
328
- // Validate property level
329
- if (roles?.length && roles.every((r) => !doesPropertyLevelMatchRole(property.propertyLevel, r)))
330
- continue;
331
- // Generate random value
332
- if (property.propertyType === types_1.PropertyType.ObjectReference) {
333
- const cache = objectReferencesCache.get(property.referencedTypePath);
334
- if (!cache || cache.size === 0) {
335
- throw new Error(`No object references found for referencedTypePath: ${property.referencedTypePath}`);
336
- }
337
- entity[getPropertySlug(property)] = selectRandomObject(cache).id;
338
- }
339
- else {
340
- entity[getPropertySlug(property)] = pickRandomValueForProperty(property, objectReferencesCache, typeReferencesCache);
341
- }
342
- }
343
- return entity;
344
- }
345
- async function throwIfEntityIsInvalid(typeRoot, entity) {
346
- const propertySlugs = Object.keys(entity);
347
- const validationMap = SLUG_VALIDATION_BY_ROOT_MAP[typeRoot] || {};
348
- const promises = propertySlugs
349
- .filter((slug) => validationMap[slug])
350
- .map((slug) => validationMap[slug](slug, entity[slug]));
351
- await Promise.all(promises);
352
- }
353
- function pickRandomValueForProperty(property, objectReferencesCache, typeReferencesCache) {
354
- const getRandomObjectReference = (referencedTypePath) => {
355
- if (!objectReferencesCache.has(referencedTypePath)) {
356
- throw new Error(`No object references found for referencedTypePath: ${referencedTypePath}`);
357
- }
358
- const cache = objectReferencesCache.get(referencedTypePath);
359
- if (cache.size === 0) {
360
- return null;
361
- }
362
- const randomIndex = Math.floor(Math.random() * cache.size);
363
- const randomObjectReference = Array.from(cache.values())[randomIndex];
364
- return randomObjectReference;
365
- };
366
- switch (property.propertyType) {
367
- case types_1.PropertyType.String:
368
- return generateRandomReadableString();
369
- case types_1.PropertyType.Text:
370
- return generateRandomReadableString();
371
- case types_1.PropertyType.Boolean:
372
- return generateRandomBooleanValue();
373
- case types_1.PropertyType.Number:
374
- return generateRandomNumber();
375
- case types_1.PropertyType.Currency:
376
- return generateRandomNumber();
377
- case types_1.PropertyType.SingleSelect:
378
- if (!property.options)
379
- throw new Error(`Option set is required for SingleSelect property ${property.slug}, ${JSON.stringify(property, null, 2)}`);
380
- return pickRandomOptions(property.options, 1)[0].value;
381
- case types_1.PropertyType.MultiSelect:
382
- if (!property.options)
383
- throw new Error('Option set is required for MultiSelect property');
384
- const randomSelection = pickRandomOptions(property.options, Math.max(2, property.options.length)); // Avoid picking more than the number of options
385
- return randomSelection.map((option) => option.value);
386
- case types_1.PropertyType.Sequence:
387
- return generateRandomNumber();
388
- case types_1.PropertyType.Date:
389
- return generateRandomDateString();
390
- case types_1.PropertyType.Percent:
391
- return generateRandomNumber(0, 100);
392
- case types_1.PropertyType.ObjectReference:
393
- const { referencedTypePath: typeForObjectReference } = property;
394
- const randomObjectReference = getRandomObjectReference(typeForObjectReference);
395
- if (!randomObjectReference) {
396
- throw new Error(`No object references found for referencedTypePath: ${typeForObjectReference}`);
397
- }
398
- return randomObjectReference.id; // Assuming the object reference has an 'id' field
399
- case types_1.PropertyType.TypeReference:
400
- const { referencedTypePath } = property;
401
- const type = typeReferencesCache.get(referencedTypePath);
402
- if (!type) {
403
- throw new Error(`Referenced type not found for path: ${referencedTypePath}`);
404
- }
405
- return type.id;
406
- case types_1.PropertyType.Formula:
407
- return undefined; // Placeholder for formula properties because they are evaluated on save anyway
408
- default:
409
- throw new Error(`Cannot handle property type: ${property.propertyType}.\n\n See property: ${JSON.stringify(property, null, 2)}`);
410
- // TODO: Handle UserList
411
- // TODO: Handle ObjectReferenceList
412
- }
413
- }
414
- exports.pickRandomValueForProperty = pickRandomValueForProperty;
415
- function pickRandomOptions(options, count) {
416
- const shuffled = options.sort(() => 0.5 - Math.random());
417
- return shuffled.slice(0, count);
418
- }
419
- function generateRandomBooleanValue() {
420
- return Math.random() < 0.5;
421
- }
422
- function generateRandomNumber(min, max) {
423
- if (min === undefined) {
424
- min = 0;
425
- }
426
- if (max === undefined) {
427
- max = 100;
428
- }
429
- return Math.floor(Math.random() * (max - min + 1)) + min;
430
- }
431
- function generateRandomReadableString() {
432
- return (0, unique_names_generator_1.uniqueNamesGenerator)({ dictionaries: [unique_names_generator_1.adjectives, unique_names_generator_1.animals, unique_names_generator_1.colors, unique_names_generator_1.starWars], length: 3 });
433
- }
434
- function generateRandomDateString() {
435
- return new Date().toISOString();
436
- }
437
- function castValueToPropertyType(value, propertyType) {
438
- switch (propertyType) {
439
- case types_1.PropertyType.Boolean:
440
- return value.toString().toLowerCase() === 'true';
441
- case types_1.PropertyType.Number:
442
- const numValue = parseFloat(value.toString());
443
- if (isNaN(numValue)) {
444
- throw new Error(`Invalid number value: ${value}`);
445
- }
446
- return numValue;
447
- case types_1.PropertyType.Date:
448
- return new Date(value.toString()).toISOString();
449
- default:
450
- return value; // For string and other types, return as is
451
- }
452
- }
453
- async function createEntity(entityName, entity) {
454
- const client = new sdk_1.Entities();
455
- const skipHydrateRelationships = SHOULD_SKIP_HYDRATE_RELATIONSHIPS;
456
- if (entityName === 'assortment-item')
457
- return (0, entities_1.createAssortmentItem)(entity, { skipHydrateRelationships }); // special case
458
- const response = await client.create({ entityName, object: entity, skipHydrateRelationships });
459
- return response;
460
- }
461
- function getReferencedObjectPaths(type) {
462
- const properties = type.typeProperties || [];
463
- return properties
464
- .filter((prop) => prop.propertyType === types_1.PropertyType.ObjectReference)
465
- .map(({ referencedTypePath }) => referencedTypePath);
466
- }
467
- exports.getReferencedObjectPaths = getReferencedObjectPaths;
468
- async function buildLocalObjectReferencesCache(paths) {
469
- const cache = new Map();
470
- const getExampleCustomEntitiesByTypePath = (path) => {
471
- const client = new sdk_1.Entities();
472
- const entities = client.get({
473
- entityName: 'custom-entity',
474
- criteria: {
475
- typePath: path,
476
- },
477
- });
478
- return entities;
479
- };
480
- const getExampleEntites = async (path) => {
481
- if (path.startsWith('custom-entity')) {
482
- return getExampleCustomEntitiesByTypePath(path);
483
- }
484
- const { root } = (0, types_2.parseTypePath)(path);
485
- const client = new sdk_1.Entities();
486
- const entities = await client.get({
487
- entityName: root,
488
- });
489
- return entities;
490
- };
491
- const entitiesByPath = await Promise.all((paths || []).map(async (path) => {
492
- const entities = await getExampleEntites(path);
493
- return { path, entities };
494
- }));
495
- entitiesByPath.forEach(({ path, entities }) => {
496
- const cacheForPath = buildObjectReferenceCache(entities);
497
- cache.set(path, cacheForPath);
498
- });
499
- return cache;
500
- }
501
- function buildObjectReferenceCache(entities) {
502
- const cache = new Map();
503
- entities.forEach((entity) => {
504
- const { id } = entity;
505
- if (id && !cache.has(id)) {
506
- cache.set(id, entity);
507
- }
508
- });
509
- return cache;
510
- }
511
- exports.buildObjectReferenceCache = buildObjectReferenceCache;
512
- function selectRandomObject(cache) {
513
- return Array.from(cache.values())[Math.floor(Math.random() * cache.size)];
514
- }
515
- exports.selectRandomObject = selectRandomObject;
516
- function requiredValues(path, typeCache) {
517
- if (path.startsWith('custom-entity')) {
518
- return [{ slug: 'typeId', value: typeCache.get(path)?.id || '' }];
519
- }
520
- }
521
- function getPropertySlug(property) {
522
- return property.propertyType === types_1.PropertyType.ObjectReference
523
- ? `${property.slug}Id`
524
- : property.slug;
525
- }
526
- function doesPropertyLevelMatchRole(propertyLevel, role) {
527
- const isMatchingLevel = propertyLevel === role;
528
- return (isMatchingLevel ||
529
- propertyLevel === types_1.PropertyLevel.ALL ||
530
- propertyLevel === types_1.PropertyLevel.OVERRIDABLE);
531
- }
532
- exports.doesPropertyLevelMatchRole = doesPropertyLevelMatchRole;
@@ -1 +0,0 @@
1
- export {};