@contrail/cli 3.4.10 → 3.4.11-alpha.0f34b47

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 (38) hide show
  1. package/README.md +3 -3
  2. package/dist/api/types.d.ts +0 -5
  3. package/dist/api/types.js +1 -36
  4. package/dist/commands/types/getAll.js +0 -18
  5. package/dist/commands/types/loadAll.js +0 -2
  6. package/dist/commands/types/mergeTypeProperties.js +0 -5
  7. package/dist/commands/types/uploadOptionSetHierarchies.js +0 -117
  8. package/dist/commands/types/uploadRuleSets.js +2 -85
  9. package/dist/commands/types/uploadTypePolicies.js +2 -86
  10. package/dist/commands/types/uploadTypePropertyPolicies.d.ts +0 -1
  11. package/dist/commands/types/uploadTypePropertyPolicies.js +3 -139
  12. package/dist/commands/types/uploadUsageInfo.d.ts +3 -0
  13. package/dist/commands/types/uploadUsageInfo.js +4 -1
  14. package/dist/templates/typescript/tsup.config.ts +0 -0
  15. package/node_modules/@contrail/loader/lib/common/chunk-by-url-length.d.ts +6 -0
  16. package/node_modules/@contrail/loader/lib/common/chunk-by-url-length.js +31 -0
  17. package/node_modules/@contrail/loader/lib/common/chunk-by-url-length.spec.d.ts +1 -0
  18. package/node_modules/@contrail/loader/lib/common/chunk-by-url-length.spec.js +70 -0
  19. package/node_modules/@contrail/loader/lib/common/data-transformer-functions.d.ts +9 -1
  20. package/node_modules/@contrail/loader/lib/common/data-transformer-functions.js +53 -8
  21. package/node_modules/@contrail/loader/lib/common/data-transformer.spec.js +128 -0
  22. package/node_modules/@contrail/loader/lib/common/entities-helper.js +2 -1
  23. package/node_modules/@contrail/loader/lib/constants.d.ts +2 -0
  24. package/node_modules/@contrail/loader/lib/constants.js +3 -1
  25. package/node_modules/@contrail/loader/lib/entities-v2/entities-helper.js +2 -1
  26. package/node_modules/@contrail/loader/lib/entities-v2/entity-processor-v2.js +2 -2
  27. package/node_modules/@contrail/loader/lib/entities-v2/entity-processor-v2.spec.js +8 -10
  28. package/node_modules/@contrail/loader/lib/entities-v2/file-preprocessor-v2.js +2 -1
  29. package/node_modules/@contrail/loader/lib/entities-v2/linesheet-v2/item-helper.js +2 -1
  30. package/node_modules/@contrail/loader/lib/entity-processor.js +2 -2
  31. package/node_modules/@contrail/loader/lib/entity-processor.spec.js +8 -10
  32. package/node_modules/@contrail/loader/lib/pipeline/item-execute-helpers.js +2 -1
  33. package/node_modules/@contrail/loader/lib/pipeline/project-item-execute-helpers.js +3 -2
  34. package/node_modules/@contrail/loader/lib/pipeline/transform.js +32 -6
  35. package/node_modules/@contrail/loader/lib/pipeline/transform.spec.js +64 -1
  36. package/node_modules/@contrail/loader/package.json +1 -1
  37. package/oclif.manifest.json +5 -2
  38. package/package.json +2 -2
@@ -4,6 +4,7 @@ exports.getPropertyVariants = exports.assignUserLists = exports.getUsersInOrg =
4
4
  const util_1 = require("@contrail/util");
5
5
  const types_1 = require("@contrail/types");
6
6
  const lodash_1 = require("lodash");
7
+ const chunk_by_url_length_1 = require("../common/chunk-by-url-length");
7
8
  const entity_types_1 = require("@contrail/entity-types");
8
9
  const pLimit = require('p-limit');
9
10
  var EntitiesLambdaCallType;
@@ -176,7 +177,7 @@ async function assignObjectReferences(client, typePaths, typesByPath, incomingEn
176
177
  const allORByFedId = {};
177
178
  for (const rootType of Object.keys(allORFedIdsByType)) {
178
179
  const fedIds = [...new Set(allORFedIdsByType[rootType])];
179
- const chunks = (0, lodash_1.chunk)(fedIds, 200);
180
+ const chunks = (0, chunk_by_url_length_1.chunkByUrlLength)(fedIds);
180
181
  const federatedPromises = [];
181
182
  for (const chunk of chunks) {
182
183
  if (!chunk?.length) {
@@ -4,7 +4,7 @@ exports.EntityProcessorV2 = void 0;
4
4
  const entities_helper_1 = require("../common/entities-helper");
5
5
  const entity_builder_helpers_1 = require("../common/entity-builder-helpers");
6
6
  const processor_registry_1 = require("../processor-registry");
7
- const lodash_1 = require("lodash");
7
+ const chunk_by_url_length_1 = require("../common/chunk-by-url-length");
8
8
  const entity_types_1 = require("@contrail/entity-types");
9
9
  const type_helper_1 = require("../common/type-helper");
10
10
  const constants_1 = require("../constants");
@@ -157,7 +157,7 @@ class EntityProcessorV2 {
157
157
  return uniqueFedIds;
158
158
  }
159
159
  static async fetchCurrentEntities(client, entityType, federatedIds) {
160
- const chunks = (0, lodash_1.chunk)(federatedIds, 200);
160
+ const chunks = (0, chunk_by_url_length_1.chunkByUrlLength)(federatedIds);
161
161
  const allCurrentEntitiesByFederatedId = {};
162
162
  const federatedPromises = [];
163
163
  for (const chunk of chunks) {
@@ -6,7 +6,7 @@ const entity_builder_helpers_1 = require("../common/entity-builder-helpers");
6
6
  const types_1 = require("@contrail/types");
7
7
  const entity_types_1 = require("@contrail/entity-types");
8
8
  const processor_registry_1 = require("../processor-registry");
9
- const lodash_1 = require("lodash");
9
+ const chunk_by_url_length_1 = require("../common/chunk-by-url-length");
10
10
  const util_1 = require("../common/util");
11
11
  const color_processor_v2_1 = require("./colors-v2/color-processor-v2");
12
12
  const constants_1 = require("../constants");
@@ -15,9 +15,7 @@ jest.mock('../processor-registry');
15
15
  jest.mock('@contrail/entity-types');
16
16
  jest.mock('../common/entities-helper');
17
17
  jest.mock('../common/type-helper');
18
- jest.mock('lodash', () => ({
19
- chunk: jest.fn(),
20
- }));
18
+ jest.mock('../common/chunk-by-url-length');
21
19
  describe('EntityProcessorV2', () => {
22
20
  const mockTypesByPath = {
23
21
  color: {
@@ -217,7 +215,7 @@ describe('EntityProcessorV2', () => {
217
215
  ['1', '2'],
218
216
  ['3', '4'],
219
217
  ];
220
- lodash_1.chunk.mockReturnValue(chunks);
218
+ chunk_by_url_length_1.chunkByUrlLength.mockReturnValue(chunks);
221
219
  const mockEntities = [
222
220
  { federatedId: '1', name: 'Entity 1' },
223
221
  { federatedId: '2', name: 'Entity 2' },
@@ -228,12 +226,12 @@ describe('EntityProcessorV2', () => {
228
226
  '1': { federatedId: '1', name: 'Entity 1' },
229
227
  '2': { federatedId: '2', name: 'Entity 2' },
230
228
  });
231
- expect(lodash_1.chunk).toHaveBeenCalledWith(federatedIds, 200);
229
+ expect(chunk_by_url_length_1.chunkByUrlLength).toHaveBeenCalledWith(federatedIds);
232
230
  expect(entities_helper_1.retryOnTimeout).toHaveBeenCalledTimes(2);
233
231
  });
234
232
  it('should handle empty federatedIds array', async () => {
235
233
  const federatedIds = [];
236
- lodash_1.chunk.mockReturnValue([]);
234
+ chunk_by_url_length_1.chunkByUrlLength.mockReturnValue([]);
237
235
  const result = await entity_processor_v2_1.EntityProcessorV2.fetchCurrentEntities(client, entity_types_1.EntityType.COLOR, federatedIds);
238
236
  expect(result).toEqual({});
239
237
  expect(entities_helper_1.retryOnTimeout).not.toHaveBeenCalled();
@@ -241,7 +239,7 @@ describe('EntityProcessorV2', () => {
241
239
  it('should handle API errors and rethrow', async () => {
242
240
  const federatedIds = ['1'];
243
241
  const chunks = [['1']];
244
- lodash_1.chunk.mockReturnValue(chunks);
242
+ chunk_by_url_length_1.chunkByUrlLength.mockReturnValue(chunks);
245
243
  const error = new Error('API Error');
246
244
  entities_helper_1.retryOnTimeout.mockRejectedValue(error);
247
245
  await expect(entity_processor_v2_1.EntityProcessorV2.fetchCurrentEntities(client, entity_types_1.EntityType.COLOR, federatedIds)).rejects.toThrow('API Error');
@@ -250,7 +248,7 @@ describe('EntityProcessorV2', () => {
250
248
  it('should handle empty response from API', async () => {
251
249
  const federatedIds = ['1'];
252
250
  const chunks = [['1']];
253
- lodash_1.chunk.mockReturnValue(chunks);
251
+ chunk_by_url_length_1.chunkByUrlLength.mockReturnValue(chunks);
254
252
  entities_helper_1.retryOnTimeout.mockResolvedValue([]);
255
253
  const result = await entity_processor_v2_1.EntityProcessorV2.fetchCurrentEntities(client, entity_types_1.EntityType.COLOR, federatedIds);
256
254
  expect(result).toEqual({});
@@ -261,7 +259,7 @@ describe('EntityProcessorV2', () => {
261
259
  ['1', '2'],
262
260
  ['3', '4'],
263
261
  ];
264
- lodash_1.chunk.mockReturnValue(chunks);
262
+ chunk_by_url_length_1.chunkByUrlLength.mockReturnValue(chunks);
265
263
  const mockEntities1 = [
266
264
  { federatedId: '1', name: 'Entity 1' },
267
265
  { federatedId: '2', name: 'Entity 2' },
@@ -188,12 +188,13 @@ class LoaderDataPreprocessorV2 {
188
188
  };
189
189
  }
190
190
  static async runPreprocessingPipeline(client, loaderProcess, reducedTypes, processedData, preprocessingStepResults, transformationErrors, transformationWarnings, systemErrors) {
191
- const { typePropertiesBySlug, typePropertiesByLabel } = (0, data_transformer_functions_1.getPropertiesBySlugAndLabel)(reducedTypes);
191
+ const { typePropertiesBySlug, typePropertiesByLabel, typePathStateBySlug } = (0, data_transformer_functions_1.getPropertiesBySlugAndLabel)(reducedTypes);
192
192
  const optionSetUsingTypePropertiesBySlug = (0, data_transformer_functions_1.getOptionSetsUsingTypePropertiesBySlug)(reducedTypes);
193
193
  const typePropertyMaps = {
194
194
  typePropertiesBySlug,
195
195
  typePropertiesByLabel,
196
196
  optionSetUsingTypePropertiesBySlug,
197
+ typePathStateBySlug,
197
198
  };
198
199
  for (const preprocessingStep of this.getPreprocessingPipeline()) {
199
200
  try {
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getAssortment = exports.convertToComparableEntities = exports.mapAssortmentItemsToItemsAndFillItemId = exports.getItemsFromFederatedIds = exports.getAssortmentItemProperties = exports.getAssortmentItems = void 0;
4
4
  const lodash_1 = require("lodash");
5
+ const chunk_by_url_length_1 = require("../../common/chunk-by-url-length");
5
6
  const entities_helper_1 = require("../../common/entities-helper");
6
7
  const pLimit = require('p-limit');
7
8
  const limit = pLimit(5);
@@ -58,7 +59,7 @@ function mapTypePropertiesToValueType(typeProperties) {
58
59
  }
59
60
  async function getItemsFromFederatedIds(client, incomingRows) {
60
61
  const federatedIds = extractUniqueFederatedIds(incomingRows);
61
- const chunks = (0, lodash_1.chunk)(federatedIds, 200);
62
+ const chunks = (0, chunk_by_url_length_1.chunkByUrlLength)(federatedIds);
62
63
  const allCurrentItemsByFederatedId = await fetchItemsByFederatedIds(client, chunks);
63
64
  return allCurrentItemsByFederatedId;
64
65
  }
@@ -4,7 +4,7 @@ exports.EntityProcessor = void 0;
4
4
  const entities_helper_1 = require("./common/entities-helper");
5
5
  const entity_builder_helpers_1 = require("./common/entity-builder-helpers");
6
6
  const processor_registry_1 = require("./processor-registry");
7
- const lodash_1 = require("lodash");
7
+ const chunk_by_url_length_1 = require("./common/chunk-by-url-length");
8
8
  const type_helper_1 = require("./common/type-helper");
9
9
  const entity_types_1 = require("@contrail/entity-types");
10
10
  const util_1 = require("./common/util");
@@ -104,7 +104,7 @@ class EntityProcessor {
104
104
  return [...uniqueFedIds, ...nonUniqueFedIds];
105
105
  }
106
106
  static async fetchCurrentEntities(client, entityType, federatedIds) {
107
- const chunks = (0, lodash_1.chunk)(federatedIds, 200);
107
+ const chunks = (0, chunk_by_url_length_1.chunkByUrlLength)(federatedIds);
108
108
  const allCurrentEntitiesByFederatedId = {};
109
109
  const federatedPromises = [];
110
110
  for (const chunk of chunks) {
@@ -6,7 +6,7 @@ const entity_builder_helpers_1 = require("./common/entity-builder-helpers");
6
6
  const types_1 = require("@contrail/types");
7
7
  const entity_types_1 = require("@contrail/entity-types");
8
8
  const processor_registry_1 = require("./processor-registry");
9
- const lodash_1 = require("lodash");
9
+ const chunk_by_url_length_1 = require("./common/chunk-by-url-length");
10
10
  const util_1 = require("./common/util");
11
11
  const constants_1 = require("./constants");
12
12
  jest.mock('./common/entity-builder-helpers');
@@ -14,9 +14,7 @@ jest.mock('./processor-registry');
14
14
  jest.mock('@contrail/entity-types');
15
15
  jest.mock('./common/entities-helper');
16
16
  jest.mock('./common/type-helper');
17
- jest.mock('lodash', () => ({
18
- chunk: jest.fn(),
19
- }));
17
+ jest.mock('./common/chunk-by-url-length');
20
18
  describe('EntityProcessor', () => {
21
19
  const mockTypesByPath = {
22
20
  color: {
@@ -203,7 +201,7 @@ describe('EntityProcessor', () => {
203
201
  ['1', '2'],
204
202
  ['3', '4'],
205
203
  ];
206
- lodash_1.chunk.mockReturnValue(chunks);
204
+ chunk_by_url_length_1.chunkByUrlLength.mockReturnValue(chunks);
207
205
  const mockEntities = [
208
206
  { federatedId: '1', name: 'Entity 1' },
209
207
  { federatedId: '2', name: 'Entity 2' },
@@ -214,12 +212,12 @@ describe('EntityProcessor', () => {
214
212
  '1': { federatedId: '1', name: 'Entity 1' },
215
213
  '2': { federatedId: '2', name: 'Entity 2' },
216
214
  });
217
- expect(lodash_1.chunk).toHaveBeenCalledWith(federatedIds, 200);
215
+ expect(chunk_by_url_length_1.chunkByUrlLength).toHaveBeenCalledWith(federatedIds);
218
216
  expect(entities_helper_1.retryOnTimeout).toHaveBeenCalledTimes(2);
219
217
  });
220
218
  it('should handle empty federatedIds array', async () => {
221
219
  const federatedIds = [];
222
- lodash_1.chunk.mockReturnValue([]);
220
+ chunk_by_url_length_1.chunkByUrlLength.mockReturnValue([]);
223
221
  const result = await entity_processor_1.EntityProcessor.fetchCurrentEntities(client, entity_types_1.EntityType.COLOR, federatedIds);
224
222
  expect(result).toEqual({});
225
223
  expect(entities_helper_1.retryOnTimeout).not.toHaveBeenCalled();
@@ -227,7 +225,7 @@ describe('EntityProcessor', () => {
227
225
  it('should handle API errors and rethrow', async () => {
228
226
  const federatedIds = ['1'];
229
227
  const chunks = [['1']];
230
- lodash_1.chunk.mockReturnValue(chunks);
228
+ chunk_by_url_length_1.chunkByUrlLength.mockReturnValue(chunks);
231
229
  const error = new Error('API Error');
232
230
  entities_helper_1.retryOnTimeout.mockRejectedValue(error);
233
231
  await expect(entity_processor_1.EntityProcessor.fetchCurrentEntities(client, entity_types_1.EntityType.COLOR, federatedIds)).rejects.toThrow('API Error');
@@ -236,7 +234,7 @@ describe('EntityProcessor', () => {
236
234
  it('should handle empty response from API', async () => {
237
235
  const federatedIds = ['1'];
238
236
  const chunks = [['1']];
239
- lodash_1.chunk.mockReturnValue(chunks);
237
+ chunk_by_url_length_1.chunkByUrlLength.mockReturnValue(chunks);
240
238
  entities_helper_1.retryOnTimeout.mockResolvedValue([]);
241
239
  const result = await entity_processor_1.EntityProcessor.fetchCurrentEntities(client, entity_types_1.EntityType.COLOR, federatedIds);
242
240
  expect(result).toEqual({});
@@ -248,7 +246,7 @@ describe('EntityProcessor', () => {
248
246
  ['1', '2'],
249
247
  ['3', '4'],
250
248
  ];
251
- lodash_1.chunk.mockReturnValue(chunks);
249
+ chunk_by_url_length_1.chunkByUrlLength.mockReturnValue(chunks);
252
250
  const mockEntities1 = [
253
251
  { federatedId: '1', name: 'Entity 1' },
254
252
  { federatedId: '2', name: 'Entity 2' },
@@ -4,6 +4,7 @@ exports.executeItemEntities = exports.previewItemEntities = exports.splitIntoFam
4
4
  const types_1 = require("./types");
5
5
  const util_1 = require("@contrail/util");
6
6
  const lodash_1 = require("lodash");
7
+ const chunk_by_url_length_1 = require("../common/chunk-by-url-length");
7
8
  const entities_helper_1 = require("../entities-v2/entities-helper");
8
9
  const type_helper_1 = require("../common/type-helper");
9
10
  const pLimit = require('p-limit');
@@ -461,7 +462,7 @@ async function batchUpdateEntities(client, entities, entityName, batchSize, limi
461
462
  return { updated, failures };
462
463
  }
463
464
  async function refreshEntityCache(client, federatedIds, cache) {
464
- const chunks = (0, lodash_1.chunk)(federatedIds, 200);
465
+ const chunks = (0, chunk_by_url_length_1.chunkByUrlLength)(federatedIds);
465
466
  const pLimitFetch = pLimit(5);
466
467
  const promises = chunks.map((batch) => pLimitFetch(async () => {
467
468
  try {
@@ -4,6 +4,7 @@ exports.applyAddedFromSource = exports.executeProjectItemEntities = exports.prev
4
4
  const types_1 = require("./types");
5
5
  const util_1 = require("@contrail/util");
6
6
  const lodash_1 = require("lodash");
7
+ const chunk_by_url_length_1 = require("../common/chunk-by-url-length");
7
8
  const entities_helper_1 = require("../entities-v2/entities-helper");
8
9
  const type_helper_1 = require("../common/type-helper");
9
10
  const item_execute_helpers_1 = require("./item-execute-helpers");
@@ -492,7 +493,7 @@ async function resolveItemsByFederatedId(client, incomingEntities, maxRetries) {
492
493
  federatedIds.add(entity.itemOptionFederatedId);
493
494
  }
494
495
  const result = {};
495
- const chunks = (0, lodash_1.chunk)(Array.from(federatedIds), 200);
496
+ const chunks = (0, chunk_by_url_length_1.chunkByUrlLength)(Array.from(federatedIds));
496
497
  const limit = pLimit(5);
497
498
  const promises = chunks.map((batch) => limit(async () => {
498
499
  try {
@@ -527,7 +528,7 @@ async function fetchCurrentProjectItemsByItemId(client, projectId, itemIds, maxR
527
528
  const result = {};
528
529
  if (!itemIds.length)
529
530
  return result;
530
- const chunks = (0, lodash_1.chunk)(itemIds, 200);
531
+ const chunks = (0, chunk_by_url_length_1.chunkByUrlLength)(itemIds);
531
532
  const limit = pLimit(5);
532
533
  const promises = chunks.map((batch) => limit(async () => {
533
534
  try {
@@ -192,10 +192,10 @@ function analyzeColumns(rows, typePropertyMaps, config) {
192
192
  if (!rows?.length)
193
193
  return { columns: [], unmappedTypeProperties: [] };
194
194
  const entityTypes = (0, types_2.loadTypeToEntityTypes)(config.loadType);
195
- const { typePropertiesBySlug, typePropertiesByLabel } = typePropertyMaps;
195
+ const { typePropertiesBySlug, typePropertiesByLabel, typePathStateBySlug } = typePropertyMaps;
196
196
  const optionSetUsingTypePropertiesBySlug = typePropertyMaps.optionSetUsingTypePropertiesBySlug;
197
197
  const csvHeaders = extractUniqueHeaders(rows);
198
- const columns = csvHeaders.map((header) => classifyColumn(header, typePropertiesBySlug, typePropertiesByLabel, optionSetUsingTypePropertiesBySlug, entityTypes));
198
+ const columns = csvHeaders.map((header) => classifyColumn(header, typePropertiesBySlug, typePropertiesByLabel, optionSetUsingTypePropertiesBySlug, entityTypes, typePathStateBySlug));
199
199
  const coveredSlugs = new Set();
200
200
  for (const column of columns) {
201
201
  if (column.matchedSlug) {
@@ -220,7 +220,15 @@ function analyzeColumns(rows, typePropertyMaps, config) {
220
220
  }
221
221
  }
222
222
  const unmappedTypeProperties = Object.entries(typePropertiesBySlug)
223
- .filter(([slug, prop]) => !coveredSlugs.has(slug.trim()) && !prop.isArchived)
223
+ .filter(([slug, prop]) => {
224
+ const trimmedSlug = slug.trim();
225
+ if (coveredSlugs.has(trimmedSlug))
226
+ return false;
227
+ if (typePathStateBySlug) {
228
+ return !isArchivedAcrossAllSubtypes(trimmedSlug, typePathStateBySlug);
229
+ }
230
+ return !prop.isArchived;
231
+ })
224
232
  .map(([slug, prop]) => ({
225
233
  slug: slug.trim(),
226
234
  label: prop.label,
@@ -243,7 +251,7 @@ function extractUniqueHeaders(rows) {
243
251
  }
244
252
  return headers;
245
253
  }
246
- function classifyColumn(header, typePropertiesBySlug, typePropertiesByLabel, optionSetProps, entityTypes) {
254
+ function classifyColumn(header, typePropertiesBySlug, typePropertiesByLabel, optionSetProps, entityTypes, typePathStateBySlug) {
247
255
  const isItemLoad = entityTypes.includes(types_1.EntityType.ITEM) || entityTypes.includes(types_1.EntityType.PROJECT_ITEM);
248
256
  const isEntityTypeSystemProp = entityTypes.some((et) => ENTITY_TYPE_SYSTEM_PROPERTIES[et]?.has(header));
249
257
  const isSystemProp = SYSTEM_PROPERTIES.has(header) || isEntityTypeSystemProp;
@@ -253,7 +261,14 @@ function classifyColumn(header, typePropertiesBySlug, typePropertiesByLabel, opt
253
261
  const baseSlugMatch = baseName !== header ? typePropertiesBySlug[baseName] : undefined;
254
262
  const matchedProp = slugMatch || labelMatch || baseSlugMatch;
255
263
  const isMapped = !!matchedProp || isSystemProp;
256
- const isArchived = matchedProp?.isArchived === true;
264
+ let isArchived;
265
+ if (matchedProp && typePathStateBySlug) {
266
+ const matchedSlug = (matchedProp.slug || '').trim();
267
+ isArchived = isArchivedAcrossAllSubtypes(matchedSlug, typePathStateBySlug);
268
+ }
269
+ else {
270
+ isArchived = matchedProp?.isArchived === true;
271
+ }
257
272
  const hasOptionSet = !!(optionSetProps[header] || optionSetProps[baseName]);
258
273
  let isRequired;
259
274
  let requiredNote;
@@ -292,6 +307,16 @@ function stripLevelSuffix(name) {
292
307
  return name.slice(0, -6);
293
308
  return name;
294
309
  }
310
+ function isArchivedAcrossAllSubtypes(slug, typePathStateBySlug) {
311
+ const states = typePathStateBySlug[slug];
312
+ if (!states || states.size === 0)
313
+ return false;
314
+ for (const state of states.values()) {
315
+ if (!state.isDisabled)
316
+ return false;
317
+ }
318
+ return true;
319
+ }
295
320
  const SUBTYPE_ENTITY_TYPES = new Set([types_1.EntityType.ITEM, types_1.EntityType.CUSTOM_ENTITY]);
296
321
  const SUBTYPE_PREFIX = {
297
322
  [types_1.EntityType.ITEM]: 'item',
@@ -344,12 +369,13 @@ async function fetchTypeDefinitions(client, rows, config) {
344
369
  }
345
370
  const typeRoots = (0, types_2.entityTypesToTypeRoots)(entityTypes);
346
371
  const reducedTypes = await (0, data_transformer_functions_1.getReducedTypes)(typeRoots, client);
347
- const { typePropertiesBySlug, typePropertiesByLabel } = (0, data_transformer_functions_1.getPropertiesBySlugAndLabel)(reducedTypes);
372
+ const { typePropertiesBySlug, typePropertiesByLabel, typePathStateBySlug } = (0, data_transformer_functions_1.getPropertiesBySlugAndLabel)(reducedTypes);
348
373
  const optionSetUsingTypePropertiesBySlug = (0, data_transformer_functions_1.getOptionSetsUsingTypePropertiesBySlug)(reducedTypes);
349
374
  const typePropertyMaps = {
350
375
  typePropertiesBySlug,
351
376
  typePropertiesByLabel,
352
377
  optionSetUsingTypePropertiesBySlug,
378
+ typePathStateBySlug,
353
379
  };
354
380
  const typesByPath = await (0, type_helper_1.buildTypesByPathForPipeline)(client, Array.from(typePaths));
355
381
  return { typePropertyMaps, typesByPath, generalErrors };
@@ -49,7 +49,11 @@ describe('transform', () => {
49
49
  getReducedTypesSpy = jest.spyOn(dataTransformerFunctions, 'getReducedTypes')
50
50
  .mockResolvedValue([]);
51
51
  getPropertiesBySlugAndLabelSpy = jest.spyOn(dataTransformerFunctions, 'getPropertiesBySlugAndLabel')
52
- .mockReturnValue({ typePropertiesBySlug: {}, typePropertiesByLabel: {} });
52
+ .mockReturnValue({
53
+ typePropertiesBySlug: {},
54
+ typePropertiesByLabel: {},
55
+ typePathStateBySlug: {},
56
+ });
53
57
  getOptionSetsUsingTypePropertiesBySlugSpy = jest.spyOn(dataTransformerFunctions, 'getOptionSetsUsingTypePropertiesBySlug')
54
58
  .mockReturnValue({});
55
59
  });
@@ -170,6 +174,7 @@ describe('transform', () => {
170
174
  active: { slug: 'active', propertyType: 'boolean' },
171
175
  },
172
176
  typePropertiesByLabel: {},
177
+ typePathStateBySlug: {},
173
178
  });
174
179
  const rows = [{ active: 'true', unmappedField: 'true' }];
175
180
  const result = await (0, transform_1.transform)(mockClient, rows, baseConfig);
@@ -294,6 +299,11 @@ describe('transform', () => {
294
299
  getPropertiesBySlugAndLabelSpy.mockReturnValue({
295
300
  typePropertiesBySlug: columnAnalysisTypeMaps.typePropertiesBySlug,
296
301
  typePropertiesByLabel: columnAnalysisTypeMaps.typePropertiesByLabel,
302
+ typePathStateBySlug: {
303
+ oldProp: new Map([['color', { isDisabled: true }]]),
304
+ color: new Map([['color', { isDisabled: false }]]),
305
+ size: new Map([['color', { isDisabled: false }]]),
306
+ },
297
307
  });
298
308
  getOptionSetsUsingTypePropertiesBySlugSpy.mockReturnValue(columnAnalysisTypeMaps.optionSetUsingTypePropertiesBySlug);
299
309
  }
@@ -328,6 +338,59 @@ describe('transform', () => {
328
338
  expect(archivedCol.isArchived).toBe(true);
329
339
  expect(archivedCol.isMapped).toBe(true);
330
340
  });
341
+ it('should not mark a column as archived when the property is active in any subtype', async () => {
342
+ getPropertiesBySlugAndLabelSpy.mockReturnValue({
343
+ typePropertiesBySlug: {
344
+ season: { slug: 'season', label: 'Season', propertyType: 'string', isArchived: false },
345
+ },
346
+ typePropertiesByLabel: {
347
+ Season: { slug: 'season', label: 'Season', propertyType: 'string', isArchived: false },
348
+ },
349
+ typePathStateBySlug: {
350
+ season: new Map([
351
+ ['item:product', { isDisabled: false }],
352
+ ['item:material', { isDisabled: true }],
353
+ ]),
354
+ },
355
+ });
356
+ getOptionSetsUsingTypePropertiesBySlugSpy.mockReturnValue({});
357
+ const config = {
358
+ loadType: [types_1.LoadType.ITEM],
359
+ conditionalColumns: [{ toProperty: 'typePath', default: 'item:product' }],
360
+ };
361
+ const rows = [{ itemFamilyFederatedId: 'fam-1', name: 'Test', season: 'SS25' }];
362
+ const result = await (0, transform_1.transform)(mockClient, rows, config);
363
+ const seasonCol = result.columns.find((c) => c.csvHeader === 'season');
364
+ expect(seasonCol).toBeDefined();
365
+ expect(seasonCol.isArchived).toBe(false);
366
+ expect(seasonCol.isMapped).toBe(true);
367
+ });
368
+ it('should mark a column as archived only when archived in every subtype that defines it', async () => {
369
+ getPropertiesBySlugAndLabelSpy.mockReturnValue({
370
+ typePropertiesBySlug: {
371
+ legacyProp: { slug: 'legacyProp', label: 'Legacy Prop', propertyType: 'string', isArchived: true },
372
+ },
373
+ typePropertiesByLabel: {
374
+ 'Legacy Prop': { slug: 'legacyProp', label: 'Legacy Prop', propertyType: 'string', isArchived: true },
375
+ },
376
+ typePathStateBySlug: {
377
+ legacyProp: new Map([
378
+ ['item:product', { isDisabled: true }],
379
+ ['item:material', { isDisabled: true }],
380
+ ]),
381
+ },
382
+ });
383
+ getOptionSetsUsingTypePropertiesBySlugSpy.mockReturnValue({});
384
+ const config = {
385
+ loadType: [types_1.LoadType.ITEM],
386
+ conditionalColumns: [{ toProperty: 'typePath', default: 'item:product' }],
387
+ };
388
+ const rows = [{ itemFamilyFederatedId: 'fam-1', name: 'Test', legacyProp: 'value' }];
389
+ const result = await (0, transform_1.transform)(mockClient, rows, config);
390
+ const legacyCol = result.columns.find((c) => c.csvHeader === 'legacyProp');
391
+ expect(legacyCol).toBeDefined();
392
+ expect(legacyCol.isArchived).toBe(true);
393
+ });
331
394
  it('should mark system properties as required for non-item loads', async () => {
332
395
  setupColumnAnalysisMocks();
333
396
  const config = { loadType: [types_1.LoadType.COLOR] };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrail/loader",
3
- "version": "2.0.2",
3
+ "version": "2.0.6",
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.10",
2
+ "version": "3.4.11-alpha.0f34b47",
3
3
  "commands": {
4
4
  "app:create": {
5
5
  "id": "app:create",
@@ -2522,7 +2522,7 @@
2522
2522
  },
2523
2523
  "types:uploadUsageInfo": {
2524
2524
  "id": "types:uploadUsageInfo",
2525
- "description": "Upload extracted usage info",
2525
+ "description": "[DEPRECATED] Upload extracted usage info. Use uploadTypeOverrides instead.",
2526
2526
  "strict": true,
2527
2527
  "pluginName": "@contrail/cli",
2528
2528
  "pluginAlias": "@contrail/cli",
@@ -2531,6 +2531,9 @@
2531
2531
  "examples": [
2532
2532
  "$ contrail types uploadUsageInfo\n"
2533
2533
  ],
2534
+ "deprecationOptions": {
2535
+ "message": "uploadUsageInfo is deprecated. Usage info is now managed as type overrides. Use `contrail types uploadTypeOverrides` instead."
2536
+ },
2534
2537
  "flags": {
2535
2538
  "logLevel": {
2536
2539
  "name": "logLevel",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrail/cli",
3
- "version": "3.4.10",
3
+ "version": "3.4.11-alpha.0f34b47",
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.2",
34
+ "@contrail/loader": "^2.0.6",
35
35
  "@contrail/org-config-migration": "^1.1.13",
36
36
  "@contrail/sdk": "^1.5.5",
37
37
  "@contrail/types": "^3.1.5",