contensis-cli 1.0.0-beta.95 → 1.0.0-beta.97

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.
@@ -33,87 +33,211 @@ var import_file_provider = require("../providers/file-provider");
33
33
  var import_diff = require("../util/diff");
34
34
  var import_logger = require("../util/logger");
35
35
  var import_os = require("../util/os");
36
- var import_yaml = require("../util/yaml");
37
- const mapCIWorkflowContent = async (cli, git) => {
38
- const workflowFile = (0, import_file_provider.readFile)(git.ciFilePath);
36
+ var import_yaml2 = require("../util/yaml");
37
+ const mapCIWorkflowContent = async (cli) => {
38
+ const workflowFile = (0, import_file_provider.readFile)(cli.git.ciFilePath);
39
39
  if (!workflowFile)
40
40
  return void 0;
41
- const blockId = git.name;
42
- if (git.type === "github") {
43
- const addGitHubActionJobStep = {
44
- name: "Push block to Contensis",
45
- id: "push-block",
46
- uses: "contensis/block-push@v1",
47
- with: {
48
- "block-id": blockId,
49
- alias: cli.currentEnv,
50
- "project-id": cli.currentProject,
51
- "client-id": "${{ secrets.CONTENSIS_CLIENT_ID }}",
52
- "shared-secret": "${{ secrets.CONTENSIS_SHARED_SECRET }}"
53
- }
54
- };
55
- const workflowDoc = (0, import_yaml.parseYamlDocument)(workflowFile);
56
- const workflowJS = workflowDoc.toJS();
57
- const setWorkflowElement = (path, value) => {
58
- const findPath = typeof path === "string" && path.includes(".") ? path.split(".").map((p) => Number(p) || Number(p) !== 0 ? p : Number(p)) : path;
59
- if (workflowDoc.hasIn(findPath)) {
60
- workflowDoc.setIn(findPath, value);
61
- } else {
62
- workflowDoc.addIn(findPath, value);
63
- }
64
- };
65
- const findExistingJobSteps = (path, resultType) => {
66
- const existingJobStep2 = (0, import_jsonpath_plus.JSONPath)({
67
- path,
68
- json: workflowJS,
69
- resultType
70
- });
71
- return existingJobStep2;
41
+ const blockId = cli.git.name;
42
+ const workflowDoc = (0, import_yaml2.parseYamlDocument)(workflowFile);
43
+ const workflowJS = workflowDoc.toJS();
44
+ if (cli.git.type === "github") {
45
+ const newWorkflow = await mapGitHubActionCIWorkflowContent(
46
+ cli,
47
+ blockId,
48
+ workflowDoc,
49
+ workflowJS
50
+ );
51
+ return {
52
+ existingWorkflow: workflowFile,
53
+ newWorkflow,
54
+ diff: (0, import_diff.diffFileContent)(workflowFile, newWorkflow)
72
55
  };
73
- const existingJobStep = findExistingJobSteps(
74
- git.type === "github" ? '$.jobs..steps.*[?(@property === "uses" && @.match(/^contensis\\/block-push/i))]^' : "",
75
- "all"
56
+ } else if (cli.git.type === "gitlab") {
57
+ const newWorkflow = await mapGitLabCIWorkflowContent(
58
+ cli,
59
+ blockId,
60
+ workflowDoc,
61
+ workflowJS
76
62
  );
77
- const addAppImageUri = async () => {
78
- const appImageUri = await determineAppImageUri(
79
- cli,
80
- Object.entries(workflowJS.env || {})
81
- );
82
- if (appImageUri.addVar)
83
- setWorkflowElement(`env.${appImageUri.var}`, appImageUri.uri);
84
- if (appImageUri.var)
85
- addGitHubActionJobStep.with["image-uri"] = `\${{ env.${appImageUri.var} }}`;
63
+ return {
64
+ existingWorkflow: workflowFile,
65
+ newWorkflow,
66
+ diff: (0, import_diff.diffFileContent)(workflowFile, newWorkflow)
86
67
  };
87
- if (existingJobStep.length) {
88
- const step = existingJobStep[0];
89
- const stepPath = step.path.replace("$[", "").replaceAll("][", ".").replace("]", "").replaceAll("'", "");
90
- cli.log.info(
91
- `Found existing Job step: ${stepPath}
92
- - name: ${step.value.name}
93
- id: ${step.value.id}
94
- `
95
- );
96
- setWorkflowElement(`${stepPath}.with.alias`, cli.currentEnv);
97
- setWorkflowElement(`${stepPath}.with.project-id`, cli.currentProject);
98
- setWorkflowElement(`${stepPath}.with.block-id`, blockId);
68
+ }
69
+ };
70
+ const findExistingJobSteps = (path, json, resultType) => {
71
+ const existingJobStep = (0, import_jsonpath_plus.JSONPath)({
72
+ path,
73
+ json,
74
+ resultType
75
+ });
76
+ return existingJobStep;
77
+ };
78
+ const setWorkflowElement = (workflowDoc, path, value) => {
79
+ const findPath = typeof path === "string" && path.includes(".") ? path.split(".").map((p) => Number(p) || Number(p) !== 0 ? p : Number(p)) : path;
80
+ if (workflowDoc.hasIn(findPath)) {
81
+ workflowDoc.setIn(findPath, value);
82
+ } else {
83
+ workflowDoc.addIn(findPath, value);
84
+ }
85
+ };
86
+ const mapGitLabCIWorkflowContent = async (cli, blockId, workflowDoc, workflowJS) => {
87
+ const addGitLabJobStage = {
88
+ stage: "push-block",
89
+ variables: {
90
+ block_id: blockId,
91
+ alias: cli.currentEnv,
92
+ project_id: cli.currentProject,
93
+ client_id: cli.clientDetailsLocation === "env" ? cli.clientId : "$CONTENSIS_CLIENT_ID",
94
+ shared_secret: cli.clientDetailsLocation === "env" ? cli.clientSecret : "$CONTENSIS_SHARED_SECRET"
95
+ }
96
+ };
97
+ const addAppImageUri = async () => {
98
+ const appImageUri = await determineAppImageUri(
99
+ cli,
100
+ Object.entries(workflowJS.variables || {}),
101
+ "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME/app:build-$CI_PIPELINE_IID"
102
+ );
103
+ if (appImageUri.addVar)
99
104
  setWorkflowElement(
100
- `${stepPath}.with.client-id`,
101
- "${{ secrets.CONTENSIS_CLIENT_ID }}"
105
+ workflowDoc,
106
+ `variables.${appImageUri.var}`,
107
+ appImageUri.uri
102
108
  );
109
+ if (appImageUri.var)
110
+ addGitLabJobStage.variables["image_uri"] = `$${appImageUri.var}`;
111
+ };
112
+ const existingJobStep = findExistingJobSteps(
113
+ '$..[?(@property === "stage" && @.match(/^push-block/i))]^',
114
+ workflowJS,
115
+ "all"
116
+ );
117
+ if (existingJobStep.length) {
118
+ const step = existingJobStep[0];
119
+ const stepPath = step.path.replace("$[", "").replaceAll("][", ".").replace("]", "").replaceAll("'", "");
120
+ cli.log.info(
121
+ `Found existing Job step:
122
+ ${stepPath}
123
+ stage: ${step.value.stage}
124
+ `
125
+ );
126
+ setWorkflowElement(
127
+ workflowDoc,
128
+ `${stepPath}.variables.alias`,
129
+ cli.currentEnv
130
+ );
131
+ setWorkflowElement(
132
+ workflowDoc,
133
+ `${stepPath}.variables.project_id`,
134
+ cli.currentProject
135
+ );
136
+ setWorkflowElement(workflowDoc, `${stepPath}.variables.block_id`, blockId);
137
+ setWorkflowElement(
138
+ workflowDoc,
139
+ `${stepPath}.variables.client_id`,
140
+ cli.clientDetailsLocation === "env" ? cli.clientId : "$CONTENSIS_CLIENT_ID"
141
+ );
142
+ setWorkflowElement(
143
+ workflowDoc,
144
+ `${stepPath}.variables.shared_secret`,
145
+ cli.clientDetailsLocation === "env" ? cli.clientSecret : "$CONTENSIS_SHARED_SECRET"
146
+ );
147
+ } else {
148
+ await addAppImageUri();
149
+ workflowDoc.addIn(["stages"], "push-block");
150
+ workflowDoc.addIn([], {
151
+ key: "push-to-contensis",
152
+ value: addGitLabJobStage
153
+ });
154
+ setWorkflowElement(
155
+ workflowDoc,
156
+ `include`,
157
+ "https://gitlab.zengenti.com/ops/contensis-ci/-/raw/main/push-block.yml"
158
+ );
159
+ }
160
+ cli.log.debug(`New file content to write
161
+
162
+ ${workflowDoc}`);
163
+ const newWorkflow = (0, import_os.normaliseLineEndings)(
164
+ workflowDoc.toString({ lineWidth: 0 })
165
+ );
166
+ return newWorkflow;
167
+ };
168
+ const mapGitHubActionCIWorkflowContent = async (cli, blockId, workflowDoc, workflowJS) => {
169
+ const addGitHubActionJobStep = {
170
+ name: "Push block to Contensis",
171
+ id: "push-block",
172
+ uses: "contensis/block-push@v1",
173
+ with: {
174
+ "block-id": blockId,
175
+ alias: cli.currentEnv,
176
+ "project-id": cli.currentProject,
177
+ "client-id": cli.clientDetailsLocation === "env" ? "${{ env.CONTENSIS_CLIENT_ID }}" : "${{ secrets.CONTENSIS_CLIENT_ID }}",
178
+ "shared-secret": cli.clientDetailsLocation === "env" ? "${{ env.CONTENSIS_SHARED_SECRET }}" : "${{ secrets.CONTENSIS_SHARED_SECRET }}"
179
+ }
180
+ };
181
+ const addAppImageUri = async () => {
182
+ const appImageUri = await determineAppImageUri(
183
+ cli,
184
+ Object.entries(workflowJS.env || {}),
185
+ "ghcr.io/${{ github.repository }}/${{ github.ref_name }}/app:build-${{ github.run_number }}"
186
+ );
187
+ if (appImageUri.addVar)
103
188
  setWorkflowElement(
104
- `${stepPath}.with.shared-secret`,
105
- "${{ secrets.CONTENSIS_SHARED_SECRET }}"
106
- );
107
- } else {
108
- const existingBuildJobStep = findExistingJobSteps(
109
- git.type === "github" ? "$.jobs[?(@property.match(/build/i))]" : "",
110
- "all"
189
+ workflowDoc,
190
+ `env.${appImageUri.var}`,
191
+ appImageUri.uri
111
192
  );
112
- let needs;
113
- if (existingBuildJobStep.length > 1) {
114
- const choices = existingBuildJobStep.map((s) => s.parentProperty);
115
- choices.push(new import_inquirer.default.Separator());
116
- choices.push("none");
193
+ if (appImageUri.var)
194
+ addGitHubActionJobStep.with["image-uri"] = `\${{ env.${appImageUri.var} }}`;
195
+ };
196
+ const existingJobStep = findExistingJobSteps(
197
+ '$.jobs..steps.*[?(@property === "uses" && @.match(/^contensis\\/block-push/i))]^',
198
+ workflowJS,
199
+ "all"
200
+ );
201
+ if (existingJobStep.length) {
202
+ const step = existingJobStep[0];
203
+ const stepPath = step.path.replace("$[", "").replaceAll("][", ".").replace("]", "").replaceAll("'", "");
204
+ cli.log.info(
205
+ `Found existing Job step: ${stepPath}
206
+ - name: ${step.value.name}
207
+ id: ${step.value.id}
208
+ `
209
+ );
210
+ setWorkflowElement(workflowDoc, `${stepPath}.with.alias`, cli.currentEnv);
211
+ setWorkflowElement(
212
+ workflowDoc,
213
+ `${stepPath}.with.project-id`,
214
+ cli.currentProject
215
+ );
216
+ setWorkflowElement(workflowDoc, `${stepPath}.with.block-id`, blockId);
217
+ setWorkflowElement(
218
+ workflowDoc,
219
+ `${stepPath}.with.client-id`,
220
+ cli.clientDetailsLocation === "env" ? "${{ env.CONTENSIS_CLIENT_ID }}" : "${{ secrets.CONTENSIS_CLIENT_ID }}"
221
+ );
222
+ setWorkflowElement(
223
+ workflowDoc,
224
+ `${stepPath}.with.shared-secret`,
225
+ cli.clientDetailsLocation === "env" ? "${{ env.CONTENSIS_SHARED_SECRET }}" : "${{ secrets.CONTENSIS_SHARED_SECRET }}"
226
+ );
227
+ } else {
228
+ const existingBuildJobStep = findExistingJobSteps(
229
+ "$.jobs[?(@property.match(/build/i))]",
230
+ workflowJS,
231
+ "all"
232
+ );
233
+ let needs;
234
+ if (existingBuildJobStep.length > 1) {
235
+ const choices = existingBuildJobStep.map((s) => s.parentProperty);
236
+ choices.push(new import_inquirer.default.Separator());
237
+ choices.push("none");
238
+ if (choices.includes("build-app"))
239
+ needs = "build-app";
240
+ else {
117
241
  ({ needs } = await import_inquirer.default.prompt([
118
242
  {
119
243
  type: "list",
@@ -126,76 +250,68 @@ const mapCIWorkflowContent = async (cli, git) => {
126
250
  )
127
251
  }
128
252
  ]));
129
- cli.log.raw("");
130
- } else if (existingBuildJobStep.length === 1)
131
- needs = existingBuildJobStep[0].parentProperty;
132
- if (existingBuildJobStep.length === 0 || needs === "none") {
133
- const choices = Object.keys(workflowJS.jobs);
134
- choices.push(new import_inquirer.default.Separator());
135
- choices.push("none");
136
- ({ needs } = await import_inquirer.default.prompt([
137
- {
138
- type: "list",
139
- prefix: "\u231B",
140
- message: cli.messages.devinit.ciMultipleJobChoices(),
141
- name: "needs",
142
- choices,
143
- default: choices.find(
144
- (j) => typeof j === "string" && j.includes("docker")
145
- )
146
- }
147
- ]));
148
- if (needs === "none")
149
- needs = void 0;
150
- cli.log.raw("");
151
253
  }
152
- await addAppImageUri();
153
- const newJob = {
154
- name: "Deploy container image to Contensis",
155
- "runs-on": "ubuntu-latest",
156
- needs,
157
- steps: [addGitHubActionJobStep]
158
- };
159
- workflowDoc.addIn(["jobs"], {
160
- key: "deploy",
161
- value: newJob
162
- });
254
+ cli.log.raw("");
255
+ } else if (existingBuildJobStep.length === 1)
256
+ needs = existingBuildJobStep[0].parentProperty;
257
+ if (existingBuildJobStep.length === 0 || needs === "none") {
258
+ const choices = Object.keys(workflowJS.jobs);
259
+ choices.push(new import_inquirer.default.Separator());
260
+ choices.push("none");
261
+ ({ needs } = await import_inquirer.default.prompt([
262
+ {
263
+ type: "list",
264
+ prefix: "\u231B",
265
+ message: cli.messages.devinit.ciMultipleJobChoices(),
266
+ name: "needs",
267
+ choices,
268
+ default: choices.find(
269
+ (j) => typeof j === "string" && j.includes("docker")
270
+ )
271
+ }
272
+ ]));
273
+ if (needs === "none")
274
+ needs = void 0;
275
+ cli.log.raw("");
163
276
  }
164
- const workflowIsValid = (0, import_yaml.validateWorkflowYaml)(workflowDoc.toString());
165
- if (workflowIsValid === true) {
166
- cli.log.success(`GitHub workflow YAML is valid`);
167
- cli.log.debug(
168
- `New file content to write to ${git.ciFilePath}
277
+ await addAppImageUri();
278
+ const newJob = {
279
+ name: "Deploy container image to Contensis",
280
+ "runs-on": "ubuntu-latest",
281
+ needs,
282
+ steps: [addGitHubActionJobStep]
283
+ };
284
+ workflowDoc.addIn(["jobs"], {
285
+ key: "deploy",
286
+ value: newJob
287
+ });
288
+ }
289
+ const workflowIsValid = (0, import_yaml2.validateWorkflowYaml)(workflowDoc.toString());
290
+ if (workflowIsValid === true) {
291
+ cli.log.success(`GitHub workflow YAML is valid`);
292
+ cli.log.debug(`New file content to write
169
293
 
170
- ${workflowDoc}`
171
- );
172
- } else if (Array.isArray(workflowIsValid)) {
173
- (0, import_logger.logError)(
174
- [
175
- ...workflowIsValid.map(
176
- (res) => new Error(`${res.code}: ${res.detail || res.title}`)
177
- ),
178
- workflowDoc.toString()
179
- ],
180
- `GitHub workflow YAML did not pass validation check`
181
- );
182
- }
183
- const newWorkflow = (0, import_os.normaliseLineEndings)(
184
- workflowDoc.toString({ lineWidth: 0 })
294
+ ${workflowDoc}`);
295
+ } else if (Array.isArray(workflowIsValid)) {
296
+ (0, import_logger.logError)(
297
+ [
298
+ ...workflowIsValid.map(
299
+ (res) => new Error(`${res.code}: ${res.detail || res.title}`)
300
+ ),
301
+ workflowDoc.toString()
302
+ ],
303
+ `GitHub workflow YAML did not pass validation check`
185
304
  );
186
- return {
187
- existingWorkflow: workflowFile,
188
- newWorkflow,
189
- diff: (0, import_diff.diffFileContent)(workflowFile, newWorkflow)
190
- };
191
305
  }
306
+ const newWorkflow = workflowDoc.toString();
307
+ return newWorkflow;
192
308
  };
193
- const determineAppImageUri = async (cli, vars) => {
309
+ const determineAppImageUri = async (cli, vars, defaultUri) => {
194
310
  const imageVars = vars.filter(
195
- ([varname, value]) => varname.toLowerCase().includes("image")
311
+ ([varname]) => varname.toLowerCase().includes("image")
196
312
  );
197
313
  const appImageVars = imageVars.filter(
198
- ([varname, value]) => varname.toLowerCase().includes("app_") || varname.toLowerCase().includes("build_") || (value == null ? void 0 : value.toLowerCase().includes("/app"))
314
+ ([varname, value]) => !varname.toLowerCase().includes("builder_") && (varname.toLowerCase().includes("app_") || varname.toLowerCase().includes("build_") || (value == null ? void 0 : value.toLowerCase().includes("/app")))
199
315
  );
200
316
  const appImageUriGuess = appImageVars == null ? void 0 : appImageVars[0];
201
317
  let appImageUri;
@@ -212,7 +328,6 @@ const determineAppImageUri = async (cli, vars) => {
212
328
  } else {
213
329
  const choices = vars.map((v) => v[0]);
214
330
  const enterOwnMsg = "enter my own / use default";
215
- const defaultUri = "ghcr.io/${{ github.repository }}/${{ github.ref_name }}/app:build-${{ github.run_number }}";
216
331
  choices.push(new import_inquirer.default.Separator());
217
332
  choices.push(enterOwnMsg);
218
333
  choices.push(defaultUri);
@@ -235,7 +350,7 @@ const determineAppImageUri = async (cli, vars) => {
235
350
  prefix: `
236
351
 
237
352
  \u{1F517}`,
238
- message: cli.messages.devinit.ciEnterOwnAppImagePrompt(),
353
+ message: cli.messages.devinit.ciEnterOwnAppImagePrompt(cli.git),
239
354
  name: "appImageUri",
240
355
  default: defaultUri
241
356
  }
@@ -245,7 +360,7 @@ const determineAppImageUri = async (cli, vars) => {
245
360
  appImageVar = void 0;
246
361
  }
247
362
  if (appImageVar)
248
- appImageUri = `\${{ env.${appImageVar} }}`;
363
+ appImageUri = cli.git.type === "github" ? `\${{ env.${appImageVar} }}` : `$${appImageVar}`;
249
364
  return {
250
365
  addVar: !appImageVar,
251
366
  uri: appImageUri,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/mappers/DevInit-to-CIWorkflow.ts"],
4
- "sourcesContent": ["import inquirer from 'inquirer';\nimport { JSONPath, JSONPathOptions } from 'jsonpath-plus';\nimport {\n GitHubActionPushBlockJob,\n GitHubActionPushBlockJobStep,\n} from '~/models/DevService';\nimport { readFile } from '~/providers/file-provider';\nimport ContensisDev from '~/services/ContensisDevService';\nimport { diffFileContent } from '~/util/diff';\nimport { GitHelper } from '~/util/git';\nimport { logError } from '~/util/logger';\nimport { normaliseLineEndings } from '~/util/os';\nimport { parseYamlDocument, validateWorkflowYaml } from '~/util/yaml';\n\ntype MappedWorkflowOutput = {\n existingWorkflow: string;\n newWorkflow: string;\n diff: string;\n};\n\nexport const mapCIWorkflowContent = async (\n cli: ContensisDev,\n git: GitHelper\n): Promise<MappedWorkflowOutput | undefined> => {\n // get existing workflow file\n const workflowFile = readFile(git.ciFilePath);\n if (!workflowFile) return undefined;\n\n const blockId = git.name;\n if (git.type === 'github') {\n const addGitHubActionJobStep: GitHubActionPushBlockJobStep = {\n name: 'Push block to Contensis',\n id: 'push-block',\n uses: 'contensis/block-push@v1',\n with: {\n 'block-id': blockId,\n // 'image-uri': '${{ steps.build.outputs.image-uri }}',\n alias: cli.currentEnv,\n 'project-id': cli.currentProject,\n 'client-id': '${{ secrets.CONTENSIS_CLIENT_ID }}',\n 'shared-secret': '${{ secrets.CONTENSIS_SHARED_SECRET }}',\n },\n };\n\n // parse yaml to js\n const workflowDoc = parseYamlDocument(workflowFile);\n const workflowJS = workflowDoc.toJS();\n const setWorkflowElement = (path: string | any[], value: any) => {\n const findPath =\n typeof path === 'string' && path.includes('.')\n ? path\n .split('.')\n .map(p => (Number(p) || Number(p) !== 0 ? p : Number(p)))\n : path;\n\n if (workflowDoc.hasIn(findPath)) {\n workflowDoc.setIn(findPath, value);\n } else {\n workflowDoc.addIn(findPath, value);\n // }\n }\n };\n const findExistingJobSteps = (\n path: string,\n resultType: JSONPathOptions['resultType']\n ) => {\n const existingJobStep = JSONPath({\n path,\n json: workflowJS,\n resultType: resultType,\n });\n\n return existingJobStep;\n };\n\n // look for line in job\n // jobs.x.steps[uses: contensis/block-push]\n const existingJobStep = findExistingJobSteps(\n git.type === 'github'\n ? '$.jobs..steps.*[?(@property === \"uses\" && @.match(/^contensis\\\\/block-push/i))]^'\n : // TODO: add jsonpath for gitlab file\n '',\n 'all'\n );\n\n const addAppImageUri = async () => {\n // Look in document level \"env\" vars\n const appImageUri = await determineAppImageUri(\n cli,\n Object.entries(workflowJS.env || {})\n );\n\n if (appImageUri.addVar)\n setWorkflowElement(`env.${appImageUri.var}`, appImageUri.uri);\n // workflowDoc.addIn(['env'], { [appImageUri.var]: appImageUri.uri });\n\n if (appImageUri.var)\n addGitHubActionJobStep.with[\n 'image-uri'\n ] = `\\${{ env.${appImageUri.var} }}`;\n };\n\n // update job step\n if (existingJobStep.length) {\n //cli.log.json(existingJobStep);\n\n // The [0] index means we're only looking at updating the first instance in the file\n const step = existingJobStep[0];\n\n // Path looks like this \"$['jobs']['build']['steps'][3]\"\n // We want it to look like this \"jobs.build.steps.3\"\n const stepPath = step.path\n .replace('$[', '')\n .replaceAll('][', '.')\n .replace(']', '')\n .replaceAll(\"'\", '');\n\n cli.log.info(\n `Found existing Job step: ${stepPath}\n - name: ${step.value.name}\n id: ${step.value.id}\\n`\n );\n\n setWorkflowElement(`${stepPath}.with.alias`, cli.currentEnv);\n setWorkflowElement(`${stepPath}.with.project-id`, cli.currentProject);\n setWorkflowElement(`${stepPath}.with.block-id`, blockId);\n\n // This is likely not needed when updating an existing push-block job step\n // we are assuming this is a forked/copied workflow with an already working image-uri reference\n // await addAppImageUri();\n\n setWorkflowElement(\n `${stepPath}.with.client-id`,\n '${{ secrets.CONTENSIS_CLIENT_ID }}'\n );\n setWorkflowElement(\n `${stepPath}.with.shared-secret`,\n '${{ secrets.CONTENSIS_SHARED_SECRET }}'\n );\n } else {\n // create job with push step\n\n // is there already a job with a property name containing \"build\"?\n const existingBuildJobStep = findExistingJobSteps(\n git.type === 'github'\n ? '$.jobs[?(@property.match(/build/i))]'\n : // TODO: add jsonpath for gitlab file\n '',\n 'all'\n ) as JSONPathOptions[]; // This isn't the correct type for this object\n\n let needs: string | undefined;\n // There are multiple jobs called *build*\n if (existingBuildJobStep.length > 1) {\n // prompt which build job we should depend on before pushing the block\n const choices = existingBuildJobStep.map(s => s.parentProperty);\n choices.push(new inquirer.Separator() as any);\n choices.push('none');\n\n ({ needs } = await inquirer.prompt([\n {\n type: 'list',\n prefix: '\u231B',\n message: cli.messages.devinit.ciMultipleBuildJobChoices(),\n name: 'needs',\n choices,\n default: choices.find(\n s => typeof s === 'string' && s.includes('docker')\n ),\n },\n ]));\n cli.log.raw('');\n } else if (existingBuildJobStep.length === 1)\n // Exactly one job step found containing a property name of *build*\n // we'll assume that is the one the push-block job depends on\n needs = existingBuildJobStep[0].parentProperty;\n\n if (existingBuildJobStep.length === 0 || needs === 'none') {\n // No existing build step found or chosen, offer all job steps in prompt\n const choices = Object.keys(workflowJS.jobs);\n choices.push(new inquirer.Separator() as any);\n choices.push('none');\n\n ({ needs } = await inquirer.prompt([\n {\n type: 'list',\n prefix: '\u231B',\n message: cli.messages.devinit.ciMultipleJobChoices(),\n name: 'needs',\n choices,\n default: choices.find(\n j => typeof j === 'string' && j.includes('docker')\n ),\n },\n ]));\n if (needs === 'none') needs = undefined;\n cli.log.raw('');\n }\n\n // Does a series of checks and prompts to determine the correct image-uri\n // for the app container build\n await addAppImageUri();\n\n const newJob: GitHubActionPushBlockJob = {\n name: 'Deploy container image to Contensis',\n 'runs-on': 'ubuntu-latest',\n needs,\n steps: [addGitHubActionJobStep],\n };\n\n // Add the new \"job\" to the Yaml Document\n workflowDoc.addIn(['jobs'], {\n key: 'deploy',\n value: newJob,\n });\n }\n\n // Workflow validation provided by @action-validator/core package\n const workflowIsValid = validateWorkflowYaml(workflowDoc.toString());\n\n // We could expand validation to check for having a build step to wait for\n // or if a valid image-uri attribute is set\n if (workflowIsValid === true) {\n cli.log.success(`GitHub workflow YAML is valid`);\n cli.log.debug(\n `New file content to write to ${git.ciFilePath}\\n\\n${workflowDoc}`\n );\n } else if (Array.isArray(workflowIsValid)) {\n // Errors\n logError(\n [\n ...workflowIsValid.map(\n res => new Error(`${res.code}: ${res.detail || res.title}`)\n ),\n workflowDoc.toString(),\n ],\n `GitHub workflow YAML did not pass validation check`\n );\n }\n const newWorkflow = normaliseLineEndings(\n workflowDoc.toString({ lineWidth: 0 })\n );\n\n return {\n existingWorkflow: workflowFile,\n newWorkflow,\n diff: diffFileContent(workflowFile, newWorkflow),\n };\n }\n};\n\nconst determineAppImageUri = async (\n cli: ContensisDev,\n vars: [string, string][]\n) => {\n // Determine container image-uri via variables and/or prompts\n\n // Find vars including the word \"image\"\n const imageVars = vars.filter(([varname, value]) =>\n varname.toLowerCase().includes('image')\n );\n // Find vars named \"image\" that include the word \"app\"\n const appImageVars = imageVars.filter(\n ([varname, value]) =>\n varname.toLowerCase().includes('app_') ||\n varname.toLowerCase().includes('build_') ||\n value?.toLowerCase().includes('/app')\n );\n\n const appImageUriGuess = appImageVars?.[0];\n\n let appImageUri: string | undefined;\n let appImageVar: string | undefined;\n\n if (appImageUriGuess) {\n cli.log.success(\n `Found variable ${cli.log.standardText(\n appImageUriGuess[0]\n )} we'll use for pulling the block image from: ${cli.log.infoText(\n appImageUriGuess[1]\n )}`\n );\n appImageVar = appImageUriGuess[0];\n } else {\n // Could not find a suitable var to use for block image-uri\n // prompt for an app image uri\n const choices = vars.map(v => v[0]);\n const enterOwnMsg = 'enter my own / use default';\n const defaultUri =\n 'ghcr.io/${{ github.repository }}/${{ github.ref_name }}/app:build-${{ github.run_number }}';\n choices.push(new inquirer.Separator() as any);\n choices.push(enterOwnMsg);\n choices.push(defaultUri);\n\n ({ appImageVar, appImageUri } = await inquirer.prompt([\n // First question determines if an existing env variable\n // already containes the tagged app image uri\n {\n type: 'list',\n prefix: '\uD83D\uDC33',\n message: cli.messages.devinit.ciMultipleAppImageVarChoices(),\n name: 'appImageVar',\n choices,\n default: choices.find(\n v => typeof v === 'string' && v.toLowerCase().includes('image')\n ),\n },\n // Subsequent prompt allows input of an image-uri if needed\n {\n type: 'input',\n when(answers) {\n return [enterOwnMsg, defaultUri].includes(answers.appImageVar);\n },\n prefix: `\\n \\n\uD83D\uDD17`,\n message: cli.messages.devinit.ciEnterOwnAppImagePrompt(),\n name: 'appImageUri',\n default: defaultUri,\n },\n ]));\n cli.log.raw('');\n\n // this indicates a uri has been added and we will add a new var\n // to the workflow to encourage users to update the docker tag part\n // of their build workflow to use the same var as the push-block job/step\n if ([enterOwnMsg, defaultUri].includes(appImageVar || ''))\n appImageVar = undefined;\n }\n\n if (appImageVar) appImageUri = `\\${{ env.${appImageVar} }}`;\n\n return {\n addVar: !appImageVar,\n uri: appImageUri,\n var: appImageVar || 'BUILD_IMAGE',\n };\n};\n"],
5
- "mappings": "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",
6
- "names": ["existingJobStep", "inquirer"]
4
+ "sourcesContent": ["import inquirer from 'inquirer';\nimport { JSONPath, JSONPathOptions } from 'jsonpath-plus';\nimport { Document } from 'yaml';\nimport {\n GitHubActionPushBlockJob,\n GitHubActionPushBlockJobStep,\n GitLabPushBlockJobStage,\n} from '~/models/DevService';\nimport { readFile } from '~/providers/file-provider';\nimport ContensisDev from '~/services/ContensisDevService';\nimport { diffFileContent } from '~/util/diff';\nimport { logError } from '~/util/logger';\nimport { normaliseLineEndings } from '~/util/os';\nimport { parseYamlDocument, validateWorkflowYaml } from '~/util/yaml';\n\ntype MappedWorkflowOutput = {\n existingWorkflow: string;\n newWorkflow: string;\n diff: string;\n};\n\nexport const mapCIWorkflowContent = async (\n cli: ContensisDev\n): Promise<MappedWorkflowOutput | undefined> => {\n // get existing workflow file\n const workflowFile = readFile(cli.git.ciFilePath);\n if (!workflowFile) return undefined;\n\n const blockId = cli.git.name;\n\n // parse yaml to js\n const workflowDoc = parseYamlDocument(workflowFile);\n const workflowJS = workflowDoc.toJS();\n\n if (cli.git.type === 'github') {\n const newWorkflow = await mapGitHubActionCIWorkflowContent(\n cli,\n blockId,\n workflowDoc,\n workflowJS\n );\n return {\n existingWorkflow: workflowFile,\n newWorkflow,\n diff: diffFileContent(workflowFile, newWorkflow),\n };\n } else if (cli.git.type === 'gitlab') {\n const newWorkflow = await mapGitLabCIWorkflowContent(\n cli,\n blockId,\n workflowDoc,\n workflowJS\n );\n return {\n existingWorkflow: workflowFile,\n newWorkflow,\n diff: diffFileContent(workflowFile, newWorkflow),\n };\n }\n};\n\nconst findExistingJobSteps = (\n path: string,\n json: any,\n resultType: JSONPathOptions['resultType']\n) => {\n const existingJobStep = JSONPath({\n path,\n json,\n resultType: resultType,\n });\n\n return existingJobStep;\n};\n\nconst setWorkflowElement = (\n workflowDoc: Document,\n path: string | any[],\n value: any\n) => {\n const findPath =\n typeof path === 'string' && path.includes('.')\n ? path.split('.').map(p => (Number(p) || Number(p) !== 0 ? p : Number(p)))\n : path;\n\n if (workflowDoc.hasIn(findPath)) {\n workflowDoc.setIn(findPath, value);\n } else {\n workflowDoc.addIn(findPath, value);\n }\n};\n\nconst mapGitLabCIWorkflowContent = async (\n cli: ContensisDev,\n blockId: string,\n workflowDoc: Document,\n workflowJS: any\n) => {\n const addGitLabJobStage: GitLabPushBlockJobStage = {\n stage: 'push-block',\n variables: {\n block_id: blockId,\n alias: cli.currentEnv,\n project_id: cli.currentProject,\n client_id:\n cli.clientDetailsLocation === 'env'\n ? cli.clientId\n : '$CONTENSIS_CLIENT_ID',\n shared_secret:\n cli.clientDetailsLocation === 'env'\n ? cli.clientSecret\n : '$CONTENSIS_SHARED_SECRET',\n },\n };\n\n const addAppImageUri = async () => {\n // Look in document level \"variables\"\n const appImageUri = await determineAppImageUri(\n cli,\n Object.entries(workflowJS.variables || {}),\n '$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME/app:build-$CI_PIPELINE_IID'\n );\n\n if (appImageUri.addVar)\n setWorkflowElement(\n workflowDoc,\n `variables.${appImageUri.var}`,\n appImageUri.uri\n );\n\n if (appImageUri.var)\n addGitLabJobStage.variables['image_uri'] = `\\$${appImageUri.var}`;\n };\n\n // look for line in job\n // jobname[stage: push-block]\n const existingJobStep = findExistingJobSteps(\n '$..[?(@property === \"stage\" && @.match(/^push-block/i))]^',\n workflowJS,\n 'all'\n );\n\n // update job step\n if (existingJobStep.length) {\n // cli.log.json(existingJobStep);\n\n // The [0] index means we're only looking at updating the first instance in the file\n const step = existingJobStep[0];\n\n // Path looks like this \"$['job_name']\"\n // We want it to look like this \"job_name\"\n const stepPath = step.path\n .replace('$[', '')\n .replaceAll('][', '.')\n .replace(']', '')\n .replaceAll(\"'\", '');\n\n cli.log.info(\n `Found existing Job step:\n ${stepPath}\n stage: ${step.value.stage}\\n`\n );\n\n setWorkflowElement(\n workflowDoc,\n `${stepPath}.variables.alias`,\n cli.currentEnv\n );\n setWorkflowElement(\n workflowDoc,\n `${stepPath}.variables.project_id`,\n cli.currentProject\n );\n setWorkflowElement(workflowDoc, `${stepPath}.variables.block_id`, blockId);\n\n // This is likely not needed when updating an existing push-block job step\n // we are assuming this is a forked/copied workflow with an already working image-uri reference\n // await addAppImageUri();\n\n setWorkflowElement(\n workflowDoc,\n `${stepPath}.variables.client_id`,\n cli.clientDetailsLocation === 'env'\n ? cli.clientId\n : '$CONTENSIS_CLIENT_ID'\n );\n setWorkflowElement(\n workflowDoc,\n `${stepPath}.variables.shared_secret`,\n cli.clientDetailsLocation === 'env'\n ? cli.clientSecret\n : '$CONTENSIS_SHARED_SECRET'\n );\n } else {\n // create job with push step\n\n // Does a series of checks and prompts to determine the correct image-uri\n // for the app container build\n await addAppImageUri();\n\n // Add the new \"job\" to the Yaml Document\n workflowDoc.addIn(['stages'], 'push-block');\n workflowDoc.addIn([], {\n key: 'push-to-contensis',\n value: addGitLabJobStage,\n });\n setWorkflowElement(\n workflowDoc,\n `include`,\n 'https://gitlab.zengenti.com/ops/contensis-ci/-/raw/main/push-block.yml'\n );\n }\n\n cli.log.debug(`New file content to write\\n\\n${workflowDoc}`);\n\n const newWorkflow = normaliseLineEndings(\n workflowDoc.toString({ lineWidth: 0 })\n );\n\n return newWorkflow;\n};\n\nconst mapGitHubActionCIWorkflowContent = async (\n cli: ContensisDev,\n blockId: string,\n workflowDoc: Document,\n workflowJS: any\n) => {\n const addGitHubActionJobStep: GitHubActionPushBlockJobStep = {\n name: 'Push block to Contensis',\n id: 'push-block',\n uses: 'contensis/block-push@v1',\n with: {\n 'block-id': blockId,\n // 'image-uri': '${{ steps.build.outputs.image-uri }}',\n alias: cli.currentEnv,\n 'project-id': cli.currentProject,\n 'client-id':\n cli.clientDetailsLocation === 'env'\n ? '${{ env.CONTENSIS_CLIENT_ID }}'\n : '${{ secrets.CONTENSIS_CLIENT_ID }}',\n 'shared-secret':\n cli.clientDetailsLocation === 'env'\n ? '${{ env.CONTENSIS_SHARED_SECRET }}'\n : '${{ secrets.CONTENSIS_SHARED_SECRET }}',\n },\n };\n\n const addAppImageUri = async () => {\n // Look in document level \"env\" vars\n const appImageUri = await determineAppImageUri(\n cli,\n Object.entries(workflowJS.env || {}),\n 'ghcr.io/${{ github.repository }}/${{ github.ref_name }}/app:build-${{ github.run_number }}'\n );\n\n if (appImageUri.addVar)\n setWorkflowElement(\n workflowDoc,\n `env.${appImageUri.var}`,\n appImageUri.uri\n );\n // workflowDoc.addIn(['env'], { [appImageUri.var]: appImageUri.uri });\n\n if (appImageUri.var)\n addGitHubActionJobStep.with[\n 'image-uri'\n ] = `\\${{ env.${appImageUri.var} }}`;\n };\n\n // look for line in job\n // jobs.x.steps[uses: contensis/block-push]\n const existingJobStep = findExistingJobSteps(\n '$.jobs..steps.*[?(@property === \"uses\" && @.match(/^contensis\\\\/block-push/i))]^',\n workflowJS,\n 'all'\n );\n\n // update job step\n if (existingJobStep.length) {\n //cli.log.json(existingJobStep);\n\n // The [0] index means we're only looking at updating the first instance in the file\n const step = existingJobStep[0];\n\n // Path looks like this \"$['jobs']['build']['steps'][3]\"\n // We want it to look like this \"jobs.build.steps.3\"\n const stepPath = step.path\n .replace('$[', '')\n .replaceAll('][', '.')\n .replace(']', '')\n .replaceAll(\"'\", '');\n\n cli.log.info(\n `Found existing Job step: ${stepPath}\n - name: ${step.value.name}\n id: ${step.value.id}\\n`\n );\n\n setWorkflowElement(workflowDoc, `${stepPath}.with.alias`, cli.currentEnv);\n setWorkflowElement(\n workflowDoc,\n `${stepPath}.with.project-id`,\n cli.currentProject\n );\n setWorkflowElement(workflowDoc, `${stepPath}.with.block-id`, blockId);\n\n // This is likely not needed when updating an existing push-block job step\n // we are assuming this is a forked/copied workflow with an already working image-uri reference\n // await addAppImageUri();\n\n setWorkflowElement(\n workflowDoc,\n `${stepPath}.with.client-id`,\n cli.clientDetailsLocation === 'env'\n ? '${{ env.CONTENSIS_CLIENT_ID }}'\n : '${{ secrets.CONTENSIS_CLIENT_ID }}'\n );\n setWorkflowElement(\n workflowDoc,\n `${stepPath}.with.shared-secret`,\n cli.clientDetailsLocation === 'env'\n ? '${{ env.CONTENSIS_SHARED_SECRET }}'\n : '${{ secrets.CONTENSIS_SHARED_SECRET }}'\n );\n } else {\n // create job with push step\n\n // is there already a job with a property name containing \"build\"?\n const existingBuildJobStep = findExistingJobSteps(\n '$.jobs[?(@property.match(/build/i))]',\n workflowJS,\n 'all'\n ) as JSONPathOptions[]; // This isn't the correct type for this object\n\n let needs: string | undefined;\n // There are multiple jobs called *build*\n if (existingBuildJobStep.length > 1) {\n // prompt which build job we should depend on before pushing the block\n const choices = existingBuildJobStep.map(s => s.parentProperty);\n choices.push(new inquirer.Separator() as any);\n choices.push('none');\n if (choices.includes('build-app')) needs = 'build-app';\n else {\n ({ needs } = await inquirer.prompt([\n {\n type: 'list',\n prefix: '\u231B',\n message: cli.messages.devinit.ciMultipleBuildJobChoices(),\n name: 'needs',\n choices,\n default: choices.find(\n s => typeof s === 'string' && s.includes('docker')\n ),\n },\n ]));\n }\n\n cli.log.raw('');\n } else if (existingBuildJobStep.length === 1)\n // Exactly one job step found containing a property name of *build*\n // we'll assume that is the one the push-block job depends on\n needs = existingBuildJobStep[0].parentProperty;\n\n if (existingBuildJobStep.length === 0 || needs === 'none') {\n // No existing build step found or chosen, offer all job steps in prompt\n const choices = Object.keys(workflowJS.jobs);\n choices.push(new inquirer.Separator() as any);\n choices.push('none');\n\n ({ needs } = await inquirer.prompt([\n {\n type: 'list',\n prefix: '\u231B',\n message: cli.messages.devinit.ciMultipleJobChoices(),\n name: 'needs',\n choices,\n default: choices.find(\n j => typeof j === 'string' && j.includes('docker')\n ),\n },\n ]));\n if (needs === 'none') needs = undefined;\n cli.log.raw('');\n }\n\n // Does a series of checks and prompts to determine the correct image-uri\n // for the app container build\n await addAppImageUri();\n\n const newJob: GitHubActionPushBlockJob = {\n name: 'Deploy container image to Contensis',\n 'runs-on': 'ubuntu-latest',\n needs,\n steps: [addGitHubActionJobStep],\n };\n\n // Add the new \"job\" to the Yaml Document\n workflowDoc.addIn(['jobs'], {\n key: 'deploy',\n value: newJob,\n });\n }\n\n // Workflow validation provided by @action-validator/core package\n const workflowIsValid = validateWorkflowYaml(workflowDoc.toString());\n\n // We could expand validation to check for having a build step to wait for\n // or if a valid image-uri attribute is set\n if (workflowIsValid === true) {\n cli.log.success(`GitHub workflow YAML is valid`);\n cli.log.debug(`New file content to write\\n\\n${workflowDoc}`);\n } else if (Array.isArray(workflowIsValid)) {\n // Errors\n logError(\n [\n ...workflowIsValid.map(\n res => new Error(`${res.code}: ${res.detail || res.title}`)\n ),\n workflowDoc.toString(),\n ],\n `GitHub workflow YAML did not pass validation check`\n );\n }\n\n // const newWorkflow = normaliseLineEndings(\n // workflowDoc.toString({ lineWidth: 0 })\n // );\n\n const newWorkflow = workflowDoc.toString();\n\n return newWorkflow;\n};\n\nconst determineAppImageUri = async (\n cli: ContensisDev,\n vars: [string, string][],\n defaultUri: string\n) => {\n // Determine container image-uri via variables and/or prompts\n\n // Find vars including the word \"image\"\n const imageVars = vars.filter(([varname]) =>\n varname.toLowerCase().includes('image')\n );\n // Find vars named \"image\" that include the word \"app\"\n const appImageVars = imageVars.filter(\n ([varname, value]) =>\n !varname.toLowerCase().includes('builder_') &&\n (varname.toLowerCase().includes('app_') ||\n varname.toLowerCase().includes('build_') ||\n value?.toLowerCase().includes('/app'))\n );\n\n const appImageUriGuess = appImageVars?.[0];\n\n let appImageUri: string | undefined;\n let appImageVar: string | undefined;\n\n if (appImageUriGuess) {\n cli.log.success(\n `Found variable ${cli.log.standardText(\n appImageUriGuess[0]\n )} we'll use for pulling the block image from: ${cli.log.infoText(\n appImageUriGuess[1]\n )}`\n );\n appImageVar = appImageUriGuess[0];\n } else {\n // Could not find a suitable var to use for block image-uri\n // prompt for an app image uri\n const choices = vars.map(v => v[0]);\n const enterOwnMsg = 'enter my own / use default';\n\n choices.push(new inquirer.Separator() as any);\n choices.push(enterOwnMsg);\n choices.push(defaultUri);\n\n ({ appImageVar, appImageUri } = await inquirer.prompt([\n // First question determines if an existing env variable\n // already containes the tagged app image uri\n {\n type: 'list',\n prefix: '\uD83D\uDC33',\n message: cli.messages.devinit.ciMultipleAppImageVarChoices(),\n name: 'appImageVar',\n choices,\n default: choices.find(\n v => typeof v === 'string' && v.toLowerCase().includes('image')\n ),\n },\n // Subsequent prompt allows input of an image-uri if needed\n {\n type: 'input',\n when(answers) {\n return [enterOwnMsg, defaultUri].includes(answers.appImageVar);\n },\n prefix: `\\n \\n\uD83D\uDD17`,\n message: cli.messages.devinit.ciEnterOwnAppImagePrompt(cli.git),\n name: 'appImageUri',\n default: defaultUri,\n },\n ]));\n cli.log.raw('');\n\n // this indicates a uri has been added and we will add a new var\n // to the workflow to encourage users to update the docker tag part\n // of their build workflow to use the same var as the push-block job/step\n if ([enterOwnMsg, defaultUri].includes(appImageVar || ''))\n appImageVar = undefined;\n }\n\n if (appImageVar)\n appImageUri =\n cli.git.type === 'github'\n ? `\\${{ env.${appImageVar} }}`\n : `\\$${appImageVar}`;\n\n // TODO: prompt further for image tag\n\n return {\n addVar: !appImageVar,\n uri: appImageUri,\n var: appImageVar || 'BUILD_IMAGE',\n };\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["import_yaml", "inquirer"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/models/DevService.d.ts"],
4
- "sourcesContent": ["export type EnvContentsToAdd = {\n ALIAS: string;\n PROJECT: string;\n ACCESS_TOKEN?: string;\n};\n\nexport type GitHubActionPushBlockJobStep = {\n name: string;\n id: 'push-block';\n uses: string;\n with: {\n 'block-id': string;\n alias: string;\n 'project-id': string;\n 'client-id': string;\n 'shared-secret': string;\n 'image-uri'?: string;\n };\n};\n\nexport type GitHubActionPushBlockJob = {\n name: string;\n 'runs-on': string;\n needs?: string;\n steps: GitHubActionPushBlockJobStep[];\n};\n"],
4
+ "sourcesContent": ["export type EnvContentsToAdd = {\n ALIAS: string;\n PROJECT: string;\n ACCESS_TOKEN?: string;\n CONTENSIS_CLIENT_ID?: string;\n CONTENSIS_CLIENT_SECRET?: string;\n};\n\nexport type GitHubActionPushBlockJobStep = {\n name: string;\n id: 'push-block';\n uses: string;\n with: {\n 'block-id': string;\n alias: string;\n 'project-id': string;\n 'client-id': string;\n 'shared-secret': string;\n 'image-uri'?: string;\n };\n};\n\nexport type GitHubActionPushBlockJob = {\n name: string;\n 'runs-on': string;\n needs?: string;\n steps: GitHubActionPushBlockJobStep[];\n};\n\nexport type GitLabPushBlockJobStage = {\n stage: string;\n variables: {\n alias: string;\n project_id: string;\n block_id: string;\n image_uri?: string;\n client_id: string;\n shared_secret: string;\n };\n};\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -63,6 +63,9 @@ class ContensisCli {
63
63
  contensis;
64
64
  contensisOpts;
65
65
  currentProject;
66
+ clientDetailsLocation;
67
+ clientId;
68
+ clientSecret;
66
69
  sourceAlias;
67
70
  targetEnv;
68
71
  urls;
@@ -1373,6 +1376,67 @@ ${children}` : ""}`,
1373
1376
  log.help(messages.connect.tip());
1374
1377
  }
1375
1378
  };
1379
+ ImportNodes = async ({
1380
+ commit,
1381
+ fromFile,
1382
+ logOutput
1383
+ }) => {
1384
+ var _a, _b, _c;
1385
+ const { currentEnv, currentProject, log, messages } = this;
1386
+ const contensis = await this.ConnectContensisImport({
1387
+ commit,
1388
+ fromFile,
1389
+ importDataType: "nodes"
1390
+ });
1391
+ if (contensis) {
1392
+ log.line();
1393
+ if (contensis.isPreview) {
1394
+ console.log(log.successText(` -- IMPORT PREVIEW -- `));
1395
+ } else {
1396
+ console.log(log.warningText(` *** COMMITTING IMPORT *** `));
1397
+ }
1398
+ const [err, result] = await contensis.MigrateNodes();
1399
+ if (err)
1400
+ (0, import_logger.logError)(err);
1401
+ else
1402
+ this.HandleFormattingAndOutput(result, () => {
1403
+ (0, import_console.printMigrateResult)(this, result, {
1404
+ showAllEntries: logOutput === "all",
1405
+ showChangedEntries: logOutput === "changes"
1406
+ });
1407
+ });
1408
+ const nodesTotalCount = result == null ? void 0 : result.nodesToMigrate[currentProject].totalCount;
1409
+ const nodesCreated = ((_a = result == null ? void 0 : result.nodesResult) == null ? void 0 : _a["created"]) || 0;
1410
+ const nodesUpdated = ((_b = result == null ? void 0 : result.nodesResult) == null ? void 0 : _b["updated"]) || 0;
1411
+ const noChange = result.nodesToMigrate[currentProject]["no change"] !== 0;
1412
+ if (!err && !((_c = result.errors) == null ? void 0 : _c.length) && (!commit && nodesTotalCount || commit && (nodesCreated || nodesUpdated))) {
1413
+ let totalCount;
1414
+ if (commit) {
1415
+ let created = typeof nodesCreated === "number" ? nodesCreated : 0;
1416
+ let updated = typeof nodesUpdated === "number" ? nodesUpdated : 0;
1417
+ totalCount = created + updated;
1418
+ } else {
1419
+ totalCount = typeof nodesTotalCount === "number" ? nodesTotalCount : 0;
1420
+ }
1421
+ log.success(messages.nodes.imported(currentEnv, commit, totalCount));
1422
+ if (!commit) {
1423
+ log.raw(``);
1424
+ log.help(messages.nodes.commitTip());
1425
+ }
1426
+ } else {
1427
+ if (noChange) {
1428
+ log.help(messages.nodes.noChange(currentEnv), err);
1429
+ } else {
1430
+ log.error(messages.nodes.failedImport(currentEnv), err);
1431
+ if (!nodesTotalCount)
1432
+ log.help(messages.nodes.notFound(currentEnv));
1433
+ }
1434
+ }
1435
+ } else {
1436
+ log.warning(messages.models.noList(currentProject));
1437
+ log.help(messages.connect.tip());
1438
+ }
1439
+ };
1376
1440
  PrintWebhookSubscriptions = async (subscriptionIdsOrNames) => {
1377
1441
  const { currentEnv, log, messages } = this;
1378
1442
  const contensis = await this.ConnectContensis();