@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
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.3.3 darwin-arm64 node-v20.19.4
20
+ @contrail/cli/3.5.0-alpha darwin-arm64 node-v22.19.0
21
21
  $ contrail --help [COMMAND]
22
22
  USAGE
23
23
  $ contrail COMMAND
@@ -51,6 +51,10 @@ To get instructions on how to set up autocomplete for your shell, run `contrail
51
51
  * [`contrail config list`](#contrail-config-list)
52
52
  * [`contrail config set`](#contrail-config-set)
53
53
  * [`contrail config use [NAME]`](#contrail-config-use-name)
54
+ * [`contrail entities create PATH`](#contrail-entities-create-path)
55
+ * [`contrail entities delete ENTITYNAME`](#contrail-entities-delete-entityname)
56
+ * [`contrail entities get TYPEPATH`](#contrail-entities-get-typepath)
57
+ * [`contrail entities update ENTITYNAME ID`](#contrail-entities-update-entityname-id)
54
58
  * [`contrail file upload FILELOCATION CONTENTTYPE`](#contrail-file-upload-filelocation-contenttype)
55
59
  * [`contrail groups export`](#contrail-groups-export)
56
60
  * [`contrail groups import GROUPSFILE`](#contrail-groups-import-groupsfile)
@@ -535,6 +539,151 @@ EXAMPLES
535
539
  $ contrail config use demo-org
536
540
  ```
537
541
 
542
+ ## `contrail entities create PATH`
543
+
544
+ (BETA) Create entities
545
+
546
+ ```
547
+ USAGE
548
+ $ contrail entities create PATH [-l error|warn|info|debug] [-e true|false] [-n <value>] [-d] [-i <value>] [-o
549
+ <value>] [-p] [-r] [-s]
550
+
551
+ ARGUMENTS
552
+ PATH Path of the entity type to create
553
+
554
+ FLAGS
555
+ -d, --dryRun If true, does not create the entity but simulates the creation
556
+ -e, --alwaysConfirmEnv=<option> [default: true] The Environment variables
557
+ <options: true|false>
558
+ -i, --inputFile=<value> A file with a JSON array of objects where each object is one entity to create. Cannot
559
+ be used with --count. Unless --precise is specified, any missing values will be
560
+ populated with random values.
561
+ -l, --logLevel=<option> The Log Level
562
+ <options: error|warn|info|debug>
563
+ -n, --count=<value> Number of random entities to create
564
+ -o, --outputFile=<value> File to save the output (optional)
565
+ -p, --preciseProperties If true, does not generate random values for properties. All values must be
566
+ specified.
567
+ -r, --readableIds If true, uses readable IDs for the created entities
568
+ -s, --skipHydrateRelationships If true, does not hydrate relationships for the created entities
569
+
570
+ DESCRIPTION
571
+ (BETA) Create entities
572
+
573
+ EXAMPLES
574
+ $ contrail entities create color -n=10 # creates 10 random colors
575
+
576
+ $ contrail entities create color # creates one item
577
+
578
+ $ contrail entities create custom-entities:franchise
579
+
580
+ $ contrail entities create project-item -n=1 -- projectId=abc # creates 10 project items within project ABC
581
+
582
+ $ contrail entities create color -r # creates a random color with a human readable ID
583
+
584
+ $ contrail entities create color -d # simulates the creation of a random color without actually creating it
585
+
586
+ $ contrail entities create custom-entity:franchise -s # creates a random color and the response does not contain hydrating relationships
587
+
588
+ $ contrail entities create color -p -- name=Electric Blue green=1 red=2 blue=3 # creates a color with specified properties
589
+
590
+ $ contrail entities create color -o /tmp/colors.json # creates a random color and saves the output to /tmp/colors.json
591
+ ```
592
+
593
+ ## `contrail entities delete ENTITYNAME`
594
+
595
+ (BETA) Delete an entity
596
+
597
+ ```
598
+ USAGE
599
+ $ contrail entities delete ENTITYNAME [-l error|warn|info|debug] [-e true|false] [-d] [-i <value>] [--id <value>]
600
+
601
+ ARGUMENTS
602
+ ENTITYNAME The name of the entity type to delete
603
+
604
+ FLAGS
605
+ -d, --dryRun If true, does not delete the entity but simulates the deletion
606
+ -e, --alwaysConfirmEnv=<option> [default: true] The Environment variables
607
+ <options: true|false>
608
+ -i, --input=<value> A JSON array of objects where each object is one entity to create. Cannot be used
609
+ with --count. Unless --precise is specified, any missing values will be populated
610
+ with random values.
611
+ -l, --logLevel=<option> The Log Level
612
+ <options: error|warn|info|debug>
613
+ --id=<value> The unique identifier of the entity
614
+
615
+ DESCRIPTION
616
+ (BETA) Delete an entity
617
+
618
+ EXAMPLES
619
+ $ contrail entities delete color 123
620
+ ```
621
+
622
+ ## `contrail entities get TYPEPATH`
623
+
624
+ (BETA) Get an entity
625
+
626
+ ```
627
+ USAGE
628
+ $ contrail entities get TYPEPATH [-l error|warn|info|debug] [-e true|false] [-o <value>] [-s] [-r <value>] [-p
629
+ <value>] [-P] [-t <value>]
630
+
631
+ ARGUMENTS
632
+ TYPEPATH The name of the entity type to fetch
633
+
634
+ FLAGS
635
+ -P, --paginated If true, fetches all entities in a paginated manner
636
+ -e, --alwaysConfirmEnv=<option> [default: true] The Environment variables
637
+ <options: true|false>
638
+ -l, --logLevel=<option> The Log Level
639
+ <options: error|warn|info|debug>
640
+ -o, --outputFile=<value> File to save the output (optional)
641
+ -p, --propertySlugs=<value> Comma-separated list of property slugs to include in the output
642
+ -r, --relations=<value> Comma-separated list of relations to include in the output
643
+ -s, --skipHydrateRelationships Skip hydrating relationships when fetching the entity
644
+ -t, --take=<value> [default: 1000] Number of entities to fetch in a single request (default is 100)
645
+
646
+ DESCRIPTION
647
+ (BETA) Get an entity
648
+
649
+ EXAMPLES
650
+ $ contrail entities get color -- id=123
651
+
652
+ $ contrail entities get loader-processes -- createdOn=2025-09-15..2025-09-16
653
+
654
+ $ contrail entities get orders -- updatedAt=2025-09-15T04:00:00Z..
655
+
656
+ $ contrail entities get events -- timestamp=..2025-09-16T23:59:59Z
657
+ ```
658
+
659
+ ## `contrail entities update ENTITYNAME ID`
660
+
661
+ (BETA) Update an entity
662
+
663
+ ```
664
+ USAGE
665
+ $ contrail entities update ENTITYNAME ID [-l error|warn|info|debug] [-e true|false] [-s] [-d] [-i <value>]
666
+
667
+ ARGUMENTS
668
+ ENTITYNAME The name of the entity type to update
669
+ ID The unique identifier of the entity
670
+
671
+ FLAGS
672
+ -d, --dryRun If true, does not create the entity but simulates the creation
673
+ -e, --alwaysConfirmEnv=<option> [default: true] The Environment variables
674
+ <options: true|false>
675
+ -i, --inputFile=<value> File containing properties to update the entity (optional)
676
+ -l, --logLevel=<option> The Log Level
677
+ <options: error|warn|info|debug>
678
+ -s, --skipHydrateRelationships Skip hydrating relationships when updating the entity
679
+
680
+ DESCRIPTION
681
+ (BETA) Update an entity
682
+
683
+ EXAMPLES
684
+ $ contrail entities update color 123 -- name=obsidian hex=000000
685
+ ```
686
+
538
687
  ## `contrail file upload FILELOCATION CONTENTTYPE`
539
688
 
540
689
  Uploads a file to the VibeIQ platform
@@ -1,3 +1,5 @@
1
+ import { TypeProperty as SDKTypeProperty } from '@contrail/types';
2
+ import { PropertyLevel, PropertyType, Type } from '@contrail/types';
1
3
  export declare function getOptionSets(): Promise<any[]>;
2
4
  export declare function getUserLists(): Promise<any[]>;
3
5
  export declare function getOptionSetHierarchies(): Promise<any[]>;
@@ -9,3 +11,36 @@ export declare function getTypePropertyPolicies(): Promise<any[]>;
9
11
  export declare function getTypePropertyPolicyLinks(): Promise<any[]>;
10
12
  export declare function getTypePolicies(): Promise<any[]>;
11
13
  export declare function getTypePolicyLinks(): Promise<any[]>;
14
+ type ColonDelimitedHelper<S extends string> = S extends `${infer Head}:${infer Tail}` ? `${Head}:${ColonDelimitedHelper<Tail>}` : S;
15
+ export type ColonDelimited = ColonDelimitedHelper<string>;
16
+ export type TypeWithProperties = Type & {
17
+ typeProperties: TypeProperty[];
18
+ };
19
+ export interface Option {
20
+ value: string;
21
+ display: string;
22
+ disabled?: boolean;
23
+ }
24
+ export interface TypeProperty extends SDKTypeProperty {
25
+ propertyType?: PropertyType;
26
+ referencedTypePath?: string;
27
+ referencedTypeRootSlug?: string;
28
+ propertyLevel?: PropertyLevel;
29
+ }
30
+ export interface TypePropertyOptionSet {
31
+ id?: string;
32
+ orgId?: string;
33
+ name: string;
34
+ slug: string;
35
+ optionSet: Option[];
36
+ isArchived?: boolean;
37
+ }
38
+ export type TypeReferencesCacheByPath = Map<string, TypeWithProperties>;
39
+ export declare function getTypeByPath(path: ColonDelimited): Promise<TypeWithProperties>;
40
+ export declare function buildLocalTypesCache(paths: ColonDelimited[]): Promise<TypeReferencesCacheByPath>;
41
+ export declare function parseTypePath(path: ColonDelimited): {
42
+ root: string;
43
+ path: string;
44
+ };
45
+ export declare function getReferencedTypePaths(type: TypeWithProperties): ColonDelimited[];
46
+ export {};
package/dist/api/types.js CHANGED
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getTypePolicyLinks = exports.getTypePolicies = exports.getTypePropertyPolicyLinks = exports.getTypePropertyPolicies = exports.getUsageInfo = exports.getRuleSetLinks = exports.getRuleSets = exports.getOptionSetHierarchyLinks = exports.getOptionSetHierarchies = exports.getUserLists = exports.getOptionSets = void 0;
3
+ exports.getReferencedTypePaths = exports.parseTypePath = exports.buildLocalTypesCache = exports.getTypeByPath = exports.getTypePolicyLinks = exports.getTypePolicies = exports.getTypePropertyPolicyLinks = exports.getTypePropertyPolicies = exports.getUsageInfo = exports.getRuleSetLinks = exports.getRuleSets = exports.getOptionSetHierarchyLinks = exports.getOptionSetHierarchies = exports.getUserLists = exports.getOptionSets = void 0;
4
4
  const sdk_1 = require("@contrail/sdk");
5
+ const types_1 = require("@contrail/types");
5
6
  async function getOptionSets() {
6
7
  return await new sdk_1.Entities().get({
7
8
  entityName: 'type-property-option-set',
@@ -77,3 +78,48 @@ async function getTypePolicyLinks() {
77
78
  });
78
79
  }
79
80
  exports.getTypePolicyLinks = getTypePolicyLinks;
81
+ const TYPES_CACHE_BY_PATH = new Map();
82
+ async function fetchTypeByPath(path) {
83
+ const { root } = parseTypePath(path);
84
+ const client = new sdk_1.Entities();
85
+ const type = await client.get({
86
+ entityName: 'type',
87
+ suffix: `roots/${root}/path/${path}`,
88
+ relations: ['typeProperties'],
89
+ });
90
+ return type;
91
+ }
92
+ async function getTypeByPath(path) {
93
+ if (TYPES_CACHE_BY_PATH.has(path)) {
94
+ return TYPES_CACHE_BY_PATH.get(path);
95
+ }
96
+ const type = await fetchTypeByPath(path);
97
+ TYPES_CACHE_BY_PATH.set(path, type);
98
+ return type;
99
+ }
100
+ exports.getTypeByPath = getTypeByPath;
101
+ async function buildLocalTypesCache(paths) {
102
+ const types = await Promise.all(paths.map((path) => getTypeByPath(path)));
103
+ const newCache = types.reduce((acc, type) => {
104
+ acc.set(type.typePath, type);
105
+ return acc;
106
+ }, new Map());
107
+ return newCache;
108
+ }
109
+ exports.buildLocalTypesCache = buildLocalTypesCache;
110
+ function parseTypePath(path) {
111
+ const parts = path.split(':').filter(Boolean);
112
+ if (parts.length === 0) {
113
+ throw new Error('Path cannot be empty');
114
+ }
115
+ const root = parts[0];
116
+ return { root, path };
117
+ }
118
+ exports.parseTypePath = parseTypePath;
119
+ function getReferencedTypePaths(type) {
120
+ const properties = type.typeProperties || [];
121
+ return properties
122
+ .filter((prop) => prop.propertyType === types_1.PropertyType.TypeReference)
123
+ .map(({ referencedTypePath }) => referencedTypePath);
124
+ }
125
+ exports.getReferencedTypePaths = getReferencedTypePaths;
@@ -40,10 +40,6 @@ async function authUser() {
40
40
  return await refreshCurrentUserOrg();
41
41
  }
42
42
  catch (e) {
43
- if (isNetworkConnectionError(e)) {
44
- logger_1.default.error("Encountered a network connection issue. Please ensure you're connected to the internet and try again");
45
- process.exit(1);
46
- }
47
43
  logger_1.default.info('Token expired. Requesting auth credentials...');
48
44
  }
49
45
  }
@@ -215,7 +211,3 @@ async function returnAndStoreConfig(config) {
215
211
  await (0, config_1.storeConfig)(configCopy);
216
212
  return configCopy;
217
213
  }
218
- function isNetworkConnectionError(e) {
219
- const cause = e?.cause;
220
- return cause?.code === 'ENOTFOUND' || cause?.code === 'ECONNREFUSED';
221
- }
@@ -8,7 +8,9 @@ export declare abstract class BaseCommand extends Command {
8
8
  logLevel: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
9
  };
10
10
  protected flags: any;
11
- protected args: any;
11
+ protected args: {
12
+ [key: string]: any;
13
+ };
12
14
  init(): Promise<void>;
13
15
  setLogLevel(logLevel: string, config?: any): void;
14
16
  private confirmEnv;
@@ -17,7 +17,7 @@ class BaseCommand extends core_1.Command {
17
17
  ...baseFlags_1.baseFlags,
18
18
  };
19
19
  flags;
20
- args;
20
+ args = {};
21
21
  async init() {
22
22
  await super.init();
23
23
  if (!this.ctor?.flags)
@@ -40,12 +40,10 @@ class DeployExtension extends basecommand_1.BaseCommand {
40
40
  await this.validateExtensionDeclaration(appDeclaration, extensionIdentifier);
41
41
  const extensionDir = this.getExtensionDirectory(extensionIdentifier);
42
42
  // 2. Package and upload extension
43
- const createdPackage = await (0, extension_package_deployer_1.createExtensionPackage)(app.id, extensionDir, {
44
- debug: this.flags.debug,
45
- });
43
+ const createdPackage = await (0, extension_package_deployer_1.createExtensionPackage)(app.id, extensionDir, { debug: this.flags.debug });
46
44
  // 3. Poll until package is ready (timeout after 1 minute)
47
45
  const readyPackage = await this.pollUntilPackageIsReady(createdPackage);
48
- logger_1.default.info('Extension package is ready...Checking for extension deployment');
46
+ logger_1.default.info("Extension package is ready...Checking for extension deployment");
49
47
  logger_1.default.debug(JSON.stringify(readyPackage, null, 2));
50
48
  const deployment = await this.pollUntilDeploymentIsReady(readyPackage.deploymentId);
51
49
  logger_1.default.info(`${chalk_1.default.green.bold('SUCCESS')} Extension package is ready.`);
@@ -0,0 +1,37 @@
1
+ import { PropertyLevel } from '@contrail/types';
2
+ import { ColonDelimited, TypeProperty as ExtendedTypeProperty, TypeReferencesCacheByPath } from '../../api/types';
3
+ import { TypeWithProperties } from '../../api/types';
4
+ import { BaseCommand } from '../../basecommand';
5
+ import { Role } from '../../helpers/entities';
6
+ export default class CreateEntity extends BaseCommand {
7
+ static description: string;
8
+ static examples: string[];
9
+ static flags: {
10
+ count: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
+ dryRun: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
+ inputFile: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
13
+ outputFile: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
14
+ preciseProperties: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
15
+ readableIds: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
16
+ skipHydrateRelationships: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
17
+ alwaysConfirmEnv: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
18
+ logLevel: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
19
+ };
20
+ static args: {
21
+ path: import("@oclif/core/lib/interfaces/parser").Arg<string, Record<string, unknown>>;
22
+ };
23
+ static strict: boolean;
24
+ run(): Promise<void>;
25
+ }
26
+ export type WithId = {
27
+ id: string;
28
+ [key: string]: any;
29
+ };
30
+ export type ObjectReferenceCache = Map<string, WithId>;
31
+ type ObjectReferenceCachesByTypePath = Map<string, ObjectReferenceCache>;
32
+ export declare function pickRandomValueForProperty(property: ExtendedTypeProperty, objectReferencesCache: ObjectReferenceCachesByTypePath, typeReferencesCache: TypeReferencesCacheByPath): number | string | string[] | boolean | null;
33
+ export declare function getReferencedObjectPaths(type: TypeWithProperties): ColonDelimited[];
34
+ export declare function buildObjectReferenceCache(entities: any[]): ObjectReferenceCache;
35
+ export declare function selectRandomObject(cache: ObjectReferenceCache): WithId;
36
+ export declare function doesPropertyLevelMatchRole(propertyLevel: PropertyLevel, role: Role): boolean;
37
+ export {};