skuba 10.0.0-node-22-20250226231811 → 10.0.1-consider-current-path-20250314071804

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 (53) hide show
  1. package/lib/cli/configure/analyseDependencies.js +4 -1
  2. package/lib/cli/configure/analyseDependencies.js.map +2 -2
  3. package/lib/cli/configure/index.js +2 -2
  4. package/lib/cli/configure/index.js.map +2 -2
  5. package/lib/cli/configure/modules/package.js +4 -1
  6. package/lib/cli/configure/modules/package.js.map +2 -2
  7. package/lib/cli/init/getConfig.js +2 -2
  8. package/lib/cli/init/getConfig.js.map +2 -2
  9. package/lib/cli/lint/index.js +1 -1
  10. package/lib/cli/lint/index.js.map +2 -2
  11. package/lib/cli/lint/internal.js +2 -1
  12. package/lib/cli/lint/internal.js.map +2 -2
  13. package/lib/cli/lint/internalLints/detectBadCodeowners.d.ts +4 -0
  14. package/lib/cli/lint/internalLints/detectBadCodeowners.js +72 -0
  15. package/lib/cli/lint/internalLints/detectBadCodeowners.js.map +7 -0
  16. package/lib/cli/lint/internalLints/noSkubaTemplateJs.js +2 -2
  17. package/lib/cli/lint/internalLints/noSkubaTemplateJs.js.map +2 -2
  18. package/lib/cli/lint/internalLints/refreshConfigFiles.js +1 -1
  19. package/lib/cli/lint/internalLints/refreshConfigFiles.js.map +2 -2
  20. package/lib/cli/lint/internalLints/upgrade/index.js +2 -2
  21. package/lib/cli/lint/internalLints/upgrade/index.js.map +2 -2
  22. package/lib/cli/migrate/nodeVersion/checks.d.ts +4 -4
  23. package/lib/cli/migrate/nodeVersion/checks.js +21 -11
  24. package/lib/cli/migrate/nodeVersion/checks.js.map +2 -2
  25. package/lib/cli/migrate/nodeVersion/getNodeTypesVersion.js +13 -33
  26. package/lib/cli/migrate/nodeVersion/getNodeTypesVersion.js.map +3 -3
  27. package/lib/cli/migrate/nodeVersion/index.js +8 -4
  28. package/lib/cli/migrate/nodeVersion/index.js.map +2 -2
  29. package/lib/utils/copy.d.ts +1 -1
  30. package/lib/utils/copy.js +11 -3
  31. package/lib/utils/copy.js.map +2 -2
  32. package/lib/utils/logo.js +3 -1
  33. package/lib/utils/logo.js.map +2 -2
  34. package/lib/utils/packageManager.d.ts +11 -8
  35. package/lib/utils/packageManager.js +23 -10
  36. package/lib/utils/packageManager.js.map +2 -2
  37. package/lib/utils/version.d.ts +17 -1
  38. package/lib/utils/version.js +48 -18
  39. package/lib/utils/version.js.map +3 -3
  40. package/package.json +6 -10
  41. package/template/express-rest-api/.gantry/common.yml +0 -1
  42. package/template/express-rest-api/Dockerfile.dev-deps +1 -1
  43. package/template/express-rest-api/package.json +2 -2
  44. package/template/greeter/Dockerfile +1 -1
  45. package/template/greeter/package.json +3 -3
  46. package/template/koa-rest-api/.gantry/common.yml +0 -1
  47. package/template/koa-rest-api/Dockerfile.dev-deps +1 -1
  48. package/template/koa-rest-api/package.json +2 -2
  49. package/template/lambda-sqs-worker-cdk/Dockerfile +1 -1
  50. package/template/lambda-sqs-worker-cdk/infra/appStack.ts +2 -2
  51. package/template/lambda-sqs-worker-cdk/package.json +5 -5
  52. package/template/oss-npm-package/_package.json +1 -1
  53. package/template/private-npm-package/_package.json +1 -1
@@ -53,7 +53,10 @@ const logDiff = (diff) => {
53
53
  const pinUnspecifiedVersions = async (dependencies) => {
54
54
  const updates = await Promise.all(
55
55
  Object.entries(dependencies).filter(([, version]) => version === "*").map(async ([name]) => {
56
- const version = await (name === "skuba" ? (0, import_version.getSkubaVersion)() : (0, import_version.latestNpmVersion)(name));
56
+ const version = await (name === "skuba" ? (0, import_version.getSkubaVersion)() : (0, import_version.getLatestNpmVersion)(name));
57
+ if (version === null) {
58
+ throw new Error(`Failed to fetch latest version of ${name}`);
59
+ }
57
60
  return [name, version];
58
61
  })
59
62
  );
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/configure/analyseDependencies.ts"],
4
- "sourcesContent": ["import path from 'path';\n\nimport fs from 'fs-extra';\nimport type { NormalizedReadResult } from 'read-pkg-up';\n\nimport { type TextProcessor, copyFiles } from '../../utils/copy';\nimport { log } from '../../utils/logging';\nimport type { ProjectType } from '../../utils/manifest';\nimport { getSkubaVersion, latestNpmVersion } from '../../utils/version';\n\nimport { diffDependencies } from './analysis/package';\nimport * as dependencyMutators from './dependencies';\nimport { formatPackage } from './processing/package';\nimport type { DependencyDiff } from './types';\n\nconst logDiff = (diff: DependencyDiff): boolean => {\n const entries = Object.entries(diff);\n\n if (entries.length === 0) {\n log.ok('\u2714 No changes');\n\n return false;\n }\n\n Object.entries(diff)\n .sort(([nameA], [nameB]) => nameA.localeCompare(nameB))\n .forEach(([name, { operation, version }]) =>\n log.plain(operation, name, log.formatSubtle(version)),\n );\n\n return true;\n};\n\nconst pinUnspecifiedVersions = async (\n dependencies: Record<string, string>,\n): Promise<void> => {\n const updates = await Promise.all(\n Object.entries(dependencies)\n .filter(([, version]) => version === '*')\n .map(async ([name]) => {\n const version = await (name === 'skuba'\n ? getSkubaVersion()\n : latestNpmVersion(name));\n\n return [name, version] as const;\n }),\n );\n\n updates.forEach(([name, version]) => {\n dependencies[name] = version;\n });\n};\n\ninterface Props {\n destinationRoot: string;\n include: (pathname: string) => boolean;\n manifest: NormalizedReadResult;\n type: ProjectType;\n}\n\nexport const analyseDependencies = async ({\n destinationRoot,\n include,\n manifest: { packageJson },\n type,\n}: Props): Promise<undefined | (() => Promise<void>)> => {\n const input = {\n dependencies: packageJson.dependencies ?? {},\n devDependencies: packageJson.devDependencies ?? {},\n type,\n };\n\n const output = {\n dependencies: { ...input.dependencies },\n devDependencies: { ...input.devDependencies },\n type,\n };\n\n const processors = Object.values(dependencyMutators).reduce<TextProcessor[]>(\n (acc, mutate) => {\n const newProcessors = mutate(output);\n acc.push(...newProcessors);\n return acc;\n },\n [],\n );\n\n await Promise.all([\n pinUnspecifiedVersions(output.dependencies),\n pinUnspecifiedVersions(output.devDependencies),\n ]);\n\n const dependencyDiff = diffDependencies({\n old: input.dependencies,\n new: output.dependencies,\n });\n\n log.newline();\n log.plain(log.bold('Dependencies:'));\n\n log.newline();\n const hasDependencyDiff = logDiff(dependencyDiff);\n\n const devDependencyDiff = diffDependencies({\n old: input.devDependencies,\n new: output.devDependencies,\n });\n\n log.newline();\n log.plain(log.bold('Dev dependencies:'));\n\n log.newline();\n const hasDevDependencyDiff = logDiff(devDependencyDiff);\n\n const packageJsonFilepath = path.join(destinationRoot, 'package.json');\n\n if (!hasDependencyDiff && !hasDevDependencyDiff) {\n return;\n }\n\n return async () => {\n const updatedPackageJson = await formatPackage({\n ...packageJson,\n dependencies: output.dependencies,\n devDependencies: output.devDependencies,\n });\n\n await fs.promises.writeFile(packageJsonFilepath, updatedPackageJson);\n\n if (processors.length === 0) {\n return;\n }\n\n await copyFiles({\n sourceRoot: destinationRoot,\n destinationRoot,\n include,\n processors,\n });\n };\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import path from 'path';\n\nimport fs from 'fs-extra';\nimport type { NormalizedReadResult } from 'read-pkg-up';\n\nimport { type TextProcessor, copyFiles } from '../../utils/copy';\nimport { log } from '../../utils/logging';\nimport type { ProjectType } from '../../utils/manifest';\nimport { getLatestNpmVersion, getSkubaVersion } from '../../utils/version';\n\nimport { diffDependencies } from './analysis/package';\nimport * as dependencyMutators from './dependencies';\nimport { formatPackage } from './processing/package';\nimport type { DependencyDiff } from './types';\n\nconst logDiff = (diff: DependencyDiff): boolean => {\n const entries = Object.entries(diff);\n\n if (entries.length === 0) {\n log.ok('\u2714 No changes');\n\n return false;\n }\n\n Object.entries(diff)\n .sort(([nameA], [nameB]) => nameA.localeCompare(nameB))\n .forEach(([name, { operation, version }]) =>\n log.plain(operation, name, log.formatSubtle(version)),\n );\n\n return true;\n};\n\nconst pinUnspecifiedVersions = async (\n dependencies: Record<string, string>,\n): Promise<void> => {\n const updates = await Promise.all(\n Object.entries(dependencies)\n .filter(([, version]) => version === '*')\n .map(async ([name]) => {\n const version = await (name === 'skuba'\n ? getSkubaVersion()\n : getLatestNpmVersion(name));\n\n if (version === null) {\n throw new Error(`Failed to fetch latest version of ${name}`);\n }\n\n return [name, version] as const;\n }),\n );\n\n updates.forEach(([name, version]) => {\n dependencies[name] = version;\n });\n};\n\ninterface Props {\n destinationRoot: string;\n include: (pathname: string) => boolean;\n manifest: NormalizedReadResult;\n type: ProjectType;\n}\n\nexport const analyseDependencies = async ({\n destinationRoot,\n include,\n manifest: { packageJson },\n type,\n}: Props): Promise<undefined | (() => Promise<void>)> => {\n const input = {\n dependencies: packageJson.dependencies ?? {},\n devDependencies: packageJson.devDependencies ?? {},\n type,\n };\n\n const output = {\n dependencies: { ...input.dependencies },\n devDependencies: { ...input.devDependencies },\n type,\n };\n\n const processors = Object.values(dependencyMutators).reduce<TextProcessor[]>(\n (acc, mutate) => {\n const newProcessors = mutate(output);\n acc.push(...newProcessors);\n return acc;\n },\n [],\n );\n\n await Promise.all([\n pinUnspecifiedVersions(output.dependencies),\n pinUnspecifiedVersions(output.devDependencies),\n ]);\n\n const dependencyDiff = diffDependencies({\n old: input.dependencies,\n new: output.dependencies,\n });\n\n log.newline();\n log.plain(log.bold('Dependencies:'));\n\n log.newline();\n const hasDependencyDiff = logDiff(dependencyDiff);\n\n const devDependencyDiff = diffDependencies({\n old: input.devDependencies,\n new: output.devDependencies,\n });\n\n log.newline();\n log.plain(log.bold('Dev dependencies:'));\n\n log.newline();\n const hasDevDependencyDiff = logDiff(devDependencyDiff);\n\n const packageJsonFilepath = path.join(destinationRoot, 'package.json');\n\n if (!hasDependencyDiff && !hasDevDependencyDiff) {\n return;\n }\n\n return async () => {\n const updatedPackageJson = await formatPackage({\n ...packageJson,\n dependencies: output.dependencies,\n devDependencies: output.devDependencies,\n });\n\n await fs.promises.writeFile(packageJsonFilepath, updatedPackageJson);\n\n if (processors.length === 0) {\n return;\n }\n\n await copyFiles({\n sourceRoot: destinationRoot,\n destinationRoot,\n include,\n processors,\n });\n };\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_package", "path", "fs"]
7
7
  }
@@ -123,12 +123,12 @@ const configure = async () => {
123
123
  });
124
124
  import_logging.log.newline();
125
125
  try {
126
- await exec(packageManager.install);
126
+ await exec(packageManager.command, "install");
127
127
  } catch {
128
128
  import_logging.log.newline();
129
129
  import_logging.log.warn(import_logging.log.bold("\u2717 Failed to install dependencies. Resume with:"));
130
130
  import_logging.log.newline();
131
- import_logging.log.plain(import_logging.log.bold(packageManager.install));
131
+ import_logging.log.plain(import_logging.log.bold(packageManager.command, "install"));
132
132
  import_logging.log.plain(import_logging.log.bold(packageManager.command, "format"));
133
133
  import_logging.log.newline();
134
134
  process.exitCode = 1;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/configure/index.ts"],
4
- "sourcesContent": ["import path from 'path';\n\nimport { Select } from 'enquirer';\n\nimport { createInclusionFilter } from '../../utils/dir';\nimport { createExec, ensureCommands } from '../../utils/exec';\nimport { log } from '../../utils/logging';\nimport { showLogoAndVersionInfo } from '../../utils/logo';\nimport { detectPackageManager } from '../../utils/packageManager';\nimport { BASE_TEMPLATE_DIR } from '../../utils/template';\nimport { hasProp } from '../../utils/validation';\n\nimport { analyseConfiguration } from './analyseConfiguration';\nimport { analyseDependencies } from './analyseDependencies';\nimport { auditWorkingTree } from './analysis/git';\nimport { getDestinationManifest } from './analysis/package';\nimport { ensureTemplateCompletion } from './ensureTemplateCompletion';\nimport { getEntryPoint } from './getEntryPoint';\nimport { getProjectType } from './getProjectType';\n\nconst shouldApply = async (name: string) => {\n if (!process.stdin.isTTY) {\n return 'yes';\n }\n const prompt = new Select({\n choices: ['yes', 'no'] as const,\n message: 'Apply changes?',\n name,\n });\n\n const result = await prompt.run();\n\n return result === 'yes';\n};\n\nexport const configure = async () => {\n await showLogoAndVersionInfo();\n\n const [manifest, packageManager] = await Promise.all([\n getDestinationManifest(),\n detectPackageManager(),\n ]);\n\n await ensureCommands(packageManager.command);\n\n const destinationRoot = path.dirname(manifest.path);\n\n log.plain('Detected project root:', log.bold(destinationRoot));\n\n const [include] = await Promise.all([\n createInclusionFilter([\n path.join(destinationRoot, '.gitignore'),\n path.join(BASE_TEMPLATE_DIR, '_.gitignore'),\n ]),\n\n auditWorkingTree(destinationRoot),\n ]);\n\n const templateConfig = await ensureTemplateCompletion({\n destinationRoot,\n include,\n manifest,\n });\n\n const type = await getProjectType({\n manifest,\n templateConfig,\n });\n\n const entryPoint = await getEntryPoint({\n destinationRoot,\n manifest,\n templateConfig,\n type,\n });\n\n const fixDependencies = await analyseDependencies({\n destinationRoot,\n include,\n manifest,\n type,\n });\n\n if (fixDependencies) {\n log.newline();\n\n if (await shouldApply('fixDependencies')) {\n await fixDependencies();\n }\n }\n\n const firstRun = hasProp(manifest.packageJson, 'skuba');\n\n const fixConfiguration = await analyseConfiguration({\n destinationRoot,\n entryPoint,\n firstRun,\n packageManager,\n type,\n });\n\n if (fixConfiguration) {\n log.newline();\n\n if (await shouldApply('fixConfiguration')) {\n await fixConfiguration();\n }\n }\n\n if (fixDependencies) {\n const exec = createExec({\n stdio: 'pipe',\n streamStdio: packageManager.command,\n });\n\n log.newline();\n try {\n await exec(packageManager.install);\n } catch {\n log.newline();\n log.warn(log.bold('\u2717 Failed to install dependencies. Resume with:'));\n\n log.newline();\n log.plain(log.bold(packageManager.install));\n log.plain(log.bold(packageManager.command, 'format'));\n\n log.newline();\n process.exitCode = 1;\n return;\n }\n }\n\n if (fixConfiguration ?? fixDependencies) {\n log.newline();\n log.ok(log.bold('\u2714 All done! Try running:'));\n\n log.newline();\n log.plain(log.bold(packageManager.command, 'format'));\n }\n\n log.newline();\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import path from 'path';\n\nimport { Select } from 'enquirer';\n\nimport { createInclusionFilter } from '../../utils/dir';\nimport { createExec, ensureCommands } from '../../utils/exec';\nimport { log } from '../../utils/logging';\nimport { showLogoAndVersionInfo } from '../../utils/logo';\nimport { detectPackageManager } from '../../utils/packageManager';\nimport { BASE_TEMPLATE_DIR } from '../../utils/template';\nimport { hasProp } from '../../utils/validation';\n\nimport { analyseConfiguration } from './analyseConfiguration';\nimport { analyseDependencies } from './analyseDependencies';\nimport { auditWorkingTree } from './analysis/git';\nimport { getDestinationManifest } from './analysis/package';\nimport { ensureTemplateCompletion } from './ensureTemplateCompletion';\nimport { getEntryPoint } from './getEntryPoint';\nimport { getProjectType } from './getProjectType';\n\nconst shouldApply = async (name: string) => {\n if (!process.stdin.isTTY) {\n return 'yes';\n }\n const prompt = new Select({\n choices: ['yes', 'no'] as const,\n message: 'Apply changes?',\n name,\n });\n\n const result = await prompt.run();\n\n return result === 'yes';\n};\n\nexport const configure = async () => {\n await showLogoAndVersionInfo();\n\n const [manifest, packageManager] = await Promise.all([\n getDestinationManifest(),\n detectPackageManager(),\n ]);\n\n await ensureCommands(packageManager.command);\n\n const destinationRoot = path.dirname(manifest.path);\n\n log.plain('Detected project root:', log.bold(destinationRoot));\n\n const [include] = await Promise.all([\n createInclusionFilter([\n path.join(destinationRoot, '.gitignore'),\n path.join(BASE_TEMPLATE_DIR, '_.gitignore'),\n ]),\n\n auditWorkingTree(destinationRoot),\n ]);\n\n const templateConfig = await ensureTemplateCompletion({\n destinationRoot,\n include,\n manifest,\n });\n\n const type = await getProjectType({\n manifest,\n templateConfig,\n });\n\n const entryPoint = await getEntryPoint({\n destinationRoot,\n manifest,\n templateConfig,\n type,\n });\n\n const fixDependencies = await analyseDependencies({\n destinationRoot,\n include,\n manifest,\n type,\n });\n\n if (fixDependencies) {\n log.newline();\n\n if (await shouldApply('fixDependencies')) {\n await fixDependencies();\n }\n }\n\n const firstRun = hasProp(manifest.packageJson, 'skuba');\n\n const fixConfiguration = await analyseConfiguration({\n destinationRoot,\n entryPoint,\n firstRun,\n packageManager,\n type,\n });\n\n if (fixConfiguration) {\n log.newline();\n\n if (await shouldApply('fixConfiguration')) {\n await fixConfiguration();\n }\n }\n\n if (fixDependencies) {\n const exec = createExec({\n stdio: 'pipe',\n streamStdio: packageManager.command,\n });\n\n log.newline();\n try {\n await exec(packageManager.command, 'install');\n } catch {\n log.newline();\n log.warn(log.bold('\u2717 Failed to install dependencies. Resume with:'));\n\n log.newline();\n log.plain(log.bold(packageManager.command, 'install'));\n log.plain(log.bold(packageManager.command, 'format'));\n\n log.newline();\n process.exitCode = 1;\n return;\n }\n }\n\n if (fixConfiguration ?? fixDependencies) {\n log.newline();\n log.ok(log.bold('\u2714 All done! Try running:'));\n\n log.newline();\n log.plain(log.bold(packageManager.command, 'format'));\n }\n\n log.newline();\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["path"]
7
7
  }
@@ -93,7 +93,10 @@ const packageModule = async ({
93
93
  outputData.scripts.prerelease,
94
94
  outputData.scripts.release ?? "skuba release"
95
95
  ].filter((script) => typeof script === "string").map(
96
- (script) => script.replace(/^smt build$/, `${packageManager.runSilent} build`).replace(/^smt /, "skuba ").trim()
96
+ (script) => script.replace(
97
+ /^smt build$/,
98
+ `${packageManager.print.runSilent} build`
99
+ ).replace(/^smt /, "skuba ").trim()
97
100
  ).filter(Boolean).join(" && ");
98
101
  if (outputData.scripts.build === "skuba build-package") {
99
102
  outputData.main = "./lib-commonjs/index.js";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/configure/modules/package.ts"],
4
- "sourcesContent": ["import { getSkubaVersion } from '../../../utils/version';\nimport { deleteFiles } from '../processing/deleteFiles';\nimport { withPackage } from '../processing/package';\nimport { merge } from '../processing/record';\nimport type { Module, Options } from '../types';\n\nconst DEFAULT_PACKAGE_FILES = [\n 'lib*/**/*.d.ts',\n 'lib*/**/*.js',\n 'lib*/**/*.js.map',\n 'lib*/**/*.json',\n];\n\nexport const packageModule = async ({\n entryPoint,\n packageManager,\n type,\n}: Options): Promise<Module> => {\n const version = await getSkubaVersion();\n\n const initialData = {\n private: type !== 'package',\n\n scripts: {\n build: type === 'package' ? 'skuba build-package' : 'skuba build',\n format: 'skuba format',\n lint: 'skuba lint',\n ...(type === 'package' ? {} : { start: 'skuba start' }),\n test: 'skuba test --coverage',\n 'test:watch': 'skuba test --watch',\n },\n skuba: {\n entryPoint,\n template: null,\n type,\n version,\n },\n };\n\n const recurringData = {\n skuba: {\n entryPoint,\n type,\n version,\n },\n };\n\n return {\n ...deleteFiles('.npmignore', 'package-lock.json'),\n\n 'package.json': (inputFile) =>\n withPackage((inputData) => {\n const outputData = merge(\n inputData,\n 'skuba' in inputData ? recurringData : initialData,\n );\n\n outputData.license ??= 'UNLICENSED';\n outputData.scripts ??= {};\n\n // Workspaces can only be enabled in private projects\n if (outputData.workspaces && !outputData.private) {\n outputData.private = true;\n }\n\n delete outputData.scripts.commit;\n delete outputData.scripts['format:check'];\n delete outputData.scripts['lint:build'];\n delete outputData.scripts['lint:compile'];\n delete outputData.scripts['lint:eslint'];\n delete outputData.scripts['lint:prettier'];\n delete outputData.scripts['lint:tslint'];\n delete outputData.scripts['test:build'];\n delete outputData.scripts['test:jest'];\n delete outputData.typings;\n\n if (type === 'package') {\n outputData.files = (\n outputData.files ?? DEFAULT_PACKAGE_FILES\n ).flatMap((filePattern) =>\n filePattern === 'lib' ? DEFAULT_PACKAGE_FILES : [filePattern],\n );\n\n outputData.version ??= '0.0.0-semantically-released';\n\n // User-defined pre- and post-scripts are confusing and dropped by e.g.\n // Yarn 2.\n outputData.scripts.release = [\n outputData.scripts.prepublish,\n outputData.scripts.prerelease,\n outputData.scripts.release ?? 'skuba release',\n ]\n .filter((script): script is string => typeof script === 'string')\n .map((script) =>\n script\n .replace(/^smt build$/, `${packageManager.runSilent} build`)\n .replace(/^smt /, 'skuba ')\n .trim(),\n )\n .filter(Boolean)\n .join(' && ');\n\n // Align with the required syntax for package.json#/paths\n if (outputData.scripts.build === 'skuba build-package') {\n outputData.main = './lib-commonjs/index.js';\n outputData.module = './lib-es2015/index.js';\n outputData.types = './lib-types/index.d.ts';\n } else {\n outputData.main = './lib/index.js';\n outputData.module = './lib/index.js';\n outputData.types = './lib/index.d.ts';\n }\n\n delete outputData.scripts.prepublish;\n delete outputData.scripts.prerelease;\n }\n\n return outputData;\n })(inputFile),\n };\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAgC;AAChC,yBAA4B;AAC5B,qBAA4B;AAC5B,oBAAsB;AAGtB,MAAM,wBAAwB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,MAAM,gBAAgB,OAAO;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,MAAgC;AAC9B,QAAM,UAAU,UAAM,gCAAgB;AAEtC,QAAM,cAAc;AAAA,IAClB,SAAS,SAAS;AAAA,IAElB,SAAS;AAAA,MACP,OAAO,SAAS,YAAY,wBAAwB;AAAA,MACpD,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,GAAI,SAAS,YAAY,CAAC,IAAI,EAAE,OAAO,cAAc;AAAA,MACrD,MAAM;AAAA,MACN,cAAc;AAAA,IAChB;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAG,gCAAY,cAAc,mBAAmB;AAAA,IAEhD,gBAAgB,CAAC,kBACf,4BAAY,CAAC,cAAc;AACzB,YAAM,iBAAa;AAAA,QACjB;AAAA,QACA,WAAW,YAAY,gBAAgB;AAAA,MACzC;AAEA,iBAAW,YAAY;AACvB,iBAAW,YAAY,CAAC;AAGxB,UAAI,WAAW,cAAc,CAAC,WAAW,SAAS;AAChD,mBAAW,UAAU;AAAA,MACvB;AAEA,aAAO,WAAW,QAAQ;AAC1B,aAAO,WAAW,QAAQ,cAAc;AACxC,aAAO,WAAW,QAAQ,YAAY;AACtC,aAAO,WAAW,QAAQ,cAAc;AACxC,aAAO,WAAW,QAAQ,aAAa;AACvC,aAAO,WAAW,QAAQ,eAAe;AACzC,aAAO,WAAW,QAAQ,aAAa;AACvC,aAAO,WAAW,QAAQ,YAAY;AACtC,aAAO,WAAW,QAAQ,WAAW;AACrC,aAAO,WAAW;AAElB,UAAI,SAAS,WAAW;AACtB,mBAAW,SACT,WAAW,SAAS,uBACpB;AAAA,UAAQ,CAAC,gBACT,gBAAgB,QAAQ,wBAAwB,CAAC,WAAW;AAAA,QAC9D;AAEA,mBAAW,YAAY;AAIvB,mBAAW,QAAQ,UAAU;AAAA,UAC3B,WAAW,QAAQ;AAAA,UACnB,WAAW,QAAQ;AAAA,UACnB,WAAW,QAAQ,WAAW;AAAA,QAChC,EACG,OAAO,CAAC,WAA6B,OAAO,WAAW,QAAQ,EAC/D;AAAA,UAAI,CAAC,WACJ,OACG,QAAQ,eAAe,GAAG,eAAe,SAAS,QAAQ,EAC1D,QAAQ,SAAS,QAAQ,EACzB,KAAK;AAAA,QACV,EACC,OAAO,OAAO,EACd,KAAK,MAAM;AAGd,YAAI,WAAW,QAAQ,UAAU,uBAAuB;AACtD,qBAAW,OAAO;AAClB,qBAAW,SAAS;AACpB,qBAAW,QAAQ;AAAA,QACrB,OAAO;AACL,qBAAW,OAAO;AAClB,qBAAW,SAAS;AACpB,qBAAW,QAAQ;AAAA,QACrB;AAEA,eAAO,WAAW,QAAQ;AAC1B,eAAO,WAAW,QAAQ;AAAA,MAC5B;AAEA,aAAO;AAAA,IACT,CAAC,EAAE,SAAS;AAAA,EAChB;AACF;",
4
+ "sourcesContent": ["import { getSkubaVersion } from '../../../utils/version';\nimport { deleteFiles } from '../processing/deleteFiles';\nimport { withPackage } from '../processing/package';\nimport { merge } from '../processing/record';\nimport type { Module, Options } from '../types';\n\nconst DEFAULT_PACKAGE_FILES = [\n 'lib*/**/*.d.ts',\n 'lib*/**/*.js',\n 'lib*/**/*.js.map',\n 'lib*/**/*.json',\n];\n\nexport const packageModule = async ({\n entryPoint,\n packageManager,\n type,\n}: Options): Promise<Module> => {\n const version = await getSkubaVersion();\n\n const initialData = {\n private: type !== 'package',\n\n scripts: {\n build: type === 'package' ? 'skuba build-package' : 'skuba build',\n format: 'skuba format',\n lint: 'skuba lint',\n ...(type === 'package' ? {} : { start: 'skuba start' }),\n test: 'skuba test --coverage',\n 'test:watch': 'skuba test --watch',\n },\n skuba: {\n entryPoint,\n template: null,\n type,\n version,\n },\n };\n\n const recurringData = {\n skuba: {\n entryPoint,\n type,\n version,\n },\n };\n\n return {\n ...deleteFiles('.npmignore', 'package-lock.json'),\n\n 'package.json': (inputFile) =>\n withPackage((inputData) => {\n const outputData = merge(\n inputData,\n 'skuba' in inputData ? recurringData : initialData,\n );\n\n outputData.license ??= 'UNLICENSED';\n outputData.scripts ??= {};\n\n // Workspaces can only be enabled in private projects\n if (outputData.workspaces && !outputData.private) {\n outputData.private = true;\n }\n\n delete outputData.scripts.commit;\n delete outputData.scripts['format:check'];\n delete outputData.scripts['lint:build'];\n delete outputData.scripts['lint:compile'];\n delete outputData.scripts['lint:eslint'];\n delete outputData.scripts['lint:prettier'];\n delete outputData.scripts['lint:tslint'];\n delete outputData.scripts['test:build'];\n delete outputData.scripts['test:jest'];\n delete outputData.typings;\n\n if (type === 'package') {\n outputData.files = (\n outputData.files ?? DEFAULT_PACKAGE_FILES\n ).flatMap((filePattern) =>\n filePattern === 'lib' ? DEFAULT_PACKAGE_FILES : [filePattern],\n );\n\n outputData.version ??= '0.0.0-semantically-released';\n\n // User-defined pre- and post-scripts are confusing and dropped by e.g.\n // Yarn 2.\n outputData.scripts.release = [\n outputData.scripts.prepublish,\n outputData.scripts.prerelease,\n outputData.scripts.release ?? 'skuba release',\n ]\n .filter((script): script is string => typeof script === 'string')\n .map((script) =>\n script\n .replace(\n /^smt build$/,\n `${packageManager.print.runSilent} build`,\n )\n .replace(/^smt /, 'skuba ')\n .trim(),\n )\n .filter(Boolean)\n .join(' && ');\n\n // Align with the required syntax for package.json#/paths\n if (outputData.scripts.build === 'skuba build-package') {\n outputData.main = './lib-commonjs/index.js';\n outputData.module = './lib-es2015/index.js';\n outputData.types = './lib-types/index.d.ts';\n } else {\n outputData.main = './lib/index.js';\n outputData.module = './lib/index.js';\n outputData.types = './lib/index.d.ts';\n }\n\n delete outputData.scripts.prepublish;\n delete outputData.scripts.prerelease;\n }\n\n return outputData;\n })(inputFile),\n };\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAgC;AAChC,yBAA4B;AAC5B,qBAA4B;AAC5B,oBAAsB;AAGtB,MAAM,wBAAwB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,MAAM,gBAAgB,OAAO;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,MAAgC;AAC9B,QAAM,UAAU,UAAM,gCAAgB;AAEtC,QAAM,cAAc;AAAA,IAClB,SAAS,SAAS;AAAA,IAElB,SAAS;AAAA,MACP,OAAO,SAAS,YAAY,wBAAwB;AAAA,MACpD,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,GAAI,SAAS,YAAY,CAAC,IAAI,EAAE,OAAO,cAAc;AAAA,MACrD,MAAM;AAAA,MACN,cAAc;AAAA,IAChB;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAG,gCAAY,cAAc,mBAAmB;AAAA,IAEhD,gBAAgB,CAAC,kBACf,4BAAY,CAAC,cAAc;AACzB,YAAM,iBAAa;AAAA,QACjB;AAAA,QACA,WAAW,YAAY,gBAAgB;AAAA,MACzC;AAEA,iBAAW,YAAY;AACvB,iBAAW,YAAY,CAAC;AAGxB,UAAI,WAAW,cAAc,CAAC,WAAW,SAAS;AAChD,mBAAW,UAAU;AAAA,MACvB;AAEA,aAAO,WAAW,QAAQ;AAC1B,aAAO,WAAW,QAAQ,cAAc;AACxC,aAAO,WAAW,QAAQ,YAAY;AACtC,aAAO,WAAW,QAAQ,cAAc;AACxC,aAAO,WAAW,QAAQ,aAAa;AACvC,aAAO,WAAW,QAAQ,eAAe;AACzC,aAAO,WAAW,QAAQ,aAAa;AACvC,aAAO,WAAW,QAAQ,YAAY;AACtC,aAAO,WAAW,QAAQ,WAAW;AACrC,aAAO,WAAW;AAElB,UAAI,SAAS,WAAW;AACtB,mBAAW,SACT,WAAW,SAAS,uBACpB;AAAA,UAAQ,CAAC,gBACT,gBAAgB,QAAQ,wBAAwB,CAAC,WAAW;AAAA,QAC9D;AAEA,mBAAW,YAAY;AAIvB,mBAAW,QAAQ,UAAU;AAAA,UAC3B,WAAW,QAAQ;AAAA,UACnB,WAAW,QAAQ;AAAA,UACnB,WAAW,QAAQ,WAAW;AAAA,QAChC,EACG,OAAO,CAAC,WAA6B,OAAO,WAAW,QAAQ,EAC/D;AAAA,UAAI,CAAC,WACJ,OACG;AAAA,YACC;AAAA,YACA,GAAG,eAAe,MAAM,SAAS;AAAA,UACnC,EACC,QAAQ,SAAS,QAAQ,EACzB,KAAK;AAAA,QACV,EACC,OAAO,OAAO,EACd,KAAK,MAAM;AAGd,YAAI,WAAW,QAAQ,UAAU,uBAAuB;AACtD,qBAAW,OAAO;AAClB,qBAAW,SAAS;AACpB,qBAAW,QAAQ;AAAA,QACrB,OAAO;AACL,qBAAW,OAAO;AAClB,qBAAW,SAAS;AACpB,qBAAW,QAAQ;AAAA,QACrB;AAEA,eAAO,WAAW,QAAQ;AAC1B,eAAO,WAAW,QAAQ;AAAA,MAC5B;AAEA,aAAO;AAAA,IACT,CAAC,EAAE,SAAS;AAAA,EAChB;AACF;",
6
6
  "names": []
7
7
  }
@@ -118,7 +118,7 @@ const cloneTemplate = async (templateName, destinationDir) => {
118
118
  import_logging.log.warn(
119
119
  "You may need to run",
120
120
  import_logging.log.bold(
121
- (0, import_packageManager.configForPackageManager)(templateConfig.packageManager).exec,
121
+ (0, import_packageManager.configForPackageManager)(templateConfig.packageManager).print.exec,
122
122
  "skuba",
123
123
  "configure"
124
124
  ),
@@ -225,7 +225,7 @@ const configureFromPrompt = async () => {
225
225
  import_logging.log.newline();
226
226
  import_logging.log.warn(
227
227
  `Resume this later with ${import_chalk.default.bold(
228
- (0, import_packageManager.configForPackageManager)(packageManager).exec,
228
+ (0, import_packageManager.configForPackageManager)(packageManager).print.exec,
229
229
  "skuba configure"
230
230
  )}.`
231
231
  );
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/init/getConfig.ts"],
4
- "sourcesContent": ["import path from 'path';\n\nimport chalk from 'chalk';\nimport { Form, type FormChoice } from 'enquirer';\nimport fs from 'fs-extra';\n\nimport { copyFiles } from '../../utils/copy';\nimport { isErrorWithCode } from '../../utils/error';\nimport { log } from '../../utils/logging';\nimport {\n DEFAULT_PACKAGE_MANAGER,\n configForPackageManager,\n} from '../../utils/packageManager';\nimport { getRandomPort } from '../../utils/port';\nimport {\n TEMPLATE_CONFIG_FILENAME,\n TEMPLATE_DIR,\n type TemplateConfig,\n templateConfigSchema,\n} from '../../utils/template';\n\nimport { downloadGitHubTemplate } from './git';\nimport {\n BASE_PROMPT_PROPS,\n type BaseFields,\n type Choice,\n GIT_PATH_PROMPT,\n SHOULD_CONTINUE_PROMPT,\n TEMPLATE_PROMPT,\n} from './prompts';\nimport { type InitConfig, initConfigInputSchema } from './types';\n\nexport const runForm = <T = Record<string, string>>(props: {\n choices: readonly Choice[];\n message: string;\n name: string;\n}) => {\n const { message, name } = props;\n\n const choices = props.choices.map((choice) => ({\n ...choice,\n validate: (value: string | undefined) => {\n if (\n !value ||\n value === '' ||\n (value === choice.initial && !choice.allowInitial)\n ) {\n return 'Form is not complete';\n }\n\n return choice.validate?.(value) ?? true;\n },\n }));\n\n const form = new Form<T>({\n choices,\n message,\n name,\n validate: async (values) => {\n const results = await Promise.all(\n choices.map((choice) => choice.validate(values[choice.name])),\n );\n\n return (\n results.find((result) => typeof result === 'string') ??\n results.every((result) => result === true)\n );\n },\n });\n\n return form.run();\n};\n\nconst confirmShouldContinue = async (choices: readonly FormChoice[]) => {\n const fieldsList = choices.map((choice) => choice.message);\n\n log.newline();\n log.plain('This template uses the following information:');\n log.newline();\n fieldsList.forEach((message) => log.subtle(`- ${message}`));\n\n log.newline();\n const result = await SHOULD_CONTINUE_PROMPT.run();\n\n return result === 'yes';\n};\n\nconst createDirectory = async (dir: string) => {\n try {\n await fs.promises.mkdir(dir);\n } catch (err) {\n if (isErrorWithCode(err, 'EEXIST')) {\n log.err(`The directory '${dir}' already exists.`);\n process.exit(1);\n }\n\n throw err;\n }\n};\n\nconst cloneTemplate = async (\n templateName: string,\n destinationDir: string,\n): Promise<TemplateConfig> => {\n const isCustomTemplate = templateName.startsWith('github:');\n\n if (isCustomTemplate) {\n const gitHubPath = templateName.slice('github:'.length);\n\n await downloadGitHubTemplate(gitHubPath, destinationDir);\n } else {\n const templateDir = path.join(TEMPLATE_DIR, templateName);\n\n await copyFiles({\n // assume built-in templates have no extraneous files\n include: () => true,\n sourceRoot: templateDir,\n destinationRoot: destinationDir,\n processors: [],\n // built-in templates have files like _package.json\n stripUnderscorePrefix: true,\n });\n }\n\n const templateConfig = getTemplateConfig(\n path.join(process.cwd(), destinationDir),\n );\n\n if (isCustomTemplate) {\n log.newline();\n log.warn(\n 'You may need to run',\n log.bold(\n configForPackageManager(templateConfig.packageManager).exec,\n 'skuba',\n 'configure',\n ),\n 'once this is done.',\n );\n }\n\n return templateConfig;\n};\n\nconst getTemplateName = async () => {\n const templateSelection = await TEMPLATE_PROMPT.run();\n\n if (templateSelection === 'github \u2192') {\n const gitHubPath = await GIT_PATH_PROMPT.run();\n return `github:${gitHubPath}`;\n }\n\n return templateSelection;\n};\n\nconst generatePlaceholders = (choices: FormChoice[]) =>\n Object.fromEntries(\n choices.map(({ name }) => [name, `<%- ${name} %>`] as const),\n );\n\nexport const getTemplateConfig = (dir: string): TemplateConfig => {\n const templateConfigPath = path.join(dir, TEMPLATE_CONFIG_FILENAME);\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const templateConfig = require(templateConfigPath) as unknown;\n\n return templateConfigSchema.parse(templateConfig);\n } catch (err) {\n if (isErrorWithCode(err, 'MODULE_NOT_FOUND')) {\n return {\n entryPoint: undefined,\n fields: [],\n packageManager: DEFAULT_PACKAGE_MANAGER,\n type: undefined,\n };\n }\n\n throw err;\n }\n};\n\nconst baseToTemplateData = async ({\n ownerName,\n platformName,\n repoName,\n defaultBranch,\n}: BaseFields) => {\n const [orgName, teamName] = ownerName.split('/');\n\n const port = String(await getRandomPort());\n\n if (!orgName) {\n throw new Error(`Invalid format for owner name: ${ownerName}`);\n }\n\n return {\n orgName,\n ownerName,\n repoName,\n defaultBranch,\n // Use standalone username in `teamName` contexts\n teamName: teamName ?? orgName,\n\n port,\n\n platformName,\n lambdaCdkArchitecture: platformName === 'amd64' ? 'X86_64' : 'ARM_64',\n lambdaServerlessArchitecture:\n platformName === 'amd64' ? 'x86_64' : platformName,\n };\n};\n\nexport const configureFromPrompt = async (): Promise<InitConfig> => {\n const { ownerName, platformName, repoName, defaultBranch } =\n await runForm<BaseFields>(BASE_PROMPT_PROPS);\n log.plain(chalk.cyan(repoName), 'by', chalk.cyan(ownerName));\n\n const templateData = await baseToTemplateData({\n ownerName,\n platformName,\n repoName,\n defaultBranch,\n });\n\n const destinationDir = repoName;\n\n await createDirectory(destinationDir);\n\n log.newline();\n const templateName = await getTemplateName();\n\n const { entryPoint, fields, noSkip, packageManager, type } =\n await cloneTemplate(templateName, destinationDir);\n\n if (fields.length === 0) {\n return {\n destinationDir,\n entryPoint,\n packageManager,\n templateComplete: true,\n templateData,\n templateName,\n type,\n };\n }\n\n const shouldContinue = noSkip ? true : await confirmShouldContinue(fields);\n\n if (shouldContinue) {\n log.newline();\n const customAnswers = await runForm({\n choices: fields,\n message: chalk.bold(`Complete ${chalk.cyan(templateName)}:`),\n name: 'customAnswers',\n });\n\n return {\n destinationDir,\n entryPoint,\n packageManager,\n templateComplete: true,\n templateData: { ...templateData, ...customAnswers },\n templateName,\n type,\n };\n }\n\n log.newline();\n log.warn(\n `Resume this later with ${chalk.bold(\n configForPackageManager(packageManager).exec,\n 'skuba configure',\n )}.`,\n );\n\n const customAnswers = generatePlaceholders(fields);\n\n return {\n destinationDir,\n entryPoint,\n packageManager,\n templateComplete: false,\n templateData: { ...templateData, ...customAnswers },\n templateName,\n type,\n };\n};\n\nexport const readJSONFromStdIn = async () => {\n let text = '';\n\n await new Promise((resolve) =>\n process.stdin\n .on('data', (chunk) => (text += chunk.toString()))\n .once('end', resolve),\n );\n\n text = text.trim();\n\n if (text === '') {\n log.err('No data from stdin.');\n process.exit(1);\n }\n\n let value: unknown;\n\n try {\n value = JSON.parse(text) as unknown;\n } catch {\n log.err('Invalid JSON from stdin.');\n process.exit(1);\n }\n\n return value;\n};\n\nconst configureFromPipe = async (): Promise<InitConfig> => {\n const value = await readJSONFromStdIn();\n\n const result = initConfigInputSchema.safeParse(value);\n\n if (!result.success) {\n log.err('Invalid data from stdin:');\n log.err(result.error);\n process.exit(1);\n }\n\n const { destinationDir, templateComplete, templateName } = result.data;\n\n const templateData = {\n ...(await baseToTemplateData(result.data.templateData)),\n ...result.data.templateData,\n };\n\n await createDirectory(destinationDir);\n\n const { entryPoint, fields, noSkip, packageManager, type } =\n await cloneTemplate(templateName, destinationDir);\n\n if (!templateComplete) {\n if (noSkip) {\n log.err('Templating for', log.bold(templateName), 'cannot be skipped.');\n process.exit(1);\n }\n\n return {\n ...result.data,\n entryPoint,\n packageManager,\n templateData: {\n ...templateData,\n ...generatePlaceholders(fields),\n },\n type,\n };\n }\n\n const required = fields.map(({ name }) => name);\n\n const provided = new Set(Object.keys(templateData));\n\n const missing = required.filter((name) => !provided.has(name));\n\n if (missing.length > 0) {\n log.err('This template uses the following information:');\n log.newline();\n missing.forEach((name) => log.err(`- ${name}`));\n process.exit(1);\n }\n\n return {\n ...result.data,\n entryPoint,\n packageManager,\n templateData,\n type,\n };\n};\n\nexport const getConfig = () =>\n process.stdin.isTTY ? configureFromPrompt() : configureFromPipe();\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import path from 'path';\n\nimport chalk from 'chalk';\nimport { Form, type FormChoice } from 'enquirer';\nimport fs from 'fs-extra';\n\nimport { copyFiles } from '../../utils/copy';\nimport { isErrorWithCode } from '../../utils/error';\nimport { log } from '../../utils/logging';\nimport {\n DEFAULT_PACKAGE_MANAGER,\n configForPackageManager,\n} from '../../utils/packageManager';\nimport { getRandomPort } from '../../utils/port';\nimport {\n TEMPLATE_CONFIG_FILENAME,\n TEMPLATE_DIR,\n type TemplateConfig,\n templateConfigSchema,\n} from '../../utils/template';\n\nimport { downloadGitHubTemplate } from './git';\nimport {\n BASE_PROMPT_PROPS,\n type BaseFields,\n type Choice,\n GIT_PATH_PROMPT,\n SHOULD_CONTINUE_PROMPT,\n TEMPLATE_PROMPT,\n} from './prompts';\nimport { type InitConfig, initConfigInputSchema } from './types';\n\nexport const runForm = <T = Record<string, string>>(props: {\n choices: readonly Choice[];\n message: string;\n name: string;\n}) => {\n const { message, name } = props;\n\n const choices = props.choices.map((choice) => ({\n ...choice,\n validate: (value: string | undefined) => {\n if (\n !value ||\n value === '' ||\n (value === choice.initial && !choice.allowInitial)\n ) {\n return 'Form is not complete';\n }\n\n return choice.validate?.(value) ?? true;\n },\n }));\n\n const form = new Form<T>({\n choices,\n message,\n name,\n validate: async (values) => {\n const results = await Promise.all(\n choices.map((choice) => choice.validate(values[choice.name])),\n );\n\n return (\n results.find((result) => typeof result === 'string') ??\n results.every((result) => result === true)\n );\n },\n });\n\n return form.run();\n};\n\nconst confirmShouldContinue = async (choices: readonly FormChoice[]) => {\n const fieldsList = choices.map((choice) => choice.message);\n\n log.newline();\n log.plain('This template uses the following information:');\n log.newline();\n fieldsList.forEach((message) => log.subtle(`- ${message}`));\n\n log.newline();\n const result = await SHOULD_CONTINUE_PROMPT.run();\n\n return result === 'yes';\n};\n\nconst createDirectory = async (dir: string) => {\n try {\n await fs.promises.mkdir(dir);\n } catch (err) {\n if (isErrorWithCode(err, 'EEXIST')) {\n log.err(`The directory '${dir}' already exists.`);\n process.exit(1);\n }\n\n throw err;\n }\n};\n\nconst cloneTemplate = async (\n templateName: string,\n destinationDir: string,\n): Promise<TemplateConfig> => {\n const isCustomTemplate = templateName.startsWith('github:');\n\n if (isCustomTemplate) {\n const gitHubPath = templateName.slice('github:'.length);\n\n await downloadGitHubTemplate(gitHubPath, destinationDir);\n } else {\n const templateDir = path.join(TEMPLATE_DIR, templateName);\n\n await copyFiles({\n // assume built-in templates have no extraneous files\n include: () => true,\n sourceRoot: templateDir,\n destinationRoot: destinationDir,\n processors: [],\n // built-in templates have files like _package.json\n stripUnderscorePrefix: true,\n });\n }\n\n const templateConfig = getTemplateConfig(\n path.join(process.cwd(), destinationDir),\n );\n\n if (isCustomTemplate) {\n log.newline();\n log.warn(\n 'You may need to run',\n log.bold(\n configForPackageManager(templateConfig.packageManager).print.exec,\n 'skuba',\n 'configure',\n ),\n 'once this is done.',\n );\n }\n\n return templateConfig;\n};\n\nconst getTemplateName = async () => {\n const templateSelection = await TEMPLATE_PROMPT.run();\n\n if (templateSelection === 'github \u2192') {\n const gitHubPath = await GIT_PATH_PROMPT.run();\n return `github:${gitHubPath}`;\n }\n\n return templateSelection;\n};\n\nconst generatePlaceholders = (choices: FormChoice[]) =>\n Object.fromEntries(\n choices.map(({ name }) => [name, `<%- ${name} %>`] as const),\n );\n\nexport const getTemplateConfig = (dir: string): TemplateConfig => {\n const templateConfigPath = path.join(dir, TEMPLATE_CONFIG_FILENAME);\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const templateConfig = require(templateConfigPath) as unknown;\n\n return templateConfigSchema.parse(templateConfig);\n } catch (err) {\n if (isErrorWithCode(err, 'MODULE_NOT_FOUND')) {\n return {\n entryPoint: undefined,\n fields: [],\n packageManager: DEFAULT_PACKAGE_MANAGER,\n type: undefined,\n };\n }\n\n throw err;\n }\n};\n\nconst baseToTemplateData = async ({\n ownerName,\n platformName,\n repoName,\n defaultBranch,\n}: BaseFields) => {\n const [orgName, teamName] = ownerName.split('/');\n\n const port = String(await getRandomPort());\n\n if (!orgName) {\n throw new Error(`Invalid format for owner name: ${ownerName}`);\n }\n\n return {\n orgName,\n ownerName,\n repoName,\n defaultBranch,\n // Use standalone username in `teamName` contexts\n teamName: teamName ?? orgName,\n\n port,\n\n platformName,\n lambdaCdkArchitecture: platformName === 'amd64' ? 'X86_64' : 'ARM_64',\n lambdaServerlessArchitecture:\n platformName === 'amd64' ? 'x86_64' : platformName,\n };\n};\n\nexport const configureFromPrompt = async (): Promise<InitConfig> => {\n const { ownerName, platformName, repoName, defaultBranch } =\n await runForm<BaseFields>(BASE_PROMPT_PROPS);\n log.plain(chalk.cyan(repoName), 'by', chalk.cyan(ownerName));\n\n const templateData = await baseToTemplateData({\n ownerName,\n platformName,\n repoName,\n defaultBranch,\n });\n\n const destinationDir = repoName;\n\n await createDirectory(destinationDir);\n\n log.newline();\n const templateName = await getTemplateName();\n\n const { entryPoint, fields, noSkip, packageManager, type } =\n await cloneTemplate(templateName, destinationDir);\n\n if (fields.length === 0) {\n return {\n destinationDir,\n entryPoint,\n packageManager,\n templateComplete: true,\n templateData,\n templateName,\n type,\n };\n }\n\n const shouldContinue = noSkip ? true : await confirmShouldContinue(fields);\n\n if (shouldContinue) {\n log.newline();\n const customAnswers = await runForm({\n choices: fields,\n message: chalk.bold(`Complete ${chalk.cyan(templateName)}:`),\n name: 'customAnswers',\n });\n\n return {\n destinationDir,\n entryPoint,\n packageManager,\n templateComplete: true,\n templateData: { ...templateData, ...customAnswers },\n templateName,\n type,\n };\n }\n\n log.newline();\n log.warn(\n `Resume this later with ${chalk.bold(\n configForPackageManager(packageManager).print.exec,\n 'skuba configure',\n )}.`,\n );\n\n const customAnswers = generatePlaceholders(fields);\n\n return {\n destinationDir,\n entryPoint,\n packageManager,\n templateComplete: false,\n templateData: { ...templateData, ...customAnswers },\n templateName,\n type,\n };\n};\n\nexport const readJSONFromStdIn = async () => {\n let text = '';\n\n await new Promise((resolve) =>\n process.stdin\n .on('data', (chunk) => (text += chunk.toString()))\n .once('end', resolve),\n );\n\n text = text.trim();\n\n if (text === '') {\n log.err('No data from stdin.');\n process.exit(1);\n }\n\n let value: unknown;\n\n try {\n value = JSON.parse(text) as unknown;\n } catch {\n log.err('Invalid JSON from stdin.');\n process.exit(1);\n }\n\n return value;\n};\n\nconst configureFromPipe = async (): Promise<InitConfig> => {\n const value = await readJSONFromStdIn();\n\n const result = initConfigInputSchema.safeParse(value);\n\n if (!result.success) {\n log.err('Invalid data from stdin:');\n log.err(result.error);\n process.exit(1);\n }\n\n const { destinationDir, templateComplete, templateName } = result.data;\n\n const templateData = {\n ...(await baseToTemplateData(result.data.templateData)),\n ...result.data.templateData,\n };\n\n await createDirectory(destinationDir);\n\n const { entryPoint, fields, noSkip, packageManager, type } =\n await cloneTemplate(templateName, destinationDir);\n\n if (!templateComplete) {\n if (noSkip) {\n log.err('Templating for', log.bold(templateName), 'cannot be skipped.');\n process.exit(1);\n }\n\n return {\n ...result.data,\n entryPoint,\n packageManager,\n templateData: {\n ...templateData,\n ...generatePlaceholders(fields),\n },\n type,\n };\n }\n\n const required = fields.map(({ name }) => name);\n\n const provided = new Set(Object.keys(templateData));\n\n const missing = required.filter((name) => !provided.has(name));\n\n if (missing.length > 0) {\n log.err('This template uses the following information:');\n log.newline();\n missing.forEach((name) => log.err(`- ${name}`));\n process.exit(1);\n }\n\n return {\n ...result.data,\n entryPoint,\n packageManager,\n templateData,\n type,\n };\n};\n\nexport const getConfig = () =>\n process.stdin.isTTY ? configureFromPrompt() : configureFromPipe();\n"],
5
+ "mappings": "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",
6
6
  "names": ["fs", "path", "chalk", "customAnswers"]
7
7
  }
@@ -62,7 +62,7 @@ const lint = async (args = process.argv.slice(2), tscWriteable = void 0, workerT
62
62
  import_logging.log.newline();
63
63
  import_logging.log.warn(
64
64
  `Try running ${import_logging.log.bold(
65
- packageManager.exec,
65
+ packageManager.print.exec,
66
66
  "skuba",
67
67
  "format"
68
68
  )} to fix them.`
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/lint/index.ts"],
4
- "sourcesContent": ["import type { Writable } from 'stream';\nimport { inspect } from 'util';\n\nimport { hasDebugFlag, hasSerialFlag } from '../../utils/args';\nimport { log } from '../../utils/logging';\nimport { detectPackageManager } from '../../utils/packageManager';\nimport { throwOnTimeout } from '../../utils/wait';\n\nimport { createAnnotations } from './annotate';\nimport { autofix } from './autofix';\nimport { externalLint } from './external';\nimport { internalLint } from './internal';\nimport type { Input } from './types';\n\nexport const lint = async (\n args = process.argv.slice(2),\n tscWriteable: Writable | undefined = undefined,\n workerThreads = true,\n) => {\n const opts: Input = {\n debug: hasDebugFlag(args),\n serial: hasSerialFlag(args),\n tscOutputStream: tscWriteable,\n workerThreads,\n };\n\n const { eslint, prettier, tscOk, tscOutputStream } = await externalLint(opts);\n const internal = await internalLint('lint', opts);\n\n try {\n await throwOnTimeout(\n createAnnotations(internal, eslint, prettier, tscOk, tscOutputStream),\n { s: 30 },\n );\n } catch (err) {\n log.warn('Failed to annotate lint results.');\n log.subtle(inspect(err));\n }\n\n if (!internal.ok || !eslint.ok || !prettier.ok || !tscOk) {\n process.exitCode = 1;\n\n const tools = [\n ...(internal.ok ? [] : ['skuba']),\n ...(eslint.ok ? [] : ['ESLint']),\n ...(prettier.ok ? [] : ['Prettier']),\n ...(tscOk ? [] : ['tsc']),\n ];\n\n log.err(`${tools.join(', ')} found issues that require triage.`);\n\n if (internal.fixable || eslint.fixable || !prettier.ok) {\n const packageManager = await detectPackageManager();\n log.newline();\n log.warn(\n `Try running ${log.bold(\n packageManager.exec,\n 'skuba',\n 'format',\n )} to fix them.`,\n );\n }\n }\n\n await autofix({\n debug: opts.debug,\n eslint: eslint.fixable,\n prettier: !prettier.ok,\n internal: internal.fixable,\n });\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAwB;AAExB,kBAA4C;AAC5C,qBAAoB;AACpB,4BAAqC;AACrC,kBAA+B;AAE/B,sBAAkC;AAClC,qBAAwB;AACxB,sBAA6B;AAC7B,sBAA6B;AAGtB,MAAM,OAAO,OAClB,OAAO,QAAQ,KAAK,MAAM,CAAC,GAC3B,eAAqC,QACrC,gBAAgB,SACb;AACH,QAAM,OAAc;AAAA,IAClB,WAAO,0BAAa,IAAI;AAAA,IACxB,YAAQ,2BAAc,IAAI;AAAA,IAC1B,iBAAiB;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,EAAE,QAAQ,UAAU,OAAO,gBAAgB,IAAI,UAAM,8BAAa,IAAI;AAC5E,QAAM,WAAW,UAAM,8BAAa,QAAQ,IAAI;AAEhD,MAAI;AACF,cAAM;AAAA,UACJ,mCAAkB,UAAU,QAAQ,UAAU,OAAO,eAAe;AAAA,MACpE,EAAE,GAAG,GAAG;AAAA,IACV;AAAA,EACF,SAAS,KAAK;AACZ,uBAAI,KAAK,kCAAkC;AAC3C,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AAAA,EACzB;AAEA,MAAI,CAAC,SAAS,MAAM,CAAC,OAAO,MAAM,CAAC,SAAS,MAAM,CAAC,OAAO;AACxD,YAAQ,WAAW;AAEnB,UAAM,QAAQ;AAAA,MACZ,GAAI,SAAS,KAAK,CAAC,IAAI,CAAC,OAAO;AAAA,MAC/B,GAAI,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ;AAAA,MAC9B,GAAI,SAAS,KAAK,CAAC,IAAI,CAAC,UAAU;AAAA,MAClC,GAAI,QAAQ,CAAC,IAAI,CAAC,KAAK;AAAA,IACzB;AAEA,uBAAI,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC,oCAAoC;AAE/D,QAAI,SAAS,WAAW,OAAO,WAAW,CAAC,SAAS,IAAI;AACtD,YAAM,iBAAiB,UAAM,4CAAqB;AAClD,yBAAI,QAAQ;AACZ,yBAAI;AAAA,QACF,eAAe,mBAAI;AAAA,UACjB,eAAe;AAAA,UACf;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,YAAM,wBAAQ;AAAA,IACZ,OAAO,KAAK;AAAA,IACZ,QAAQ,OAAO;AAAA,IACf,UAAU,CAAC,SAAS;AAAA,IACpB,UAAU,SAAS;AAAA,EACrB,CAAC;AACH;",
4
+ "sourcesContent": ["import type { Writable } from 'stream';\nimport { inspect } from 'util';\n\nimport { hasDebugFlag, hasSerialFlag } from '../../utils/args';\nimport { log } from '../../utils/logging';\nimport { detectPackageManager } from '../../utils/packageManager';\nimport { throwOnTimeout } from '../../utils/wait';\n\nimport { createAnnotations } from './annotate';\nimport { autofix } from './autofix';\nimport { externalLint } from './external';\nimport { internalLint } from './internal';\nimport type { Input } from './types';\n\nexport const lint = async (\n args = process.argv.slice(2),\n tscWriteable: Writable | undefined = undefined,\n workerThreads = true,\n) => {\n const opts: Input = {\n debug: hasDebugFlag(args),\n serial: hasSerialFlag(args),\n tscOutputStream: tscWriteable,\n workerThreads,\n };\n\n const { eslint, prettier, tscOk, tscOutputStream } = await externalLint(opts);\n const internal = await internalLint('lint', opts);\n\n try {\n await throwOnTimeout(\n createAnnotations(internal, eslint, prettier, tscOk, tscOutputStream),\n { s: 30 },\n );\n } catch (err) {\n log.warn('Failed to annotate lint results.');\n log.subtle(inspect(err));\n }\n\n if (!internal.ok || !eslint.ok || !prettier.ok || !tscOk) {\n process.exitCode = 1;\n\n const tools = [\n ...(internal.ok ? [] : ['skuba']),\n ...(eslint.ok ? [] : ['ESLint']),\n ...(prettier.ok ? [] : ['Prettier']),\n ...(tscOk ? [] : ['tsc']),\n ];\n\n log.err(`${tools.join(', ')} found issues that require triage.`);\n\n if (internal.fixable || eslint.fixable || !prettier.ok) {\n const packageManager = await detectPackageManager();\n log.newline();\n log.warn(\n `Try running ${log.bold(\n packageManager.print.exec,\n 'skuba',\n 'format',\n )} to fix them.`,\n );\n }\n }\n\n await autofix({\n debug: opts.debug,\n eslint: eslint.fixable,\n prettier: !prettier.ok,\n internal: internal.fixable,\n });\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAwB;AAExB,kBAA4C;AAC5C,qBAAoB;AACpB,4BAAqC;AACrC,kBAA+B;AAE/B,sBAAkC;AAClC,qBAAwB;AACxB,sBAA6B;AAC7B,sBAA6B;AAGtB,MAAM,OAAO,OAClB,OAAO,QAAQ,KAAK,MAAM,CAAC,GAC3B,eAAqC,QACrC,gBAAgB,SACb;AACH,QAAM,OAAc;AAAA,IAClB,WAAO,0BAAa,IAAI;AAAA,IACxB,YAAQ,2BAAc,IAAI;AAAA,IAC1B,iBAAiB;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,EAAE,QAAQ,UAAU,OAAO,gBAAgB,IAAI,UAAM,8BAAa,IAAI;AAC5E,QAAM,WAAW,UAAM,8BAAa,QAAQ,IAAI;AAEhD,MAAI;AACF,cAAM;AAAA,UACJ,mCAAkB,UAAU,QAAQ,UAAU,OAAO,eAAe;AAAA,MACpE,EAAE,GAAG,GAAG;AAAA,IACV;AAAA,EACF,SAAS,KAAK;AACZ,uBAAI,KAAK,kCAAkC;AAC3C,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AAAA,EACzB;AAEA,MAAI,CAAC,SAAS,MAAM,CAAC,OAAO,MAAM,CAAC,SAAS,MAAM,CAAC,OAAO;AACxD,YAAQ,WAAW;AAEnB,UAAM,QAAQ;AAAA,MACZ,GAAI,SAAS,KAAK,CAAC,IAAI,CAAC,OAAO;AAAA,MAC/B,GAAI,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ;AAAA,MAC9B,GAAI,SAAS,KAAK,CAAC,IAAI,CAAC,UAAU;AAAA,MAClC,GAAI,QAAQ,CAAC,IAAI,CAAC,KAAK;AAAA,IACzB;AAEA,uBAAI,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC,oCAAoC;AAE/D,QAAI,SAAS,WAAW,OAAO,WAAW,CAAC,SAAS,IAAI;AACtD,YAAM,iBAAiB,UAAM,4CAAqB;AAClD,yBAAI,QAAQ;AACZ,yBAAI;AAAA,QACF,eAAe,mBAAI;AAAA,UACjB,eAAe,MAAM;AAAA,UACrB;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,YAAM,wBAAQ;AAAA,IACZ,OAAO,KAAK;AAAA,IACZ,QAAQ,OAAO;AAAA,IACf,UAAU,CAAC,SAAS;AAAA,IACpB,UAAU,SAAS;AAAA,EACrB,CAAC;AACH;",
6
6
  "names": []
7
7
  }
@@ -34,12 +34,13 @@ module.exports = __toCommonJS(internal_exports);
34
34
  var import_util = require("util");
35
35
  var import_chalk = __toESM(require("chalk"));
36
36
  var import_logging = require("../../utils/logging");
37
+ var import_detectBadCodeowners = require("./internalLints/detectBadCodeowners");
37
38
  var import_noSkubaTemplateJs = require("./internalLints/noSkubaTemplateJs");
38
39
  var import_refreshConfigFiles = require("./internalLints/refreshConfigFiles");
39
40
  var import_upgrade = require("./internalLints/upgrade");
40
41
  const lints = [
41
42
  // Run upgradeSkuba before refreshConfigFiles for npmrc handling
42
- [import_upgrade.upgradeSkuba],
43
+ [import_upgrade.upgradeSkuba, import_detectBadCodeowners.tryDetectBadCodeowners],
43
44
  [import_noSkubaTemplateJs.noSkubaTemplateJs, import_refreshConfigFiles.tryRefreshConfigFiles]
44
45
  ];
45
46
  const lintSerially = async (mode, logger) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/lint/internal.ts"],
4
- "sourcesContent": ["import { inspect } from 'util';\n\nimport chalk from 'chalk';\n\nimport { type Logger, createLogger } from '../../utils/logging';\n\nimport { noSkubaTemplateJs } from './internalLints/noSkubaTemplateJs';\nimport { tryRefreshConfigFiles } from './internalLints/refreshConfigFiles';\nimport { upgradeSkuba } from './internalLints/upgrade';\nimport type { Input } from './types';\n\nexport type InternalLintResult = {\n ok: boolean;\n fixable: boolean;\n annotations?: Array<{\n start_line?: number;\n end_line?: number;\n path: string;\n message: string;\n }>;\n};\n\nconst lints: Array<\n Array<\n (mode: 'format' | 'lint', logger: Logger) => Promise<InternalLintResult>\n >\n> = [\n // Run upgradeSkuba before refreshConfigFiles for npmrc handling\n [upgradeSkuba],\n [noSkubaTemplateJs, tryRefreshConfigFiles],\n];\n\nconst lintSerially = async (mode: 'format' | 'lint', logger: Logger) => {\n const results: InternalLintResult[] = [];\n for (const lintGroup of lints) {\n for (const lint of lintGroup) {\n results.push(await lint(mode, logger));\n }\n }\n return results;\n};\n\nconst lintConcurrently = async (mode: 'format' | 'lint', logger: Logger) => {\n const results: InternalLintResult[] = [];\n\n for (const lintGroup of lints) {\n results.push(\n ...(await Promise.all(lintGroup.map((lint) => lint(mode, logger)))),\n );\n }\n\n return results;\n};\n\nconst selectLintFunction = (input?: Input) => {\n const isSerial = input?.debug || input?.serial;\n return isSerial ? lintSerially : lintConcurrently;\n};\n\nexport const internalLint = async (\n mode: 'format' | 'lint',\n input?: Input,\n): Promise<InternalLintResult> => {\n const start = process.hrtime.bigint();\n const logger = createLogger(\n input?.debug ?? false,\n ...(mode === 'lint' ? [chalk.blueBright('skuba \u2502')] : []),\n );\n\n try {\n const lint = selectLintFunction(input);\n const results = await lint(mode, logger);\n const result = combineResults(results);\n const end = process.hrtime.bigint();\n logger.plain(`Processed skuba lints in ${logger.timing(start, end)}.`);\n return result;\n } catch (err) {\n logger.err(logger.bold('Failed to run skuba lints.'));\n logger.subtle(inspect(err));\n\n process.exitCode = 1;\n\n return { ok: false, fixable: false, annotations: [] };\n }\n};\n\nconst combineResults = (results: InternalLintResult[]): InternalLintResult =>\n results.reduce(\n (cur, next) => ({\n ok: cur.ok && next.ok,\n fixable: cur.fixable || next.fixable,\n annotations: [...(cur.annotations ?? []), ...(next.annotations ?? [])],\n }),\n { ok: true, fixable: false },\n );\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,mBAAkB;AAElB,qBAA0C;AAE1C,+BAAkC;AAClC,gCAAsC;AACtC,qBAA6B;AAc7B,MAAM,QAIF;AAAA;AAAA,EAEF,CAAC,2BAAY;AAAA,EACb,CAAC,4CAAmB,+CAAqB;AAC3C;AAEA,MAAM,eAAe,OAAO,MAAyB,WAAmB;AACtE,QAAM,UAAgC,CAAC;AACvC,aAAW,aAAa,OAAO;AAC7B,eAAW,QAAQ,WAAW;AAC5B,cAAQ,KAAK,MAAM,KAAK,MAAM,MAAM,CAAC;AAAA,IACvC;AAAA,EACF;AACA,SAAO;AACT;AAEA,MAAM,mBAAmB,OAAO,MAAyB,WAAmB;AAC1E,QAAM,UAAgC,CAAC;AAEvC,aAAW,aAAa,OAAO;AAC7B,YAAQ;AAAA,MACN,GAAI,MAAM,QAAQ,IAAI,UAAU,IAAI,CAAC,SAAS,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IACnE;AAAA,EACF;AAEA,SAAO;AACT;AAEA,MAAM,qBAAqB,CAAC,UAAkB;AAC5C,QAAM,WAAW,OAAO,SAAS,OAAO;AACxC,SAAO,WAAW,eAAe;AACnC;AAEO,MAAM,eAAe,OAC1B,MACA,UACgC;AAChC,QAAM,QAAQ,QAAQ,OAAO,OAAO;AACpC,QAAM,aAAS;AAAA,IACb,OAAO,SAAS;AAAA,IAChB,GAAI,SAAS,SAAS,CAAC,aAAAA,QAAM,WAAW,iBAAY,CAAC,IAAI,CAAC;AAAA,EAC5D;AAEA,MAAI;AACF,UAAM,OAAO,mBAAmB,KAAK;AACrC,UAAM,UAAU,MAAM,KAAK,MAAM,MAAM;AACvC,UAAM,SAAS,eAAe,OAAO;AACrC,UAAM,MAAM,QAAQ,OAAO,OAAO;AAClC,WAAO,MAAM,4BAA4B,OAAO,OAAO,OAAO,GAAG,CAAC,GAAG;AACrE,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,WAAO,IAAI,OAAO,KAAK,4BAA4B,CAAC;AACpD,WAAO,WAAO,qBAAQ,GAAG,CAAC;AAE1B,YAAQ,WAAW;AAEnB,WAAO,EAAE,IAAI,OAAO,SAAS,OAAO,aAAa,CAAC,EAAE;AAAA,EACtD;AACF;AAEA,MAAM,iBAAiB,CAAC,YACtB,QAAQ;AAAA,EACN,CAAC,KAAK,UAAU;AAAA,IACd,IAAI,IAAI,MAAM,KAAK;AAAA,IACnB,SAAS,IAAI,WAAW,KAAK;AAAA,IAC7B,aAAa,CAAC,GAAI,IAAI,eAAe,CAAC,GAAI,GAAI,KAAK,eAAe,CAAC,CAAE;AAAA,EACvE;AAAA,EACA,EAAE,IAAI,MAAM,SAAS,MAAM;AAC7B;",
4
+ "sourcesContent": ["import { inspect } from 'util';\n\nimport chalk from 'chalk';\n\nimport { type Logger, createLogger } from '../../utils/logging';\n\nimport { tryDetectBadCodeowners } from './internalLints/detectBadCodeowners';\nimport { noSkubaTemplateJs } from './internalLints/noSkubaTemplateJs';\nimport { tryRefreshConfigFiles } from './internalLints/refreshConfigFiles';\nimport { upgradeSkuba } from './internalLints/upgrade';\nimport type { Input } from './types';\n\nexport type InternalLintResult = {\n ok: boolean;\n fixable: boolean;\n annotations?: Array<{\n start_line?: number;\n end_line?: number;\n path: string;\n message: string;\n }>;\n};\n\nconst lints: Array<\n Array<\n (mode: 'format' | 'lint', logger: Logger) => Promise<InternalLintResult>\n >\n> = [\n // Run upgradeSkuba before refreshConfigFiles for npmrc handling\n [upgradeSkuba, tryDetectBadCodeowners],\n [noSkubaTemplateJs, tryRefreshConfigFiles],\n];\n\nconst lintSerially = async (mode: 'format' | 'lint', logger: Logger) => {\n const results: InternalLintResult[] = [];\n for (const lintGroup of lints) {\n for (const lint of lintGroup) {\n results.push(await lint(mode, logger));\n }\n }\n return results;\n};\n\nconst lintConcurrently = async (mode: 'format' | 'lint', logger: Logger) => {\n const results: InternalLintResult[] = [];\n\n for (const lintGroup of lints) {\n results.push(\n ...(await Promise.all(lintGroup.map((lint) => lint(mode, logger)))),\n );\n }\n\n return results;\n};\n\nconst selectLintFunction = (input?: Input) => {\n const isSerial = input?.debug || input?.serial;\n return isSerial ? lintSerially : lintConcurrently;\n};\n\nexport const internalLint = async (\n mode: 'format' | 'lint',\n input?: Input,\n): Promise<InternalLintResult> => {\n const start = process.hrtime.bigint();\n const logger = createLogger(\n input?.debug ?? false,\n ...(mode === 'lint' ? [chalk.blueBright('skuba \u2502')] : []),\n );\n\n try {\n const lint = selectLintFunction(input);\n const results = await lint(mode, logger);\n const result = combineResults(results);\n const end = process.hrtime.bigint();\n logger.plain(`Processed skuba lints in ${logger.timing(start, end)}.`);\n return result;\n } catch (err) {\n logger.err(logger.bold('Failed to run skuba lints.'));\n logger.subtle(inspect(err));\n\n process.exitCode = 1;\n\n return { ok: false, fixable: false, annotations: [] };\n }\n};\n\nconst combineResults = (results: InternalLintResult[]): InternalLintResult =>\n results.reduce(\n (cur, next) => ({\n ok: cur.ok && next.ok,\n fixable: cur.fixable || next.fixable,\n annotations: [...(cur.annotations ?? []), ...(next.annotations ?? [])],\n }),\n { ok: true, fixable: false },\n );\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,mBAAkB;AAElB,qBAA0C;AAE1C,iCAAuC;AACvC,+BAAkC;AAClC,gCAAsC;AACtC,qBAA6B;AAc7B,MAAM,QAIF;AAAA;AAAA,EAEF,CAAC,6BAAc,iDAAsB;AAAA,EACrC,CAAC,4CAAmB,+CAAqB;AAC3C;AAEA,MAAM,eAAe,OAAO,MAAyB,WAAmB;AACtE,QAAM,UAAgC,CAAC;AACvC,aAAW,aAAa,OAAO;AAC7B,eAAW,QAAQ,WAAW;AAC5B,cAAQ,KAAK,MAAM,KAAK,MAAM,MAAM,CAAC;AAAA,IACvC;AAAA,EACF;AACA,SAAO;AACT;AAEA,MAAM,mBAAmB,OAAO,MAAyB,WAAmB;AAC1E,QAAM,UAAgC,CAAC;AAEvC,aAAW,aAAa,OAAO;AAC7B,YAAQ;AAAA,MACN,GAAI,MAAM,QAAQ,IAAI,UAAU,IAAI,CAAC,SAAS,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,IACnE;AAAA,EACF;AAEA,SAAO;AACT;AAEA,MAAM,qBAAqB,CAAC,UAAkB;AAC5C,QAAM,WAAW,OAAO,SAAS,OAAO;AACxC,SAAO,WAAW,eAAe;AACnC;AAEO,MAAM,eAAe,OAC1B,MACA,UACgC;AAChC,QAAM,QAAQ,QAAQ,OAAO,OAAO;AACpC,QAAM,aAAS;AAAA,IACb,OAAO,SAAS;AAAA,IAChB,GAAI,SAAS,SAAS,CAAC,aAAAA,QAAM,WAAW,iBAAY,CAAC,IAAI,CAAC;AAAA,EAC5D;AAEA,MAAI;AACF,UAAM,OAAO,mBAAmB,KAAK;AACrC,UAAM,UAAU,MAAM,KAAK,MAAM,MAAM;AACvC,UAAM,SAAS,eAAe,OAAO;AACrC,UAAM,MAAM,QAAQ,OAAO,OAAO;AAClC,WAAO,MAAM,4BAA4B,OAAO,OAAO,OAAO,GAAG,CAAC,GAAG;AACrE,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,WAAO,IAAI,OAAO,KAAK,4BAA4B,CAAC;AACpD,WAAO,WAAO,qBAAQ,GAAG,CAAC;AAE1B,YAAQ,WAAW;AAEnB,WAAO,EAAE,IAAI,OAAO,SAAS,OAAO,aAAa,CAAC,EAAE;AAAA,EACtD;AACF;AAEA,MAAM,iBAAiB,CAAC,YACtB,QAAQ;AAAA,EACN,CAAC,KAAK,UAAU;AAAA,IACd,IAAI,IAAI,MAAM,KAAK;AAAA,IACnB,SAAS,IAAI,WAAW,KAAK;AAAA,IAC7B,aAAa,CAAC,GAAI,IAAI,eAAe,CAAC,GAAI,GAAI,KAAK,eAAe,CAAC,CAAE;AAAA,EACvE;AAAA,EACA,EAAE,IAAI,MAAM,SAAS,MAAM;AAC7B;",
6
6
  "names": ["chalk"]
7
7
  }
@@ -0,0 +1,4 @@
1
+ import type { Logger } from '../../../utils/logging';
2
+ import type { InternalLintResult } from '../internal';
3
+ export declare const detectBadCodeowners: () => Promise<InternalLintResult>;
4
+ export declare const tryDetectBadCodeowners: (_mode: "format" | "lint", logger: Logger) => Promise<InternalLintResult>;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var detectBadCodeowners_exports = {};
20
+ __export(detectBadCodeowners_exports, {
21
+ detectBadCodeowners: () => detectBadCodeowners,
22
+ tryDetectBadCodeowners: () => tryDetectBadCodeowners
23
+ });
24
+ module.exports = __toCommonJS(detectBadCodeowners_exports);
25
+ var import_util = require("util");
26
+ var import__ = require("../../..");
27
+ var import_project = require("../../configure/analysis/project");
28
+ const detectBadCodeowners = async () => {
29
+ const gitRoot = await import__.Git.findRoot({ dir: process.cwd() });
30
+ const reader = (0, import_project.createDestinationFileReader)(gitRoot ?? process.cwd());
31
+ const annotations = (await Promise.all(
32
+ [".github/CODEOWNERS", "CODEOWNERS", "docs/CODEOWNERS"].map(
33
+ async (filename) => {
34
+ const lines = (await reader(filename))?.split("\n");
35
+ if (lines?.some((line) => line.startsWith("- "))) {
36
+ return [
37
+ {
38
+ message: "CODEOWNERS file has a line starting with `- `. This is probably an autoformatting mistake, where your editor thinks this file is a markdown file and is trying to format a list item. Did you mean to use `*` instead?",
39
+ path: filename
40
+ }
41
+ ];
42
+ }
43
+ return [];
44
+ }
45
+ )
46
+ )).flat();
47
+ annotations.sort((a, b) => a.path.localeCompare(b.path));
48
+ return {
49
+ ok: annotations.length === 0,
50
+ fixable: false,
51
+ annotations
52
+ };
53
+ };
54
+ const tryDetectBadCodeowners = async (_mode, logger) => {
55
+ try {
56
+ return await detectBadCodeowners();
57
+ } catch (err) {
58
+ logger.warn("Failed to detect bad CODEOWNERS.");
59
+ logger.subtle((0, import_util.inspect)(err));
60
+ return {
61
+ ok: false,
62
+ fixable: false,
63
+ annotations: []
64
+ };
65
+ }
66
+ };
67
+ // Annotate the CommonJS export names for ESM import in node:
68
+ 0 && (module.exports = {
69
+ detectBadCodeowners,
70
+ tryDetectBadCodeowners
71
+ });
72
+ //# sourceMappingURL=detectBadCodeowners.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/cli/lint/internalLints/detectBadCodeowners.ts"],
4
+ "sourcesContent": ["import { inspect } from 'util';\n\nimport { Git } from '../../..';\nimport type { Logger } from '../../../utils/logging';\nimport { createDestinationFileReader } from '../../configure/analysis/project';\nimport type { InternalLintResult } from '../internal';\n\nexport const detectBadCodeowners = async (): Promise<InternalLintResult> => {\n const gitRoot = await Git.findRoot({ dir: process.cwd() });\n const reader = createDestinationFileReader(gitRoot ?? process.cwd());\n\n const annotations = (\n await Promise.all(\n ['.github/CODEOWNERS', 'CODEOWNERS', 'docs/CODEOWNERS'].map(\n async (filename) => {\n const lines = (await reader(filename))?.split('\\n');\n\n if (lines?.some((line) => line.startsWith('- '))) {\n return [\n {\n message:\n 'CODEOWNERS file has a line starting with `- `. This is probably an autoformatting mistake, where your editor thinks this file is a markdown file and is trying to format a list item. Did you mean to use `*` instead?',\n path: filename,\n },\n ];\n }\n\n return [];\n },\n ),\n )\n ).flat();\n\n // TODO: Use `toSorted` once we drop support for Node 18.\n annotations.sort((a, b) => a.path.localeCompare(b.path));\n\n return {\n ok: annotations.length === 0,\n fixable: false,\n annotations,\n };\n};\n\nexport const tryDetectBadCodeowners = async (\n _mode: 'format' | 'lint',\n logger: Logger,\n): Promise<InternalLintResult> => {\n try {\n return await detectBadCodeowners();\n } catch (err) {\n logger.warn('Failed to detect bad CODEOWNERS.');\n logger.subtle(inspect(err));\n\n return {\n ok: false,\n fixable: false,\n annotations: [],\n };\n }\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,eAAoB;AAEpB,qBAA4C;AAGrC,MAAM,sBAAsB,YAAyC;AAC1E,QAAM,UAAU,MAAM,aAAI,SAAS,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC;AACzD,QAAM,aAAS,4CAA4B,WAAW,QAAQ,IAAI,CAAC;AAEnE,QAAM,eACJ,MAAM,QAAQ;AAAA,IACZ,CAAC,sBAAsB,cAAc,iBAAiB,EAAE;AAAA,MACtD,OAAO,aAAa;AAClB,cAAM,SAAS,MAAM,OAAO,QAAQ,IAAI,MAAM,IAAI;AAElD,YAAI,OAAO,KAAK,CAAC,SAAS,KAAK,WAAW,IAAI,CAAC,GAAG;AAChD,iBAAO;AAAA,YACL;AAAA,cACE,SACE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,eAAO,CAAC;AAAA,MACV;AAAA,IACF;AAAA,EACF,GACA,KAAK;AAGP,cAAY,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAEvD,SAAO;AAAA,IACL,IAAI,YAAY,WAAW;AAAA,IAC3B,SAAS;AAAA,IACT;AAAA,EACF;AACF;AAEO,MAAM,yBAAyB,OACpC,OACA,WACgC;AAChC,MAAI;AACF,WAAO,MAAM,oBAAoB;AAAA,EACnC,SAAS,KAAK;AACZ,WAAO,KAAK,kCAAkC;AAC9C,WAAO,WAAO,qBAAQ,GAAG,CAAC;AAE1B,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,aAAa,CAAC;AAAA,IAChB;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -50,7 +50,7 @@ const noSkubaTemplateJs = async (_mode, logger) => {
50
50
  if (await (0, import_fs_extra.pathExists)(templateConfigPath)) {
51
51
  logger.err(
52
52
  `Template is incomplete; run ${logger.bold(
53
- packageManager.exec,
53
+ packageManager.print.exec,
54
54
  "skuba",
55
55
  "configure"
56
56
  )}. ${logger.dim("no-skuba-template-js")}`
@@ -61,7 +61,7 @@ const noSkubaTemplateJs = async (_mode, logger) => {
61
61
  annotations: [
62
62
  {
63
63
  path: "skuba.template.js",
64
- message: `Template is incomplete; run ${packageManager.exec} skuba configure.`
64
+ message: `Template is incomplete; run ${packageManager.print.exec} skuba configure.`
65
65
  }
66
66
  ]
67
67
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/lint/internalLints/noSkubaTemplateJs.ts"],
4
- "sourcesContent": ["import path from 'path';\n\nimport { pathExists } from 'fs-extra';\n\nimport type { Logger } from '../../../utils/logging';\nimport { getConsumerManifest } from '../../../utils/manifest';\nimport { detectPackageManager } from '../../../utils/packageManager';\nimport type { InternalLintResult } from '../internal';\n\nexport const noSkubaTemplateJs = async (\n _mode: 'format' | 'lint',\n logger: Logger,\n): Promise<InternalLintResult> => {\n const [manifest, packageManager] = await Promise.all([\n getConsumerManifest(),\n detectPackageManager(),\n ]);\n\n if (!manifest) {\n // This will throw elsewhere\n return { ok: true, fixable: false };\n }\n\n const templateConfigPath = path.join(\n path.dirname(manifest.path),\n 'skuba.template.js',\n );\n\n if (await pathExists(templateConfigPath)) {\n logger.err(\n `Template is incomplete; run ${logger.bold(\n packageManager.exec,\n 'skuba',\n 'configure',\n )}. ${logger.dim('no-skuba-template-js')}`,\n );\n\n return {\n ok: false,\n fixable: false,\n annotations: [\n {\n path: 'skuba.template.js',\n message: `Template is incomplete; run ${packageManager.exec} skuba configure.`,\n },\n ],\n };\n }\n\n return { ok: true, fixable: false };\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAEjB,sBAA2B;AAG3B,sBAAoC;AACpC,4BAAqC;AAG9B,MAAM,oBAAoB,OAC/B,OACA,WACgC;AAChC,QAAM,CAAC,UAAU,cAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,QACnD,qCAAoB;AAAA,QACpB,4CAAqB;AAAA,EACvB,CAAC;AAED,MAAI,CAAC,UAAU;AAEb,WAAO,EAAE,IAAI,MAAM,SAAS,MAAM;AAAA,EACpC;AAEA,QAAM,qBAAqB,YAAAA,QAAK;AAAA,IAC9B,YAAAA,QAAK,QAAQ,SAAS,IAAI;AAAA,IAC1B;AAAA,EACF;AAEA,MAAI,UAAM,4BAAW,kBAAkB,GAAG;AACxC,WAAO;AAAA,MACL,+BAA+B,OAAO;AAAA,QACpC,eAAe;AAAA,QACf;AAAA,QACA;AAAA,MACF,CAAC,KAAK,OAAO,IAAI,sBAAsB,CAAC;AAAA,IAC1C;AAEA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,aAAa;AAAA,QACX;AAAA,UACE,MAAM;AAAA,UACN,SAAS,+BAA+B,eAAe,IAAI;AAAA,QAC7D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,IAAI,MAAM,SAAS,MAAM;AACpC;",
4
+ "sourcesContent": ["import path from 'path';\n\nimport { pathExists } from 'fs-extra';\n\nimport type { Logger } from '../../../utils/logging';\nimport { getConsumerManifest } from '../../../utils/manifest';\nimport { detectPackageManager } from '../../../utils/packageManager';\nimport type { InternalLintResult } from '../internal';\n\nexport const noSkubaTemplateJs = async (\n _mode: 'format' | 'lint',\n logger: Logger,\n): Promise<InternalLintResult> => {\n const [manifest, packageManager] = await Promise.all([\n getConsumerManifest(),\n detectPackageManager(),\n ]);\n\n if (!manifest) {\n // This will throw elsewhere\n return { ok: true, fixable: false };\n }\n\n const templateConfigPath = path.join(\n path.dirname(manifest.path),\n 'skuba.template.js',\n );\n\n if (await pathExists(templateConfigPath)) {\n logger.err(\n `Template is incomplete; run ${logger.bold(\n packageManager.print.exec,\n 'skuba',\n 'configure',\n )}. ${logger.dim('no-skuba-template-js')}`,\n );\n\n return {\n ok: false,\n fixable: false,\n annotations: [\n {\n path: 'skuba.template.js',\n message: `Template is incomplete; run ${packageManager.print.exec} skuba configure.`,\n },\n ],\n };\n }\n\n return { ok: true, fixable: false };\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAEjB,sBAA2B;AAG3B,sBAAoC;AACpC,4BAAqC;AAG9B,MAAM,oBAAoB,OAC/B,OACA,WACgC;AAChC,QAAM,CAAC,UAAU,cAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,QACnD,qCAAoB;AAAA,QACpB,4CAAqB;AAAA,EACvB,CAAC;AAED,MAAI,CAAC,UAAU;AAEb,WAAO,EAAE,IAAI,MAAM,SAAS,MAAM;AAAA,EACpC;AAEA,QAAM,qBAAqB,YAAAA,QAAK;AAAA,IAC9B,YAAAA,QAAK,QAAQ,SAAS,IAAI;AAAA,IAC1B;AAAA,EACF;AAEA,MAAI,UAAM,4BAAW,kBAAkB,GAAG;AACxC,WAAO;AAAA,MACL,+BAA+B,OAAO;AAAA,QACpC,eAAe,MAAM;AAAA,QACrB;AAAA,QACA;AAAA,MACF,CAAC,KAAK,OAAO,IAAI,sBAAsB,CAAC;AAAA,IAC1C;AAEA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,aAAa;AAAA,QACX;AAAA,UACE,MAAM;AAAA,UACN,SAAS,+BAA+B,eAAe,MAAM,IAAI;AAAA,QACnE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,IAAI,MAAM,SAAS,MAAM;AACpC;",
6
6
  "names": ["path"]
7
7
  }
@@ -119,7 +119,7 @@ const refreshConfigFiles = async (mode, logger) => {
119
119
  msg: `The ${logger.bold(
120
120
  filename
121
121
  )} file is out of date. Run \`${logger.bold(
122
- packageManager2.exec,
122
+ packageManager2.print.exec,
123
123
  "skuba",
124
124
  "format"
125
125
  )}\` to update it.`,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/cli/lint/internalLints/refreshConfigFiles.ts"],
4
- "sourcesContent": ["import path from 'path';\nimport { inspect, stripVTControlCharacters as stripAnsi } from 'util';\n\nimport { writeFile } from 'fs-extra';\n\nimport { Git } from '../../..';\nimport type { Logger } from '../../../utils/logging';\nimport { NPMRC_LINES, hasNpmrcSecret } from '../../../utils/npmrc';\nimport {\n type PackageManagerConfig,\n detectPackageManager,\n} from '../../../utils/packageManager';\nimport { readBaseTemplateFile } from '../../../utils/template';\nimport { getDestinationManifest } from '../../configure/analysis/package';\nimport { createDestinationFileReader } from '../../configure/analysis/project';\nimport { mergeWithConfigFile } from '../../configure/processing/configFile';\nimport type { InternalLintResult } from '../internal';\n\nconst ensureNoAuthToken = (fileContents: string) =>\n fileContents\n .split('\\n')\n .filter((line) => !hasNpmrcSecret(line))\n .join('\\n');\n\ntype RefreshableConfigFile = {\n name: string;\n type: 'ignore' | 'npmrc';\n additionalMapping?: (\n s: string,\n packageManager: PackageManagerConfig,\n ) => string;\n if?: (packageManager: PackageManagerConfig) => boolean;\n};\n\nconst removeRedundantNpmrc = (contents: string) => {\n const npmrcLines = contents\n .split('\\n')\n .filter((line) => NPMRC_LINES.includes(line.trim()));\n\n // If we're only left with !.npmrc line we can remove it\n // TODO: Consider if we should generalise this\n if (npmrcLines.length > 0 && npmrcLines.every((line) => line.includes('!'))) {\n return contents\n .split('\\n')\n .filter((line) => !NPMRC_LINES.includes(line.trim()))\n .join('\\n');\n }\n return contents;\n};\n\nexport const REFRESHABLE_CONFIG_FILES: RefreshableConfigFile[] = [\n {\n name: '.gitignore',\n type: 'ignore',\n additionalMapping: removeRedundantNpmrc,\n },\n { name: '.prettierignore', type: 'ignore' },\n {\n name: '.npmrc',\n type: 'npmrc',\n additionalMapping: ensureNoAuthToken,\n if: (packageManager: PackageManagerConfig) =>\n packageManager.command === 'pnpm',\n },\n {\n name: '.dockerignore',\n type: 'ignore',\n additionalMapping: removeRedundantNpmrc,\n },\n];\n\nexport const refreshConfigFiles = async (\n mode: 'format' | 'lint',\n logger: Logger,\n) => {\n const [manifest, gitRoot] = await Promise.all([\n getDestinationManifest(),\n Git.findRoot({ dir: process.cwd() }),\n ]);\n\n const destinationRoot = path.dirname(manifest.path);\n\n const readDestinationFile = createDestinationFileReader(destinationRoot);\n\n const refreshConfigFile = async (\n {\n name: filename,\n type: fileType,\n additionalMapping = (s) => s,\n if: condition = () => true,\n }: RefreshableConfigFile,\n packageManager: PackageManagerConfig,\n ) => {\n if (!condition(packageManager)) {\n return { needsChange: false };\n }\n\n const [inputFile, templateFile, isGitIgnored] = await Promise.all([\n readDestinationFile(filename),\n readBaseTemplateFile(`_${filename}`),\n gitRoot\n ? Git.isFileGitIgnored({\n gitRoot,\n absolutePath: path.join(destinationRoot, filename),\n })\n : false,\n ]);\n\n // If the file is gitignored and doesn't exist, don't make it\n if (inputFile === undefined && isGitIgnored) {\n return { needsChange: false };\n }\n\n const data = additionalMapping(\n inputFile\n ? mergeWithConfigFile(templateFile, fileType)(inputFile)\n : templateFile,\n packageManager,\n );\n\n const filepath = path.join(destinationRoot, filename);\n\n if (mode === 'format') {\n if (data === inputFile) {\n return { needsChange: false };\n }\n\n await writeFile(filepath, data);\n return {\n needsChange: false,\n msg: `Refreshed ${logger.bold(filename)}.`,\n filename,\n };\n }\n\n if (data !== inputFile) {\n return {\n needsChange: true,\n msg: `The ${logger.bold(\n filename,\n )} file is out of date. Run \\`${logger.bold(\n packageManager.exec,\n 'skuba',\n 'format',\n )}\\` to update it.`,\n filename,\n };\n }\n\n return { needsChange: false };\n };\n\n const packageManager = await detectPackageManager(destinationRoot);\n\n const results = await Promise.all(\n REFRESHABLE_CONFIG_FILES.map((conf) =>\n refreshConfigFile(conf, packageManager),\n ),\n );\n\n // Log after for reproducible test output ordering\n results.forEach((result) => {\n if (result.msg) {\n logger.warn(result.msg, logger.dim('refresh-config-files'));\n }\n });\n\n const anyNeedChanging = results.some(({ needsChange }) => needsChange);\n\n return {\n ok: !anyNeedChanging,\n fixable: anyNeedChanging,\n annotations: results.flatMap(({ needsChange, filename, msg }) =>\n needsChange && msg\n ? [\n {\n path: filename,\n message: stripAnsi(msg),\n },\n ]\n : [],\n ),\n };\n};\n\nexport const tryRefreshConfigFiles = async (\n mode: 'format' | 'lint',\n logger: Logger,\n): Promise<InternalLintResult> => {\n try {\n return await refreshConfigFiles(mode, logger);\n } catch (err) {\n logger.warn('Failed to refresh config files.');\n logger.subtle(inspect(err));\n\n return {\n ok: false,\n fixable: false,\n annotations: [],\n };\n }\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import path from 'path';\nimport { inspect, stripVTControlCharacters as stripAnsi } from 'util';\n\nimport { writeFile } from 'fs-extra';\n\nimport { Git } from '../../..';\nimport type { Logger } from '../../../utils/logging';\nimport { NPMRC_LINES, hasNpmrcSecret } from '../../../utils/npmrc';\nimport {\n type PackageManagerConfig,\n detectPackageManager,\n} from '../../../utils/packageManager';\nimport { readBaseTemplateFile } from '../../../utils/template';\nimport { getDestinationManifest } from '../../configure/analysis/package';\nimport { createDestinationFileReader } from '../../configure/analysis/project';\nimport { mergeWithConfigFile } from '../../configure/processing/configFile';\nimport type { InternalLintResult } from '../internal';\n\nconst ensureNoAuthToken = (fileContents: string) =>\n fileContents\n .split('\\n')\n .filter((line) => !hasNpmrcSecret(line))\n .join('\\n');\n\ntype RefreshableConfigFile = {\n name: string;\n type: 'ignore' | 'npmrc';\n additionalMapping?: (\n s: string,\n packageManager: PackageManagerConfig,\n ) => string;\n if?: (packageManager: PackageManagerConfig) => boolean;\n};\n\nconst removeRedundantNpmrc = (contents: string) => {\n const npmrcLines = contents\n .split('\\n')\n .filter((line) => NPMRC_LINES.includes(line.trim()));\n\n // If we're only left with !.npmrc line we can remove it\n // TODO: Consider if we should generalise this\n if (npmrcLines.length > 0 && npmrcLines.every((line) => line.includes('!'))) {\n return contents\n .split('\\n')\n .filter((line) => !NPMRC_LINES.includes(line.trim()))\n .join('\\n');\n }\n return contents;\n};\n\nexport const REFRESHABLE_CONFIG_FILES: RefreshableConfigFile[] = [\n {\n name: '.gitignore',\n type: 'ignore',\n additionalMapping: removeRedundantNpmrc,\n },\n { name: '.prettierignore', type: 'ignore' },\n {\n name: '.npmrc',\n type: 'npmrc',\n additionalMapping: ensureNoAuthToken,\n if: (packageManager: PackageManagerConfig) =>\n packageManager.command === 'pnpm',\n },\n {\n name: '.dockerignore',\n type: 'ignore',\n additionalMapping: removeRedundantNpmrc,\n },\n];\n\nexport const refreshConfigFiles = async (\n mode: 'format' | 'lint',\n logger: Logger,\n) => {\n const [manifest, gitRoot] = await Promise.all([\n getDestinationManifest(),\n Git.findRoot({ dir: process.cwd() }),\n ]);\n\n const destinationRoot = path.dirname(manifest.path);\n\n const readDestinationFile = createDestinationFileReader(destinationRoot);\n\n const refreshConfigFile = async (\n {\n name: filename,\n type: fileType,\n additionalMapping = (s) => s,\n if: condition = () => true,\n }: RefreshableConfigFile,\n packageManager: PackageManagerConfig,\n ) => {\n if (!condition(packageManager)) {\n return { needsChange: false };\n }\n\n const [inputFile, templateFile, isGitIgnored] = await Promise.all([\n readDestinationFile(filename),\n readBaseTemplateFile(`_${filename}`),\n gitRoot\n ? Git.isFileGitIgnored({\n gitRoot,\n absolutePath: path.join(destinationRoot, filename),\n })\n : false,\n ]);\n\n // If the file is gitignored and doesn't exist, don't make it\n if (inputFile === undefined && isGitIgnored) {\n return { needsChange: false };\n }\n\n const data = additionalMapping(\n inputFile\n ? mergeWithConfigFile(templateFile, fileType)(inputFile)\n : templateFile,\n packageManager,\n );\n\n const filepath = path.join(destinationRoot, filename);\n\n if (mode === 'format') {\n if (data === inputFile) {\n return { needsChange: false };\n }\n\n await writeFile(filepath, data);\n return {\n needsChange: false,\n msg: `Refreshed ${logger.bold(filename)}.`,\n filename,\n };\n }\n\n if (data !== inputFile) {\n return {\n needsChange: true,\n msg: `The ${logger.bold(\n filename,\n )} file is out of date. Run \\`${logger.bold(\n packageManager.print.exec,\n 'skuba',\n 'format',\n )}\\` to update it.`,\n filename,\n };\n }\n\n return { needsChange: false };\n };\n\n const packageManager = await detectPackageManager(destinationRoot);\n\n const results = await Promise.all(\n REFRESHABLE_CONFIG_FILES.map((conf) =>\n refreshConfigFile(conf, packageManager),\n ),\n );\n\n // Log after for reproducible test output ordering\n results.forEach((result) => {\n if (result.msg) {\n logger.warn(result.msg, logger.dim('refresh-config-files'));\n }\n });\n\n const anyNeedChanging = results.some(({ needsChange }) => needsChange);\n\n return {\n ok: !anyNeedChanging,\n fixable: anyNeedChanging,\n annotations: results.flatMap(({ needsChange, filename, msg }) =>\n needsChange && msg\n ? [\n {\n path: filename,\n message: stripAnsi(msg),\n },\n ]\n : [],\n ),\n };\n};\n\nexport const tryRefreshConfigFiles = async (\n mode: 'format' | 'lint',\n logger: Logger,\n): Promise<InternalLintResult> => {\n try {\n return await refreshConfigFiles(mode, logger);\n } catch (err) {\n logger.warn('Failed to refresh config files.');\n logger.subtle(inspect(err));\n\n return {\n ok: false,\n fixable: false,\n annotations: [],\n };\n }\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AACjB,kBAA+D;AAE/D,sBAA0B;AAE1B,eAAoB;AAEpB,mBAA4C;AAC5C,4BAGO;AACP,sBAAqC;AACrC,qBAAuC;AACvC,qBAA4C;AAC5C,wBAAoC;AAGpC,MAAM,oBAAoB,CAAC,iBACzB,aACG,MAAM,IAAI,EACV,OAAO,CAAC,SAAS,KAAC,6BAAe,IAAI,CAAC,EACtC,KAAK,IAAI;AAYd,MAAM,uBAAuB,CAAC,aAAqB;AACjD,QAAM,aAAa,SAChB,MAAM,IAAI,EACV,OAAO,CAAC,SAAS,yBAAY,SAAS,KAAK,KAAK,CAAC,CAAC;AAIrD,MAAI,WAAW,SAAS,KAAK,WAAW,MAAM,CAAC,SAAS,KAAK,SAAS,GAAG,CAAC,GAAG;AAC3E,WAAO,SACJ,MAAM,IAAI,EACV,OAAO,CAAC,SAAS,CAAC,yBAAY,SAAS,KAAK,KAAK,CAAC,CAAC,EACnD,KAAK,IAAI;AAAA,EACd;AACA,SAAO;AACT;AAEO,MAAM,2BAAoD;AAAA,EAC/D;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,mBAAmB;AAAA,EACrB;AAAA,EACA,EAAE,MAAM,mBAAmB,MAAM,SAAS;AAAA,EAC1C;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,mBAAmB;AAAA,IACnB,IAAI,CAAC,mBACH,eAAe,YAAY;AAAA,EAC/B;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,mBAAmB;AAAA,EACrB;AACF;AAEO,MAAM,qBAAqB,OAChC,MACA,WACG;AACH,QAAM,CAAC,UAAU,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC5C,uCAAuB;AAAA,IACvB,aAAI,SAAS,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC;AAAA,EACrC,CAAC;AAED,QAAM,kBAAkB,YAAAA,QAAK,QAAQ,SAAS,IAAI;AAElD,QAAM,0BAAsB,4CAA4B,eAAe;AAEvE,QAAM,oBAAoB,OACxB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,oBAAoB,CAAC,MAAM;AAAA,IAC3B,IAAI,YAAY,MAAM;AAAA,EACxB,GACAC,oBACG;AACH,QAAI,CAAC,UAAUA,eAAc,GAAG;AAC9B,aAAO,EAAE,aAAa,MAAM;AAAA,IAC9B;AAEA,UAAM,CAAC,WAAW,cAAc,YAAY,IAAI,MAAM,QAAQ,IAAI;AAAA,MAChE,oBAAoB,QAAQ;AAAA,UAC5B,sCAAqB,IAAI,QAAQ,EAAE;AAAA,MACnC,UACI,aAAI,iBAAiB;AAAA,QACnB;AAAA,QACA,cAAc,YAAAD,QAAK,KAAK,iBAAiB,QAAQ;AAAA,MACnD,CAAC,IACD;AAAA,IACN,CAAC;AAGD,QAAI,cAAc,UAAa,cAAc;AAC3C,aAAO,EAAE,aAAa,MAAM;AAAA,IAC9B;AAEA,UAAM,OAAO;AAAA,MACX,gBACI,uCAAoB,cAAc,QAAQ,EAAE,SAAS,IACrD;AAAA,MACJC;AAAA,IACF;AAEA,UAAM,WAAW,YAAAD,QAAK,KAAK,iBAAiB,QAAQ;AAEpD,QAAI,SAAS,UAAU;AACrB,UAAI,SAAS,WAAW;AACtB,eAAO,EAAE,aAAa,MAAM;AAAA,MAC9B;AAEA,gBAAM,2BAAU,UAAU,IAAI;AAC9B,aAAO;AAAA,QACL,aAAa;AAAA,QACb,KAAK,aAAa,OAAO,KAAK,QAAQ,CAAC;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAEA,QAAI,SAAS,WAAW;AACtB,aAAO;AAAA,QACL,aAAa;AAAA,QACb,KAAK,OAAO,OAAO;AAAA,UACjB;AAAA,QACF,CAAC,+BAA+B,OAAO;AAAA,UACrCC,gBAAe,MAAM;AAAA,UACrB;AAAA,UACA;AAAA,QACF,CAAC;AAAA,QACD;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,aAAa,MAAM;AAAA,EAC9B;AAEA,QAAM,iBAAiB,UAAM,4CAAqB,eAAe;AAEjE,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,yBAAyB;AAAA,MAAI,CAAC,SAC5B,kBAAkB,MAAM,cAAc;AAAA,IACxC;AAAA,EACF;AAGA,UAAQ,QAAQ,CAAC,WAAW;AAC1B,QAAI,OAAO,KAAK;AACd,aAAO,KAAK,OAAO,KAAK,OAAO,IAAI,sBAAsB,CAAC;AAAA,IAC5D;AAAA,EACF,CAAC;AAED,QAAM,kBAAkB,QAAQ,KAAK,CAAC,EAAE,YAAY,MAAM,WAAW;AAErE,SAAO;AAAA,IACL,IAAI,CAAC;AAAA,IACL,SAAS;AAAA,IACT,aAAa,QAAQ;AAAA,MAAQ,CAAC,EAAE,aAAa,UAAU,IAAI,MACzD,eAAe,MACX;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,aAAS,YAAAC,0BAAU,GAAG;AAAA,QACxB;AAAA,MACF,IACA,CAAC;AAAA,IACP;AAAA,EACF;AACF;AAEO,MAAM,wBAAwB,OACnC,MACA,WACgC;AAChC,MAAI;AACF,WAAO,MAAM,mBAAmB,MAAM,MAAM;AAAA,EAC9C,SAAS,KAAK;AACZ,WAAO,KAAK,iCAAiC;AAC7C,WAAO,WAAO,qBAAQ,GAAG,CAAC;AAE1B,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,aAAa,CAAC;AAAA,IAChB;AAAA,EACF;AACF;",
6
6
  "names": ["path", "packageManager", "stripAnsi"]
7
7
  }
@@ -96,7 +96,7 @@ const upgradeSkuba = async (mode, logger) => {
96
96
  }
97
97
  logger.warn(
98
98
  `skuba has patches to apply. Run ${logger.bold(
99
- packageManager.exec,
99
+ packageManager.print.exec,
100
100
  "skuba",
101
101
  "format"
102
102
  )} to run them. ${logger.dim("skuba-patches")}`
@@ -109,7 +109,7 @@ const upgradeSkuba = async (mode, logger) => {
109
109
  // package.json as likely skuba version has changed
110
110
  // TODO: locate the "skuba": {} config in the package.json and annotate on the version property
111
111
  path: manifest.path,
112
- message: `skuba has patches to apply. Run ${packageManager.exec} skuba format to run them.`
112
+ message: `skuba has patches to apply. Run ${packageManager.print.exec} skuba format to run them.`
113
113
  }
114
114
  ]
115
115
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/cli/lint/internalLints/upgrade/index.ts"],
4
- "sourcesContent": ["import path from 'path';\n\nimport { readdir, writeFile } from 'fs-extra';\nimport type readPkgUp from 'read-pkg-up';\nimport { gte, sort } from 'semver';\n\nimport type { Logger } from '../../../../utils/logging';\nimport { getConsumerManifest } from '../../../../utils/manifest';\nimport {\n type PackageManagerConfig,\n detectPackageManager,\n} from '../../../../utils/packageManager';\nimport { getSkubaVersion } from '../../../../utils/version';\nimport { formatPackage } from '../../../configure/processing/package';\nimport type { SkubaPackageJson } from '../../../init/writePackageJson';\nimport type { InternalLintResult } from '../../internal';\n\nexport type Patches = Patch[];\nexport type Patch = {\n apply: PatchFunction;\n description: string;\n};\nexport type PatchReturnType =\n | { result: 'apply' }\n | { result: 'skip'; reason?: string };\n\nexport type PatchConfig = {\n mode: 'format' | 'lint';\n manifest: readPkgUp.NormalizedReadResult;\n packageManager: PackageManagerConfig;\n dir?: string;\n};\n\nexport type PatchFunction = (config: PatchConfig) => Promise<PatchReturnType>;\n\nconst getPatches = async (manifestVersion: string): Promise<Patches> => {\n const patches = await readdir(path.join(__dirname, 'patches'), {\n withFileTypes: true,\n });\n\n // The patches are sorted by the version they were added from.\n // Only return patches that are newer or equal to the current version.\n const patchesForVersion = sort(\n patches.flatMap((patch) =>\n // Is a directory rather than a JavaScript source file\n patch.isDirectory() &&\n // Has been added since the last patch run on the project\n gte(patch.name, manifestVersion)\n ? patch.name\n : [],\n ),\n );\n\n return (await Promise.all(patchesForVersion.map(resolvePatches))).flat();\n};\n\nconst fileExtensions = ['js', 'ts'];\n\n// Hack to allow our Jest environment/transform to resolve the patches\n// In normal scenarios this will resolve immediately after the .js import\nconst resolvePatches = async (version: string): Promise<Patches> => {\n for (const extension of fileExtensions) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n return (await import(`./patches/${version}/index.${extension}`)).patches;\n } catch {\n // Ignore\n }\n }\n throw new Error(`Could not resolve patches for ${version}`);\n};\n\nexport const upgradeSkuba = async (\n mode: 'lint' | 'format',\n logger: Logger,\n): Promise<InternalLintResult> => {\n const [currentVersion, manifest, packageManager] = await Promise.all([\n getSkubaVersion(),\n getConsumerManifest(),\n detectPackageManager(),\n ]);\n\n if (!manifest) {\n throw new Error('Could not find a package json for this project');\n }\n\n manifest.packageJson.skuba ??= { version: '1.0.0' };\n\n const manifestVersion = (manifest.packageJson.skuba as SkubaPackageJson)\n .version;\n\n // We are up to date, skip patches\n if (gte(manifestVersion, currentVersion)) {\n return { ok: true, fixable: false };\n }\n\n const patches = await getPatches(manifestVersion);\n // No patches to apply even if version out of date. Early exit to avoid unnecessary commits.\n if (patches.length === 0) {\n return { ok: true, fixable: false };\n }\n\n if (mode === 'lint') {\n const results = await Promise.all(\n patches.map(\n async ({ apply }) =>\n await apply({\n mode,\n manifest,\n packageManager,\n }),\n ),\n );\n\n // No patches are applicable. Early exit to avoid unnecessary commits.\n if (results.every(({ result }) => result === 'skip')) {\n return { ok: true, fixable: false };\n }\n\n logger.warn(\n `skuba has patches to apply. Run ${logger.bold(\n packageManager.exec,\n 'skuba',\n 'format',\n )} to run them. ${logger.dim('skuba-patches')}`,\n );\n\n return {\n ok: false,\n fixable: true,\n annotations: [\n {\n // package.json as likely skuba version has changed\n // TODO: locate the \"skuba\": {} config in the package.json and annotate on the version property\n path: manifest.path,\n message: `skuba has patches to apply. Run ${packageManager.exec} skuba format to run them.`,\n },\n ],\n };\n }\n\n logger.plain('Updating skuba...');\n\n // Run these in series in case a subsequent patch relies on a previous patch\n for (const { apply, description } of patches) {\n const result = await apply({\n mode,\n manifest,\n packageManager,\n });\n logger.newline();\n if (result.result === 'skip') {\n logger.plain(\n `Patch skipped: ${description}${\n result.reason ? ` - ${result.reason}` : ''\n }`,\n );\n } else {\n logger.plain(`Patch applied: ${description}`);\n }\n }\n\n (manifest.packageJson.skuba as SkubaPackageJson).version = currentVersion;\n\n const updatedPackageJson = await formatPackage(manifest.packageJson);\n\n await writeFile(manifest.path, updatedPackageJson);\n logger.newline();\n logger.plain('skuba update complete.');\n logger.newline();\n\n return {\n ok: true,\n fixable: false,\n };\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import path from 'path';\n\nimport { readdir, writeFile } from 'fs-extra';\nimport type readPkgUp from 'read-pkg-up';\nimport { gte, sort } from 'semver';\n\nimport type { Logger } from '../../../../utils/logging';\nimport { getConsumerManifest } from '../../../../utils/manifest';\nimport {\n type PackageManagerConfig,\n detectPackageManager,\n} from '../../../../utils/packageManager';\nimport { getSkubaVersion } from '../../../../utils/version';\nimport { formatPackage } from '../../../configure/processing/package';\nimport type { SkubaPackageJson } from '../../../init/writePackageJson';\nimport type { InternalLintResult } from '../../internal';\n\nexport type Patches = Patch[];\nexport type Patch = {\n apply: PatchFunction;\n description: string;\n};\nexport type PatchReturnType =\n | { result: 'apply' }\n | { result: 'skip'; reason?: string };\n\nexport type PatchConfig = {\n mode: 'format' | 'lint';\n manifest: readPkgUp.NormalizedReadResult;\n packageManager: PackageManagerConfig;\n dir?: string;\n};\n\nexport type PatchFunction = (config: PatchConfig) => Promise<PatchReturnType>;\n\nconst getPatches = async (manifestVersion: string): Promise<Patches> => {\n const patches = await readdir(path.join(__dirname, 'patches'), {\n withFileTypes: true,\n });\n\n // The patches are sorted by the version they were added from.\n // Only return patches that are newer or equal to the current version.\n const patchesForVersion = sort(\n patches.flatMap((patch) =>\n // Is a directory rather than a JavaScript source file\n patch.isDirectory() &&\n // Has been added since the last patch run on the project\n gte(patch.name, manifestVersion)\n ? patch.name\n : [],\n ),\n );\n\n return (await Promise.all(patchesForVersion.map(resolvePatches))).flat();\n};\n\nconst fileExtensions = ['js', 'ts'];\n\n// Hack to allow our Jest environment/transform to resolve the patches\n// In normal scenarios this will resolve immediately after the .js import\nconst resolvePatches = async (version: string): Promise<Patches> => {\n for (const extension of fileExtensions) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n return (await import(`./patches/${version}/index.${extension}`)).patches;\n } catch {\n // Ignore\n }\n }\n throw new Error(`Could not resolve patches for ${version}`);\n};\n\nexport const upgradeSkuba = async (\n mode: 'lint' | 'format',\n logger: Logger,\n): Promise<InternalLintResult> => {\n const [currentVersion, manifest, packageManager] = await Promise.all([\n getSkubaVersion(),\n getConsumerManifest(),\n detectPackageManager(),\n ]);\n\n if (!manifest) {\n throw new Error('Could not find a package json for this project');\n }\n\n manifest.packageJson.skuba ??= { version: '1.0.0' };\n\n const manifestVersion = (manifest.packageJson.skuba as SkubaPackageJson)\n .version;\n\n // We are up to date, skip patches\n if (gte(manifestVersion, currentVersion)) {\n return { ok: true, fixable: false };\n }\n\n const patches = await getPatches(manifestVersion);\n // No patches to apply even if version out of date. Early exit to avoid unnecessary commits.\n if (patches.length === 0) {\n return { ok: true, fixable: false };\n }\n\n if (mode === 'lint') {\n const results = await Promise.all(\n patches.map(\n async ({ apply }) =>\n await apply({\n mode,\n manifest,\n packageManager,\n }),\n ),\n );\n\n // No patches are applicable. Early exit to avoid unnecessary commits.\n if (results.every(({ result }) => result === 'skip')) {\n return { ok: true, fixable: false };\n }\n\n logger.warn(\n `skuba has patches to apply. Run ${logger.bold(\n packageManager.print.exec,\n 'skuba',\n 'format',\n )} to run them. ${logger.dim('skuba-patches')}`,\n );\n\n return {\n ok: false,\n fixable: true,\n annotations: [\n {\n // package.json as likely skuba version has changed\n // TODO: locate the \"skuba\": {} config in the package.json and annotate on the version property\n path: manifest.path,\n message: `skuba has patches to apply. Run ${packageManager.print.exec} skuba format to run them.`,\n },\n ],\n };\n }\n\n logger.plain('Updating skuba...');\n\n // Run these in series in case a subsequent patch relies on a previous patch\n for (const { apply, description } of patches) {\n const result = await apply({\n mode,\n manifest,\n packageManager,\n });\n logger.newline();\n if (result.result === 'skip') {\n logger.plain(\n `Patch skipped: ${description}${\n result.reason ? ` - ${result.reason}` : ''\n }`,\n );\n } else {\n logger.plain(`Patch applied: ${description}`);\n }\n }\n\n (manifest.packageJson.skuba as SkubaPackageJson).version = currentVersion;\n\n const updatedPackageJson = await formatPackage(manifest.packageJson);\n\n await writeFile(manifest.path, updatedPackageJson);\n logger.newline();\n logger.plain('skuba update complete.');\n logger.newline();\n\n return {\n ok: true,\n fixable: false,\n };\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["path"]
7
7
  }