@contrail/cli 3.6.0-alpha-3 → 3.6.0-alpha-4

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-3 darwin-arm64 node-v22.19.0
20
+ @contrail/cli/3.6.0-alpha-4 darwin-arm64 node-v22.19.0
21
21
  $ contrail --help [COMMAND]
22
22
  USAGE
23
23
  $ contrail COMMAND
@@ -54,7 +54,7 @@ To get instructions on how to set up autocomplete for your shell, run `contrail
54
54
  * [`contrail entities create PATH`](#contrail-entities-create-path)
55
55
  * [`contrail entities delete ENTITYNAME`](#contrail-entities-delete-entityname)
56
56
  * [`contrail entities get TYPEPATH`](#contrail-entities-get-typepath)
57
- * [`contrail entities update ENTITYNAME ID`](#contrail-entities-update-entityname-id)
57
+ * [`contrail entities update ENTITYNAME [ID]`](#contrail-entities-update-entityname-id)
58
58
  * [`contrail file upload FILELOCATION CONTENTTYPE`](#contrail-file-upload-filelocation-contenttype)
59
59
  * [`contrail groups export`](#contrail-groups-export)
60
60
  * [`contrail groups import GROUPSFILE`](#contrail-groups-import-groupsfile)
@@ -495,7 +495,7 @@ Set a variable in the configuration
495
495
  ```
496
496
  USAGE
497
497
  $ contrail config set [-l error|warn|info|debug] [-e true|false] [--orgSlug <value>] [--environment
498
- dev|development|prod|production] [--apiUserToken <value>] [--config <value>]
498
+ dev|development|prod|production|local] [--apiUserToken <value>] [--config <value>]
499
499
 
500
500
  FLAGS
501
501
  -e, --alwaysConfirmEnv=<option> [default: true] The Environment variables
@@ -505,7 +505,7 @@ FLAGS
505
505
  --apiUserToken=<value> The API User Token
506
506
  --config=<value> The config name
507
507
  --environment=<option> The Environment
508
- <options: dev|development|prod|production>
508
+ <options: dev|development|prod|production|local>
509
509
  --orgSlug=<value> The org slug
510
510
 
511
511
  DESCRIPTION
@@ -625,14 +625,15 @@ EXAMPLES
625
625
 
626
626
  ```
627
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>]
628
+ $ contrail entities get TYPEPATH [-l error|warn|info|debug] [-e true|false] [-o <value>] [-p <value>] [-P] [-s
629
+ <value>] [-S] [-t <value>] [-r <value>]
630
630
 
631
631
  ARGUMENTS
632
632
  TYPEPATH The name of the entity type to fetch
633
633
 
634
634
  FLAGS
635
635
  -P, --paginated If true, fetches all entities in a paginated manner
636
+ -S, --skipHydrateRelationships Skip hydrating relationships when fetching the entity
636
637
  -e, --alwaysConfirmEnv=<option> [default: true] The Environment variables
637
638
  <options: true|false>
638
639
  -l, --logLevel=<option> The Log Level
@@ -640,7 +641,7 @@ FLAGS
640
641
  -o, --outputFile=<value> File to save the output (optional)
641
642
  -p, --propertySlugs=<value> Comma-separated list of property slugs to include in the output
642
643
  -r, --relations=<value> Comma-separated list of relations to include in the output
643
- -s, --skipHydrateRelationships Skip hydrating relationships when fetching the entity
644
+ -s, --skip=<value> Number of entities to skip (used with paginated fetch)
644
645
  -t, --take=<value> Number of entities to fetch in a single request (default is 100)
645
646
 
646
647
  DESCRIPTION
@@ -656,19 +657,20 @@ EXAMPLES
656
657
  $ contrail entities get events -- timestamp=..2025-09-16T23:59:59Z
657
658
  ```
658
659
 
659
- ## `contrail entities update ENTITYNAME ID`
660
+ ## `contrail entities update ENTITYNAME [ID]`
660
661
 
661
662
  (BETA) Update an entity
662
663
 
663
664
  ```
664
665
  USAGE
665
- $ contrail entities update ENTITYNAME ID [-l error|warn|info|debug] [-e true|false] [-s] [-d] [-i <value>]
666
+ $ contrail entities update ENTITYNAME [ID] [-l error|warn|info|debug] [-e true|false] [-s] [-d] [-i <value>] [-F]
666
667
 
667
668
  ARGUMENTS
668
669
  ENTITYNAME The name of the entity type to update
669
670
  ID The unique identifier of the entity
670
671
 
671
672
  FLAGS
673
+ -F, --force Force update without validation. Internal use only
672
674
  -d, --dryRun If true, does not create the entity but simulates the creation
673
675
  -e, --alwaysConfirmEnv=<option> [default: true] The Environment variables
674
676
  <options: true|false>
@@ -55,7 +55,9 @@ async function authUser() {
55
55
  logger_1.default.info(`Failed to refresh token: ${e}. Requesting auth credentials...`);
56
56
  }
57
57
  }
58
- return await authenticateWithUsernamePassword(config);
58
+ const authContext = await authenticateWithUsernamePassword(config);
59
+ await (0, config_1.storeConfig)(authContext);
60
+ return authContext;
59
61
  }
60
62
  exports.authUser = authUser;
61
63
  async function getOrgSlug(config) {
@@ -77,7 +79,7 @@ async function authenticateWithApiKey(config, apiKey, orgSlug) {
77
79
  const apiGateway = config?.apiGateway ?? CONFIGURATION.apiGateway;
78
80
  sdk_1.Auth.config = {
79
81
  apiUserToken: apiKey,
80
- apiRefreshToken: null,
82
+ apiRefreshToken: undefined,
81
83
  apiGateway,
82
84
  orgSlug,
83
85
  };
@@ -145,20 +147,25 @@ async function authenticateWithUsernamePassword(config) {
145
147
  async function setAuthContext(user, params) {
146
148
  const apiGateway = params?.apiGateway ?? CONFIGURATION.apiGateway;
147
149
  const { vibeAccessToken, vibeRefreshToken } = await getVibeAccessTokenFromCognitoAccessToken(user.idToken.jwtToken, apiGateway);
148
- // Set Auth Config
149
150
  sdk_1.Auth.config = {
150
151
  apiUserToken: vibeAccessToken,
151
152
  apiRefreshToken: vibeRefreshToken,
152
153
  apiGateway,
153
154
  orgSlug: params.orgSlug,
154
155
  };
155
- // SET SDK CONFIG
156
156
  (0, sdk_1.setConfig)(sdk_1.Auth.config);
157
157
  return refreshCurrentUserOrg();
158
158
  }
159
159
  async function refreshCurrentUserOrg() {
160
160
  logger_1.default.debug('refreshing current user org...');
161
- const currentUser = await (0, sdk_1.getCurrentUser)();
161
+ const currentUser = await (0, sdk_1.getCurrentUser)().catch((e) => {
162
+ console.error('error getting current user', e.message);
163
+ if (isExpiredTokenError(e)) {
164
+ console.log('try frefreshing');
165
+ return;
166
+ }
167
+ throw e;
168
+ });
162
169
  if (!currentUser) {
163
170
  const config = await (0, config_1.getConfig)();
164
171
  try {
@@ -181,6 +188,9 @@ async function refreshCurrentUserOrg() {
181
188
  // await checkTelemetry(current_Version);
182
189
  return Object.assign({}, sdk_1.Auth.config);
183
190
  }
191
+ function isExpiredTokenError(e) {
192
+ return e?.message?.includes('token is expired');
193
+ }
184
194
  async function getVibeAccessTokenFromCognitoAccessToken(cognitoAccessToken, apiGateway) {
185
195
  const url = `${apiGateway}/auth/cognito/`;
186
196
  const response = await fetch(url, {
@@ -15,7 +15,7 @@ class SetConfig extends basecommand_1.BaseCommand {
15
15
  environment: core_1.Flags.string({
16
16
  description: 'The Environment',
17
17
  required: false,
18
- options: ['dev', 'development', 'prod', 'production'],
18
+ options: ['dev', 'development', 'prod', 'production', 'local'],
19
19
  }),
20
20
  apiUserToken: core_1.Flags.string({
21
21
  description: 'The API User Token',
@@ -4,11 +4,12 @@ export default class GetEntity extends BaseCommand {
4
4
  static examples: string[];
5
5
  static flags: {
6
6
  outputFile: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
- skipHydrateRelationships: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
- relations: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
7
  propertySlugs: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
8
  paginated: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ skip: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
+ skipHydrateRelationships: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
11
11
  take: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
12
+ relations: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
12
13
  alwaysConfirmEnv: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
13
14
  logLevel: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
14
15
  };
@@ -26,17 +26,6 @@ class GetEntity extends basecommand_1.BaseCommand {
26
26
  description: 'File to save the output (optional)',
27
27
  required: false,
28
28
  }),
29
- skipHydrateRelationships: core_1.Flags.boolean({
30
- char: 's',
31
- description: 'Skip hydrating relationships when fetching the entity',
32
- required: false,
33
- default: false,
34
- }),
35
- relations: core_1.Flags.string({
36
- char: 'r',
37
- description: 'Comma-separated list of relations to include in the output',
38
- required: false,
39
- }),
40
29
  propertySlugs: core_1.Flags.string({
41
30
  char: 'p',
42
31
  description: 'Comma-separated list of property slugs to include in the output',
@@ -48,12 +37,28 @@ class GetEntity extends basecommand_1.BaseCommand {
48
37
  required: false,
49
38
  default: false,
50
39
  }),
40
+ skip: core_1.Flags.integer({
41
+ char: 's',
42
+ description: 'Number of entities to skip (used with paginated fetch)',
43
+ required: false,
44
+ }),
45
+ skipHydrateRelationships: core_1.Flags.boolean({
46
+ char: 'S',
47
+ description: 'Skip hydrating relationships when fetching the entity',
48
+ required: false,
49
+ default: false,
50
+ }),
51
51
  take: core_1.Flags.integer({
52
52
  char: 't',
53
53
  description: 'Number of entities to fetch in a single request (default is 100)',
54
54
  required: false,
55
55
  default: MAX_NUMBER_OF_ENTITIES_TO_FETCH,
56
56
  }),
57
+ relations: core_1.Flags.string({
58
+ char: 'r',
59
+ description: 'Comma-separated list of relations to include in the output',
60
+ required: false,
61
+ }),
57
62
  };
58
63
  static args = {
59
64
  typePath: core_1.Args.string({
@@ -67,9 +72,9 @@ class GetEntity extends basecommand_1.BaseCommand {
67
72
  await (0, login_1.authUser)();
68
73
  const { args, flags, argv } = await this.parse(GetEntity);
69
74
  const { typePath } = args;
70
- const { outputFile, propertySlugs, relations: relationString, skipHydrateRelationships, paginated: shouldUsePaginatedFind, take: numToTake, } = flags;
75
+ const { outputFile, paginated: shouldUsePaginatedFind, propertySlugs, relations: relationString, skip, skipHydrateRelationships, take, } = flags;
71
76
  SHOULD_USE_PAGINATED_FIND = shouldUsePaginatedFind;
72
- MAX_NUMBER_OF_ENTITIES_TO_FETCH = numToTake;
77
+ MAX_NUMBER_OF_ENTITIES_TO_FETCH = take;
73
78
  if (MAX_NUMBER_OF_ENTITIES_TO_FETCH)
74
79
  console.log(`Will limit output to ${MAX_NUMBER_OF_ENTITIES_TO_FETCH} entities.`);
75
80
  const propertySpecificationArgs = argv
@@ -93,10 +98,11 @@ class GetEntity extends basecommand_1.BaseCommand {
93
98
  // thinks it is hard to read. Consider breaking it into smaller functions.
94
99
  if (SHOULD_USE_PAGINATED_FIND) {
95
100
  const stream = streamPaginatedFind(typePath, {
101
+ criteria: convertPropertySpecIntoCriteria(propertySpecBySlug),
96
102
  skipHydrateRelationships,
103
+ skip,
97
104
  relations,
98
105
  propertySlugs: propertySlugsArray,
99
- criteria: convertPropertySpecIntoCriteria(propertySpecBySlug),
100
106
  });
101
107
  const writer = outputFile ? fs_1.default.createWriteStream(outputFile) : process.stdout;
102
108
  writer.write('[\n');
@@ -116,6 +122,8 @@ class GetEntity extends basecommand_1.BaseCommand {
116
122
  skipHydrateRelationships,
117
123
  relations,
118
124
  propertySlugs: propertySlugsArray,
125
+ skip,
126
+ take,
119
127
  });
120
128
  if (outputFile) {
121
129
  fs_1.default.writeFileSync(outputFile, JSON.stringify(response, null, 2));
@@ -133,17 +141,14 @@ class GetEntity extends basecommand_1.BaseCommand {
133
141
  }
134
142
  exports.default = GetEntity;
135
143
  async function getEntityByTypePath(typePath, propertySpec, options = {}) {
136
- const { propertySlugs, relations, skipHydrateRelationships } = options;
144
+ const { propertySlugs, relations, skipHydrateRelationships, skip, take } = options;
137
145
  const id = propertySpec?.get('id')?.toString() || undefined;
146
+ const criteria = convertPropertySpecIntoCriteria(propertySpec || new Map());
138
147
  const { root: entityName } = (0, types_1.parseTypePath)(typePath);
139
- let criteria = {};
140
148
  if (entityName === 'custom-entity' && !id) {
141
149
  criteria.typePath = typePath;
142
150
  }
143
- else {
144
- criteria = convertPropertySpecIntoCriteria(propertySpec || new Map());
145
- }
146
- return find(entityName, { id, skipHydrateRelationships, relations, propertySlugs, criteria });
151
+ return find(entityName, { id, skipHydrateRelationships, relations, propertySlugs, criteria, skip, take });
147
152
  }
148
153
  function convertPropertySpecIntoCriteria(propertySpec) {
149
154
  const criteria = {};
@@ -154,11 +159,13 @@ function convertPropertySpecIntoCriteria(propertySpec) {
154
159
  }
155
160
  async function find(entityName, options = {}) {
156
161
  const client = new sdk_1.Entities();
157
- const { criteria, id, propertySlugs, skipHydrateRelationships, relations } = options;
162
+ const { criteria, id, propertySlugs, skipHydrateRelationships, relations, skip, take } = options;
158
163
  const queryOptions = {
159
164
  entityName,
160
165
  skipHydrateRelationships,
161
166
  relations,
167
+ skip,
168
+ take
162
169
  };
163
170
  if (propertySlugs && propertySlugs.length > 0) {
164
171
  queryOptions.customParams = { propertySlugs: propertySlugs.join(',') };
@@ -6,6 +6,7 @@ export default class UpdateEntity extends BaseCommand {
6
6
  skipHydrateRelationships: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
7
7
  dryRun: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
8
  inputFile: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
+ force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
10
  alwaysConfirmEnv: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
11
  logLevel: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
12
  };
@@ -33,6 +33,11 @@ class UpdateEntity extends basecommand_1.BaseCommand {
33
33
  description: 'File containing properties to update the entity (optional)',
34
34
  required: false,
35
35
  }),
36
+ force: core_1.Flags.boolean({
37
+ char: 'F',
38
+ description: 'Force update without validation. Internal use only',
39
+ required: false,
40
+ })
36
41
  };
37
42
  static args = {
38
43
  entityName: core_1.Args.string({
@@ -41,7 +46,7 @@ class UpdateEntity extends basecommand_1.BaseCommand {
41
46
  }),
42
47
  id: core_1.Args.string({
43
48
  description: 'The unique identifier of the entity',
44
- required: true,
49
+ required: false,
45
50
  }),
46
51
  };
47
52
  static strict = false;
@@ -49,34 +54,34 @@ class UpdateEntity extends basecommand_1.BaseCommand {
49
54
  this.log('🚨 This command is in BETA and may change or be removed at any time.');
50
55
  await (0, login_1.authUser)();
51
56
  const { args, argv } = await this.parse(UpdateEntity);
52
- const { id, entityName } = args;
53
- const { dryRun: isDryRun, inputFile: inputFilename, skipHydrateRelationships } = this.flags;
57
+ const { id: specifiedId, entityName } = args;
58
+ const { dryRun: isDryRun, inputFile: inputFilename, skipHydrateRelationships, force } = this.flags;
54
59
  const propertySpecArgs = argv.slice(1, argv.length).filter(propertySpecifications_1.isValidPropertySpecification);
55
60
  const propertySpec = (0, propertySpecifications_1.parsePropertySpecificationsIntoMap)(propertySpecArgs);
56
- if (propertySpec.size === 0) {
57
- throw new Error('No valid properties provided for update');
58
- }
59
- if (inputFilename && id) {
61
+ if (inputFilename && specifiedId) {
60
62
  throw new Error('You cannot use --input and --id together. Please specify one or the other.');
61
63
  }
62
- const partialEntitiesArray = inputFilename
63
- ? (0, file_helpers_1.parseFileAsJsonArray)(inputFilename).map(({ id }) => ({ id }))
64
- : [{ id }];
64
+ const entitiesToUpdate = inputFilename
65
+ ? (0, file_helpers_1.parseFileAsJsonArray)(inputFilename)
66
+ : [{ id: specifiedId }];
65
67
  const results = {
66
68
  idsSuccessfullyUpdated: new Set(),
67
69
  idsFailedToUpdate: new Set(),
68
- numEntriesSkipped: partialEntitiesArray.filter(({ id }) => !id).length,
70
+ numEntriesSkipped: entitiesToUpdate.filter(({ id }) => !id).length,
69
71
  };
70
- const idsToUpdate = partialEntitiesArray.map(({ id }) => id).filter(Boolean);
72
+ const entitiesWithId = entitiesToUpdate.filter(({ id }) => id);
71
73
  propertySpec.delete('id'); // Remove 'id' from the property spec if it exists
72
- const changes = [...propertySpec.entries()].reduce((acc, [key, value]) => {
74
+ // will be applied to all entities
75
+ const fixedValues = [...propertySpec.entries()].reduce((acc, [key, value]) => {
73
76
  acc[key] = value;
74
77
  return acc;
75
78
  }, {});
76
- async function updateEntity(id) {
79
+ async function updateEntity(entity) {
80
+ const newEntityState = { ...entity, ...fixedValues };
81
+ const id = entity.id;
77
82
  const promise = isDryRun
78
- ? mockUpdateById(entityName, id, changes, { skipHydrateRelationships })
79
- : updateEntityById(entityName, id, changes, { skipHydrateRelationships });
83
+ ? mockUpdateById(entityName, id, newEntityState, { skipHydrateRelationships })
84
+ : updateEntityById(entityName, id, newEntityState, { skipHydrateRelationships, force });
80
85
  promise
81
86
  .catch(() => {
82
87
  results.idsFailedToUpdate.add(id);
@@ -87,8 +92,8 @@ class UpdateEntity extends basecommand_1.BaseCommand {
87
92
  return promise;
88
93
  }
89
94
  try {
90
- const limit = (0, p_limit_1.default)(5); // Limit concurrency to 5
91
- const responses = await Promise.all(idsToUpdate.map((id) => limit(() => updateEntity(id))));
95
+ const limit = (0, p_limit_1.default)(20);
96
+ const responses = await Promise.all(entitiesWithId.map((entity) => limit(() => updateEntity(entity))));
92
97
  const messagePrefix = isDryRun
93
98
  ? 'Dry run. Update skipped. Changes would be:'
94
99
  : 'Entity updated successfully:';
@@ -105,8 +110,10 @@ class UpdateEntity extends basecommand_1.BaseCommand {
105
110
  exports.default = UpdateEntity;
106
111
  async function updateEntityById(entityName, id, changes, options = {}) {
107
112
  const client = new sdk_1.Entities();
108
- const { skipHydrateRelationships } = options;
109
- return client.update({ entityName, id, object: changes, skipHydrateRelationships });
113
+ const { skipHydrateRelationships, force } = options;
114
+ const fullPath = force ? `maintenance/items/${id}` : undefined;
115
+ console.log(fullPath);
116
+ return client.update({ entityName, id, object: changes, skipHydrateRelationships, fullPath });
110
117
  }
111
118
  async function mockUpdateById(entityName, id, changes, options = {}) {
112
119
  const client = new sdk_1.Entities();
@@ -1,16 +1,17 @@
1
1
  export declare const ENVIRONMENTS: {
2
2
  dev: string;
3
3
  prod: string;
4
+ local: string;
4
5
  };
5
6
  export declare function initializeVibeIQConfig(): Promise<void>;
6
7
  export declare function readVibeIQConfig(): Promise<any>;
7
8
  export declare function writeVibeIQConfig(config: any): Promise<void>;
8
9
  export declare function storeVibeIQConfig(incomingConfig: any): Promise<void>;
9
10
  export declare function createConfig(fileName: any): Promise<void>;
10
- export declare function writeConfig(config: any, configName?: string): Promise<void>;
11
+ export declare function writeConfig(config: any, configName?: string | null): Promise<void>;
11
12
  export declare function getConfig(): Promise<any>;
12
- export declare function storeConfig(incomingConfig: any, configName?: string, merge?: boolean): Promise<void>;
13
+ export declare function storeConfig(incomingConfig: any, configName?: string | null, merge?: boolean): Promise<void>;
13
14
  export declare function getConfigFiles(): Promise<any>;
14
15
  export declare function getConfigContent(fileName: string): Promise<any>;
15
- export declare function validateEnvironments(envName?: any): Promise<any>;
16
+ export declare function validateEnvironments(envName?: string | null): Promise<any>;
16
17
  export declare function checkTelemetry(cliVersion: string): Promise<void>;
@@ -15,6 +15,7 @@ const defaultConfigFileLocation = (0, node_path_1.join)(configDirectoryLocation,
15
15
  exports.ENVIRONMENTS = {
16
16
  dev: 'https://api.dev.vibeiq.com/dev/api',
17
17
  prod: 'https://api.vibeiq.com/prod/api',
18
+ local: 'http://localhost:3000/api',
18
19
  };
19
20
  async function initializeVibeIQConfig() {
20
21
  try {
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.6.0-alpha-3",
2
+ "version": "3.6.0-alpha-4",
3
3
  "commands": {
4
4
  "app:create": {
5
5
  "id": "app:create",
@@ -604,7 +604,8 @@
604
604
  "dev",
605
605
  "development",
606
606
  "prod",
607
- "production"
607
+ "production",
608
+ "local"
608
609
  ]
609
610
  },
610
611
  "apiUserToken": {
@@ -905,22 +906,6 @@
905
906
  "required": false,
906
907
  "multiple": false
907
908
  },
908
- "skipHydrateRelationships": {
909
- "name": "skipHydrateRelationships",
910
- "type": "boolean",
911
- "char": "s",
912
- "description": "Skip hydrating relationships when fetching the entity",
913
- "required": false,
914
- "allowNo": false
915
- },
916
- "relations": {
917
- "name": "relations",
918
- "type": "option",
919
- "char": "r",
920
- "description": "Comma-separated list of relations to include in the output",
921
- "required": false,
922
- "multiple": false
923
- },
924
909
  "propertySlugs": {
925
910
  "name": "propertySlugs",
926
911
  "type": "option",
@@ -937,6 +922,22 @@
937
922
  "required": false,
938
923
  "allowNo": false
939
924
  },
925
+ "skip": {
926
+ "name": "skip",
927
+ "type": "option",
928
+ "char": "s",
929
+ "description": "Number of entities to skip (used with paginated fetch)",
930
+ "required": false,
931
+ "multiple": false
932
+ },
933
+ "skipHydrateRelationships": {
934
+ "name": "skipHydrateRelationships",
935
+ "type": "boolean",
936
+ "char": "S",
937
+ "description": "Skip hydrating relationships when fetching the entity",
938
+ "required": false,
939
+ "allowNo": false
940
+ },
940
941
  "take": {
941
942
  "name": "take",
942
943
  "type": "option",
@@ -944,6 +945,14 @@
944
945
  "description": "Number of entities to fetch in a single request (default is 100)",
945
946
  "required": false,
946
947
  "multiple": false
948
+ },
949
+ "relations": {
950
+ "name": "relations",
951
+ "type": "option",
952
+ "char": "r",
953
+ "description": "Comma-separated list of relations to include in the output",
954
+ "required": false,
955
+ "multiple": false
947
956
  }
948
957
  },
949
958
  "args": {
@@ -1017,6 +1026,14 @@
1017
1026
  "description": "File containing properties to update the entity (optional)",
1018
1027
  "required": false,
1019
1028
  "multiple": false
1029
+ },
1030
+ "force": {
1031
+ "name": "force",
1032
+ "type": "boolean",
1033
+ "char": "F",
1034
+ "description": "Force update without validation. Internal use only",
1035
+ "required": false,
1036
+ "allowNo": false
1020
1037
  }
1021
1038
  },
1022
1039
  "args": {
@@ -1028,7 +1045,7 @@
1028
1045
  "id": {
1029
1046
  "name": "id",
1030
1047
  "description": "The unique identifier of the entity",
1031
- "required": true
1048
+ "required": false
1032
1049
  }
1033
1050
  }
1034
1051
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrail/cli",
3
- "version": "3.6.0-alpha-3",
3
+ "version": "3.6.0-alpha-4",
4
4
  "description": "VibeIQ's Contrail Platform CLI.",
5
5
  "bin": {
6
6
  "contrail-cli": "./bin/run",