@contrail/cli 3.4.8 → 3.4.9-alpha.bd39c0c

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.4.8 linux-x64 node-v20.20.2
20
+ @contrail/cli/3.4.9-alpha.bd39c0c linux-x64 node-v24.14.1
21
21
  $ contrail --help [COMMAND]
22
22
  USAGE
23
23
  $ contrail COMMAND
@@ -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: {
@@ -237,9 +237,9 @@ function convertFromDisplayToValue(csvJSON, optionSetUsingTypePropertiesBySlug,
237
237
  if (value === null || value === undefined) {
238
238
  continue;
239
239
  }
240
- const values = value?.split(',');
240
+ const values = value?.split(',').map((v) => v.trim());
241
241
  for (let i = 0; i < values?.length; i++) {
242
- const innerValue = values[i].trim();
242
+ const innerValue = values[i];
243
243
  if (!property || property?.optionLookupByValue[innerValue]) {
244
244
  continue;
245
245
  }
@@ -572,6 +572,27 @@ describe('Data Transformer Functions', () => {
572
572
  expect(csvJSON[0].color).toEqual('red,blue');
573
573
  expect(csvJSON[1].color).toEqual('blue');
574
574
  });
575
+ it('should trim spaces from multi-select values that match by value lookup', () => {
576
+ const csvJSON = [
577
+ {
578
+ id: '1',
579
+ color: 'red, blue , green',
580
+ },
581
+ ];
582
+ const optionSetUsingTypePropertiesBySlug = {
583
+ color: {
584
+ propertyType: 'multi_select',
585
+ optionLookupByDisplay: {},
586
+ optionLookupByValue: {
587
+ red: { value: 'red' },
588
+ blue: { value: 'blue' },
589
+ green: { value: 'green' },
590
+ },
591
+ },
592
+ };
593
+ (0, data_transformer_functions_1.convertFromDisplayToValue)(csvJSON, optionSetUsingTypePropertiesBySlug, [], []);
594
+ expect(csvJSON[0].color).toEqual('red,blue,green');
595
+ });
575
596
  it('should handle empty values for multi select values, returning the same values', () => {
576
597
  const csvJSON = [
577
598
  {
@@ -48,7 +48,10 @@ function addProperty(propertyName, allPropertiesSlugs, valueType, object, value)
48
48
  value = null;
49
49
  }
50
50
  if (valueType === types_1.PropertyType.MultiSelect && typeof value === 'string') {
51
- value = value.split(',');
51
+ value = value
52
+ .split(',')
53
+ .map((v) => v.trim())
54
+ .filter((v) => v.length > 0);
52
55
  }
53
56
  const propertyLevels = propertyName.split('.');
54
57
  if (allPropertiesSlugs.includes(propertyLevels[0])) {
@@ -23,6 +23,11 @@ describe('addProperty', () => {
23
23
  const result = (0, entity_builder_helpers_1.addProperty)('testMultiSelect', ['testMultiSelect'], entity_types_1.PropertyType.MultiSelect, obj, obj.testMultiSelect);
24
24
  expect(result.testMultiSelect).toEqual(['1', '2']);
25
25
  });
26
+ it('should trim spaces and drop empties when splitting a spaced multi-select string', () => {
27
+ const obj = { testMultiSelect: '1, 2 , 3,, ' };
28
+ const result = (0, entity_builder_helpers_1.addProperty)('testMultiSelect', ['testMultiSelect'], entity_types_1.PropertyType.MultiSelect, obj, obj.testMultiSelect);
29
+ expect(result.testMultiSelect).toEqual(['1', '2', '3']);
30
+ });
26
31
  it('should set date value as null when value is ""', () => {
27
32
  const obj = { testDate: '' };
28
33
  const result = (0, entity_builder_helpers_1.addProperty)('testDate', ['testDate'], entity_types_1.PropertyType.Date, obj, obj.testDate);
@@ -3,3 +3,4 @@ import { LoaderConfig, ExecuteOptions, ConstructedEntitySet } from './types';
3
3
  import { ItemExecutionResult, ItemPreviewResult } from './item-execute-helpers';
4
4
  export declare function previewProjectItemEntities(client: EntitiesClient, entitySet: ConstructedEntitySet, config: LoaderConfig, projectNameById?: Record<string, string>): Promise<ItemPreviewResult>;
5
5
  export declare function executeProjectItemEntities(client: EntitiesClient, entitySet: ConstructedEntitySet, config: LoaderConfig, options?: ExecuteOptions): Promise<ItemExecutionResult>;
6
+ export declare function applyAddedFromSource(changes: any, existingProjectItem: any | undefined): void;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.executeProjectItemEntities = exports.previewProjectItemEntities = void 0;
3
+ exports.applyAddedFromSource = exports.executeProjectItemEntities = exports.previewProjectItemEntities = void 0;
4
4
  const types_1 = require("./types");
5
5
  const util_1 = require("@contrail/util");
6
6
  const lodash_1 = require("lodash");
@@ -63,6 +63,7 @@ async function previewProjectItemEntities(client, entitySet, config, projectName
63
63
  delete changes.projectId;
64
64
  changes.projectId = projectId;
65
65
  changes.itemId = item.id;
66
+ applyAddedFromSource(changes, existing);
66
67
  if ((0, entities_helper_1.UpdateNeeded)(changes, existing)) {
67
68
  familyToUpdate.push(family);
68
69
  }
@@ -111,6 +112,7 @@ async function previewProjectItemEntities(client, entitySet, config, projectName
111
112
  delete changes.projectId;
112
113
  changes.projectId = projectId;
113
114
  changes.itemId = item.id;
115
+ applyAddedFromSource(changes, existing);
114
116
  if ((0, entities_helper_1.UpdateNeeded)(changes, existing)) {
115
117
  optionToUpdate.push(opt);
116
118
  }
@@ -290,6 +292,7 @@ async function executeProjectItemEntities(client, entitySet, config, options) {
290
292
  delete changes.projectId;
291
293
  changes.projectId = projectId;
292
294
  changes.itemId = item.id;
295
+ applyAddedFromSource(changes, existingProjectItem);
293
296
  if (existingProjectItem) {
294
297
  if (!(0, entities_helper_1.UpdateNeeded)(changes, existingProjectItem)) {
295
298
  familyUnchangedCount++;
@@ -358,6 +361,7 @@ async function executeProjectItemEntities(client, entitySet, config, options) {
358
361
  delete changes.projectId;
359
362
  changes.projectId = projectId;
360
363
  changes.itemId = item.id;
364
+ applyAddedFromSource(changes, existingProjectItem);
361
365
  if (existingProjectItem) {
362
366
  if (!(0, entities_helper_1.UpdateNeeded)(changes, existingProjectItem)) {
363
367
  optionUnchangedCount++;
@@ -420,6 +424,15 @@ async function executeProjectItemEntities(client, entitySet, config, options) {
420
424
  return { summaries, skippedRows: allSkippedRows, warnings: allWarnings, hasFailures };
421
425
  }
422
426
  exports.executeProjectItemEntities = executeProjectItemEntities;
427
+ function applyAddedFromSource(changes, existingProjectItem) {
428
+ if (existingProjectItem?.addedFromSource) {
429
+ delete changes.addedFromSource;
430
+ }
431
+ else {
432
+ changes.addedFromSource = 'LOADER';
433
+ }
434
+ }
435
+ exports.applyAddedFromSource = applyAddedFromSource;
423
436
  function splitForProjectItems(incomingEntities, typesByPath) {
424
437
  const byCompositeKey = {};
425
438
  for (const entity of incomingEntities) {
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const project_item_execute_helpers_1 = require("./project-item-execute-helpers");
4
+ describe('applyAddedFromSource', () => {
5
+ it('sets addedFromSource=LOADER when no existing project-item is present (create)', () => {
6
+ const changes = { name: 'New Project Item' };
7
+ (0, project_item_execute_helpers_1.applyAddedFromSource)(changes, undefined);
8
+ expect(changes.addedFromSource).toBe('LOADER');
9
+ });
10
+ it('sets addedFromSource=LOADER when existing project-item has no addedFromSource', () => {
11
+ const changes = { name: 'Updated' };
12
+ const existing = { id: 'proj:item', name: 'Old' };
13
+ (0, project_item_execute_helpers_1.applyAddedFromSource)(changes, existing);
14
+ expect(changes.addedFromSource).toBe('LOADER');
15
+ });
16
+ it('preserves the existing addedFromSource by removing it from the upsert payload', () => {
17
+ const changes = { name: 'Updated', addedFromSource: 'LOADER' };
18
+ const existing = { id: 'proj:item', addedFromSource: 'MANUAL' };
19
+ (0, project_item_execute_helpers_1.applyAddedFromSource)(changes, existing);
20
+ expect(changes).not.toHaveProperty('addedFromSource');
21
+ });
22
+ it('strips a row-supplied addedFromSource so it cannot overwrite a previously persisted one', () => {
23
+ const changes = { name: 'Updated', addedFromSource: 'EXTERNAL_SYSTEM' };
24
+ const existing = { id: 'proj:item', addedFromSource: 'API_INTEGRATION' };
25
+ (0, project_item_execute_helpers_1.applyAddedFromSource)(changes, existing);
26
+ expect(changes).not.toHaveProperty('addedFromSource');
27
+ });
28
+ it('treats an existing project-item with empty-string addedFromSource as "unset" and applies LOADER', () => {
29
+ const changes = {};
30
+ const existing = { id: 'proj:item', addedFromSource: '' };
31
+ (0, project_item_execute_helpers_1.applyAddedFromSource)(changes, existing);
32
+ expect(changes.addedFromSource).toBe('LOADER');
33
+ });
34
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrail/loader",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Client library for helping with loader jobs.",
5
5
  "homepage": "https://archergreysorg.github.io/contrail-loader/",
6
6
  "main": "lib/index.js",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.4.8",
2
+ "version": "3.4.9-alpha.bd39c0c",
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.4.8",
3
+ "version": "3.4.9-alpha.bd39c0c",
4
4
  "description": "VibeIQ's Contrail Platform CLI.",
5
5
  "bin": {
6
6
  "contrail-cli": "./bin/run",
@@ -31,7 +31,7 @@
31
31
  ],
32
32
  "dependencies": {
33
33
  "@contrail/entity-types": "^1.6.1",
34
- "@contrail/loader": "^2.0.0",
34
+ "@contrail/loader": "^2.0.2",
35
35
  "@contrail/org-config-migration": "^1.1.13",
36
36
  "@contrail/sdk": "^1.5.5",
37
37
  "@contrail/types": "^3.1.5",
@@ -134,7 +134,7 @@
134
134
  "format": "prettier --write \"**/*.ts\"",
135
135
  "copy-templates": "cp -r templates/ dist/templates",
136
136
  "postpack": "shx rm -f oclif.manifest.json",
137
- "prepack": "yarn build && oclif manifest && oclif readme",
137
+ "prepack": "npm run build && oclif manifest && oclif readme",
138
138
  "test": "jest",
139
139
  "version": "oclif readme && git add README.md"
140
140
  },