@pagopa/dx-cli 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/index.js +329 -54
  2. package/package.json +4 -1
package/bin/index.js CHANGED
@@ -2,22 +2,10 @@
2
2
 
3
3
  // src/index.ts
4
4
  import "core-js/actual/set/index.js";
5
- import { configure, getConsoleSink, getLogger as getLogger4 } from "@logtape/logtape";
6
-
7
- // src/adapters/codemods/example.ts
8
- import { okAsync } from "neverthrow";
9
- var apply = () => {
10
- console.log("Hello from example codemod!");
11
- return okAsync(void 0);
12
- };
13
- var example_default = {
14
- apply,
15
- description: "An example codemod that does nothing",
16
- id: "example"
17
- };
5
+ import { configure, getConsoleSink, getLogger as getLogger9 } from "@logtape/logtape";
18
6
 
19
7
  // src/adapters/codemods/registry.ts
20
- import { okAsync as okAsync2 } from "neverthrow";
8
+ import { okAsync } from "neverthrow";
21
9
  var LocalCodemodRegistry = class {
22
10
  #m;
23
11
  constructor() {
@@ -27,22 +15,296 @@ var LocalCodemodRegistry = class {
27
15
  this.#m.set(codemod.id, codemod);
28
16
  }
29
17
  getAll() {
30
- return okAsync2(Array.from(this.#m.values()));
18
+ return okAsync(Array.from(this.#m.values()));
31
19
  }
32
20
  getById(id) {
33
- return okAsync2(this.#m.get(id));
21
+ return okAsync(this.#m.get(id));
22
+ }
23
+ };
24
+
25
+ // src/adapters/codemods/update-code-review.ts
26
+ import { getLogger as getLogger2 } from "@logtape/logtape";
27
+ import { replaceInFile } from "replace-in-file";
28
+
29
+ // src/adapters/codemods/git.ts
30
+ import { getLogger } from "@logtape/logtape";
31
+ import { Octokit } from "octokit";
32
+ var getLatestCommitSha = async (owner, repo, ref = "main") => {
33
+ const octokit = new Octokit();
34
+ const response = await octokit.rest.repos.getCommit({
35
+ owner,
36
+ ref,
37
+ repo
38
+ });
39
+ return response.data.sha;
40
+ };
41
+ var getLatestCommitShaOrRef = async (owner, repo, ref = "main") => {
42
+ const logger2 = getLogger(["dx-cli", "codemod"]);
43
+ return getLatestCommitSha(owner, repo, ref).catch(() => {
44
+ logger2.warn(
45
+ "Failed to fetch the latest commit from {owner}/{repo}, fallback to {fallback}",
46
+ { fallback: ref, owner, repo }
47
+ );
48
+ return ref;
49
+ });
50
+ };
51
+
52
+ // src/adapters/codemods/update-code-review.ts
53
+ var updateJSCodeReview = async (sha) => {
54
+ const logger2 = getLogger2(["dx-cli", "codemod"]);
55
+ const results = await replaceInFile({
56
+ allowEmptyPaths: true,
57
+ files: [".github/workflows/*.yaml"],
58
+ from: [/pagopa\/dx\/.github\/workflows\/js_code_review.yaml@(\S+)/g],
59
+ to: [`pagopa/dx/.github/workflows/js_code_review.yaml@${sha}`]
60
+ });
61
+ const updated = results.filter((r) => r.hasChanged).map((r) => r.file);
62
+ updated.forEach((filename) => {
63
+ logger2.info("Workflow {filename} updated", { filename });
64
+ });
65
+ return updated;
66
+ };
67
+ var updateCodeReview = {
68
+ apply: async () => {
69
+ const logger2 = getLogger2(["dx-cli", "codemod"]);
70
+ const owner = "pagopa";
71
+ const repo = "dx";
72
+ return getLatestCommitSha(owner, repo).then(async (sha) => {
73
+ await updateJSCodeReview(sha);
74
+ }).catch(() => {
75
+ logger2.error(
76
+ "Failed to fetch the latest commit sha from {owner}/{repo}",
77
+ {
78
+ owner,
79
+ repo
80
+ }
81
+ );
82
+ });
83
+ },
84
+ description: "Update js_code_review workflow to its latest version",
85
+ id: "update-code-review"
86
+ };
87
+
88
+ // src/adapters/codemods/use-azure-appsvc.ts
89
+ import { getLogger as getLogger3 } from "@logtape/logtape";
90
+ import { replaceInFile as replaceInFile2 } from "replace-in-file";
91
+ import YAML from "yaml";
92
+ var isChildOf = (path2, key) => {
93
+ const ancestor = path2.at(-1);
94
+ return YAML.isPair(ancestor) && YAML.isScalar(ancestor.key) && typeof ancestor.key.value === "string" && ancestor.key.value === key;
95
+ };
96
+ var migrateWorkflow = (sha) => (workflow, filename) => {
97
+ const logger2 = getLogger3(["dx-cli", "codemod"]);
98
+ logger2.debug("Processing {filename} file", { filename });
99
+ const document = YAML.parseDocument(workflow);
100
+ let updated = false;
101
+ YAML.visit(document, {
102
+ Map(_, map, path2) {
103
+ if (isChildOf(path2, "jobs") || isChildOf(path2, "with")) {
104
+ return void 0;
105
+ }
106
+ if (map.has("jobs")) {
107
+ return void 0;
108
+ }
109
+ if (map.has("uses")) {
110
+ const uses = map.get("uses");
111
+ if (typeof uses === "string" && uses.match(
112
+ /^pagopa\/dx\/.github\/workflows\/(web|function)_app_deploy/
113
+ )) {
114
+ logger2.debug("Adding disable_auto_staging_deploy");
115
+ map.addIn(["with", "disable_auto_staging_deploy"], true);
116
+ updated = true;
117
+ return void 0;
118
+ }
119
+ }
120
+ return YAML.visit.SKIP;
121
+ },
122
+ Pair(_, pair) {
123
+ if (YAML.isScalar(pair.key)) {
124
+ if (pair.key.value === "function_app_name") {
125
+ updated = true;
126
+ logger2.debug("Updating function_app_name to web_app_name");
127
+ return new YAML.Pair("web_app_name", pair.value);
128
+ }
129
+ if (pair.key.value === "use_staging_slot") {
130
+ updated = true;
131
+ logger2.debug("Removing use_staging_slot");
132
+ return YAML.visit.REMOVE;
133
+ }
134
+ if (pair.key.value === "uses") {
135
+ updated = true;
136
+ logger2.debug("Updating uses value");
137
+ return new YAML.Pair(
138
+ "uses",
139
+ `pagopa/dx/.github/workflows/release-azure-appsvc.yaml@${sha}`
140
+ );
141
+ }
142
+ }
143
+ }
144
+ });
145
+ if (updated) {
146
+ logger2.info("Workflow {filename} updated", {
147
+ filename
148
+ });
149
+ return YAML.stringify(document);
150
+ }
151
+ logger2.debug("No changes applied to {filename}", { filename });
152
+ return workflow;
153
+ };
154
+ var useAzureAppsvc = {
155
+ apply: async () => {
156
+ const sha = await getLatestCommitShaOrRef("pagopa", "dx");
157
+ await replaceInFile2({
158
+ allowEmptyPaths: true,
159
+ files: [".github/workflows/*.yaml"],
160
+ processor: migrateWorkflow(sha)
161
+ });
162
+ },
163
+ description: "Refactor legacy deploy workflows to use release-azure-appsvc",
164
+ id: "use-azure-appsvc"
165
+ };
166
+
167
+ // src/adapters/codemods/use-pnpm.ts
168
+ import { getLogger as getLogger4 } from "@logtape/logtape";
169
+ import { $ } from "execa";
170
+ import * as fs from "fs/promises";
171
+ import { replaceInFile as replaceInFile3 } from "replace-in-file";
172
+ import YAML2 from "yaml";
173
+ async function preparePackageJsonForPnpm() {
174
+ const packageJson2 = await fs.readFile("package.json", "utf-8");
175
+ const manifest = JSON.parse(packageJson2);
176
+ let workspaces = [];
177
+ if (Object.hasOwn(manifest, "packageManager")) {
178
+ delete manifest.packageManager;
179
+ }
180
+ if (Object.hasOwn(manifest, "workspaces")) {
181
+ if (Array.isArray(manifest.workspaces)) {
182
+ workspaces = manifest.workspaces;
183
+ }
184
+ delete manifest.workspaces;
185
+ }
186
+ await fs.writeFile("package.json", JSON.stringify(manifest, null, 2));
187
+ return workspaces;
188
+ }
189
+ async function removeFiles(...files) {
190
+ await Promise.all(
191
+ files.map(
192
+ (file) => (
193
+ // Remove the file if it exists, fail silently if it doesn't.
194
+ fs.rm(file, { force: true, recursive: true }).catch(() => void 0)
195
+ )
196
+ )
197
+ );
198
+ }
199
+ async function replaceYarnOccurrences() {
200
+ const logger2 = getLogger4(["dx-cli", "codemod"]);
201
+ logger2.info("Replacing yarn occurrences in files...");
202
+ const results = await replaceInFile3({
203
+ allowEmptyPaths: true,
204
+ files: ["**/*.json", "**/*.md", "**/Dockerfile", "**/docker-compose.yml"],
205
+ from: [
206
+ "https://yarnpkg.com/",
207
+ "https://classic.yarnpkg.com/",
208
+ /yarn workspace (\S+)/g,
209
+ /yarn workspace/g,
210
+ /yarn install --immutable/g,
211
+ /yarn -q dlx/g,
212
+ /Yarn/gi
213
+ ],
214
+ ignore: ["**/node_modules/**", "**/dist/**", "**/build/**"],
215
+ to: [
216
+ "https://pnpm.io/",
217
+ "https://pnpm.io/",
218
+ "pnpm --filter $1",
219
+ "pnpm --filter <package-selector>",
220
+ "pnpm install --frozen-lockfile",
221
+ "pnpm dlx",
222
+ "pnpm"
223
+ ]
224
+ });
225
+ const count = results.reduce(
226
+ (acc, file) => file.hasChanged ? acc + 1 : acc,
227
+ 0
228
+ );
229
+ logger2.info("Replaced yarn occurrences in {count} files", { count });
230
+ }
231
+ async function updateDXWorkflows() {
232
+ const logger2 = getLogger4(["dx-cli", "codemod"]);
233
+ logger2.info("Updating Github Workflows workflows...");
234
+ const sha = await getLatestCommitShaOrRef("pagopa", "dx");
235
+ const ignore = await updateJSCodeReview(sha);
236
+ await replaceInFile3({
237
+ allowEmptyPaths: true,
238
+ files: [".github/workflows/*.yaml"],
239
+ ignore,
240
+ processor: migrateWorkflow(sha)
241
+ });
242
+ }
243
+ async function writePnpmWorkspaceFile(workspaces) {
244
+ const pnpmWorkspace = {
245
+ packages: workspaces.length > 0 ? workspaces : ["apps/*", "packages/*"]
246
+ };
247
+ const yamlContent = YAML2.stringify(pnpmWorkspace);
248
+ await fs.writeFile("pnpm-workspace.yaml", yamlContent, "utf-8");
249
+ }
250
+ var apply = async (info) => {
251
+ if (info.packageManager === "pnpm") {
252
+ throw new Error("Project is already using pnpm");
34
253
  }
254
+ const logger2 = getLogger4(["dx-cli", "codemod"]);
255
+ logger2.info("Remove unused fields from {file}", {
256
+ file: "package.json"
257
+ });
258
+ const workspaces = await preparePackageJsonForPnpm();
259
+ logger2.info("Create {file}", {
260
+ file: "pnpm-workspace.yaml"
261
+ });
262
+ await writePnpmWorkspaceFile(workspaces);
263
+ logger2.info("Remove node_modules and yarn files");
264
+ await removeFiles(
265
+ ".yarnrc",
266
+ ".yarnrc.yml",
267
+ "yarn.config.cjs",
268
+ ".yarn",
269
+ ".pnp.cjs",
270
+ ".pnp.loader.cjs",
271
+ "node_modules"
272
+ );
273
+ logger2.info("Importing {source} to {target}", {
274
+ source: "yarn.lock",
275
+ target: "pnpm-lock.yaml"
276
+ });
277
+ try {
278
+ await fs.access("yarn.lock");
279
+ await $`corepack pnpm@latest import yarn.lock`;
280
+ await removeFiles("yarn.lock");
281
+ } catch {
282
+ logger2.info("No yarn.lock file found, skipping import.");
283
+ }
284
+ await $`corepack pnpm@latest add --config pnpm-plugin-pagopa`;
285
+ await replaceYarnOccurrences();
286
+ await updateDXWorkflows();
287
+ logger2.info("Setting pnpm as the package manager...");
288
+ await $`corepack use pnpm@latest`;
289
+ };
290
+ var use_pnpm_default = {
291
+ apply,
292
+ description: "A codemod that switches the project to use pnpm",
293
+ id: "use-pnpm"
35
294
  };
36
295
 
37
296
  // src/adapters/codemods/index.ts
38
297
  var registry = new LocalCodemodRegistry();
39
- registry.add(example_default);
298
+ registry.add(use_pnpm_default);
299
+ registry.add(useAzureAppsvc);
300
+ registry.add(updateCodeReview);
40
301
  var codemods_default = registry;
41
302
 
42
303
  // src/adapters/commander/index.ts
43
304
  import { Command as Command6 } from "commander";
44
305
 
45
306
  // src/adapters/commander/commands/codemod.ts
307
+ import { getLogger as getLogger5 } from "@logtape/logtape";
46
308
  import { Command } from "commander";
47
309
  var makeCodemodCommand = ({
48
310
  applyCodemodById: applyCodemodById2,
@@ -50,16 +312,14 @@ var makeCodemodCommand = ({
50
312
  }) => new Command("codemod").description("Manage and apply migration scripts to the repository").addCommand(
51
313
  new Command("list").description("List available migration scripts").action(async function() {
52
314
  await listCodemods2().andTee(
53
- (codemods) => (
54
- // eslint-disable-next-line no-console
55
- console.table(codemods, ["id", "description"])
56
- )
315
+ (codemods) => console.table(codemods, ["id", "description"])
57
316
  ).orTee((error) => this.error(error.message));
58
317
  })
59
318
  ).addCommand(
60
319
  new Command("apply").argument("<id>", "The id of the codemod to apply").description("Apply migration scripts to the repository").action(async function(id) {
320
+ const logger2 = getLogger5(["dx-cli", "codemod"]);
61
321
  await applyCodemodById2(id).andTee(() => {
62
- console.log("Codemod applied successfully \u2705");
322
+ logger2.info("Codemod applied \u2705");
63
323
  }).orTee((error) => this.error(error.message));
64
324
  })
65
325
  );
@@ -140,7 +400,7 @@ var checkMonorepoScripts = async (dependencies, config2) => {
140
400
 
141
401
  // src/domain/repository.ts
142
402
  import { ok as ok2 } from "neverthrow";
143
- import fs from "path";
403
+ import fs2 from "path";
144
404
  import coerce from "semver/functions/coerce.js";
145
405
  import semverGte from "semver/functions/gte.js";
146
406
  var isVersionValid = (version, minVersion) => {
@@ -155,7 +415,7 @@ var checkPreCommitConfig = async (dependencies, config2) => {
155
415
  const { repositoryReader: repositoryReader2 } = dependencies;
156
416
  const checkName = "Pre-commit Configuration";
157
417
  const preCommitResult = await repositoryReader2.fileExists(
158
- fs.join(config2.repository.root, ".pre-commit-config.yaml")
418
+ fs2.join(config2.repository.root, ".pre-commit-config.yaml")
159
419
  );
160
420
  if (preCommitResult.isOk() && preCommitResult.value) {
161
421
  return ok2({
@@ -176,7 +436,7 @@ var checkTurboConfig = async (dependencies, config2) => {
176
436
  const checkName = "Turbo Configuration";
177
437
  const repoRoot2 = config2.repository.root;
178
438
  const turboResult = await repositoryReader2.fileExists(
179
- fs.join(repoRoot2, "turbo.json")
439
+ fs2.join(repoRoot2, "turbo.json")
180
440
  );
181
441
  if (turboResult.isErr()) {
182
442
  return ok2({
@@ -315,7 +575,7 @@ var makeDoctorCommand = (dependencies, config2) => new Command2().name("doctor")
315
575
  import { Command as Command3 } from "commander";
316
576
 
317
577
  // src/domain/info.ts
318
- import { getLogger } from "@logtape/logtape";
578
+ import { getLogger as getLogger6 } from "@logtape/logtape";
319
579
  import { join } from "path";
320
580
  var detectFromLockFile = async (dependencies, config2) => {
321
581
  const { repositoryReader: repositoryReader2 } = dependencies;
@@ -341,7 +601,7 @@ var detectPackageManager = async (dependencies, config2) => {
341
601
  var detectNodeVersion = async ({ repositoryReader: repositoryReader2 }, nodeVersionFilePath) => await repositoryReader2.readFile(nodeVersionFilePath).map((nodeVersion) => nodeVersion.trim()).unwrapOr(void 0);
342
602
  var detectTerraformVersion = async ({ repositoryReader: repositoryReader2 }, terraformVersionFilePath) => await repositoryReader2.readFile(terraformVersionFilePath).map((tfVersion) => tfVersion.trim()).unwrapOr(void 0);
343
603
  var detectTurboVersion = ({ devDependencies }) => devDependencies.get("turbo")?.trim();
344
- var getInfo = async (dependencies, config2) => ({
604
+ var getInfo = (dependencies, config2) => async () => ({
345
605
  node: await detectNodeVersion(
346
606
  { repositoryReader: dependencies.repositoryReader },
347
607
  `${config2.repository.root}/.node-version`
@@ -354,13 +614,13 @@ var getInfo = async (dependencies, config2) => ({
354
614
  turbo: detectTurboVersion(dependencies.packageJson)
355
615
  });
356
616
  var printInfo = (result) => {
357
- const logger2 = getLogger("json");
617
+ const logger2 = getLogger6("json");
358
618
  logger2.info(JSON.stringify(result));
359
619
  };
360
620
 
361
621
  // src/adapters/commander/commands/info.ts
362
622
  var makeInfoCommand = (dependencies, config2) => new Command3().name("info").description("Display information about the project").action(async () => {
363
- const result = await getInfo(dependencies, config2);
623
+ const result = await getInfo(dependencies, config2)();
364
624
  printInfo(result);
365
625
  });
366
626
 
@@ -402,22 +662,22 @@ var makeInitCommand = () => new Command4().name("init").description(
402
662
  import { Command as Command5 } from "commander";
403
663
 
404
664
  // src/domain/version.ts
405
- import { getLogger as getLogger2 } from "@logtape/logtape";
665
+ import { getLogger as getLogger7 } from "@logtape/logtape";
406
666
  function printVersion() {
407
- const logger2 = getLogger2(["dx-cli", "version"]);
408
- logger2.info(`dx CLI version: ${"0.6.0"}`);
667
+ const logger2 = getLogger7(["dx-cli", "version"]);
668
+ logger2.info(`dx CLI version: ${"0.7.0"}`);
409
669
  }
410
670
 
411
671
  // src/adapters/commander/commands/version.ts
412
672
  var makeVersionCommand = () => new Command5().name("version").alias("v").action(() => printVersion());
413
673
 
414
674
  // src/adapters/commander/index.ts
415
- var makeCli = (deps2, config2) => {
675
+ var makeCli = (deps2, config2, cliDeps) => {
416
676
  const program2 = new Command6();
417
- program2.name("dx").description("The CLI for DX-Platform").version("0.6.0");
677
+ program2.name("dx").description("The CLI for DX-Platform").version("0.7.0");
418
678
  program2.addCommand(makeDoctorCommand(deps2, config2));
419
679
  if (process.env.ENABLE_CODEMODS) {
420
- program2.addCommand(makeCodemodCommand(deps2));
680
+ program2.addCommand(makeCodemodCommand(cliDeps));
421
681
  }
422
682
  if (process.env.ENABLE_INIT_COMMAND) {
423
683
  program2.addCommand(makeInitCommand());
@@ -428,9 +688,9 @@ var makeCli = (deps2, config2) => {
428
688
  };
429
689
 
430
690
  // src/adapters/logtape/validation-reporter.ts
431
- import { getLogger as getLogger3 } from "@logtape/logtape";
691
+ import { getLogger as getLogger8 } from "@logtape/logtape";
432
692
  var makeValidationReporter = () => {
433
- const logger2 = getLogger3(["dx-cli", "validation"]);
693
+ const logger2 = getLogger8(["dx-cli", "validation"]);
434
694
  return {
435
695
  reportCheckResult(result) {
436
696
  if (result.isValid) {
@@ -448,7 +708,7 @@ import * as process3 from "process";
448
708
 
449
709
  // src/adapters/node/fs/file-reader.ts
450
710
  import { ResultAsync as ResultAsync6 } from "neverthrow";
451
- import fs2 from "fs/promises";
711
+ import fs3 from "fs/promises";
452
712
 
453
713
  // src/adapters/zod/index.ts
454
714
  import { ResultAsync as ResultAsync5 } from "neverthrow";
@@ -465,13 +725,13 @@ var parseJson = Result2.fromThrowable(
465
725
  );
466
726
 
467
727
  // src/adapters/node/fs/file-reader.ts
468
- var readFile = (filePath) => ResultAsync6.fromPromise(
469
- fs2.readFile(filePath, "utf-8"),
728
+ var readFile2 = (filePath) => ResultAsync6.fromPromise(
729
+ fs3.readFile(filePath, "utf-8"),
470
730
  (cause) => new Error(`Failed to read file: ${filePath}`, { cause })
471
731
  );
472
- var readFileAndDecode = (filePath, schema) => readFile(filePath).andThen(parseJson).andThen(decode(schema));
732
+ var readFileAndDecode = (filePath, schema) => readFile2(filePath).andThen(parseJson).andThen(decode(schema));
473
733
  var fileExists = (path2) => ResultAsync6.fromPromise(
474
- fs2.stat(path2),
734
+ fs3.stat(path2),
475
735
  () => new Error(`${path2} not found.`)
476
736
  ).map(() => true);
477
737
 
@@ -501,7 +761,7 @@ var makePackageJsonReader = () => ({
501
761
 
502
762
  // src/adapters/node/repository.ts
503
763
  import * as glob from "glob";
504
- import { okAsync as okAsync3, ResultAsync as ResultAsync7 } from "neverthrow";
764
+ import { okAsync as okAsync2, ResultAsync as ResultAsync7 } from "neverthrow";
505
765
  import * as path from "path";
506
766
  import { z as z3 } from "zod/v4";
507
767
 
@@ -535,11 +795,11 @@ var resolveWorkspacePattern = (repoRoot2, pattern) => ResultAsync7.fromPromise(
535
795
  subDirectories.map((directory) => path.join(repoRoot2, directory))
536
796
  )
537
797
  );
538
- var getWorkspaces = (repoRoot2) => readFile(path.join(repoRoot2, "pnpm-workspace.yaml")).andThen(parseYaml).andThen(
798
+ var getWorkspaces = (repoRoot2) => readFile2(path.join(repoRoot2, "pnpm-workspace.yaml")).andThen(parseYaml).andThen(
539
799
  (obj) => (
540
800
  // If no packages are defined, go on with an empty array
541
801
  decode(z3.object({ packages: z3.array(z3.string()) }))(obj).orElse(
542
- () => okAsync3({ packages: [] })
802
+ () => okAsync2({ packages: [] })
543
803
  )
544
804
  )
545
805
  ).andThen(
@@ -567,7 +827,7 @@ var makeRepositoryReader = () => ({
567
827
  fileExists,
568
828
  findRepositoryRoot,
569
829
  getWorkspaces,
570
- readFile
830
+ readFile: readFile2
571
831
  });
572
832
 
573
833
  // src/config.ts
@@ -581,10 +841,23 @@ var getConfig = (repositoryRoot2) => ({
581
841
  });
582
842
 
583
843
  // src/use-cases/apply-codemod.ts
584
- import { errAsync, okAsync as okAsync4 } from "neverthrow";
585
- var applyCodemodById = (registry2) => (id) => registry2.getById(id).andThen(
586
- (codemod) => codemod ? okAsync4(codemod) : errAsync(new Error(`Codemod with id ${id} not found`))
587
- ).andThen((codemod) => codemod.apply());
844
+ import { errAsync, okAsync as okAsync3, ResultAsync as ResultAsync8 } from "neverthrow";
845
+ var getCodemodById = (registry2, id) => registry2.getById(id).andThen(
846
+ (codemod) => codemod ? okAsync3(codemod) : errAsync(new Error(`Codemod with id ${id} not found`))
847
+ );
848
+ var safeGetInfo = (getInfo2) => ResultAsync8.fromPromise(
849
+ getInfo2(),
850
+ (error) => new Error("Failed to get info", { cause: error })
851
+ );
852
+ var applyCodemodById = (registry2, getInfo2) => (id) => ResultAsync8.combine([
853
+ safeGetInfo(getInfo2),
854
+ getCodemodById(registry2, id)
855
+ ]).andThen(
856
+ ([info, codemod]) => ResultAsync8.fromPromise(codemod.apply(info), (error) => {
857
+ const message = error instanceof Error ? `: ${error.message}` : "";
858
+ return new Error("Failed to apply codemod" + message, { cause: error });
859
+ })
860
+ );
588
861
 
589
862
  // src/use-cases/list-codemods.ts
590
863
  var listCodemods = (registry2) => () => registry2.getAll();
@@ -607,7 +880,7 @@ await configure({
607
880
  }
608
881
  }
609
882
  });
610
- var logger = getLogger4(["dx-cli"]);
883
+ var logger = getLogger9(["dx-cli"]);
611
884
  var repositoryReader = makeRepositoryReader();
612
885
  var packageJsonReader = makePackageJsonReader();
613
886
  var validationReporter = makeValidationReporter();
@@ -626,13 +899,15 @@ if (repoPackageJson.isErr()) {
626
899
  }
627
900
  var packageJson = repoPackageJson.value;
628
901
  var deps = {
629
- applyCodemodById: applyCodemodById(codemods_default),
630
- listCodemods: listCodemods(codemods_default),
631
902
  packageJson,
632
903
  packageJsonReader,
633
904
  repositoryReader,
634
905
  validationReporter
635
906
  };
636
907
  var config = getConfig(repositoryRoot);
637
- var program = makeCli(deps, config);
908
+ var useCases = {
909
+ applyCodemodById: applyCodemodById(codemods_default, getInfo(deps, config)),
910
+ listCodemods: listCodemods(codemods_default)
911
+ };
912
+ var program = makeCli(deps, config, useCases);
638
913
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagopa/dx-cli",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "description": "A CLI useful to manage DX tools.",
6
6
  "repository": {
@@ -22,9 +22,12 @@
22
22
  "@logtape/logtape": "^1.0.0",
23
23
  "commander": "^14.0.0",
24
24
  "core-js": "^3.44.0",
25
+ "execa": "^9.6.0",
25
26
  "glob": "^11.0.3",
26
27
  "neverthrow": "^8.2.0",
27
28
  "node-plop": "^0.32.1",
29
+ "octokit": "^5.0.3",
30
+ "replace-in-file": "^8.3.0",
28
31
  "semver": "^7.7.2",
29
32
  "yaml": "^2.8.0",
30
33
  "zod": "^3.25.28",