@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 +11 -9
- package/dist/auth/login.js +15 -5
- package/dist/commands/config/set.js +1 -1
- package/dist/commands/entities/get.d.ts +3 -2
- package/dist/commands/entities/get.js +28 -21
- package/dist/commands/entities/update.d.ts +1 -0
- package/dist/commands/entities/update.js +27 -20
- package/dist/helpers/config/config.d.ts +4 -3
- package/dist/helpers/config/config.js +1 -0
- package/oclif.manifest.json +36 -19
- package/package.json +1 -1
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-
|
|
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>] [-
|
|
629
|
-
<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, --
|
|
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>
|
package/dist/auth/login.js
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
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,
|
|
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 =
|
|
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
|
-
|
|
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:
|
|
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 (
|
|
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
|
|
63
|
-
? (0, file_helpers_1.parseFileAsJsonArray)(inputFilename)
|
|
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:
|
|
70
|
+
numEntriesSkipped: entitiesToUpdate.filter(({ id }) => !id).length,
|
|
69
71
|
};
|
|
70
|
-
const
|
|
72
|
+
const entitiesWithId = entitiesToUpdate.filter(({ id }) => id);
|
|
71
73
|
propertySpec.delete('id'); // Remove 'id' from the property spec if it exists
|
|
72
|
-
|
|
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(
|
|
79
|
+
async function updateEntity(entity) {
|
|
80
|
+
const newEntityState = { ...entity, ...fixedValues };
|
|
81
|
+
const id = entity.id;
|
|
77
82
|
const promise = isDryRun
|
|
78
|
-
? mockUpdateById(entityName, id,
|
|
79
|
-
: updateEntityById(entityName, id,
|
|
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)(
|
|
91
|
-
const responses = await Promise.all(
|
|
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
|
-
|
|
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?:
|
|
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 {
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.6.0-alpha-
|
|
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":
|
|
1048
|
+
"required": false
|
|
1032
1049
|
}
|
|
1033
1050
|
}
|
|
1034
1051
|
},
|