skuba 7.0.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/jest-preset.js +7 -1
- package/lib/api/git/commitAllChanges.d.ts +2 -2
- package/lib/api/git/commitAllChanges.js.map +2 -2
- package/lib/api/net/waitFor.d.ts +1 -1
- package/lib/api/net/waitFor.js.map +2 -2
- package/lib/cli/adapter/eslint.d.ts +2 -2
- package/lib/cli/adapter/eslint.js.map +2 -2
- package/lib/cli/adapter/prettier.d.ts +8 -1
- package/lib/cli/adapter/prettier.js +6 -4
- package/lib/cli/adapter/prettier.js.map +2 -2
- package/lib/cli/build/assets.d.ts +1 -1
- package/lib/cli/build/assets.js.map +2 -2
- package/lib/cli/configure/analyseDependencies.js.map +2 -2
- package/lib/cli/configure/analysis/package.js.map +2 -2
- package/lib/cli/configure/ensureTemplateCompletion.d.ts +1 -1
- package/lib/cli/configure/ensureTemplateCompletion.js.map +2 -2
- package/lib/cli/configure/index.js +1 -1
- package/lib/cli/configure/index.js.map +1 -1
- package/lib/cli/configure/patchDockerfile.d.ts +1 -0
- package/lib/cli/configure/patchDockerfile.js +65 -0
- package/lib/cli/configure/patchDockerfile.js.map +7 -0
- package/lib/cli/configure/processing/typescript.js +1 -1
- package/lib/cli/configure/processing/typescript.js.map +2 -2
- package/lib/cli/format.js +2 -0
- package/lib/cli/format.js.map +2 -2
- package/lib/cli/init/getConfig.d.ts +2 -2
- package/lib/cli/init/getConfig.js +1 -1
- package/lib/cli/init/getConfig.js.map +2 -2
- package/lib/cli/init/prompts.d.ts +1 -1
- package/lib/cli/init/prompts.js.map +2 -2
- package/lib/cli/lint/autofix.js +15 -0
- package/lib/cli/lint/autofix.js.map +2 -2
- package/lib/cli/lint/eslint.d.ts +1 -1
- package/lib/cli/lint/eslint.js.map +2 -2
- package/lib/cli/lint/prettier.d.ts +1 -1
- package/lib/cli/lint/prettier.js.map +2 -2
- package/lib/cli/test/reporters/prettier/index.d.ts +4 -0
- package/lib/cli/test/reporters/prettier/index.js +67 -0
- package/lib/cli/test/reporters/prettier/index.js.map +7 -0
- package/lib/index.js.map +1 -1
- package/lib/utils/copy.d.ts +1 -1
- package/lib/utils/copy.js.map +1 -1
- package/lib/utils/exec.d.ts +1 -2
- package/lib/utils/exec.js.map +2 -2
- package/lib/utils/manifest.d.ts +1 -2
- package/lib/utils/manifest.js.map +2 -2
- package/lib/utils/validation.d.ts +1 -1
- package/lib/utils/validation.js.map +1 -1
- package/lib/wrapper/http.d.ts +1 -1
- package/lib/wrapper/http.js.map +2 -2
- package/package.json +8 -8
- package/template/base/_.prettierignore +1 -0
- package/template/express-rest-api/Dockerfile +1 -1
- package/template/koa-rest-api/Dockerfile +1 -1
- package/template/koa-rest-api/package.json +1 -1
- package/template/koa-rest-api/src/framework/server.ts +1 -1
- package/template/koa-rest-api/src/testing/server.ts +1 -1
- package/template/lambda-sqs-worker/src/services/jobScorer.ts +5 -2
- package/template/lambda-sqs-worker-cdk/infra/appStack.ts +1 -1
package/lib/cli/format.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/cli/format.ts"],
|
|
4
|
-
"sourcesContent": ["import chalk from 'chalk';\n\nimport { hasDebugFlag } from '../utils/args';\nimport { createLogger, log } from '../utils/logging';\n\nimport { runESLint } from './adapter/eslint';\nimport { runPrettier } from './adapter/prettier';\nimport { tryAddEmptyExports } from './configure/addEmptyExports';\nimport { tryPatchRenovateConfig } from './configure/patchRenovateConfig';\nimport { tryPatchServerListener } from './configure/patchServerListener';\nimport { tryRefreshIgnoreFiles } from './configure/refreshIgnoreFiles';\n\nexport const format = async (args = process.argv.slice(2)): Promise<void> => {\n await Promise.all([\n tryAddEmptyExports(),\n tryPatchRenovateConfig(),\n tryPatchServerListener(),\n tryRefreshIgnoreFiles(),\n ]);\n\n const debug = hasDebugFlag(args);\n const logger = createLogger(debug);\n\n log.plain(chalk.magenta('ESLint'));\n\n const eslint = await runESLint('format', logger);\n\n log.newline();\n log.plain(chalk.cyan('Prettier'));\n\n const prettier = await runPrettier('format', logger);\n\n if (eslint.ok && prettier.ok) {\n return;\n }\n\n const tools = [\n ...(eslint.ok ? [] : ['ESLint']),\n ...(prettier.ok ? [] : ['Prettier']),\n ];\n\n log.newline();\n log.err(tools.join(', '), 'found issues that require triage.');\n\n process.exitCode = 1;\n};\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAElB,kBAA6B;AAC7B,qBAAkC;AAElC,oBAA0B;AAC1B,sBAA4B;AAC5B,6BAAmC;AACnC,iCAAuC;AACvC,iCAAuC;AACvC,gCAAsC;AAE/B,MAAM,SAAS,OAAO,OAAO,QAAQ,KAAK,MAAM,CAAC,MAAqB;AAC3E,QAAM,QAAQ,IAAI;AAAA,QAChB,2CAAmB;AAAA,QACnB,mDAAuB;AAAA,QACvB,mDAAuB;AAAA,QACvB,iDAAsB;AAAA,EACxB,CAAC;AAED,QAAM,YAAQ,0BAAa,IAAI;AAC/B,QAAM,aAAS,6BAAa,KAAK;AAEjC,qBAAI,MAAM,aAAAA,QAAM,QAAQ,QAAQ,CAAC;AAEjC,QAAM,SAAS,UAAM,yBAAU,UAAU,MAAM;AAE/C,qBAAI,QAAQ;AACZ,qBAAI,MAAM,aAAAA,QAAM,KAAK,UAAU,CAAC;AAEhC,QAAM,WAAW,UAAM,6BAAY,UAAU,MAAM;AAEnD,MAAI,OAAO,MAAM,SAAS,IAAI;AAC5B;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ,GAAI,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ;AAAA,IAC9B,GAAI,SAAS,KAAK,CAAC,IAAI,CAAC,UAAU;AAAA,EACpC;AAEA,qBAAI,QAAQ;AACZ,qBAAI,IAAI,MAAM,KAAK,IAAI,GAAG,mCAAmC;AAE7D,UAAQ,WAAW;AACrB;",
|
|
4
|
+
"sourcesContent": ["import chalk from 'chalk';\n\nimport { hasDebugFlag } from '../utils/args';\nimport { createLogger, log } from '../utils/logging';\n\nimport { runESLint } from './adapter/eslint';\nimport { runPrettier } from './adapter/prettier';\nimport { tryAddEmptyExports } from './configure/addEmptyExports';\nimport { tryPatchDockerfile } from './configure/patchDockerfile';\nimport { tryPatchRenovateConfig } from './configure/patchRenovateConfig';\nimport { tryPatchServerListener } from './configure/patchServerListener';\nimport { tryRefreshIgnoreFiles } from './configure/refreshIgnoreFiles';\n\nexport const format = async (args = process.argv.slice(2)): Promise<void> => {\n await Promise.all([\n tryAddEmptyExports(),\n tryPatchRenovateConfig(),\n tryPatchDockerfile(),\n tryPatchServerListener(),\n tryRefreshIgnoreFiles(),\n ]);\n\n const debug = hasDebugFlag(args);\n const logger = createLogger(debug);\n\n log.plain(chalk.magenta('ESLint'));\n\n const eslint = await runESLint('format', logger);\n\n log.newline();\n log.plain(chalk.cyan('Prettier'));\n\n const prettier = await runPrettier('format', logger);\n\n if (eslint.ok && prettier.ok) {\n return;\n }\n\n const tools = [\n ...(eslint.ok ? [] : ['ESLint']),\n ...(prettier.ok ? [] : ['Prettier']),\n ];\n\n log.newline();\n log.err(tools.join(', '), 'found issues that require triage.');\n\n process.exitCode = 1;\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAElB,kBAA6B;AAC7B,qBAAkC;AAElC,oBAA0B;AAC1B,sBAA4B;AAC5B,6BAAmC;AACnC,6BAAmC;AACnC,iCAAuC;AACvC,iCAAuC;AACvC,gCAAsC;AAE/B,MAAM,SAAS,OAAO,OAAO,QAAQ,KAAK,MAAM,CAAC,MAAqB;AAC3E,QAAM,QAAQ,IAAI;AAAA,QAChB,2CAAmB;AAAA,QACnB,mDAAuB;AAAA,QACvB,2CAAmB;AAAA,QACnB,mDAAuB;AAAA,QACvB,iDAAsB;AAAA,EACxB,CAAC;AAED,QAAM,YAAQ,0BAAa,IAAI;AAC/B,QAAM,aAAS,6BAAa,KAAK;AAEjC,qBAAI,MAAM,aAAAA,QAAM,QAAQ,QAAQ,CAAC;AAEjC,QAAM,SAAS,UAAM,yBAAU,UAAU,MAAM;AAE/C,qBAAI,QAAQ;AACZ,qBAAI,MAAM,aAAAA,QAAM,KAAK,UAAU,CAAC;AAEhC,QAAM,WAAW,UAAM,6BAAY,UAAU,MAAM;AAEnD,MAAI,OAAO,MAAM,SAAS,IAAI;AAC5B;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ,GAAI,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ;AAAA,IAC9B,GAAI,SAAS,KAAK,CAAC,IAAI,CAAC,UAAU;AAAA,EACpC;AAEA,qBAAI,QAAQ;AACZ,qBAAI,IAAI,MAAM,KAAK,IAAI,GAAG,mCAAmC;AAE7D,UAAQ,WAAW;AACrB;",
|
|
6
6
|
"names": ["chalk"]
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TemplateConfig } from '../../utils/template';
|
|
2
|
-
import type
|
|
3
|
-
import type
|
|
2
|
+
import { type InitConfig } from './types';
|
|
3
|
+
import { type FormChoice } from 'enquirer';
|
|
4
4
|
export declare const runForm: <T = Record<string, string>>(props: {
|
|
5
5
|
choices: Readonly<FormChoice[]>;
|
|
6
6
|
message: string;
|
|
@@ -216,7 +216,7 @@ const configureFromPrompt = async () => {
|
|
|
216
216
|
const configureFromPipe = async () => {
|
|
217
217
|
let text = "";
|
|
218
218
|
await new Promise(
|
|
219
|
-
(resolve) => process.stdin.on("data", (chunk) => text += chunk).once("end", resolve)
|
|
219
|
+
(resolve) => process.stdin.on("data", (chunk) => text += chunk.toString()).once("end", resolve)
|
|
220
220
|
);
|
|
221
221
|
text = text.trim();
|
|
222
222
|
if (text === "") {
|
|
@@ -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 fs from 'fs-extra';\n\nimport { copyFiles } from '../../utils/copy';\nimport { isErrorWithCode } from '../../utils/error';\nimport { log } from '../../utils/logging';\nimport { getRandomPort } from '../../utils/port';\nimport {\n TEMPLATE_CONFIG_FILENAME,\n TEMPLATE_DIR,\n TemplateConfig,\n} from '../../utils/template';\n\nimport { downloadGitHubTemplate } from './git';\nimport
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAEjB,mBAAkB;AAClB,sBAAe;AAEf,kBAA0B;AAC1B,mBAAgC;AAChC,qBAAoB;AACpB,kBAA8B;AAC9B,sBAIO;AAEP,iBAAuC;
|
|
4
|
+
"sourcesContent": ["import path from 'path';\n\nimport chalk from 'chalk';\nimport fs from 'fs-extra';\n\nimport { copyFiles } from '../../utils/copy';\nimport { isErrorWithCode } from '../../utils/error';\nimport { log } from '../../utils/logging';\nimport { getRandomPort } from '../../utils/port';\nimport {\n TEMPLATE_CONFIG_FILENAME,\n TEMPLATE_DIR,\n TemplateConfig,\n} from '../../utils/template';\n\nimport { downloadGitHubTemplate } from './git';\nimport {\n BASE_PROMPT_PROPS,\n type BaseFields,\n GIT_PATH_PROMPT,\n SHOULD_CONTINUE_PROMPT,\n TEMPLATE_PROMPT,\n} from './prompts';\nimport { type InitConfig, InitConfigInput } from './types';\n\nimport { Form, type FormChoice } from 'enquirer';\n\nexport const runForm = <T = Record<string, string>>(props: {\n choices: Readonly<FormChoice[]>;\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 (!value || value === '' || value === choice.initial) {\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 (templateName: string, destinationDir: string) => {\n if (templateName.startsWith('github:')) {\n const gitHubPath = templateName.slice('github:'.length);\n return downloadGitHubTemplate(gitHubPath, destinationDir);\n }\n\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\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-var-requires */\n const templateConfig = require(templateConfigPath) as unknown;\n\n return TemplateConfig.check(templateConfig);\n } catch (err) {\n if (isErrorWithCode(err, 'MODULE_NOT_FOUND')) {\n return {\n entryPoint: undefined,\n fields: [],\n type: undefined,\n };\n }\n\n throw err;\n }\n};\n\nconst baseToTemplateData = async ({\n ownerName,\n platformName,\n repoName,\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 // 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 } = await runForm<BaseFields>(\n BASE_PROMPT_PROPS,\n );\n log.plain(chalk.cyan(repoName), 'by', chalk.cyan(ownerName));\n\n const templateData = await baseToTemplateData({\n ownerName,\n platformName,\n repoName,\n });\n\n const destinationDir = repoName;\n\n await createDirectory(destinationDir);\n\n log.newline();\n const templateName = await getTemplateName();\n\n await cloneTemplate(templateName, destinationDir);\n\n const { entryPoint, fields, noSkip, type } = getTemplateConfig(\n path.join(process.cwd(), destinationDir),\n );\n\n if (fields.length === 0) {\n return {\n destinationDir,\n entryPoint,\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 templateComplete: true,\n templateData: { ...templateData, ...customAnswers },\n templateName,\n type,\n };\n }\n\n log.newline();\n log.warn(`Resume this later with ${chalk.bold('yarn skuba configure')}.`);\n\n const customAnswers = generatePlaceholders(fields);\n\n return {\n destinationDir,\n entryPoint,\n templateComplete: false,\n templateData: { ...templateData, ...customAnswers },\n templateName,\n type,\n };\n};\n\nconst configureFromPipe = async (): Promise<InitConfig> => {\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 const result = InitConfigInput.validate(value);\n\n if (!result.success) {\n log.err('Invalid data from stdin:');\n log.err(result.message);\n process.exit(1);\n }\n\n const { destinationDir, templateComplete, templateName } = result.value;\n\n const templateData = {\n ...(await baseToTemplateData(result.value.templateData)),\n ...result.value.templateData,\n };\n\n await createDirectory(destinationDir);\n\n await cloneTemplate(templateName, destinationDir);\n\n const { entryPoint, fields, noSkip, type } = getTemplateConfig(\n path.join(process.cwd(), destinationDir),\n );\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.value,\n entryPoint,\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.value,\n entryPoint,\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
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/cli/init/prompts.ts"],
|
|
4
|
-
"sourcesContent": ["import { pathExists } from 'fs-extra';\n\nimport { TEMPLATE_NAMES_WITH_BYO } from '../../utils/template';\n\nimport
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAA2B;AAE3B,sBAAwC;
|
|
4
|
+
"sourcesContent": ["import { pathExists } from 'fs-extra';\n\nimport { TEMPLATE_NAMES_WITH_BYO } from '../../utils/template';\n\nimport {\n PLATFORM_OPTIONS,\n type Platform,\n isGitHubOrg,\n isGitHubRepo,\n isGitHubTeam,\n isPlatform,\n} from './validation';\n\nimport { Input, Select } from 'enquirer';\n\nexport type BaseFields = Record<\n (typeof BASE_CHOICES)[number]['name'],\n string\n> & {\n platformName: Platform;\n};\n\nconst BASE_CHOICES = [\n {\n name: 'ownerName',\n message: 'Owner',\n initial: 'SEEK-Jobs/my-team',\n validate: (value: unknown) => {\n if (typeof value !== 'string') {\n return 'required';\n }\n\n const [org, team] = value.split('/');\n\n if (!org || !isGitHubOrg(org)) {\n return 'fails GitHub validation';\n }\n\n return (\n team === undefined || isGitHubTeam(team) || 'fails GitHub validation'\n );\n },\n },\n {\n name: 'repoName',\n message: 'Repo',\n initial: 'my-repo',\n validate: async (value: unknown) => {\n if (typeof value !== 'string') {\n return 'required';\n }\n\n if (!isGitHubRepo(value)) {\n return 'fails GitHub validation';\n }\n\n const exists = await pathExists(value);\n\n return !exists || `'${value}' is an existing directory`;\n },\n },\n {\n name: 'platformName',\n message: 'Platform',\n initial: PLATFORM_OPTIONS,\n validate: (value: unknown) =>\n isPlatform(value) || `must be ${PLATFORM_OPTIONS}`,\n },\n] as const;\n\nexport const BASE_PROMPT_PROPS = {\n choices: BASE_CHOICES,\n message: 'For starters, some project details:',\n name: 'baseAnswers',\n};\n\nexport const SHOULD_CONTINUE_PROMPT = new Select({\n choices: ['yes', 'no'] as const,\n message: 'Fill this in now?',\n name: 'shouldContinue',\n});\n\nexport const GIT_PATH_PROMPT = new Input({\n message: 'Git path',\n name: 'gitPath',\n initial: 'seek-oss/skuba',\n validate: (value) => /[^/]+\\/[^/]+/.test(value) || 'Path is not valid',\n});\n\nexport const TEMPLATE_PROMPT = new Select({\n choices: TEMPLATE_NAMES_WITH_BYO,\n message: 'Select a template:',\n name: 'templateName',\n});\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAA2B;AAE3B,sBAAwC;AAExC,wBAOO;AAEP,sBAA8B;AAS9B,MAAM,eAAe;AAAA,EACnB;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU,CAAC,UAAmB;AAC5B,UAAI,OAAO,UAAU,UAAU;AAC7B,eAAO;AAAA,MACT;AAEA,YAAM,CAAC,KAAK,IAAI,IAAI,MAAM,MAAM,GAAG;AAEnC,UAAI,CAAC,OAAO,KAAC,+BAAY,GAAG,GAAG;AAC7B,eAAO;AAAA,MACT;AAEA,aACE,SAAS,cAAa,gCAAa,IAAI,KAAK;AAAA,IAEhD;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU,OAAO,UAAmB;AAClC,UAAI,OAAO,UAAU,UAAU;AAC7B,eAAO;AAAA,MACT;AAEA,UAAI,KAAC,gCAAa,KAAK,GAAG;AACxB,eAAO;AAAA,MACT;AAEA,YAAM,SAAS,UAAM,4BAAW,KAAK;AAErC,aAAO,CAAC,UAAU,IAAI,KAAK;AAAA,IAC7B;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU,CAAC,cACT,8BAAW,KAAK,KAAK,WAAW,kCAAgB;AAAA,EACpD;AACF;AAEO,MAAM,oBAAoB;AAAA,EAC/B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,MAAM;AACR;AAEO,MAAM,yBAAyB,IAAI,uBAAO;AAAA,EAC/C,SAAS,CAAC,OAAO,IAAI;AAAA,EACrB,SAAS;AAAA,EACT,MAAM;AACR,CAAC;AAEM,MAAM,kBAAkB,IAAI,sBAAM;AAAA,EACvC,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU,CAAC,UAAU,eAAe,KAAK,KAAK,KAAK;AACrD,CAAC;AAEM,MAAM,kBAAkB,IAAI,uBAAO;AAAA,EACxC,SAAS;AAAA,EACT,SAAS;AAAA,EACT,MAAM;AACR,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/lib/cli/lint/autofix.js
CHANGED
|
@@ -36,6 +36,7 @@ var import_path = __toESM(require("path"));
|
|
|
36
36
|
var import_util = require("util");
|
|
37
37
|
var import_fs_extra = __toESM(require("fs-extra"));
|
|
38
38
|
var import_simple_git = __toESM(require("simple-git"));
|
|
39
|
+
var Buildkite = __toESM(require("../../api/buildkite"));
|
|
39
40
|
var Git = __toESM(require("../../api/git"));
|
|
40
41
|
var GitHub = __toESM(require("../../api/github"));
|
|
41
42
|
var import_env = require("../../utils/env");
|
|
@@ -47,6 +48,7 @@ var import_addEmptyExports = require("../configure/addEmptyExports");
|
|
|
47
48
|
var import_renovate = require("../configure/modules/renovate");
|
|
48
49
|
var import_patchServerListener = require("../configure/patchServerListener");
|
|
49
50
|
var import_refreshIgnoreFiles = require("../configure/refreshIgnoreFiles");
|
|
51
|
+
const RENOVATE_DEFAULT_PREFIX = "renovate";
|
|
50
52
|
const AUTOFIX_COMMIT_MESSAGE = "Run `skuba format`";
|
|
51
53
|
const AUTOFIX_DELETE_FILES = [
|
|
52
54
|
// Try to delete this SEEK-Jobs/gutenberg automation file that may have been
|
|
@@ -90,6 +92,19 @@ const shouldPush = async ({
|
|
|
90
92
|
if (isDefaultBuildkiteBranch || isProtectedGitHubBranch) {
|
|
91
93
|
return false;
|
|
92
94
|
}
|
|
95
|
+
if (currentBranch?.startsWith(RENOVATE_DEFAULT_PREFIX)) {
|
|
96
|
+
try {
|
|
97
|
+
await GitHub.getPullRequestNumber();
|
|
98
|
+
} catch (error) {
|
|
99
|
+
const warning = "An autofix is available, but it was not pushed because an open pull request for this Renovate branch could not be found. If a pull request has since been created, retry the lint step to push the fix.";
|
|
100
|
+
import_logging.log.warn(warning);
|
|
101
|
+
try {
|
|
102
|
+
await Buildkite.annotate(Buildkite.md.terminal(warning));
|
|
103
|
+
} catch {
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
93
108
|
let headCommitMessage;
|
|
94
109
|
try {
|
|
95
110
|
headCommitMessage = await Git.getHeadCommitMessage({ dir });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/cli/lint/autofix.ts"],
|
|
4
|
-
"sourcesContent": ["import path from 'path';\nimport { inspect } from 'util';\n\nimport fs from 'fs-extra';\nimport simpleGit from 'simple-git';\n\nimport * as Git from '../../api/git';\nimport * as GitHub from '../../api/github';\nimport { isCiEnv } from '../../utils/env';\nimport { createLogger, log } from '../../utils/logging';\nimport { throwOnTimeout } from '../../utils/wait';\nimport { runESLint } from '../adapter/eslint';\nimport { runPrettier } from '../adapter/prettier';\nimport { JEST_SETUP_FILES } from '../configure/addEmptyExports';\nimport { RENOVATE_CONFIG_FILENAMES } from '../configure/modules/renovate';\nimport { SERVER_LISTENER_FILENAME } from '../configure/patchServerListener';\nimport { REFRESHABLE_IGNORE_FILES } from '../configure/refreshIgnoreFiles';\n\nimport type { Input } from './types';\n\nconst AUTOFIX_COMMIT_MESSAGE = 'Run `skuba format`';\n\nconst AUTOFIX_DELETE_FILES = [\n // Try to delete this SEEK-Jobs/gutenberg automation file that may have been\n // accidentally committed in a prior autofix.\n 'Dockerfile-incunabulum',\n];\n\nconst AUTOFIX_CODEGEN_FILES = new Set<string>([\n ...AUTOFIX_DELETE_FILES,\n ...JEST_SETUP_FILES,\n ...REFRESHABLE_IGNORE_FILES,\n ...RENOVATE_CONFIG_FILENAMES,\n SERVER_LISTENER_FILENAME,\n]);\n\nexport const AUTOFIX_IGNORE_FILES: Git.ChangedFile[] = [\n {\n path: '.npmrc',\n state: 'added',\n },\n {\n // This file may already exist in version control, but we shouldn't commit\n // further changes as the CI environment may have appended an npm token.\n path: '.npmrc',\n state: 'modified',\n },\n {\n path: 'Dockerfile-incunabulum',\n state: 'added',\n },\n];\n\nconst shouldPush = async ({\n currentBranch,\n dir,\n}: {\n currentBranch?: string;\n dir: string;\n}) => {\n if (!isCiEnv()) {\n // We're not running in a CI environment so we don't need to push autofixes.\n // Ideally we'd drive this off of repository write permissions, but that is\n // non-trivial to infer without attempting an actual write.\n return false;\n }\n\n const isDefaultBuildkiteBranch =\n currentBranch &&\n [process.env.BUILDKITE_PIPELINE_DEFAULT_BRANCH, 'master', 'main'].includes(\n currentBranch,\n );\n\n const isProtectedGitHubBranch = process.env.GITHUB_REF_PROTECTED === 'true';\n\n if (isDefaultBuildkiteBranch || isProtectedGitHubBranch) {\n // The current branch is a protected branch.\n // We respect GitHub Flow; avoid pushing directly to the default branch.\n return false;\n }\n\n let headCommitMessage;\n try {\n headCommitMessage = await Git.getHeadCommitMessage({ dir });\n } catch {}\n\n if (headCommitMessage === AUTOFIX_COMMIT_MESSAGE) {\n // Short circuit when the head commit appears to be one of our autofixes.\n // Repeating the same operation is unlikely to correct outstanding issues.\n return false;\n }\n\n // Allow the push attempt to go ahead if our guards have been cleared.\n return true;\n};\n\ninterface AutofixParameters {\n debug: Input['debug'];\n\n eslint: boolean;\n prettier: boolean;\n}\n\n/**\n * @returns Whether skuba codegenned a file change which should be included in\n * an autofix commit.\n */\nconst tryCodegen = async (dir: string): Promise<boolean> => {\n try {\n // Try to forcibly remove `AUTOFIX_DELETE_FILES` from source control.\n // These may include outdated configuration files or internal files that\n // were accidentally committed by an autofix.\n await Promise.all(\n AUTOFIX_DELETE_FILES.map((filename) =>\n fs.promises.rm(path.join(dir, filename), { force: true }),\n ),\n );\n\n // Search codegenned file changes in the local Git working directory.\n // These may include the `AUTOFIX_DELETE_FILES` deleted above or fixups to\n // ignore files and module exports that were run at the start of the\n // `skuba lint` command.\n const changedFiles = await Git.getChangedFiles({\n dir,\n\n ignore: AUTOFIX_IGNORE_FILES,\n });\n\n // Determine if a meaningful codegen change\n return changedFiles.some((changedFile) =>\n AUTOFIX_CODEGEN_FILES.has(changedFile.path),\n );\n } catch (err) {\n log.warn(log.bold('Failed to evaluate codegen changes.'));\n log.subtle(inspect(err));\n\n return false;\n }\n};\n\nexport const autofix = async (params: AutofixParameters): Promise<void> => {\n const dir = process.cwd();\n\n const codegen = await tryCodegen(dir);\n\n if (!params.eslint && !params.prettier && !codegen) {\n return;\n }\n\n let currentBranch;\n try {\n currentBranch = await Git.currentBranch({ dir });\n } catch {}\n\n if (!(await shouldPush({ currentBranch, dir }))) {\n return;\n }\n\n try {\n log.newline();\n if (!params.eslint && !params.prettier) {\n log.warn('Trying to push codegen updates...');\n } else {\n log.warn(\n `Trying to autofix with ${\n params.eslint ? 'ESLint and ' : ''\n }Prettier...`,\n );\n\n const logger = createLogger(params.debug);\n\n if (params.eslint) {\n await runESLint('format', logger);\n }\n // Unconditionally re-run Prettier; reaching here means we have pre-existing\n // format violations or may have created new ones through ESLint fixes.\n await runPrettier('format', logger);\n }\n\n if (process.env.GITHUB_ACTIONS) {\n // GitHub runners have Git installed locally\n const ref = await Git.commitAllChanges({\n dir,\n message: AUTOFIX_COMMIT_MESSAGE,\n\n ignore: AUTOFIX_IGNORE_FILES,\n });\n\n if (!ref) {\n return log.warn('No autofixes detected.');\n }\n\n await throwOnTimeout(simpleGit().push(), { s: 30 });\n log.warn(`Pushed fix commit ${ref}.`);\n return;\n }\n\n // Other CI Environments, use GitHub API\n if (!currentBranch) {\n log.warn('Could not determine the current branch.');\n log.warn(\n 'Please propagate BUILDKITE_BRANCH, GITHUB_HEAD_REF, GITHUB_REF_NAME, or the .git directory to your container.',\n );\n return;\n }\n\n const ref = await throwOnTimeout(\n GitHub.uploadAllFileChanges({\n branch: currentBranch,\n dir,\n messageHeadline: AUTOFIX_COMMIT_MESSAGE,\n\n ignore: AUTOFIX_IGNORE_FILES,\n }),\n { s: 30 },\n );\n\n if (!ref) {\n return log.warn('No autofixes detected.');\n }\n\n log.warn(`Pushed fix commit ${ref}.`);\n } catch (err) {\n log.warn(log.bold('Failed to push fix commit.'));\n log.warn(\n log.bold(\n 'Does your CI environment have write access to your Git repository?',\n ),\n );\n log.subtle(inspect(err));\n }\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import path from 'path';\nimport { inspect } from 'util';\n\nimport fs from 'fs-extra';\nimport simpleGit from 'simple-git';\n\nimport * as Buildkite from '../../api/buildkite';\nimport * as Git from '../../api/git';\nimport * as GitHub from '../../api/github';\nimport { isCiEnv } from '../../utils/env';\nimport { createLogger, log } from '../../utils/logging';\nimport { throwOnTimeout } from '../../utils/wait';\nimport { runESLint } from '../adapter/eslint';\nimport { runPrettier } from '../adapter/prettier';\nimport { JEST_SETUP_FILES } from '../configure/addEmptyExports';\nimport { RENOVATE_CONFIG_FILENAMES } from '../configure/modules/renovate';\nimport { SERVER_LISTENER_FILENAME } from '../configure/patchServerListener';\nimport { REFRESHABLE_IGNORE_FILES } from '../configure/refreshIgnoreFiles';\n\nimport type { Input } from './types';\n\nconst RENOVATE_DEFAULT_PREFIX = 'renovate';\n\nconst AUTOFIX_COMMIT_MESSAGE = 'Run `skuba format`';\n\nconst AUTOFIX_DELETE_FILES = [\n // Try to delete this SEEK-Jobs/gutenberg automation file that may have been\n // accidentally committed in a prior autofix.\n 'Dockerfile-incunabulum',\n];\n\nconst AUTOFIX_CODEGEN_FILES = new Set<string>([\n ...AUTOFIX_DELETE_FILES,\n ...JEST_SETUP_FILES,\n ...REFRESHABLE_IGNORE_FILES,\n ...RENOVATE_CONFIG_FILENAMES,\n SERVER_LISTENER_FILENAME,\n]);\n\nexport const AUTOFIX_IGNORE_FILES: Git.ChangedFile[] = [\n {\n path: '.npmrc',\n state: 'added',\n },\n {\n // This file may already exist in version control, but we shouldn't commit\n // further changes as the CI environment may have appended an npm token.\n path: '.npmrc',\n state: 'modified',\n },\n {\n path: 'Dockerfile-incunabulum',\n state: 'added',\n },\n];\n\nconst shouldPush = async ({\n currentBranch,\n dir,\n}: {\n currentBranch?: string;\n dir: string;\n}) => {\n if (!isCiEnv()) {\n // We're not running in a CI environment so we don't need to push autofixes.\n // Ideally we'd drive this off of repository write permissions, but that is\n // non-trivial to infer without attempting an actual write.\n return false;\n }\n\n const isDefaultBuildkiteBranch =\n currentBranch &&\n [process.env.BUILDKITE_PIPELINE_DEFAULT_BRANCH, 'master', 'main'].includes(\n currentBranch,\n );\n\n const isProtectedGitHubBranch = process.env.GITHUB_REF_PROTECTED === 'true';\n\n if (isDefaultBuildkiteBranch || isProtectedGitHubBranch) {\n // The current branch is a protected branch.\n // We respect GitHub Flow; avoid pushing directly to the default branch.\n return false;\n }\n\n if (currentBranch?.startsWith(RENOVATE_DEFAULT_PREFIX)) {\n try {\n await GitHub.getPullRequestNumber();\n } catch (error) {\n const warning =\n 'An autofix is available, but it was not pushed because an open pull request for this Renovate branch could not be found. If a pull request has since been created, retry the lint step to push the fix.';\n log.warn(warning);\n try {\n await Buildkite.annotate(Buildkite.md.terminal(warning));\n } catch {}\n\n return false;\n }\n }\n\n let headCommitMessage;\n try {\n headCommitMessage = await Git.getHeadCommitMessage({ dir });\n } catch {}\n\n if (headCommitMessage === AUTOFIX_COMMIT_MESSAGE) {\n // Short circuit when the head commit appears to be one of our autofixes.\n // Repeating the same operation is unlikely to correct outstanding issues.\n return false;\n }\n\n // Allow the push attempt to go ahead if our guards have been cleared.\n return true;\n};\n\ninterface AutofixParameters {\n debug: Input['debug'];\n\n eslint: boolean;\n prettier: boolean;\n}\n\n/**\n * @returns Whether skuba codegenned a file change which should be included in\n * an autofix commit.\n */\nconst tryCodegen = async (dir: string): Promise<boolean> => {\n try {\n // Try to forcibly remove `AUTOFIX_DELETE_FILES` from source control.\n // These may include outdated configuration files or internal files that\n // were accidentally committed by an autofix.\n await Promise.all(\n AUTOFIX_DELETE_FILES.map((filename) =>\n fs.promises.rm(path.join(dir, filename), { force: true }),\n ),\n );\n\n // Search codegenned file changes in the local Git working directory.\n // These may include the `AUTOFIX_DELETE_FILES` deleted above or fixups to\n // ignore files and module exports that were run at the start of the\n // `skuba lint` command.\n const changedFiles = await Git.getChangedFiles({\n dir,\n\n ignore: AUTOFIX_IGNORE_FILES,\n });\n\n // Determine if a meaningful codegen change\n return changedFiles.some((changedFile) =>\n AUTOFIX_CODEGEN_FILES.has(changedFile.path),\n );\n } catch (err) {\n log.warn(log.bold('Failed to evaluate codegen changes.'));\n log.subtle(inspect(err));\n\n return false;\n }\n};\n\nexport const autofix = async (params: AutofixParameters): Promise<void> => {\n const dir = process.cwd();\n\n const codegen = await tryCodegen(dir);\n\n if (!params.eslint && !params.prettier && !codegen) {\n return;\n }\n\n let currentBranch;\n try {\n currentBranch = await Git.currentBranch({ dir });\n } catch {}\n\n if (!(await shouldPush({ currentBranch, dir }))) {\n return;\n }\n\n try {\n log.newline();\n if (!params.eslint && !params.prettier) {\n log.warn('Trying to push codegen updates...');\n } else {\n log.warn(\n `Trying to autofix with ${\n params.eslint ? 'ESLint and ' : ''\n }Prettier...`,\n );\n\n const logger = createLogger(params.debug);\n\n if (params.eslint) {\n await runESLint('format', logger);\n }\n // Unconditionally re-run Prettier; reaching here means we have pre-existing\n // format violations or may have created new ones through ESLint fixes.\n await runPrettier('format', logger);\n }\n\n if (process.env.GITHUB_ACTIONS) {\n // GitHub runners have Git installed locally\n const ref = await Git.commitAllChanges({\n dir,\n message: AUTOFIX_COMMIT_MESSAGE,\n\n ignore: AUTOFIX_IGNORE_FILES,\n });\n\n if (!ref) {\n return log.warn('No autofixes detected.');\n }\n\n await throwOnTimeout(simpleGit().push(), { s: 30 });\n log.warn(`Pushed fix commit ${ref}.`);\n return;\n }\n\n // Other CI Environments, use GitHub API\n if (!currentBranch) {\n log.warn('Could not determine the current branch.');\n log.warn(\n 'Please propagate BUILDKITE_BRANCH, GITHUB_HEAD_REF, GITHUB_REF_NAME, or the .git directory to your container.',\n );\n return;\n }\n\n const ref = await throwOnTimeout(\n GitHub.uploadAllFileChanges({\n branch: currentBranch,\n dir,\n messageHeadline: AUTOFIX_COMMIT_MESSAGE,\n\n ignore: AUTOFIX_IGNORE_FILES,\n }),\n { s: 30 },\n );\n\n if (!ref) {\n return log.warn('No autofixes detected.');\n }\n\n log.warn(`Pushed fix commit ${ref}.`);\n } catch (err) {\n log.warn(log.bold('Failed to push fix commit.'));\n log.warn(\n log.bold(\n 'Does your CI environment have write access to your Git repository?',\n ),\n );\n log.subtle(inspect(err));\n }\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["fs", "path", "ref", "simpleGit"]
|
|
7
7
|
}
|
package/lib/cli/lint/eslint.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ESLintOutput } from '../adapter/eslint';
|
|
2
2
|
import type { Input } from './types';
|
|
3
3
|
export declare const runESLintInCurrentThread: ({ debug }: Input) => Promise<ESLintOutput>;
|
|
4
4
|
export declare const runESLintInWorkerThread: (input: Input) => Promise<ESLintOutput>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/cli/lint/eslint.ts"],
|
|
4
|
-
"sourcesContent": ["import path from 'path';\nimport { isMainThread } from 'worker_threads';\n\nimport chalk from 'chalk';\n\nimport { createLogger } from '../../utils/logging';\nimport { execWorkerThread, postWorkerOutput } from '../../utils/worker';\nimport type
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AACjB,4BAA6B;AAE7B,mBAAkB;AAElB,qBAA6B;AAC7B,oBAAmD;
|
|
4
|
+
"sourcesContent": ["import path from 'path';\nimport { isMainThread } from 'worker_threads';\n\nimport chalk from 'chalk';\n\nimport { createLogger } from '../../utils/logging';\nimport { execWorkerThread, postWorkerOutput } from '../../utils/worker';\nimport { type ESLintOutput, runESLint } from '../adapter/eslint';\n\nimport type { Input } from './types';\n\nconst LOG_PREFIX = chalk.magenta('ESLint \u2502');\n\nexport const runESLintInCurrentThread = ({ debug }: Input) =>\n runESLint('lint', createLogger(debug, LOG_PREFIX));\n\nexport const runESLintInWorkerThread = (input: Input) =>\n execWorkerThread<Input, ESLintOutput>(\n path.posix.join(__dirname, 'eslint.js'),\n input,\n );\n\nif (!isMainThread) {\n postWorkerOutput(runESLintInCurrentThread, createLogger(false, LOG_PREFIX));\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AACjB,4BAA6B;AAE7B,mBAAkB;AAElB,qBAA6B;AAC7B,oBAAmD;AACnD,oBAA6C;AAI7C,MAAM,aAAa,aAAAA,QAAM,QAAQ,iBAAY;AAEtC,MAAM,2BAA2B,CAAC,EAAE,MAAM,UAC/C,yBAAU,YAAQ,6BAAa,OAAO,UAAU,CAAC;AAE5C,MAAM,0BAA0B,CAAC,cACtC;AAAA,EACE,YAAAC,QAAK,MAAM,KAAK,WAAW,WAAW;AAAA,EACtC;AACF;AAEF,IAAI,CAAC,oCAAc;AACjB,sCAAiB,8BAA0B,6BAAa,OAAO,UAAU,CAAC;AAC5E;",
|
|
6
6
|
"names": ["chalk", "path"]
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type PrettierOutput } from '../adapter/prettier';
|
|
2
2
|
import type { Input } from './types';
|
|
3
3
|
export declare const runPrettierInCurrentThread: ({ debug }: Input) => Promise<PrettierOutput>;
|
|
4
4
|
export declare const runPrettierInWorkerThread: (input: Input) => Promise<PrettierOutput>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/cli/lint/prettier.ts"],
|
|
4
|
-
"sourcesContent": ["import path from 'path';\nimport { isMainThread } from 'worker_threads';\n\nimport chalk from 'chalk';\n\nimport { createLogger } from '../../utils/logging';\nimport { execWorkerThread, postWorkerOutput } from '../../utils/worker';\nimport type
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AACjB,4BAA6B;AAE7B,mBAAkB;AAElB,qBAA6B;AAC7B,oBAAmD;
|
|
4
|
+
"sourcesContent": ["import path from 'path';\nimport { isMainThread } from 'worker_threads';\n\nimport chalk from 'chalk';\n\nimport { createLogger } from '../../utils/logging';\nimport { execWorkerThread, postWorkerOutput } from '../../utils/worker';\nimport { type PrettierOutput, runPrettier } from '../adapter/prettier';\n\nimport type { Input } from './types';\n\nconst LOG_PREFIX = chalk.cyan('Prettier \u2502');\n\nexport const runPrettierInCurrentThread = ({ debug }: Input) =>\n runPrettier('lint', createLogger(debug, LOG_PREFIX));\n\nexport const runPrettierInWorkerThread = (input: Input) =>\n execWorkerThread<Input, PrettierOutput>(\n path.posix.join(__dirname, 'prettier.js'),\n input,\n );\n\nif (!isMainThread) {\n postWorkerOutput(runPrettierInCurrentThread, createLogger(false, LOG_PREFIX));\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AACjB,4BAA6B;AAE7B,mBAAkB;AAElB,qBAA6B;AAC7B,oBAAmD;AACnD,sBAAiD;AAIjD,MAAM,aAAa,aAAAA,QAAM,KAAK,iBAAY;AAEnC,MAAM,6BAA6B,CAAC,EAAE,MAAM,UACjD,6BAAY,YAAQ,6BAAa,OAAO,UAAU,CAAC;AAE9C,MAAM,4BAA4B,CAAC,cACxC;AAAA,EACE,YAAAC,QAAK,MAAM,KAAK,WAAW,aAAa;AAAA,EACxC;AACF;AAEF,IAAI,CAAC,oCAAc;AACjB,sCAAiB,gCAA4B,6BAAa,OAAO,UAAU,CAAC;AAC9E;",
|
|
6
6
|
"names": ["chalk", "path"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var prettier_exports = {};
|
|
30
|
+
__export(prettier_exports, {
|
|
31
|
+
default: () => SnapshotPrettifier
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(prettier_exports);
|
|
34
|
+
var import_fs_extra = __toESM(require("fs-extra"));
|
|
35
|
+
var import_prettier = require("prettier");
|
|
36
|
+
var import_prettier2 = require("../../../../cli/adapter/prettier");
|
|
37
|
+
class SnapshotPrettifier {
|
|
38
|
+
async onTestFileResult(...[test, testResult]) {
|
|
39
|
+
if (!testResult.snapshot.added && !testResult.snapshot.updated) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const filepath = test.path;
|
|
43
|
+
try {
|
|
44
|
+
const [config, data] = await Promise.all([
|
|
45
|
+
(0, import_prettier.resolveConfig)(filepath),
|
|
46
|
+
import_fs_extra.default.promises.readFile(filepath, "utf-8")
|
|
47
|
+
]);
|
|
48
|
+
const formatted = await (0, import_prettier2.formatOrLintFile)(
|
|
49
|
+
{
|
|
50
|
+
data,
|
|
51
|
+
filepath,
|
|
52
|
+
options: {
|
|
53
|
+
...config,
|
|
54
|
+
filepath
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"format",
|
|
58
|
+
null
|
|
59
|
+
);
|
|
60
|
+
if (typeof formatted === "string") {
|
|
61
|
+
await import_fs_extra.default.promises.writeFile(filepath, formatted);
|
|
62
|
+
}
|
|
63
|
+
} catch {
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/cli/test/reporters/prettier/index.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Reporter } from '@jest/reporters';\nimport fs from 'fs-extra';\nimport { resolveConfig } from 'prettier';\n\nimport { formatOrLintFile } from '../../../../cli/adapter/prettier';\n\nexport default class SnapshotPrettifier\n implements Pick<Reporter, 'onTestFileResult'>\n{\n async onTestFileResult(\n ...[test, testResult]: Parameters<NonNullable<Reporter['onTestFileResult']>>\n ): Promise<void> {\n if (!testResult.snapshot.added && !testResult.snapshot.updated) {\n return;\n }\n\n const filepath = test.path;\n\n // This is a best-effort workaround to automatically format code.\n // Don't pollute console output if it fails for whatever reason.\n try {\n const [config, data] = await Promise.all([\n resolveConfig(filepath),\n fs.promises.readFile(filepath, 'utf-8'),\n ]);\n\n const formatted = await formatOrLintFile(\n {\n data,\n filepath,\n options: {\n ...config,\n filepath,\n },\n },\n 'format',\n null,\n );\n\n if (typeof formatted === 'string') {\n await fs.promises.writeFile(filepath, formatted);\n }\n } catch {}\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,sBAAe;AACf,sBAA8B;AAE9B,IAAAA,mBAAiC;AAEjC,MAAO,mBAEP;AAAA,EACE,MAAM,oBACD,CAAC,MAAM,UAAU,GACL;AACf,QAAI,CAAC,WAAW,SAAS,SAAS,CAAC,WAAW,SAAS,SAAS;AAC9D;AAAA,IACF;AAEA,UAAM,WAAW,KAAK;AAItB,QAAI;AACF,YAAM,CAAC,QAAQ,IAAI,IAAI,MAAM,QAAQ,IAAI;AAAA,YACvC,+BAAc,QAAQ;AAAA,QACtB,gBAAAC,QAAG,SAAS,SAAS,UAAU,OAAO;AAAA,MACxC,CAAC;AAED,YAAM,YAAY,UAAM;AAAA,QACtB;AAAA,UACE;AAAA,UACA;AAAA,UACA,SAAS;AAAA,YACP,GAAG;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,UAAI,OAAO,cAAc,UAAU;AACjC,cAAM,gBAAAA,QAAG,SAAS,UAAU,UAAU,SAAS;AAAA,MACjD;AAAA,IACF,QAAQ;AAAA,IAAC;AAAA,EACX;AACF;",
|
|
6
|
+
"names": ["import_prettier", "fs"]
|
|
7
|
+
}
|
package/lib/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Entry point for the Node.js development API.\n *\n * This is where skuba imports point to:\n *\n * ```typescript\n * import { Net } from 'skuba';\n *\n * const { Net } = require('skuba');\n * ```\n */\n\nexport * as Buildkite from './api/buildkite';\nexport * as Git from './api/git';\nexport * as GitHub from './api/github';\nexport * as Jest from './api/jest';\nexport * as Net from './api/net';\n\n// evanw/esbuild#2388\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace WebAssembly {\n interface Module {}\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * Entry point for the Node.js development API.\n *\n * This is where skuba imports point to:\n *\n * ```typescript\n * import { Net } from 'skuba';\n *\n * const { Net } = require('skuba');\n * ```\n */\n\nexport * as Buildkite from './api/buildkite';\nexport * as Git from './api/git';\nexport * as GitHub from './api/github';\nexport * as Jest from './api/jest';\nexport * as Net from './api/net';\n\n// evanw/esbuild#2388\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace WebAssembly {\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\n interface Module {}\n }\n}\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA,gBAA2B;AAC3B,UAAqB;AACrB,aAAwB;AACxB,WAAsB;AACtB,UAAqB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/lib/utils/copy.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ interface CopyFilesOptions {
|
|
|
5
5
|
destinationRoot: string;
|
|
6
6
|
include: (pathname: string) => boolean;
|
|
7
7
|
overwrite?: boolean;
|
|
8
|
-
processors:
|
|
8
|
+
processors: TextProcessor[];
|
|
9
9
|
stripUnderscorePrefix?: boolean;
|
|
10
10
|
}
|
|
11
11
|
export declare const createEjsRenderer: (templateData: Record<string, unknown>) => TextProcessor;
|
package/lib/utils/copy.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/copy.ts"],
|
|
4
|
-
"sourcesContent": ["import path from 'path';\n\nimport ejs from 'ejs';\nimport fs from 'fs-extra';\n\nimport { isErrorWithCode } from './error';\nimport { log } from './logging';\n\nexport type TextProcessor = (contents: string) => string;\n\nexport const copyFile = async (\n sourcePath: string,\n destinationPath: string,\n {\n overwrite = true,\n processors,\n }: Pick<CopyFilesOptions, 'overwrite' | 'processors'>,\n) => {\n const oldContents = await fs.promises.readFile(sourcePath, 'utf8');\n\n const newContents = processors.reduce(\n (contents, process) => process(contents),\n oldContents,\n );\n\n if (oldContents === newContents && sourcePath === destinationPath) {\n return;\n }\n\n try {\n await fs.promises.writeFile(destinationPath, newContents, {\n flag: overwrite ? 'w' : 'wx',\n });\n } catch (err) {\n if (isErrorWithCode(err, 'EEXIST')) {\n return;\n }\n\n throw err;\n }\n};\n\ninterface CopyFilesOptions {\n sourceRoot: string;\n destinationRoot: string;\n\n include: (pathname: string) => boolean;\n overwrite?: boolean;\n processors:
|
|
4
|
+
"sourcesContent": ["import path from 'path';\n\nimport ejs from 'ejs';\nimport fs from 'fs-extra';\n\nimport { isErrorWithCode } from './error';\nimport { log } from './logging';\n\nexport type TextProcessor = (contents: string) => string;\n\nexport const copyFile = async (\n sourcePath: string,\n destinationPath: string,\n {\n overwrite = true,\n processors,\n }: Pick<CopyFilesOptions, 'overwrite' | 'processors'>,\n) => {\n const oldContents = await fs.promises.readFile(sourcePath, 'utf8');\n\n const newContents = processors.reduce(\n (contents, process) => process(contents),\n oldContents,\n );\n\n if (oldContents === newContents && sourcePath === destinationPath) {\n return;\n }\n\n try {\n await fs.promises.writeFile(destinationPath, newContents, {\n flag: overwrite ? 'w' : 'wx',\n });\n } catch (err) {\n if (isErrorWithCode(err, 'EEXIST')) {\n return;\n }\n\n throw err;\n }\n};\n\ninterface CopyFilesOptions {\n sourceRoot: string;\n destinationRoot: string;\n\n include: (pathname: string) => boolean;\n overwrite?: boolean;\n processors: TextProcessor[];\n stripUnderscorePrefix?: boolean;\n}\n\nexport const createEjsRenderer =\n (templateData: Record<string, unknown>): TextProcessor =>\n (contents) =>\n ejs.render(contents, templateData);\n\nexport const createStringReplacer =\n (\n replacements: Array<{\n input: RegExp;\n output: string;\n }>,\n ): TextProcessor =>\n (contents) =>\n replacements.reduce(\n (newContents, { input, output }) => newContents.replace(input, output),\n contents,\n );\n\nexport const copyFiles = async (\n opts: CopyFilesOptions,\n currentSourceDir: string = opts.sourceRoot,\n currentDestinationDir: string = opts.destinationRoot,\n) => {\n const filenames = await fs.promises.readdir(currentSourceDir);\n\n const toDestinationPath = (filename: string) =>\n path.join(\n currentDestinationDir,\n opts.stripUnderscorePrefix\n ? filename\n .replace(/^_\\./, '.')\n .replace(/^_package\\.json/, 'package.json')\n : filename,\n );\n\n const filteredFilenames = filenames.filter((filename) =>\n opts.include(\n path.relative(opts.destinationRoot, toDestinationPath(filename)),\n ),\n );\n\n await Promise.all(\n filteredFilenames.map(async (filename) => {\n const sourcePath = path.join(currentSourceDir, filename);\n const destinationPath = toDestinationPath(filename);\n\n try {\n await copyFile(sourcePath, destinationPath, opts);\n } catch (err) {\n if (isErrorWithCode(err, 'EISDIR')) {\n await fs.promises.mkdir(destinationPath, { recursive: true });\n return copyFiles(opts, sourcePath, destinationPath);\n }\n\n log.err('Failed to render', log.bold(sourcePath));\n\n throw err;\n }\n }),\n );\n};\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAEjB,iBAAgB;AAChB,sBAAe;AAEf,mBAAgC;AAChC,qBAAoB;AAIb,MAAM,WAAW,OACtB,YACA,iBACA;AAAA,EACE,YAAY;AAAA,EACZ;AACF,MACG;AACH,QAAM,cAAc,MAAM,gBAAAA,QAAG,SAAS,SAAS,YAAY,MAAM;AAEjE,QAAM,cAAc,WAAW;AAAA,IAC7B,CAAC,UAAU,YAAY,QAAQ,QAAQ;AAAA,IACvC;AAAA,EACF;AAEA,MAAI,gBAAgB,eAAe,eAAe,iBAAiB;AACjE;AAAA,EACF;AAEA,MAAI;AACF,UAAM,gBAAAA,QAAG,SAAS,UAAU,iBAAiB,aAAa;AAAA,MACxD,MAAM,YAAY,MAAM;AAAA,IAC1B,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAI,8BAAgB,KAAK,QAAQ,GAAG;AAClC;AAAA,IACF;AAEA,UAAM;AAAA,EACR;AACF;AAYO,MAAM,oBACX,CAAC,iBACD,CAAC,aACC,WAAAC,QAAI,OAAO,UAAU,YAAY;AAE9B,MAAM,uBACX,CACE,iBAKF,CAAC,aACC,aAAa;AAAA,EACX,CAAC,aAAa,EAAE,OAAO,OAAO,MAAM,YAAY,QAAQ,OAAO,MAAM;AAAA,EACrE;AACF;AAEG,MAAM,YAAY,OACvB,MACA,mBAA2B,KAAK,YAChC,wBAAgC,KAAK,oBAClC;AACH,QAAM,YAAY,MAAM,gBAAAD,QAAG,SAAS,QAAQ,gBAAgB;AAE5D,QAAM,oBAAoB,CAAC,aACzB,YAAAE,QAAK;AAAA,IACH;AAAA,IACA,KAAK,wBACD,SACG,QAAQ,QAAQ,GAAG,EACnB,QAAQ,mBAAmB,cAAc,IAC5C;AAAA,EACN;AAEF,QAAM,oBAAoB,UAAU;AAAA,IAAO,CAAC,aAC1C,KAAK;AAAA,MACH,YAAAA,QAAK,SAAS,KAAK,iBAAiB,kBAAkB,QAAQ,CAAC;AAAA,IACjE;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ,kBAAkB,IAAI,OAAO,aAAa;AACxC,YAAM,aAAa,YAAAA,QAAK,KAAK,kBAAkB,QAAQ;AACvD,YAAM,kBAAkB,kBAAkB,QAAQ;AAElD,UAAI;AACF,cAAM,SAAS,YAAY,iBAAiB,IAAI;AAAA,MAClD,SAAS,KAAK;AACZ,gBAAI,8BAAgB,KAAK,QAAQ,GAAG;AAClC,gBAAM,gBAAAF,QAAG,SAAS,MAAM,iBAAiB,EAAE,WAAW,KAAK,CAAC;AAC5D,iBAAO,UAAU,MAAM,YAAY,eAAe;AAAA,QACpD;AAEA,2BAAI,IAAI,oBAAoB,mBAAI,KAAK,UAAU,CAAC;AAEhD,cAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AACF;",
|
|
6
6
|
"names": ["fs", "ejs", "path"]
|
|
7
7
|
}
|
package/lib/utils/exec.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import stream from 'stream';
|
|
3
3
|
import type { Color } from 'chalk';
|
|
4
|
-
import
|
|
5
|
-
import execa from 'execa';
|
|
4
|
+
import execa, { type ExecaChildProcess } from 'execa';
|
|
6
5
|
export type Exec = (command: string, ...args: string[]) => ExecaChildProcess<string>;
|
|
7
6
|
interface ExecConcurrentlyCommand {
|
|
8
7
|
command: string;
|
package/lib/utils/exec.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/exec.ts"],
|
|
4
|
-
"sourcesContent": ["import { cpus } from 'os';\nimport stream from 'stream';\nimport util from 'util';\n\nimport type { Color } from 'chalk';\nimport concurrently from 'concurrently';\nimport
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAqB;AACrB,oBAAmB;AACnB,kBAAiB;AAGjB,0BAAyB;
|
|
4
|
+
"sourcesContent": ["import { cpus } from 'os';\nimport stream from 'stream';\nimport util from 'util';\n\nimport type { Color } from 'chalk';\nimport concurrently from 'concurrently';\nimport execa, { type ExecaChildProcess } from 'execa';\nimport npmRunPath from 'npm-run-path';\nimport npmWhich from 'npm-which';\n\nimport { ConcurrentlyErrors, isErrorWithCode } from './error';\nimport { log } from './logging';\n\nclass YarnSpamFilter extends stream.Transform {\n silenced = false;\n\n _transform(\n chunk: Uint8Array,\n _encoding: BufferEncoding,\n callback: stream.TransformCallback,\n ) {\n const str = Buffer.from(chunk).toString();\n\n // Yarn spews the entire installed dependency tree after this message\n if (str.startsWith('info Direct dependencies')) {\n this.silenced = true;\n }\n\n if (\n !this.silenced &&\n // This isn't very useful given the command generates a lockfile\n !str.startsWith('info No lockfile found')\n ) {\n this.push(chunk);\n }\n\n callback();\n }\n}\n\nclass YarnWarningFilter extends stream.Transform {\n _transform(\n chunk: Uint8Array,\n _encoding: BufferEncoding,\n callback: stream.TransformCallback,\n ) {\n const str = Buffer.from(chunk).toString();\n\n // Filter out annoying deprecation warnings that users can do little about\n if (!str.startsWith('warning skuba >')) {\n this.push(chunk);\n }\n\n callback();\n }\n}\n\nexport type Exec = (\n command: string,\n ...args: string[]\n) => ExecaChildProcess<string>;\n\ninterface ExecConcurrentlyCommand {\n command: string;\n name: string;\n prefixColor?: typeof Color;\n}\n\ninterface ExecConcurrentlyOptions {\n /**\n * The maximum number of processes that can execute concurrently.\n *\n * Defaults to the CPU core count.\n */\n maxProcesses?: number;\n\n /**\n * A set length to pad names to.\n *\n * Defaults to the length of the longest command name.\n */\n nameLength?: number;\n\n /**\n * The stream that logging output will be written to.\n *\n * Defaults to `process.stdout`.\n */\n outputStream?: stream.Writable;\n}\n\ntype ExecOptions = execa.Options & { streamStdio?: true | 'yarn' };\n\nconst envWithPath = {\n PATH: npmRunPath({ cwd: __dirname }),\n};\n\nconst runCommand = (command: string, args: string[], opts?: ExecOptions) => {\n const subprocess = execa(command, args, {\n localDir: __dirname,\n preferLocal: true,\n stdio: 'inherit',\n ...opts,\n });\n\n switch (opts?.streamStdio) {\n case 'yarn':\n const stderrFilter = new YarnWarningFilter();\n const stdoutFilter = new YarnSpamFilter();\n\n subprocess.stderr?.pipe(stderrFilter).pipe(process.stderr);\n subprocess.stdout?.pipe(stdoutFilter).pipe(process.stdout);\n\n break;\n\n case true:\n subprocess.stderr?.pipe(process.stderr);\n subprocess.stdout?.pipe(process.stdout);\n\n break;\n }\n\n return subprocess;\n};\n\nconst whichCallback = npmWhich(__dirname);\n\nconst which = util.promisify<string, string>(whichCallback);\n\nexport const createExec =\n (opts: ExecOptions): Exec =>\n (command, ...args) =>\n runCommand(command, args, opts);\n\nexport const exec: Exec = (command, ...args) => runCommand(command, args);\n\nexport const execConcurrently = async (\n commands: ExecConcurrentlyCommand[],\n { maxProcesses, nameLength, outputStream }: ExecConcurrentlyOptions = {},\n) => {\n const maxNameLength =\n nameLength ??\n commands.reduce(\n (length, command) => Math.max(length, command.name.length),\n 0,\n );\n\n try {\n await concurrently(\n commands.map(({ command, name, prefixColor }) => ({\n command,\n env: envWithPath,\n name: name.padEnd(maxNameLength),\n prefixColor,\n })),\n {\n maxProcesses: maxProcesses ?? cpus().length,\n\n outputStream,\n\n // Use a minimalist logging prefix.\n prefix: '{name} \u2502',\n },\n ).result;\n } catch (err) {\n const result = ConcurrentlyErrors.validate(err);\n\n if (!result.success) {\n throw err;\n }\n\n const failed = result.value\n .filter(({ exitCode }) => exitCode !== 0)\n .sort(({ index: indexA }, { index: indexB }) => indexA - indexB)\n .map((subprocess) => subprocess.command.name);\n\n throw Error(\n `${failed.join(', ')} subprocess${\n failed.length === 1 ? '' : 'es'\n } failed.`,\n );\n }\n};\n\nexport const ensureCommands = async (...names: string[]) => {\n let success = true;\n\n await Promise.all(\n names.map(async (name) => {\n const result = await hasCommand(name);\n\n if (!result) {\n success = false;\n\n log.err(log.bold(name), 'needs to be installed.');\n }\n }),\n );\n\n if (!success) {\n process.exit(1);\n }\n};\n\nexport const hasCommand = async (name: string) => {\n try {\n await which(name);\n\n return true;\n } catch (err) {\n if (isErrorWithCode(err, 'ENOENT')) {\n return false;\n }\n\n throw err;\n }\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["stream", "npmRunPath", "execa", "npmWhich", "util", "concurrently"]
|
|
7
7
|
}
|
package/lib/utils/manifest.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import readPkgUp from 'read-pkg-up';
|
|
1
|
+
import readPkgUp, { type NormalizedPackageJson } from 'read-pkg-up';
|
|
3
2
|
import * as t from 'runtypes';
|
|
4
3
|
export type ProjectType = t.Static<typeof ProjectType>;
|
|
5
4
|
export declare const ProjectType: t.Union<[t.Literal<"application">, t.Literal<"package">]>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/manifest.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable new-cap */\n\nimport
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable new-cap */\n\nimport readPkgUp, { type NormalizedPackageJson } from 'read-pkg-up';\nimport * as t from 'runtypes';\n\nimport { hasProp } from './validation';\n\nexport type ProjectType = t.Static<typeof ProjectType>;\n\nexport const ProjectType = t.Union(\n t.Literal('application'),\n t.Literal('package'),\n);\n\nexport const PROJECT_TYPES = ['application', 'package'] as const;\n\nconst DEFAULT_ENTRY_POINT = 'src/app.ts';\n\nlet skubaManifest: NormalizedPackageJson | undefined;\n\nexport const getSkubaManifest = async (): Promise<NormalizedPackageJson> => {\n if (skubaManifest !== undefined) {\n return skubaManifest;\n }\n\n const result = await readPkgUp({ cwd: __dirname });\n\n if (result === undefined) {\n throw Error('skuba could not find its own manifest');\n }\n\n return (skubaManifest = result.packageJson);\n};\n\nexport const getConsumerManifest = () => readPkgUp();\n\nexport const getPropFromConsumerManifest = async <\n T extends string,\n V = unknown,\n>(\n prop: T,\n): Promise<V | undefined> => {\n const result = await getConsumerManifest();\n\n return result !== undefined && hasProp<T, V>(result.packageJson.skuba, prop)\n ? result.packageJson.skuba[prop]\n : undefined;\n};\n\nexport const getStringPropFromConsumerManifest = async <T extends string>(\n prop: T,\n): Promise<string | undefined> => {\n const result = await getPropFromConsumerManifest(prop);\n\n return typeof result === 'string' ? result : undefined;\n};\n\nexport const getEntryPointFromManifest = async (): Promise<string> => {\n const entryPoint = await getStringPropFromConsumerManifest('entryPoint');\n\n return entryPoint ?? DEFAULT_ENTRY_POINT;\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,yBAAsD;AACtD,QAAmB;AAEnB,wBAAwB;AAIjB,MAAM,cAAc,EAAE;AAAA,EAC3B,EAAE,QAAQ,aAAa;AAAA,EACvB,EAAE,QAAQ,SAAS;AACrB;AAEO,MAAM,gBAAgB,CAAC,eAAe,SAAS;AAEtD,MAAM,sBAAsB;AAE5B,IAAI;AAEG,MAAM,mBAAmB,YAA4C;AAC1E,MAAI,kBAAkB,QAAW;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,UAAM,mBAAAA,SAAU,EAAE,KAAK,UAAU,CAAC;AAEjD,MAAI,WAAW,QAAW;AACxB,UAAM,MAAM,uCAAuC;AAAA,EACrD;AAEA,SAAQ,gBAAgB,OAAO;AACjC;AAEO,MAAM,sBAAsB,UAAM,mBAAAA,SAAU;AAE5C,MAAM,8BAA8B,OAIzC,SAC2B;AAC3B,QAAM,SAAS,MAAM,oBAAoB;AAEzC,SAAO,WAAW,cAAa,2BAAc,OAAO,YAAY,OAAO,IAAI,IACvE,OAAO,YAAY,MAAM,IAAI,IAC7B;AACN;AAEO,MAAM,oCAAoC,OAC/C,SACgC;AAChC,QAAM,SAAS,MAAM,4BAA4B,IAAI;AAErD,SAAO,OAAO,WAAW,WAAW,SAAS;AAC/C;AAEO,MAAM,4BAA4B,YAA6B;AACpE,QAAM,aAAa,MAAM,kCAAkC,YAAY;AAEvE,SAAO,cAAc;AACvB;",
|
|
6
6
|
"names": ["readPkgUp"]
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const isFunction: (data: unknown) => data is (...args: unknown[]) =>
|
|
1
|
+
export declare const isFunction: (data: unknown) => data is (...args: unknown[]) => Promise<unknown>;
|
|
2
2
|
export declare const isIpPort: (value: unknown) => value is number;
|
|
3
3
|
export declare const isObject: (value: unknown) => value is Record<PropertyKey, unknown>;
|
|
4
4
|
export declare const hasProp: <P extends PropertyKey, V = unknown>(value: unknown, prop: P) => value is Record<P, V>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/validation.ts"],
|
|
4
|
-
"sourcesContent": ["export const isFunction = (\n data: unknown,\n): data is (...args: unknown[]) =>
|
|
4
|
+
"sourcesContent": ["export const isFunction = (\n data: unknown,\n): data is (...args: unknown[]) => Promise<unknown> =>\n typeof data === 'function';\n\nexport const isIpPort = (value: unknown): value is number =>\n typeof value === 'number' &&\n Number.isSafeInteger(value) &&\n value >= 0 &&\n value <= 65535;\n\nexport const isObject = (\n value: unknown,\n): value is Record<PropertyKey, unknown> =>\n typeof value === 'object' && value !== null;\n\nexport const hasProp = <P extends PropertyKey, V = unknown>(\n value: unknown,\n prop: P,\n): value is Record<P, V> => isObject(value) && value.hasOwnProperty(prop);\n\nexport const hasNumberProp = <P extends PropertyKey>(\n value: unknown,\n prop: P,\n): value is Record<P, number> =>\n isObject(value) && typeof value[prop] === 'number';\n\nexport const hasStringProp = <P extends PropertyKey>(\n value: unknown,\n prop: P,\n): value is Record<P, string> =>\n isObject(value) && typeof value[prop] === 'string';\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,aAAa,CACxB,SAEA,OAAO,SAAS;AAEX,MAAM,WAAW,CAAC,UACvB,OAAO,UAAU,YACjB,OAAO,cAAc,KAAK,KAC1B,SAAS,KACT,SAAS;AAEJ,MAAM,WAAW,CACtB,UAEA,OAAO,UAAU,YAAY,UAAU;AAElC,MAAM,UAAU,CACrB,OACA,SAC0B,SAAS,KAAK,KAAK,MAAM,eAAe,IAAI;AAEjE,MAAM,gBAAgB,CAC3B,OACA,SAEA,SAAS,KAAK,KAAK,OAAO,MAAM,IAAI,MAAM;AAErC,MAAM,gBAAgB,CAC3B,OACA,SAEA,SAAS,KAAK,KAAK,OAAO,MAAM,IAAI,MAAM;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/lib/wrapper/http.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import http from 'http';
|
|
|
5
5
|
* - The request body is JSON parsed and passed into the function as parameters.
|
|
6
6
|
* - The function's return value is JSON stringified into the response body.
|
|
7
7
|
*/
|
|
8
|
-
export declare const createRequestListenerFromFunction: (fn: (...args: unknown[]) =>
|
|
8
|
+
export declare const createRequestListenerFromFunction: (fn: (...args: unknown[]) => Promise<unknown>) => http.RequestListener;
|
|
9
9
|
/**
|
|
10
10
|
* Create a HTTP server based on the supplied `http.RequestListener`.
|
|
11
11
|
*
|
package/lib/wrapper/http.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/wrapper/http.ts"],
|
|
4
|
-
"sourcesContent": ["import http from 'http';\nimport type { AddressInfo } from 'net';\n\nimport { serializeError } from 'serialize-error';\n\nimport { log } from '../utils/logging';\n\n/**\n * Create an HTTP request listener based on the supplied function.\n *\n * - The request body is JSON parsed and passed into the function as parameters.\n * - The function's return value is JSON stringified into the response body.\n */\nexport const createRequestListenerFromFunction =\n (
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAGjB,6BAA+B;AAE/B,qBAAoB;AAQb,MAAM,oCACX,
|
|
4
|
+
"sourcesContent": ["import http from 'http';\nimport type { AddressInfo } from 'net';\n\nimport { serializeError } from 'serialize-error';\n\nimport { log } from '../utils/logging';\n\n/**\n * Create an HTTP request listener based on the supplied function.\n *\n * - The request body is JSON parsed and passed into the function as parameters.\n * - The function's return value is JSON stringified into the response body.\n */\nexport const createRequestListenerFromFunction =\n (fn: (...args: unknown[]) => Promise<unknown>): http.RequestListener =>\n async (req, res) => {\n const writeJsonResponse = (statusCode: number, jsonResponse: unknown) => {\n res.writeHead(statusCode, { 'Content-Type': 'application/json' });\n\n return new Promise<void>((resolve, reject) =>\n jsonResponse === undefined\n ? res.end(resolve)\n : res.write(JSON.stringify(jsonResponse, null, 2), 'utf8', (err) =>\n err ? reject(err) : res.end(resolve),\n ),\n );\n };\n\n try {\n const requestBody = await new Promise<string>((resolve, reject) => {\n const data: Buffer[] = [];\n\n req\n .on('data', (chunk: Buffer) => data.push(chunk))\n .on('end', () => resolve(Buffer.concat(data).toString()))\n .on('error', (err) => reject(err));\n });\n\n // Treat an empty body as no arguments\n const jsonRequest: unknown = requestBody ? JSON.parse(requestBody) : [];\n\n // Pass a non-array request body as the first parameter\n const args: unknown[] = Array.isArray(jsonRequest)\n ? jsonRequest\n : [jsonRequest];\n\n const response: unknown = await fn(...args);\n\n await writeJsonResponse(200, response);\n } catch (err) {\n await writeJsonResponse(500, serializeError(err));\n }\n };\n\n/**\n * Create a HTTP server based on the supplied `http.RequestListener`.\n *\n * This function resolves when the server is closed.\n */\nexport const serveRequestListener = (\n requestListener: http.RequestListener,\n port?: number,\n) => {\n const server = http.createServer(requestListener);\n return startServer(server, port);\n};\n\n/**\n * Returns a HTTP server wrapped in a promise\n *\n * This function resolves when the server is closed.\n */\nexport const startServer = (server: http.Server, port?: number) =>\n new Promise<void>((resolve, reject) =>\n server\n .listen(port)\n .on('close', resolve)\n .on('error', reject)\n .on('listening', () => {\n const address = server.address() as AddressInfo;\n\n log.ok('listening on port', log.bold(address.port));\n }),\n );\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAGjB,6BAA+B;AAE/B,qBAAoB;AAQb,MAAM,oCACX,CAAC,OACD,OAAO,KAAK,QAAQ;AAClB,QAAM,oBAAoB,CAAC,YAAoB,iBAA0B;AACvE,QAAI,UAAU,YAAY,EAAE,gBAAgB,mBAAmB,CAAC;AAEhE,WAAO,IAAI;AAAA,MAAc,CAAC,SAAS,WACjC,iBAAiB,SACb,IAAI,IAAI,OAAO,IACf,IAAI;AAAA,QAAM,KAAK,UAAU,cAAc,MAAM,CAAC;AAAA,QAAG;AAAA,QAAQ,CAAC,QACxD,MAAM,OAAO,GAAG,IAAI,IAAI,IAAI,OAAO;AAAA,MACrC;AAAA,IACN;AAAA,EACF;AAEA,MAAI;AACF,UAAM,cAAc,MAAM,IAAI,QAAgB,CAAC,SAAS,WAAW;AACjE,YAAM,OAAiB,CAAC;AAExB,UACG,GAAG,QAAQ,CAAC,UAAkB,KAAK,KAAK,KAAK,CAAC,EAC9C,GAAG,OAAO,MAAM,QAAQ,OAAO,OAAO,IAAI,EAAE,SAAS,CAAC,CAAC,EACvD,GAAG,SAAS,CAAC,QAAQ,OAAO,GAAG,CAAC;AAAA,IACrC,CAAC;AAGD,UAAM,cAAuB,cAAc,KAAK,MAAM,WAAW,IAAI,CAAC;AAGtE,UAAM,OAAkB,MAAM,QAAQ,WAAW,IAC7C,cACA,CAAC,WAAW;AAEhB,UAAM,WAAoB,MAAM,GAAG,GAAG,IAAI;AAE1C,UAAM,kBAAkB,KAAK,QAAQ;AAAA,EACvC,SAAS,KAAK;AACZ,UAAM,kBAAkB,SAAK,uCAAe,GAAG,CAAC;AAAA,EAClD;AACF;AAOK,MAAM,uBAAuB,CAClC,iBACA,SACG;AACH,QAAM,SAAS,YAAAA,QAAK,aAAa,eAAe;AAChD,SAAO,YAAY,QAAQ,IAAI;AACjC;AAOO,MAAM,cAAc,CAAC,QAAqB,SAC/C,IAAI;AAAA,EAAc,CAAC,SAAS,WAC1B,OACG,OAAO,IAAI,EACX,GAAG,SAAS,OAAO,EACnB,GAAG,SAAS,MAAM,EAClB,GAAG,aAAa,MAAM;AACrB,UAAM,UAAU,OAAO,QAAQ;AAE/B,uBAAI,GAAG,qBAAqB,mBAAI,KAAK,QAAQ,IAAI,CAAC;AAAA,EACpD,CAAC;AACL;",
|
|
6
6
|
"names": ["http"]
|
|
7
7
|
}
|