@contrail/cli 3.4.11-alpha.0f34b47 → 3.4.11-alpha.11e1d43

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.4.11-alpha.0f34b47 linux-x64 node-v24.14.1
20
+ @contrail/cli/3.4.11-alpha.11e1d43 linux-x64 node-v24.14.1
21
21
  $ contrail --help [COMMAND]
22
22
  USAGE
23
23
  $ contrail COMMAND
@@ -1405,7 +1405,7 @@ EXAMPLES
1405
1405
 
1406
1406
  ## `contrail types uploadUsageInfo`
1407
1407
 
1408
- [DEPRECATED] Upload extracted usage info. Use uploadTypeOverrides instead.
1408
+ Upload extracted usage info
1409
1409
 
1410
1410
  ```
1411
1411
  USAGE
@@ -1420,7 +1420,7 @@ FLAGS
1420
1420
  <options: error|warn|info|debug>
1421
1421
 
1422
1422
  DESCRIPTION
1423
- [DEPRECATED] Upload extracted usage info. Use uploadTypeOverrides instead.
1423
+ Upload extracted usage info
1424
1424
 
1425
1425
  EXAMPLES
1426
1426
  $ contrail types uploadUsageInfo
@@ -1,8 +1,13 @@
1
1
  export declare function getOptionSets(): Promise<any[]>;
2
2
  export declare function getUserLists(): Promise<any[]>;
3
3
  export declare function getOptionSetHierarchies(): Promise<any[]>;
4
+ export declare function getOptionSetHierarchyLinks(): Promise<any[]>;
4
5
  export declare function getRuleSets(): Promise<any[]>;
6
+ export declare function getRuleSetLinks(): Promise<any[]>;
7
+ export declare function getUsageInfo(): Promise<any[]>;
5
8
  export declare function getTypePropertyPolicies(): Promise<any[]>;
9
+ export declare function getTypePropertyPolicyLinks(): Promise<any[]>;
6
10
  export declare function getTypePolicies(): Promise<any[]>;
7
11
  export declare function getTypeOverrideCopies(): Promise<any[]>;
8
12
  export declare function uploadTypeOverrideObjects(reducedOverrides: any): Promise<void>;
13
+ export declare function getTypePolicyLinks(): Promise<any[]>;
package/dist/api/types.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uploadTypeOverrideObjects = exports.getTypeOverrideCopies = exports.getTypePolicies = exports.getTypePropertyPolicies = exports.getRuleSets = exports.getOptionSetHierarchies = exports.getUserLists = exports.getOptionSets = void 0;
3
+ exports.getTypePolicyLinks = exports.uploadTypeOverrideObjects = exports.getTypeOverrideCopies = 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
5
  async function getOptionSets() {
6
6
  return await new sdk_1.Entities().get({
@@ -21,6 +21,13 @@ async function getOptionSetHierarchies() {
21
21
  });
22
22
  }
23
23
  exports.getOptionSetHierarchies = getOptionSetHierarchies;
24
+ async function getOptionSetHierarchyLinks() {
25
+ const entitiesClient = new sdk_1.Entities();
26
+ return await entitiesClient.get({
27
+ entityName: 'type-option-set-hierarchy-link',
28
+ });
29
+ }
30
+ exports.getOptionSetHierarchyLinks = getOptionSetHierarchyLinks;
24
31
  async function getRuleSets() {
25
32
  const entitiesClient = new sdk_1.Entities();
26
33
  return await entitiesClient.get({
@@ -28,6 +35,20 @@ async function getRuleSets() {
28
35
  });
29
36
  }
30
37
  exports.getRuleSets = getRuleSets;
38
+ async function getRuleSetLinks() {
39
+ const entitiesClient = new sdk_1.Entities();
40
+ return await entitiesClient.get({
41
+ entityName: 'type-rule-set-link',
42
+ });
43
+ }
44
+ exports.getRuleSetLinks = getRuleSetLinks;
45
+ async function getUsageInfo() {
46
+ const entitiesClient = new sdk_1.Entities();
47
+ return await entitiesClient.get({
48
+ entityName: 'type-property-usage-info',
49
+ });
50
+ }
51
+ exports.getUsageInfo = getUsageInfo;
31
52
  async function getTypePropertyPolicies() {
32
53
  const entitiesClient = new sdk_1.Entities();
33
54
  return await entitiesClient.get({
@@ -35,6 +56,13 @@ async function getTypePropertyPolicies() {
35
56
  });
36
57
  }
37
58
  exports.getTypePropertyPolicies = getTypePropertyPolicies;
59
+ async function getTypePropertyPolicyLinks() {
60
+ const entitiesClient = new sdk_1.Entities();
61
+ return await entitiesClient.get({
62
+ entityName: 'type-property-policy-link',
63
+ });
64
+ }
65
+ exports.getTypePropertyPolicyLinks = getTypePropertyPolicyLinks;
38
66
  async function getTypePolicies() {
39
67
  const entitiesClient = new sdk_1.Entities();
40
68
  return await entitiesClient.get({
@@ -58,3 +86,10 @@ async function uploadTypeOverrideObjects(reducedOverrides) {
58
86
  });
59
87
  }
60
88
  exports.uploadTypeOverrideObjects = uploadTypeOverrideObjects;
89
+ async function getTypePolicyLinks() {
90
+ const entitiesClient = new sdk_1.Entities();
91
+ return await entitiesClient.get({
92
+ entityName: 'type-policy-link',
93
+ });
94
+ }
95
+ exports.getTypePolicyLinks = getTypePolicyLinks;
@@ -54,9 +54,14 @@ async function getAll(outDir, overwrite) {
54
54
  types: await (0, type_extractor_1.getTypes)(),
55
55
  optionSets: await (0, types_1.getOptionSets)(),
56
56
  optionSetHierarchies: await (0, types_1.getOptionSetHierarchies)(),
57
+ optionSetHierarchyLinks: await (0, types_1.getOptionSetHierarchyLinks)(),
57
58
  ruleSets: await (0, types_1.getRuleSets)(),
59
+ ruleSetLinks: await (0, types_1.getRuleSetLinks)(),
60
+ usageInfo: await (0, types_1.getUsageInfo)(),
58
61
  typePropertyPolicies: await (0, types_1.getTypePropertyPolicies)(),
62
+ typePropertyPolicyLinks: await (0, types_1.getTypePropertyPolicyLinks)(),
59
63
  typePolicies: await (0, types_1.getTypePolicies)(),
64
+ typePolicyLinks: await (0, types_1.getTypePolicyLinks)(),
60
65
  typeOverrides: await (0, types_1.getTypeOverrideCopies)(),
61
66
  orgUsers: await (0, users_1.getUserOrgs)(),
62
67
  groups: await (0, users_1.getGroups)(),
@@ -120,18 +125,31 @@ async function saveData(reducedData, dir, overwrite) {
120
125
  split: true,
121
126
  fileLabel: 'identifier',
122
127
  },
128
+ reducedOptionSetHierarchyLinks: {
129
+ filename: 'type-option-set-hierarchy-links',
130
+ split: false,
131
+ fileLabel: '',
132
+ },
123
133
  reducedRuleSets: { filename: 'rule-sets', split: true, fileLabel: 'name' },
134
+ reducedRuleSetLinks: { filename: 'rule-set-links', split: false, fileLabel: '' },
135
+ reducedUsageInfo: { filename: 'usage-info', split: false, fileLabel: '' },
124
136
  reducedTypePropertyPolicies: {
125
137
  filename: 'type-property-policies',
126
138
  split: true,
127
139
  fileLabel: 'label',
128
140
  },
141
+ reducedTypePropertyPolicyLinks: {
142
+ filename: 'type-property-policy-links',
143
+ split: false,
144
+ fileLabel: '',
145
+ },
129
146
  reducedOverrides: {
130
147
  filename: 'type-overrides',
131
148
  split: false,
132
149
  fileLabel: '',
133
150
  },
134
151
  reducedTypePolicies: { filename: 'type-policies', split: true, fileLabel: 'label' },
152
+ reducedTypePolicyLinks: { filename: 'type-policy-links', split: false, fileLabel: '' },
135
153
  };
136
154
  for (const [key, folder] of Object.entries(propertyToFolderMap)) {
137
155
  const CURRENT_DIR = process.cwd();
@@ -7,6 +7,7 @@ const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
7
  const login_1 = require("../../auth/login");
8
8
  const uploadOptionSets_1 = require("./uploadOptionSets");
9
9
  const uploadOptionSetHierarchies_1 = require("./uploadOptionSetHierarchies");
10
+ const uploadUsageInfo_1 = require("./uploadUsageInfo");
10
11
  const uploadRuleSets_1 = require("./uploadRuleSets");
11
12
  const uploadTypePropertyPolicies_1 = require("./uploadTypePropertyPolicies");
12
13
  const type_uploader_1 = require("../../helpers/types/type-uploader");
@@ -40,6 +41,7 @@ async function loadAll(dir, skipPolicies = false) {
40
41
  await (0, uploadOptionSets_1.uploadOptionSets)(dir);
41
42
  await (0, type_uploader_1.uploadTypes)(dir);
42
43
  await (0, uploadOptionSetHierarchies_1.uploadOptionSetHierarchies)(dir);
44
+ await (0, uploadUsageInfo_1.uploadUsageInfo)(dir);
43
45
  await (0, uploadRuleSets_1.uploadRuleSets)(dir);
44
46
  if (!skipPolicies) {
45
47
  await (0, uploadTypePropertyPolicies_1.uploadTypePropertyPolicies)(dir);
@@ -62,9 +62,14 @@ async function mergeTypeProperties(fileLocation, typePaths) {
62
62
  types: await (0, type_extractor_1.getTypes)(),
63
63
  optionSets: await (0, types_2.getOptionSets)(),
64
64
  optionSetHierarchies: [],
65
+ optionSetHierarchyLinks: [],
65
66
  ruleSets: [],
67
+ ruleSetLinks: [],
68
+ usageInfo: [],
66
69
  typePropertyPolicies: [],
70
+ typePropertyPolicyLinks: [],
67
71
  typePolicies: [],
72
+ typePolicyLinks: [],
68
73
  };
69
74
  const reducedData = await (0, types_1.getAllReducedTypes)(data);
70
75
  for (const typePath of typePaths) {
@@ -8,6 +8,7 @@ const path = tslib_1.__importStar(require("path"));
8
8
  const login_1 = require("../../auth/login");
9
9
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
10
10
  const core_1 = require("@oclif/core");
11
+ const type_extractor_1 = require("../../helpers/types/type-extractor");
11
12
  const basecommand_1 = require("../../basecommand");
12
13
  const logger_1 = tslib_1.__importDefault(require("../../logger"));
13
14
  const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
@@ -37,6 +38,8 @@ async function uploadOptionSetHierarchies(dir) {
37
38
  logger_1.default.info(`${chalk_1.default.yellow.bold('OPTION SET HIERARCHIES')} Uploading`);
38
39
  const optionSetHierarchies = await loadOptionSetHierarchies(dir);
39
40
  await uploadOSH(optionSetHierarchies);
41
+ const optionSetHierarchyLinks = await loadOptionSetHierarchyLinks(dir);
42
+ await uploadOSHLinks(optionSetHierarchyLinks);
40
43
  logger_1.default.info(`${chalk_1.default.yellow.bold('OPTION SET HIERARCHIES')} Uploaded`);
41
44
  }
42
45
  catch (e) {
@@ -60,6 +63,14 @@ function loadOptionSetHierarchies(fromDir) {
60
63
  throw new Error(`ERROR PARSING YAML: ${e}`);
61
64
  }
62
65
  }
66
+ function loadOptionSetHierarchyLinks(fromDir) {
67
+ try {
68
+ return js_yaml_1.default.load(fs_1.default.readFileSync(path.join(fromDir, 'type-option-set-hierarchy-links.yml'), 'utf8'));
69
+ }
70
+ catch (e) {
71
+ throw new Error(`ERROR PARSING YAML: ${e}`);
72
+ }
73
+ }
63
74
  async function uploadOSH(loadedOSHs) {
64
75
  const optionSets = await new sdk_1.Entities().get({
65
76
  entityName: 'type-property-option-set',
@@ -139,3 +150,109 @@ function transformOSHNameToID(hierarchy, optionSets) {
139
150
  }
140
151
  return true;
141
152
  }
153
+ async function uploadOSHLinks(reducedOSHLinks) {
154
+ const typesWithProperties = await (0, type_extractor_1.getTypes)();
155
+ const typeProperties = [];
156
+ typesWithProperties.forEach((type) => {
157
+ if (type.typeProperties) {
158
+ for (const tp of type.typeProperties) {
159
+ tp.typeId = type.id;
160
+ tp.typeSlug = type.slug;
161
+ typeProperties.push(tp);
162
+ }
163
+ }
164
+ });
165
+ const currentOSHs = await new sdk_1.Entities().get({
166
+ entityName: 'option-set-hierarchy',
167
+ });
168
+ const currentOSHLinks = await new sdk_1.Entities().get({
169
+ entityName: 'type-option-set-hierarchy-link',
170
+ });
171
+ const currentOSHLinkHashes = {};
172
+ for (const currentLink of currentOSHLinks) {
173
+ const foundType = typesWithProperties.find((x) => x.id === currentLink.typeId);
174
+ const foundOSH = currentOSHs.find((osh) => osh.id === currentLink.optionSetHierarchyId);
175
+ const foundTPSlugs = typeProperties
176
+ .filter((x) => currentLink?.hierarchyTypePropertyIds?.includes(x.id))
177
+ .map((x) => x.slug);
178
+ if (!foundType ||
179
+ !foundOSH ||
180
+ foundTPSlugs.length !== currentLink.hierarchyTypePropertyIds.length) {
181
+ logger_1.default.info(`skipping unhashable, invalid type option set hierarchy link: ${JSON.stringify(currentLink, null, 2)}`);
182
+ }
183
+ // don't mutate original array
184
+ const sortedFoundTPSlugs = [...foundTPSlugs].sort();
185
+ const hash = `${foundType.slug}|${foundOSH.name}|${sortedFoundTPSlugs.join('|')}`;
186
+ currentOSHLinkHashes[hash] = currentLink;
187
+ }
188
+ const reducedLinksByHashes = {};
189
+ for (const loadedLink of reducedOSHLinks) {
190
+ // don't mutate original array
191
+ const sortedTPSlugs = [...loadedLink.typePropertySlugs].sort();
192
+ const hash = `${loadedLink.typeSlug}|${loadedLink.optionSetHierarchyIdentifier}|${sortedTPSlugs.join('|')}}`;
193
+ reducedLinksByHashes[hash] = loadedLink;
194
+ }
195
+ for (const loadedLink of reducedOSHLinks) {
196
+ try {
197
+ // don't mutate original array
198
+ const sortedTPSlugs = [...loadedLink.typePropertySlugs].sort();
199
+ const found = currentOSHLinkHashes[`${loadedLink.typeSlug}|${loadedLink.optionSetHierarchyIdentifier}|${sortedTPSlugs.join('|')}`];
200
+ if (!found) {
201
+ if (!transformReducedLink(loadedLink, typesWithProperties, currentOSHs)) {
202
+ continue;
203
+ }
204
+ logger_1.default.debug(`Creating: ${JSON.stringify(loadedLink, null, 2)}`);
205
+ await new sdk_1.Entities().create({
206
+ entityName: 'type-option-set-hierarchy-link',
207
+ object: {
208
+ hierarchyTypePropertyIds: loadedLink.hierarchyTypePropertyIds,
209
+ optionSetHierarchyId: loadedLink.optionSetHierarchyId,
210
+ typeId: loadedLink.typeId,
211
+ },
212
+ });
213
+ }
214
+ }
215
+ catch (err) {
216
+ logger_1.default.error(`Error uploading type option set hierarchy links: ${err}`);
217
+ }
218
+ }
219
+ for (const [currentLinkHash, currentLink] of Object.entries(currentOSHLinkHashes)) {
220
+ try {
221
+ const found = reducedLinksByHashes[currentLinkHash];
222
+ if (!found) {
223
+ logger_1.default.debug(`Deleting: ${JSON.stringify(currentLinkHash)}`);
224
+ await new sdk_1.Entities().delete({
225
+ entityName: 'type-option-set-hierarchy-link',
226
+ id: currentLink['id'],
227
+ });
228
+ }
229
+ }
230
+ catch (err) {
231
+ logger_1.default.error(`Error Deleting rule set link: ${err}`);
232
+ }
233
+ }
234
+ }
235
+ function transformReducedLink(OSHLink, typesWithProperties, OSHs) {
236
+ logger_1.default.debug(`OSHLink before transform: ${JSON.stringify(OSHLink, null, 2)}`);
237
+ const foundType = typesWithProperties.find((x) => x.slug === OSHLink.typeSlug);
238
+ if (!foundType) {
239
+ logger_1.default.error(`OSH Links: Could not find type with slug ${OSHLink.typeSlug}`);
240
+ return false;
241
+ }
242
+ OSHLink.typeId = foundType.id;
243
+ const foundTPs = foundType?.typeProperties?.filter((x) => OSHLink.typePropertySlugs.includes(x.slug)) ?? [];
244
+ if (foundTPs.length !== OSHLink.typePropertySlugs.length) {
245
+ logger_1.default.error(`OSH Links: Could not find all type properties with slugs ${OSHLink.typePropertySlugs}`);
246
+ return false;
247
+ }
248
+ logger_1.default.debug(`foundTPs: ${JSON.stringify(foundTPs)}`);
249
+ OSHLink.hierarchyTypePropertyIds = foundTPs.map((x) => x.id);
250
+ const foundOSH = OSHs.find((x) => x.identifier === OSHLink.optionSetHierarchyIdentifier);
251
+ if (!foundOSH) {
252
+ logger_1.default.error(`OSH Links: Could not find option set hierarchy with identifier ${OSHLink.optionSetHierarchyIdentifier}`);
253
+ return false;
254
+ }
255
+ OSHLink.optionSetHierarchyId = foundOSH.id;
256
+ logger_1.default.debug(`OSHLink after transform: ${JSON.stringify(OSHLink, null, 2)}`);
257
+ return true;
258
+ }
@@ -35,8 +35,9 @@ async function uploadRuleSets(dir) {
35
35
  try {
36
36
  await (0, login_1.authUser)();
37
37
  logger_1.default.info(`${chalk_1.default.yellow.bold('RULE SET')} Uploading`);
38
- const reducedRuleSets = await loadReducedRuleSets(dir);
38
+ const [reducedRuleSets, reducedRuleSetLinks] = await loadReducedRuleSets(dir);
39
39
  await uploadRuleSetObjects(reducedRuleSets);
40
+ await uploadRuleSetLinkObjects(reducedRuleSetLinks);
40
41
  logger_1.default.info(`${chalk_1.default.yellow.bold('RULE SET')} Uploaded`);
41
42
  }
42
43
  catch (e) {
@@ -48,13 +49,15 @@ async function uploadRuleSets(dir) {
48
49
  exports.uploadRuleSets = uploadRuleSets;
49
50
  function loadReducedRuleSets(fromDir) {
50
51
  const ruleSets = [];
52
+ let ruleSetLinks = [];
51
53
  const dir = path.join(fromDir, 'rule-sets');
52
54
  try {
53
55
  const files = fs_1.default.readdirSync(dir);
54
56
  for (const file of files) {
55
57
  ruleSets.push(js_yaml_1.default.load(fs_1.default.readFileSync(path.join(dir, file), 'utf8')));
56
58
  }
57
- return ruleSets;
59
+ ruleSetLinks = js_yaml_1.default.load(fs_1.default.readFileSync(path.join(fromDir, 'rule-set-links.yml'), 'utf8'));
60
+ return [ruleSets, ruleSetLinks];
58
61
  }
59
62
  catch (e) {
60
63
  throw new Error(`ERROR PARSING YAML: ${e}`);
@@ -113,3 +116,83 @@ async function uploadRuleSetObjects(reducedRuleSets) {
113
116
  }
114
117
  }
115
118
  }
119
+ async function uploadRuleSetLinkObjects(loadedRuleSetLinks) {
120
+ const types = await new sdk_1.Entities().get({
121
+ entityName: 'type',
122
+ });
123
+ const currentRuleSets = await new sdk_1.Entities().get({
124
+ entityName: 'type-rule-set',
125
+ });
126
+ const currentRuleSetLinks = await new sdk_1.Entities().get({
127
+ entityName: 'type-rule-set-link',
128
+ });
129
+ const currentLinksHashes = {};
130
+ for (const currentLink of currentRuleSetLinks) {
131
+ const foundType = types.find((t) => t.id === currentLink.typeId);
132
+ const foundRuleSet = currentRuleSets.find((rs) => rs.id === currentLink.typeRuleSetId);
133
+ const hash = `${foundType.slug}|${foundRuleSet.name}`;
134
+ currentLinksHashes[hash] = currentLink;
135
+ }
136
+ const reducedLinksByHashes = {};
137
+ for (const loadedLink of loadedRuleSetLinks) {
138
+ const hash = `${loadedLink.type}|${loadedLink.ruleSet}`;
139
+ reducedLinksByHashes[hash] = loadedLink;
140
+ }
141
+ for (const loadedRuleSetLink of loadedRuleSetLinks) {
142
+ try {
143
+ const found = currentLinksHashes[`${loadedRuleSetLink.type}|${loadedRuleSetLink.ruleSet}`];
144
+ if (!found) {
145
+ if (!transformReducedLink(loadedRuleSetLink, types, currentRuleSets)) {
146
+ continue;
147
+ }
148
+ logger_1.default.info(`Creating: ${JSON.stringify(loadedRuleSetLink, null, 2)}`);
149
+ await new sdk_1.Entities().create({
150
+ entityName: 'type-rule-set-link',
151
+ object: {
152
+ typeRuleSetId: loadedRuleSetLink.ruleSet,
153
+ typeId: loadedRuleSetLink.type,
154
+ },
155
+ });
156
+ }
157
+ else {
158
+ if (!transformReducedLink(loadedRuleSetLink, types, currentRuleSets)) {
159
+ continue;
160
+ }
161
+ logger_1.default.info(`skipping updating existing rule set link: ${loadedRuleSetLink}`);
162
+ }
163
+ }
164
+ catch (err) {
165
+ logger_1.default.error(`Error Uploading rule set links: ${err}`);
166
+ }
167
+ }
168
+ for (const [currentLinkHash, currentLink] of Object.entries(currentLinksHashes)) {
169
+ try {
170
+ const found = reducedLinksByHashes[currentLinkHash];
171
+ if (!found) {
172
+ logger_1.default.info(`Deleting: ${currentLinkHash}`);
173
+ await new sdk_1.Entities().delete({
174
+ entityName: 'type-rule-set-link',
175
+ id: currentLink['id'],
176
+ });
177
+ }
178
+ }
179
+ catch (err) {
180
+ logger_1.default.error(`Error Deleting rule set link: ${err}`);
181
+ }
182
+ }
183
+ }
184
+ function transformReducedLink(ruleSetLink, types, ruleSets) {
185
+ const foundType = types.find((t) => t.slug === ruleSetLink.type);
186
+ if (!foundType) {
187
+ logger_1.default.error(`Could not find type with name ${ruleSetLink.type}`);
188
+ return false;
189
+ }
190
+ ruleSetLink.type = foundType.id;
191
+ const foundRuleSet = ruleSets.find((rs) => rs.identifier === ruleSetLink.ruleSet);
192
+ if (!foundRuleSet) {
193
+ logger_1.default.error(`Could not find rule set with name ${foundType.ruleSet}`);
194
+ return false;
195
+ }
196
+ ruleSetLink.ruleSet = foundRuleSet.id;
197
+ return true;
198
+ }
@@ -8,6 +8,7 @@ const path = tslib_1.__importStar(require("path"));
8
8
  const login_1 = require("../../auth/login");
9
9
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
10
10
  const core_1 = require("@oclif/core");
11
+ const type_extractor_1 = require("../../helpers/types/type-extractor");
11
12
  const users_1 = require("../../api/users");
12
13
  const basecommand_1 = require("../../basecommand");
13
14
  const logger_1 = tslib_1.__importDefault(require("../../logger"));
@@ -36,8 +37,9 @@ async function uploadTypePolicies(dir) {
36
37
  try {
37
38
  await (0, login_1.authUser)();
38
39
  logger_1.default.info(`${chalk_1.default.yellow.bold('TYPE POLICY')} Uploading`);
39
- const reducedTypePolicies = await loadTypePolicies(dir);
40
+ const [reducedTypePolicies, reducedTypePolicyLinks] = await loadTypePolicies(dir);
40
41
  await uploadTypePolicyObjects(reducedTypePolicies);
42
+ await uploadTypePolicyLinks(reducedTypePolicyLinks);
41
43
  logger_1.default.info(`${chalk_1.default.yellow.bold('TYPE POLICY')} Uploaded`);
42
44
  }
43
45
  catch (e) {
@@ -49,13 +51,15 @@ async function uploadTypePolicies(dir) {
49
51
  exports.uploadTypePolicies = uploadTypePolicies;
50
52
  function loadTypePolicies(fromDir) {
51
53
  const tps = [];
54
+ let tpLinks = [];
52
55
  const dir = path.join(fromDir, 'type-policies');
53
56
  try {
54
57
  const files = fs_1.default.readdirSync(dir);
55
58
  for (const file of files) {
56
59
  tps.push(js_yaml_1.default.load(fs_1.default.readFileSync(path.join(dir, file), 'utf8')));
57
60
  }
58
- return tps;
61
+ tpLinks = js_yaml_1.default.load(fs_1.default.readFileSync(path.join(fromDir, 'type-policy-links.yml'), 'utf8'));
62
+ return [tps, tpLinks];
59
63
  }
60
64
  catch (e) {
61
65
  throw new Error(`ERROR PARSING YAML: ${e}`);
@@ -148,3 +152,83 @@ async function uploadTypePolicyObjects(reducedTypePolicies) {
148
152
  }
149
153
  }
150
154
  }
155
+ async function uploadTypePolicyLinks(reducedTypePolicyLinks) {
156
+ const types = await (0, type_extractor_1.getTypes)();
157
+ const currentTypePolicies = await new sdk_1.Entities().get({
158
+ entityName: 'type-policy',
159
+ });
160
+ const currentTypePolicyLinks = await new sdk_1.Entities().get({
161
+ entityName: 'type-policy-link',
162
+ });
163
+ const currentLinksHashes = {};
164
+ for (const currentLink of currentTypePolicyLinks) {
165
+ const foundType = types.find((type) => type.id === currentLink.typeId);
166
+ const foundTypePolicy = currentTypePolicies.find((tp) => tp.id === currentLink.typePolicyId);
167
+ if (!foundType || !foundTypePolicy) {
168
+ logger_1.default.info(`skipping unhashable, invalid policy link: ${JSON.stringify(currentLink, null, 2)}`);
169
+ }
170
+ const hash = `${foundType.slug}|${foundTypePolicy.identifier}`;
171
+ currentLinksHashes[hash] = currentLink;
172
+ }
173
+ const reducedLinksByHashes = {};
174
+ for (const loadedLink of reducedTypePolicyLinks) {
175
+ const hash = `${loadedLink.typeSlug}|${loadedLink.typePolicyIdentifier}`;
176
+ reducedLinksByHashes[hash] = loadedLink;
177
+ }
178
+ for (const loadedTPLink of reducedTypePolicyLinks) {
179
+ try {
180
+ const found = currentLinksHashes[`${loadedTPLink.typeSlug}|${loadedTPLink.typePolicyIdentifier}`];
181
+ if (!found) {
182
+ if (!transformReducedLink(loadedTPLink, types, currentTypePolicies)) {
183
+ continue;
184
+ }
185
+ logger_1.default.info(`Creating: ${loadedTPLink.typeSlug}|${loadedTPLink.typePolicyIdentifier}`);
186
+ await new sdk_1.Entities().create({
187
+ entityName: 'type-policy-link',
188
+ object: {
189
+ typePolicyId: loadedTPLink.typePolicyId,
190
+ typeId: loadedTPLink.typeId,
191
+ },
192
+ });
193
+ }
194
+ else {
195
+ if (!transformReducedLink(loadedTPLink, types, currentTypePolicies)) {
196
+ continue;
197
+ }
198
+ }
199
+ }
200
+ catch (err) {
201
+ logger_1.default.error(`Error Uploading type policy links: ${err}`);
202
+ }
203
+ }
204
+ for (const [currentLinkHash, currentLink] of Object.entries(currentLinksHashes)) {
205
+ try {
206
+ const found = reducedLinksByHashes[currentLinkHash];
207
+ if (!found) {
208
+ logger_1.default.info(`Deleting: ${currentLinkHash}`);
209
+ await new sdk_1.Entities().delete({
210
+ entityName: 'type-policy-link',
211
+ id: currentLink['id'],
212
+ });
213
+ }
214
+ }
215
+ catch (err) {
216
+ logger_1.default.error(`Error Deleting rule set link: ${err}`);
217
+ }
218
+ }
219
+ }
220
+ function transformReducedLink(typePolicyLink, types, typePolicies) {
221
+ const foundType = types.find((type) => type.slug === typePolicyLink.typeSlug);
222
+ if (!foundType) {
223
+ logger_1.default.error(`Could not find type with slug ${typePolicyLink.typeSlug}`);
224
+ return false;
225
+ }
226
+ typePolicyLink.typeId = foundType.id;
227
+ const foundTypePolicy = typePolicies.find((tpp) => tpp.identifier === typePolicyLink.typePolicyIdentifier);
228
+ if (!foundTypePolicy) {
229
+ logger_1.default.error(`Could not find type policy with identifier ${typePolicyLink.typePolicyIdentifier}`);
230
+ return false;
231
+ }
232
+ typePolicyLink.typePolicyId = foundTypePolicy.id;
233
+ return true;
234
+ }
@@ -10,3 +10,4 @@ export default class UploadTypePropertyPolicies extends BaseCommand {
10
10
  run(): Promise<void>;
11
11
  }
12
12
  export declare function uploadTypePropertyPolicies(dir: string): Promise<void>;
13
+ export declare function findAllOccurrences(array: any, evaluator: any): any[];