@contrail/cli 3.6.0-alpha-5 → 3.6.0-alpha-6

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/README.md CHANGED
@@ -17,7 +17,7 @@ $ npm install -g @contrail/cli
17
17
  $ contrail COMMAND
18
18
  running command...
19
19
  $ contrail (--version)
20
- @contrail/cli/3.6.0-alpha-5 darwin-arm64 node-v22.19.0
20
+ @contrail/cli/3.6.0-alpha-6 darwin-arm64 node-v23.5.0
21
21
  $ contrail --help [COMMAND]
22
22
  USAGE
23
23
  $ contrail COMMAND
@@ -90,7 +90,8 @@ const FIND_VALID_VALUE_MAP = {
90
90
  if (entity.itemFamilyId)
91
91
  return; // skip if already specified
92
92
  if (entity.roles?.includes('option')) {
93
- entity.itemFamilyId = Array.from(validValues)[Math.floor(Math.random() * validValues.size)];
93
+ entity.itemFamilyId =
94
+ Array.from(validValues)[Math.floor(Math.random() * validValues.size)];
94
95
  // can reuse itemFamilyId for options
95
96
  }
96
97
  },
@@ -238,18 +239,24 @@ class CreateEntity extends basecommand_1.BaseCommand {
238
239
  ? (0, file_helpers_1.parseFileAsJsonArray)(inputFilename)
239
240
  : Array.from({ length: count || 1 }).fill({});
240
241
  NUM_ENTITIES_TO_CREATE = partialEntities.length;
242
+ const { root: entityName } = (0, types_2.parseTypePath)(entityTypePath);
241
243
  // Ensure we have the required properties for the entity type
242
- if (SLUGS_THAT_MUST_BE_SPECIFIED_BY_TYPE_PATH[entityTypePath]) {
243
- const requiredSlugs = SLUGS_THAT_MUST_BE_SPECIFIED_BY_TYPE_PATH[entityTypePath];
244
+ if (SLUGS_THAT_MUST_BE_SPECIFIED_BY_TYPE_PATH[entityName]) {
245
+ const requiredSlugs = SLUGS_THAT_MUST_BE_SPECIFIED_BY_TYPE_PATH[entityName];
244
246
  for (const slug of requiredSlugs) {
245
- if (!propertySpecBySlug.has(slug)) {
246
- this.error(`Property '${slug}' must be specified for entity type '${entityTypePath}'.`);
247
+ // Check if the property is specified in command-line args
248
+ const isInCommandLineArgs = propertySpecBySlug.has(slug);
249
+ // Check if all entities from input file have this property
250
+ const allEntitiesHaveProperty = inputFilename
251
+ ? partialEntities.every((entity) => entity[slug] !== undefined && entity[slug] !== null)
252
+ : false;
253
+ if (!isInCommandLineArgs && !allEntitiesHaveProperty) {
254
+ this.error(`Property '${slug}' must be specified for entity type '${entityName}'.`);
247
255
  }
248
256
  }
249
257
  }
250
258
  try {
251
259
  const entitiesToCreate = await buildEntitiesToCreate(entityTypePath, partialEntities, propertySpecBySlug);
252
- const { root: entityName } = (0, types_2.parseTypePath)(entityTypePath);
253
260
  const createdEntities = await createEntities(entityName, entitiesToCreate);
254
261
  if (outputFilename) {
255
262
  fs_1.default.writeFileSync(outputFilename, JSON.stringify(createdEntities, null, 2));
@@ -294,15 +301,26 @@ async function buildEntitiesToCreate(entityTypePath, entities, propertySpecifica
294
301
  }));
295
302
  const limit = (0, p_limit_1.default)(30);
296
303
  await Promise.all(populatedEntities.map(async () => limit(() => throwIfEntityIsInvalid)));
304
+ // Skip system value generation if -p flag is set (preciseProperties mode)
305
+ if (SHOULD_ONLY_USE_SPECIFIED_PROPERTIES) {
306
+ console.log('Precise properties mode: skipping system value generation.');
307
+ return populatedEntities;
308
+ }
297
309
  // Add system values if needed
298
310
  const { root } = (0, types_2.parseTypePath)(type.typePath);
299
311
  const valueFinderApplierForEntity = FIND_VALID_VALUE_MAP[root] || [];
300
312
  for (const { slug, findValidValuesFn, applyValueToEntityFn } of valueFinderApplierForEntity) {
301
- // If the property is already specified, skip it unless it is a role for an option or family
313
+ // If the property is already specified in command-line args, skip it
302
314
  if (propertySpecificationBySlug?.has(slug)) {
303
315
  console.log(`Skipping property ${slug} because it is already specified.`);
304
316
  continue;
305
317
  }
318
+ // If all entities already have this property, skip finding values
319
+ const allEntitiesHaveProperty = populatedEntities.every((entity) => entity[slug] !== undefined && entity[slug] !== null);
320
+ if (allEntitiesHaveProperty) {
321
+ console.log(`Skipping property ${slug} because all entities already have this value.`);
322
+ continue;
323
+ }
306
324
  const values = await findValidValuesFn(populatedEntities, entities.length);
307
325
  if (values) {
308
326
  populatedEntities.forEach((e) => applyValueToEntityFn(e, values));
@@ -452,7 +470,10 @@ function generateRandomNumber(min, max) {
452
470
  return Math.floor(Math.random() * (max - min + 1)) + min;
453
471
  }
454
472
  function generateRandomReadableString() {
455
- 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.animals, unique_names_generator_1.colors], length: 5 });
473
+ return (0, unique_names_generator_1.uniqueNamesGenerator)({
474
+ dictionaries: [unique_names_generator_1.adjectives, unique_names_generator_1.animals, unique_names_generator_1.colors, unique_names_generator_1.animals, unique_names_generator_1.colors],
475
+ length: 5,
476
+ });
456
477
  }
457
478
  function generateRandomDateString() {
458
479
  return new Date().toISOString();
@@ -148,7 +148,15 @@ async function getEntityByTypePath(typePath, propertySpec, options = {}) {
148
148
  if (entityName === 'custom-entity' && !id) {
149
149
  criteria.typePath = typePath;
150
150
  }
151
- return find(entityName, { id, skipHydrateRelationships, relations, propertySlugs, criteria, skip, take });
151
+ return find(entityName, {
152
+ id,
153
+ skipHydrateRelationships,
154
+ relations,
155
+ propertySlugs,
156
+ criteria,
157
+ skip,
158
+ take,
159
+ });
152
160
  }
153
161
  function convertPropertySpecIntoCriteria(propertySpec) {
154
162
  const criteria = {};
@@ -165,7 +173,7 @@ async function find(entityName, options = {}) {
165
173
  skipHydrateRelationships,
166
174
  relations,
167
175
  skip,
168
- take
176
+ take,
169
177
  };
170
178
  if (propertySlugs && propertySlugs.length > 0) {
171
179
  queryOptions.customParams = { propertySlugs: propertySlugs.join(',') };
@@ -37,7 +37,7 @@ class UpdateEntity extends basecommand_1.BaseCommand {
37
37
  char: 'F',
38
38
  description: 'Force update without validation. Internal use only',
39
39
  required: false,
40
- })
40
+ }),
41
41
  };
42
42
  static args = {
43
43
  entityName: core_1.Args.string({
@@ -55,7 +55,7 @@ class UpdateEntity extends basecommand_1.BaseCommand {
55
55
  await (0, login_1.authUser)();
56
56
  const { args, argv } = await this.parse(UpdateEntity);
57
57
  const { id: specifiedId, entityName } = args;
58
- const { dryRun: isDryRun, inputFile: inputFilename, skipHydrateRelationships, force } = this.flags;
58
+ const { dryRun: isDryRun, inputFile: inputFilename, skipHydrateRelationships, force, } = this.flags;
59
59
  const propertySpecArgs = argv.slice(1, argv.length).filter(propertySpecifications_1.isValidPropertySpecification);
60
60
  const propertySpec = (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(propertySpecArgs);
61
61
  if (inputFilename && specifiedId) {
@@ -71,7 +71,7 @@ async function uploadFile(incomingFileName) {
71
71
  async function loadFile(config) {
72
72
  const entities = new sdk_1.Entities();
73
73
  // start a load job referencing the newly created file
74
- logger_1.default.info(`Loading with config: ${config}`);
74
+ logger_1.default.info(`Loading with config: ${JSON.stringify(config, null, 2)}`);
75
75
  const loadJob = await entities.create({
76
76
  entityName: 'loader-process',
77
77
  object: {
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.6.0-alpha-5",
2
+ "version": "3.6.0-alpha-6",
3
3
  "commands": {
4
4
  "app:create": {
5
5
  "id": "app:create",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrail/cli",
3
- "version": "3.6.0-alpha-5",
3
+ "version": "3.6.0-alpha-6",
4
4
  "description": "VibeIQ's Contrail Platform CLI.",
5
5
  "bin": {
6
6
  "contrail-cli": "./bin/run",