@contrail/cli 3.3.3 → 3.5.0-alpha

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 (50) hide show
  1. package/README.md +150 -1
  2. package/dist/api/types.d.ts +35 -0
  3. package/dist/api/types.js +47 -1
  4. package/dist/auth/login.js +0 -8
  5. package/dist/basecommand.d.ts +3 -1
  6. package/dist/basecommand.js +1 -1
  7. package/dist/commands/app/extension/deploy.js +2 -4
  8. package/dist/commands/entities/create.d.ts +37 -0
  9. package/dist/commands/entities/create.js +555 -0
  10. package/dist/commands/entities/create.spec.d.ts +1 -0
  11. package/dist/commands/entities/create.spec.js +514 -0
  12. package/dist/commands/entities/delete.d.ts +16 -0
  13. package/dist/commands/entities/delete.js +118 -0
  14. package/dist/commands/entities/get.d.ts +20 -0
  15. package/dist/commands/entities/get.js +204 -0
  16. package/dist/commands/entities/update.d.ts +18 -0
  17. package/dist/commands/entities/update.js +116 -0
  18. package/dist/commands/types/uploadUsageInfo.js +2 -14
  19. package/dist/common.d.ts +1 -1
  20. package/dist/helpers/app/app-deployer.js +4 -8
  21. package/dist/helpers/app/extension-package-deployer.js +1 -1
  22. package/dist/helpers/config/config.js +3 -3
  23. package/dist/helpers/entities/assortment-items.d.ts +10 -0
  24. package/dist/helpers/entities/assortment-items.js +84 -0
  25. package/dist/helpers/entities/batchFetch.d.ts +8 -0
  26. package/dist/helpers/entities/batchFetch.js +41 -0
  27. package/dist/helpers/entities/index.d.ts +3 -0
  28. package/dist/helpers/entities/index.js +6 -0
  29. package/dist/helpers/entities/items.d.ts +10 -0
  30. package/dist/helpers/entities/items.js +102 -0
  31. package/dist/helpers/entities/project-items.d.ts +3 -0
  32. package/dist/helpers/entities/project-items.js +65 -0
  33. package/dist/helpers/file-helpers.d.ts +1 -0
  34. package/dist/helpers/file-helpers.js +19 -1
  35. package/dist/helpers/propertySpecifications/dateRanges.d.ts +38 -0
  36. package/dist/helpers/propertySpecifications/dateRanges.js +89 -0
  37. package/dist/helpers/propertySpecifications/dateRanges.spec.d.ts +1 -0
  38. package/dist/helpers/propertySpecifications/dateRanges.spec.js +95 -0
  39. package/dist/helpers/propertySpecifications/propertySpecifications.d.ts +27 -0
  40. package/dist/helpers/propertySpecifications/propertySpecifications.js +70 -0
  41. package/dist/helpers/propertySpecifications/propertySpecifications.spec.d.ts +1 -0
  42. package/dist/helpers/propertySpecifications/propertySpecifications.spec.js +266 -0
  43. package/dist/helpers/types/type-uploader.js +0 -7
  44. package/dist/interfaces.d.ts +0 -1
  45. package/dist/templates/typescript/README.md +1 -3
  46. package/dist/templates/typescript/assets/sample.json +1 -1
  47. package/dist/templates/typescript/eslintrc.json +4 -1
  48. package/dist/templates/typescript/tsconfig.json +21 -5
  49. package/oclif.manifest.json +361 -1
  50. package/package.json +6 -5
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const propertySpecifications_1 = require("./propertySpecifications");
4
+ describe('parsePropertySpecification', () => {
5
+ it('should parse a valid property specification', () => {
6
+ const spec = 'name=john';
7
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
8
+ expect(result).toEqual({
9
+ slug: 'name',
10
+ value: 'john',
11
+ });
12
+ });
13
+ it('should parse property specification with numeric value', () => {
14
+ const spec = 'id=123';
15
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
16
+ expect(result).toEqual({
17
+ slug: 'id',
18
+ value: '123',
19
+ });
20
+ });
21
+ it('should parse property specification with hex color value', () => {
22
+ const spec = 'hex=000000';
23
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
24
+ expect(result).toEqual({
25
+ slug: 'hex',
26
+ value: '000000',
27
+ });
28
+ });
29
+ it('should parse property specification with spaces in value', () => {
30
+ const spec = 'name=john doe';
31
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
32
+ expect(result).toEqual({
33
+ slug: 'name',
34
+ value: 'john doe',
35
+ });
36
+ });
37
+ it('should parse property specification with equals sign in value', () => {
38
+ const spec = 'formula=x=y+z';
39
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
40
+ expect(result).toEqual({
41
+ slug: 'formula',
42
+ value: 'x=y+z', // Now correctly keeps everything after first equals
43
+ });
44
+ });
45
+ it('should parse property specification with empty value', () => {
46
+ const spec = 'description=';
47
+ // Current implementation throws error for empty values
48
+ expect(() => (0, propertySpecifications_1.parsePropertySpecification)(spec)).toThrow('Invalid property specification: description=');
49
+ });
50
+ it('should throw error for spec without equals sign', () => {
51
+ const spec = 'invalidspec';
52
+ expect(() => (0, propertySpecifications_1.parsePropertySpecification)(spec)).toThrow('Invalid property specification: invalidspec');
53
+ });
54
+ it('should throw error for spec with only equals sign', () => {
55
+ const spec = '=';
56
+ expect(() => (0, propertySpecifications_1.parsePropertySpecification)(spec)).toThrow('Invalid property specification: =');
57
+ });
58
+ it('should throw error for spec with empty slug', () => {
59
+ const spec = '=value';
60
+ expect(() => (0, propertySpecifications_1.parsePropertySpecification)(spec)).toThrow('Invalid property specification: =value');
61
+ });
62
+ it('should parse property specification with special characters in slug', () => {
63
+ const spec = 'property_name=value';
64
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
65
+ expect(result).toEqual({
66
+ slug: 'property_name',
67
+ value: 'value',
68
+ });
69
+ });
70
+ it('should parse property specification with hyphenated slug', () => {
71
+ const spec = 'property-name=value';
72
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
73
+ expect(result).toEqual({
74
+ slug: 'property-name',
75
+ value: 'value',
76
+ });
77
+ });
78
+ });
79
+ describe('parsePropertySpecificationsIntoMap', () => {
80
+ it('should parse multiple property specifications into a map', () => {
81
+ const specs = ['name=obsidian', 'hex=000000', 'id=123'];
82
+ const result = (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(specs);
83
+ expect(result).toBeInstanceOf(Map);
84
+ expect(result.get('name')).toBe('obsidian');
85
+ expect(result.get('hex')).toBe('000000');
86
+ expect(result.get('id')).toBe('123');
87
+ expect(result.size).toBe(3);
88
+ });
89
+ it('should handle empty array', () => {
90
+ const specs = [];
91
+ const result = (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(specs);
92
+ expect(result).toBeInstanceOf(Map);
93
+ expect(result.size).toBe(0);
94
+ });
95
+ it('should handle single property specification', () => {
96
+ const specs = ['name=john'];
97
+ const result = (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(specs);
98
+ expect(result).toBeInstanceOf(Map);
99
+ expect(result.get('name')).toBe('john');
100
+ expect(result.size).toBe(1);
101
+ });
102
+ it('should handle property specifications with complex values', () => {
103
+ const specs = [
104
+ 'description=This is a long description with spaces',
105
+ 'formula=x=y+z',
106
+ 'url=https://example.com',
107
+ ];
108
+ const result = (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(specs);
109
+ expect(result.get('description')).toBe('This is a long description with spaces');
110
+ expect(result.get('formula')).toBe('x=y+z'); // Now correctly handles multiple equals
111
+ expect(result.get('url')).toBe('https://example.com');
112
+ expect(result.size).toBe(3);
113
+ });
114
+ it('should handle duplicate slugs by overwriting with last value', () => {
115
+ const specs = ['name=first', 'name=second', 'name=third'];
116
+ const result = (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(specs);
117
+ expect(result.get('name')).toBe('third');
118
+ expect(result.size).toBe(1);
119
+ });
120
+ it('should handle property specifications with empty values', () => {
121
+ const specs = ['name=john', 'description=', 'notes='];
122
+ // Current implementation throws error for empty values
123
+ expect(() => (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(specs)).toThrow('Invalid property specification: description=');
124
+ });
125
+ it('should throw error for invalid property specifications', () => {
126
+ const specs = [
127
+ 'name=john',
128
+ 'invalid',
129
+ ];
130
+ expect(() => (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(specs)).toThrow('Invalid property specification: invalid');
131
+ });
132
+ });
133
+ describe('isValidPropertySpecification', () => {
134
+ it('should return true for valid property specifications', () => {
135
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('name=john')).toBe(true);
136
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('id=123')).toBe(true);
137
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('hex=000000')).toBe(true);
138
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('description=This is a description')).toBe(true);
139
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('formula=x=y+z')).toBe(true);
140
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('property_name=value')).toBe(true);
141
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('property-name=value')).toBe(true);
142
+ });
143
+ it('should return true for property specifications with empty values', () => {
144
+ // Current implementation rejects empty values
145
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('description=')).toBe(false);
146
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('notes=')).toBe(false);
147
+ });
148
+ it('should return false for invalid property specifications', () => {
149
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('invalid')).toBe(false);
150
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('')).toBe(false);
151
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('=')).toBe(false);
152
+ expect((0, propertySpecifications_1.isValidPropertySpecification)('=value')).toBe(false);
153
+ });
154
+ it('should return false for null or undefined', () => {
155
+ expect((0, propertySpecifications_1.isValidPropertySpecification)(null)).toBe(false);
156
+ expect((0, propertySpecifications_1.isValidPropertySpecification)(undefined)).toBe(false);
157
+ });
158
+ it('should return false for non-string values', () => {
159
+ expect((0, propertySpecifications_1.isValidPropertySpecification)(123)).toBe(false);
160
+ expect((0, propertySpecifications_1.isValidPropertySpecification)({})).toBe(false);
161
+ expect((0, propertySpecifications_1.isValidPropertySpecification)([])).toBe(false);
162
+ });
163
+ it('should act as type guard', () => {
164
+ const maybeSpec = 'name=john';
165
+ if ((0, propertySpecifications_1.isValidPropertySpecification)(maybeSpec)) {
166
+ // TypeScript should recognize maybeSpec as PropertySpecificationString
167
+ const parsed = (0, propertySpecifications_1.parsePropertySpecification)(maybeSpec);
168
+ expect(parsed.slug).toBe('name');
169
+ expect(parsed.value).toBe('john');
170
+ }
171
+ });
172
+ });
173
+ describe('integration tests', () => {
174
+ it('should work with the example from the comments', () => {
175
+ // Example: contrail entities get color -- id=123
176
+ const getSpecs = ['id=123'];
177
+ const getMap = (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(getSpecs);
178
+ expect(getMap.get('id')).toBe('123');
179
+ expect(getMap.size).toBe(1);
180
+ });
181
+ it('should work with the update example from the comments', () => {
182
+ // Example: contrail entities update color 123 -- name=obsidian hex=000000
183
+ const updateSpecs = ['name=obsidian', 'hex=000000'];
184
+ const updateMap = (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(updateSpecs);
185
+ expect(updateMap.get('name')).toBe('obsidian');
186
+ expect(updateMap.get('hex')).toBe('000000');
187
+ expect(updateMap.size).toBe(2);
188
+ });
189
+ it('should handle validation before parsing', () => {
190
+ const userInputs = ['name=john', 'invalid', 'id=123', '=empty'];
191
+ const validSpecs = userInputs.filter(propertySpecifications_1.isValidPropertySpecification);
192
+ expect(validSpecs).toEqual(['name=john', 'id=123']);
193
+ const map = (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(validSpecs);
194
+ expect(map.get('name')).toBe('john');
195
+ expect(map.get('id')).toBe('123');
196
+ expect(map.size).toBe(2);
197
+ });
198
+ });
199
+ describe('edge cases and limitations', () => {
200
+ it('should handle multiple equals signs correctly', () => {
201
+ // This test shows that multiple equals signs are now handled correctly
202
+ const spec = 'calculation=2+2=4';
203
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
204
+ expect(result).toEqual({
205
+ slug: 'calculation',
206
+ value: '2+2=4', // now preserves everything after first equals
207
+ });
208
+ });
209
+ it('should handle the specific example equation=x+z=1', () => {
210
+ const spec = 'equation=x+z=1';
211
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
212
+ expect(result).toEqual({
213
+ slug: 'equation',
214
+ value: 'x+z=1',
215
+ });
216
+ });
217
+ it('should handle mathematical expressions with one equals', () => {
218
+ const spec = 'formula=x+y';
219
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
220
+ expect(result).toEqual({
221
+ slug: 'formula',
222
+ value: 'x+y',
223
+ });
224
+ });
225
+ it('should handle URLs without equals signs', () => {
226
+ const spec = 'url=https://example.com/path';
227
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
228
+ expect(result).toEqual({
229
+ slug: 'url',
230
+ value: 'https://example.com/path',
231
+ });
232
+ });
233
+ it('should handle JSON-like values', () => {
234
+ const spec = 'config={"key":"value"}';
235
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
236
+ expect(result).toEqual({
237
+ slug: 'config',
238
+ value: '{"key":"value"}',
239
+ });
240
+ });
241
+ it('should handle comma-separated values', () => {
242
+ const spec = 'tags=red,blue,green';
243
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
244
+ expect(result).toEqual({
245
+ slug: 'tags',
246
+ value: 'red,blue,green',
247
+ });
248
+ });
249
+ it('should handle escaped characters', () => {
250
+ const spec = 'message=Hello\\nWorld';
251
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
252
+ expect(result).toEqual({
253
+ slug: 'message',
254
+ value: 'Hello\\nWorld',
255
+ });
256
+ });
257
+ it('should handle whitespace in slugs', () => {
258
+ // This documents current behavior - spaces in slugs are allowed
259
+ const spec = 'property name=value';
260
+ const result = (0, propertySpecifications_1.parsePropertySpecification)(spec);
261
+ expect(result).toEqual({
262
+ slug: 'property name',
263
+ value: 'value',
264
+ });
265
+ });
266
+ });
@@ -188,7 +188,6 @@ async function uploadReducedTypeProperties(type, currentPropertyTypes, newProper
188
188
  validationFunction: newPropertyType.validationFunction,
189
189
  numberFormat: newPropertyType.numberFormat,
190
190
  sequenceSeedValue: newPropertyType.sequenceSeedValue,
191
- copyBehavior: newPropertyType?.copyBehavior,
192
191
  }),
193
192
  headers: {
194
193
  Accept: 'application/json',
@@ -200,11 +199,6 @@ async function uploadReducedTypeProperties(type, currentPropertyTypes, newProper
200
199
  // !newPropertyType.inherited &&
201
200
  // !typePropertiesEqual(found, newPropertyType, optionSetIdBySlug)
202
201
  ) {
203
- // Skip platform-managed entities
204
- if (newPropertyType.core) {
205
- logger_1.default.debug(`Skipping platform-managed property: ${newPropertyType.slug}`);
206
- continue;
207
- }
208
202
  const proposedTP = {
209
203
  isArchived: newPropertyType.isArchived ?? null,
210
204
  propertyType: newPropertyType.propertyType ?? null,
@@ -229,7 +223,6 @@ async function uploadReducedTypeProperties(type, currentPropertyTypes, newProper
229
223
  validationFunction: newPropertyType.validationFunction ?? null,
230
224
  numberFormat: newPropertyType.numberFormat ?? null,
231
225
  sequenceSeedValue: newPropertyType.sequenceSeedValue ?? null,
232
- copyBehavior: newPropertyType.copyBehavior ?? null,
233
226
  };
234
227
  // logger.debug(
235
228
  // `found type property option set: ${newPropertyType.typePropertyOptionSetSlug}, ${proposedTP.typePropertyOptionSetId}, `,
@@ -360,7 +360,6 @@ export interface ReducedTypeProperty {
360
360
  validationFunction?: string;
361
361
  numberFormat?: any;
362
362
  sequenceSeedValue?: number;
363
- copyBehavior?: string;
364
363
  }
365
364
  export interface ReducedOptionSet {
366
365
  name: string;
@@ -1,7 +1,5 @@
1
1
  ### Running your app
2
-
3
2
  Run `npm run start` at the root directory of your app (where the `package.json` file is located).
4
3
 
5
4
  ### Publishing your app
6
-
7
- Run `contrail app publish` to publish a new version of the app.
5
+ Run `contrail app publish` to publish a new version of the app.
@@ -1,3 +1,3 @@
1
1
  {
2
2
  "foo": "bar"
3
- }
3
+ }
@@ -25,7 +25,10 @@
25
25
  "no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 0 }],
26
26
  "no-trailing-spaces": "error",
27
27
  "no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
28
- "@typescript-eslint/no-empty-function": ["error", { "allow": ["arrowFunctions"] }],
28
+ "@typescript-eslint/no-empty-function": [
29
+ "error",
30
+ { "allow": ["arrowFunctions"] }
31
+ ],
29
32
  "@typescript-eslint/no-explicit-any": "off",
30
33
  "@typescript-eslint/no-var-requires": "warn",
31
34
  "no-unused-vars": "off",
@@ -4,7 +4,15 @@
4
4
  "emitDecoratorMetadata": true,
5
5
  "esModuleInterop": true,
6
6
  "experimentalDecorators": true,
7
- "lib": ["es5", "ES2015", "ES2016", "ES2017", "ES2020", "dom", "esnext.asynciterable"],
7
+ "lib": [
8
+ "es5",
9
+ "ES2015",
10
+ "ES2016",
11
+ "ES2017",
12
+ "ES2020",
13
+ "dom",
14
+ "esnext.asynciterable"
15
+ ],
8
16
  "module": "CommonJS",
9
17
  // "moduleResolution": "node",
10
18
  "noImplicitAny": false,
@@ -14,8 +22,16 @@
14
22
  "strict": false,
15
23
  "strictPropertyInitialization": false,
16
24
  "target": "ES2020",
17
- "types": ["node", "jest"]
25
+ "types": [
26
+ "node", "jest"
27
+ ]
18
28
  },
19
- "exclude": ["node_modules", "**/__tests__/*"],
20
- "include": ["src", "package.json"]
21
- }
29
+ "exclude": [
30
+ "node_modules",
31
+ "**/__tests__/*"
32
+ ],
33
+ "include": [
34
+ "src",
35
+ "package.json"
36
+ ]
37
+ }