skuba 16.0.5 → 16.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/lib/cli/configure/dependencies/skubaDeps.js +5 -5
- package/lib/cli/configure/dependencies/skubaDeps.js.map +1 -1
- package/lib/cli/lint/internalLints/upgrade/patches/7.3.1/index.js +0 -5
- package/lib/cli/lint/internalLints/upgrade/patches/7.3.1/index.js.map +2 -2
- package/lib/cli/migrate/esm/migrateLambdas.js +48 -42
- package/lib/cli/migrate/esm/migrateLambdas.js.map +2 -2
- package/lib/cli/migrate/esm/patchInstrumentation.js +8 -5
- package/lib/cli/migrate/esm/patchInstrumentation.js.map +2 -2
- package/package.json +5 -5
- package/template/express-rest-api/package.json +5 -5
- package/template/greeter/README.md +1 -1
- package/template/koa-rest-api/package.json +5 -5
- package/template/lambda-sqs-worker-cdk/README.md +1 -1
- package/template/lambda-sqs-worker-cdk/package.json +4 -4
- package/template/oss-npm-package/.github/workflows/release.yml +1 -1
- package/template/oss-npm-package/.github/workflows/validate.yml +1 -1
- package/lib/cli/configure/processing/typescript.d.ts +0 -23
- package/lib/cli/configure/processing/typescript.js +0 -163
- package/lib/cli/configure/processing/typescript.js.map +0 -7
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
- Write in [TypeScript]
|
|
13
13
|
- Enforce coding standards with [ESLint] and [Prettier]
|
|
14
|
-
- Test with [
|
|
14
|
+
- Test with [Vitest]
|
|
15
15
|
- Deploy with [Gantry] or the [AWS CDK]
|
|
16
16
|
|
|
17
17
|
[aws cdk]: https://docs.aws.amazon.com/cdk/latest/guide/work-with-cdk-typescript.html
|
|
@@ -52,7 +52,7 @@ If you're new here, jump ahead to the [CLI] section to [create a new project] or
|
|
|
52
52
|
[create a new project]: ./docs/cli/init.md
|
|
53
53
|
[development]: ./docs/development-api
|
|
54
54
|
[eslint]: https://eslint.org/
|
|
55
|
-
[
|
|
55
|
+
[vitest]: https://vitest.dev/
|
|
56
56
|
[prettier]: https://prettier.io/
|
|
57
57
|
[runtime]: ./docs/runtime-api
|
|
58
58
|
[templates]: ./docs/templates
|
|
@@ -8,18 +8,18 @@ const DEV_DEPENDENCIES = [
|
|
|
8
8
|
"tslint-config-seek",
|
|
9
9
|
"tslint",
|
|
10
10
|
// bundled
|
|
11
|
-
"@
|
|
11
|
+
"@vitest/coverage-istanbul",
|
|
12
|
+
"@vitest/coverage-v8",
|
|
13
|
+
"@vitest/ui",
|
|
12
14
|
"concurrently",
|
|
13
15
|
"eslint-config-skuba",
|
|
14
16
|
"eslint",
|
|
15
|
-
"jest",
|
|
16
17
|
"prettier",
|
|
17
18
|
"semantic-release",
|
|
18
|
-
"ts-jest",
|
|
19
|
-
"ts-node",
|
|
20
19
|
"tsconfig-seek",
|
|
21
20
|
"tsx",
|
|
22
|
-
"typescript"
|
|
21
|
+
"typescript",
|
|
22
|
+
"vitest"
|
|
23
23
|
];
|
|
24
24
|
export const skubaDeps = ({ dependencies, devDependencies }) => {
|
|
25
25
|
DEV_DEPENDENCIES.forEach((dep) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cli/configure/dependencies/skubaDeps.ts"],
|
|
4
|
-
"sourcesContent": ["import type { DependencySet } from '../types.js';\n\nconst DEV_DEPENDENCIES = [\n // replaced\n '@seek/seek-module-toolkit',\n 'eslint-config-seek',\n 'nodemon',\n 'ts-node-dev',\n 'tslint-config-seek',\n 'tslint',\n\n // bundled\n '@
|
|
4
|
+
"sourcesContent": ["import type { DependencySet } from '../types.js';\n\nconst DEV_DEPENDENCIES = [\n // replaced\n '@seek/seek-module-toolkit',\n 'eslint-config-seek',\n 'nodemon',\n 'ts-node-dev',\n 'tslint-config-seek',\n 'tslint',\n\n // bundled\n '@vitest/coverage-istanbul',\n '@vitest/coverage-v8',\n '@vitest/ui',\n 'concurrently',\n 'eslint-config-skuba',\n 'eslint',\n 'prettier',\n 'semantic-release',\n 'tsconfig-seek',\n 'tsx',\n 'typescript',\n 'vitest',\n] as const;\n\nexport const skubaDeps = ({ dependencies, devDependencies }: DependencySet) => {\n DEV_DEPENDENCIES.forEach((dep) => {\n delete dependencies[dep];\n delete devDependencies[dep];\n });\n\n return [];\n};\n"],
|
|
5
5
|
"mappings": ";AAEA,MAAM,mBAAmB;AAAA;AAAA,EAEvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,aAAM,YAAY,CAAC,EAAE,cAAc,gBAAgB,MAAqB;AAC7E,mBAAiB,QAAQ,CAAC,QAAQ;AAChC,WAAO,aAAa,GAAG;AACvB,WAAO,gBAAgB,GAAG;AAAA,EAC5B,CAAC;AAED,SAAO,CAAC;AACV;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
import { tryPatchRenovateConfig } from "../../../patchRenovateConfig.js";
|
|
3
|
-
import { tryAddEmptyExports } from "./addEmptyExports.js";
|
|
4
3
|
import { tryPatchDockerfile } from "./patchDockerfile.js";
|
|
5
4
|
import { tryPatchServerListener } from "./patchServerListener.js";
|
|
6
5
|
export const patches = [
|
|
7
|
-
{
|
|
8
|
-
apply: tryAddEmptyExports,
|
|
9
|
-
description: "Add empty exports to Jest files for compliance with TypeScript isolated modules"
|
|
10
|
-
},
|
|
11
6
|
{
|
|
12
7
|
apply: tryPatchRenovateConfig,
|
|
13
8
|
description: "Update Renovate config to support private SEEK packages"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/cli/lint/internalLints/upgrade/patches/7.3.1/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { tryPatchRenovateConfig } from '../../../patchRenovateConfig.js';\nimport type { Patches } from '../../index.js';\n\nimport {
|
|
5
|
-
"mappings": ";AAAA,SAAS,8BAA8B;AAGvC,SAAS,0BAA0B;AACnC,SAAS,
|
|
4
|
+
"sourcesContent": ["import { tryPatchRenovateConfig } from '../../../patchRenovateConfig.js';\nimport type { Patches } from '../../index.js';\n\nimport { tryPatchDockerfile } from './patchDockerfile.js';\nimport { tryPatchServerListener } from './patchServerListener.js';\n\nexport const patches: Patches = [\n {\n apply: tryPatchRenovateConfig,\n description: 'Update Renovate config to support private SEEK packages',\n },\n {\n apply: tryPatchDockerfile,\n description: 'Upgrade Node.js Distroless Docker image to -debian12 variant',\n },\n {\n apply: tryPatchServerListener,\n description: 'Add keepAliveTimeout to server listener',\n },\n];\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAS,8BAA8B;AAGvC,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AAEhC,aAAM,UAAmB;AAAA,EAC9B;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -244,11 +244,56 @@ const migrateServerlessLambdas = async (serverlessFiles, containsDatadogLambdaIm
|
|
|
244
244
|
registerAstGrepLanguages();
|
|
245
245
|
return (await Promise.all(
|
|
246
246
|
serverlessFiles.map(async ({ file, contents }) => {
|
|
247
|
+
const astRoot = (await parseAsync("yaml", contents)).root();
|
|
248
|
+
const edits = [];
|
|
249
|
+
const datadogSettings = astRoot.find({
|
|
250
|
+
rule: {
|
|
251
|
+
kind: "block_node",
|
|
252
|
+
inside: {
|
|
253
|
+
kind: "block_mapping_pair",
|
|
254
|
+
regex: "^datadog:"
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
if (datadogSettings) {
|
|
259
|
+
const addLayers = datadogSettings.find({
|
|
260
|
+
rule: {
|
|
261
|
+
kind: "block_mapping_pair",
|
|
262
|
+
regex: "^addLayers:"
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
const addLayersDisabled = addLayers?.text().includes("false");
|
|
266
|
+
if (addLayersDisabled) {
|
|
267
|
+
const redirectHandlers = datadogSettings.find({
|
|
268
|
+
rule: {
|
|
269
|
+
kind: "block_node",
|
|
270
|
+
inside: {
|
|
271
|
+
kind: "block_mapping_pair",
|
|
272
|
+
regex: "^redirectHandlers:"
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
if (!redirectHandlers) {
|
|
277
|
+
const indent = datadogSettings.range().start.column;
|
|
278
|
+
edits.push({
|
|
279
|
+
startPos: datadogSettings.range().end.index,
|
|
280
|
+
endPos: datadogSettings.range().end.index,
|
|
281
|
+
insertedText: `
|
|
282
|
+
${" ".repeat(indent)}redirectHandlers: false${!containsDatadogLambdaImport ? " # TODO: Wrap your handler with the `datadog` function wrapper from `datadog-lambda-js` or the `withLambdaExtension` function wrapper from `seek-datadog-custom-metrics/lambda`. Alternatively, remove this setting and enable addLayers: true" : ""}
|
|
283
|
+
`
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
247
288
|
if (!contents.includes("esbuild")) {
|
|
248
|
-
|
|
289
|
+
if (edits.length === 0) {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
return {
|
|
293
|
+
contents: astRoot.commitEdits(edits),
|
|
294
|
+
file
|
|
295
|
+
};
|
|
249
296
|
}
|
|
250
|
-
const edits = [];
|
|
251
|
-
const astRoot = (await parseAsync("yaml", contents)).root();
|
|
252
297
|
const esbuildAst = astRoot.find({
|
|
253
298
|
rule: {
|
|
254
299
|
kind: "block_node",
|
|
@@ -348,45 +393,6 @@ ${" ".repeat(indent + 2)}- main
|
|
|
348
393
|
} else {
|
|
349
394
|
edits.push(mainFields.replace("mainFields:\n - module\n - main\n"));
|
|
350
395
|
}
|
|
351
|
-
const datadogSettings = astRoot.find({
|
|
352
|
-
rule: {
|
|
353
|
-
kind: "block_node",
|
|
354
|
-
inside: {
|
|
355
|
-
kind: "block_mapping_pair",
|
|
356
|
-
regex: "^datadog:"
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
});
|
|
360
|
-
if (datadogSettings) {
|
|
361
|
-
const addLayers = datadogSettings.find({
|
|
362
|
-
rule: {
|
|
363
|
-
kind: "block_mapping_pair",
|
|
364
|
-
regex: "^addLayers:"
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
const addLayersDisabled = addLayers?.text().includes("false");
|
|
368
|
-
if (addLayersDisabled && containsDatadogLambdaImport) {
|
|
369
|
-
const redirectHandlers = datadogSettings.find({
|
|
370
|
-
rule: {
|
|
371
|
-
kind: "block_node",
|
|
372
|
-
inside: {
|
|
373
|
-
kind: "block_mapping_pair",
|
|
374
|
-
regex: "^redirectHandlers:"
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
});
|
|
378
|
-
if (!redirectHandlers) {
|
|
379
|
-
const indent = datadogSettings.range().start.column;
|
|
380
|
-
edits.push({
|
|
381
|
-
startPos: datadogSettings.range().end.index,
|
|
382
|
-
endPos: datadogSettings.range().end.index,
|
|
383
|
-
insertedText: `
|
|
384
|
-
${" ".repeat(indent)}redirectHandlers: false
|
|
385
|
-
`
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
396
|
if (edits.length === 0) {
|
|
391
397
|
return null;
|
|
392
398
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cli/migrate/esm/migrateLambdas.ts"],
|
|
4
|
-
"sourcesContent": ["import { inspect } from 'util';\n\nimport { type Edit, parseAsync } from '@ast-grep/napi';\nimport fg from 'fast-glob';\nimport fs from 'fs-extra';\n\nimport { log } from '../../../utils/logging.js';\nimport { getCustomConditions } from '../../build/tsc.js';\nimport { registerAstGrepLanguages } from '../../lint/internalLints/registerAstGrepLanguages.js';\nimport type { PatchFunction } from '../../lint/internalLints/upgrade/index.js';\n\nconst migrateCdkLambdas = async (\n tsFiles: Array<{ file: string; contents: string }>,\n containsDatadogLambdaImport: boolean,\n) =>\n (\n await Promise.all(\n tsFiles.map(async ({ file, contents }) => {\n if (!contents.includes('NodejsFunction')) {\n return null;\n }\n\n const edits: Edit[] = [];\n\n const astRoot = (await parseAsync('TypeScript', contents)).root();\n\n const workerAst = astRoot.find({\n rule: {\n kind: 'new_expression',\n regex: '^new (aws_lambda_nodejs.NodejsFunction|NodejsFunction)',\n },\n });\n\n if (!workerAst) {\n return null;\n }\n\n const bundlingObject = workerAst.find({\n rule: {\n kind: 'object',\n inside: {\n kind: 'pair',\n regex: '^bundling',\n },\n },\n });\n\n if (!bundlingObject) {\n return null;\n }\n\n const format = bundlingObject.find({\n rule: {\n kind: 'pair',\n regex: '^format',\n },\n });\n\n const containsAwsLambdaNodeJsImport = astRoot.find({\n rule: {\n kind: 'import_specifier',\n regex: 'aws_lambda_nodejs',\n },\n });\n\n if (!format) {\n edits.push({\n startPos: bundlingObject.range().end.index - 1,\n endPos: bundlingObject.range().end.index - 1,\n insertedText: `\\nformat: ${containsAwsLambdaNodeJsImport ? 'aws_lambda_nodejs.' : ''}OutputFormat.ESM,\\n`,\n });\n if (!containsAwsLambdaNodeJsImport) {\n const lastImport = astRoot.find({\n rule: {\n kind: 'import_statement',\n inside: {\n kind: 'program',\n },\n nthChild: {\n ofRule: {\n kind: 'import_statement',\n },\n position: 1,\n reverse: true,\n },\n },\n });\n\n const insertPos = lastImport\n ? lastImport.range().end.index\n : astRoot.range().start.index;\n\n edits.push({\n startPos: insertPos,\n endPos: insertPos,\n insertedText:\n \"import { OutputFormat } from 'aws-cdk-lib/aws-lambda-nodejs';\\n\",\n });\n }\n } else {\n edits.push(format.replace(format.text().replace('CJS', 'ESM')));\n }\n\n const mainFields = bundlingObject.find({\n rule: {\n kind: 'pair',\n regex: '^mainFields',\n },\n });\n\n if (!mainFields) {\n edits.push({\n startPos: bundlingObject.range().end.index - 1,\n endPos: bundlingObject.range().end.index - 1,\n insertedText: \"\\nmainFields: ['module', 'main'],\\n\",\n });\n } else {\n edits.push(mainFields.replace(\"mainFields: ['module', 'main']\"));\n }\n\n const nodeModules = bundlingObject.find({\n rule: {\n kind: 'pair',\n regex: '^nodeModules',\n },\n });\n\n if (!nodeModules) {\n edits.push({\n startPos: bundlingObject.range().end.index - 1,\n endPos: bundlingObject.range().end.index - 1,\n insertedText: \"\\nnodeModules: ['pino'],\\n\",\n });\n } else {\n const nodeModulesArray = nodeModules.find({\n rule: {\n kind: 'array',\n },\n });\n\n if (nodeModulesArray && !nodeModules.text().includes('pino')) {\n edits.push({\n startPos: nodeModulesArray.range().end.index - 1,\n endPos: nodeModulesArray.range().end.index - 1,\n insertedText: `${nodeModules.text().includes('[') ? ',' : ''} 'pino'`,\n });\n }\n }\n\n const esbuildArgs = bundlingObject.find({\n rule: {\n kind: 'pair',\n regex: '^esbuildArgs',\n },\n });\n\n if (!esbuildArgs) {\n const customCondition = getCustomConditions();\n edits.push({\n startPos: bundlingObject.range().end.index - 1,\n endPos: bundlingObject.range().end.index - 1,\n insertedText: `\\nesbuildArgs: {\\n '--conditions': '${customCondition.join(',')},module',\\n},\\n`,\n });\n } else {\n const conditions = esbuildArgs.find({\n rule: {\n kind: 'pair',\n regex: \"^'--conditions'\",\n },\n });\n\n if (!conditions) {\n const customCondition = getCustomConditions();\n edits.push({\n startPos: esbuildArgs.range().end.index - 1,\n endPos: esbuildArgs.range().end.index - 1,\n insertedText: `\\n'--conditions': '${customCondition.join(',')},module',\\n`,\n });\n } else {\n const conditionsValue = conditions.field('value');\n if (conditionsValue && !conditionsValue.text().includes('module')) {\n edits.push({\n startPos: conditionsValue.range().end.index - 1,\n endPos: conditionsValue.range().end.index - 1,\n insertedText: ',module',\n });\n }\n }\n\n const datadogSettings = astRoot.find({\n rule: {\n kind: 'object',\n inside: {\n kind: 'arguments',\n inside: {\n kind: 'new_expression',\n regex: '^new DatadogLambda',\n },\n },\n },\n });\n\n const nodeLayerVersion = datadogSettings?.find({\n rule: {\n kind: 'pair',\n regex: '^nodeLayerVersion',\n },\n });\n\n const redirectHandler = datadogSettings?.find({\n rule: {\n kind: 'pair',\n regex: '^redirectHandler',\n },\n });\n\n if (datadogSettings && !nodeLayerVersion && !redirectHandler) {\n if (containsDatadogLambdaImport) {\n edits.push({\n startPos: datadogSettings.range().end.index - 1,\n endPos: datadogSettings.range().end.index - 1,\n insertedText: '\\nredirectHandler: false,\\n',\n });\n } else {\n const extensionVersion = datadogSettings.find({\n rule: {\n kind: 'lexical_declaration',\n regex: '^const DATADOG_EXTENSION_LAYER_VERSION ',\n },\n });\n\n const lastImport = astRoot.find({\n rule: {\n kind: 'import_statement',\n inside: {\n kind: 'program',\n },\n nthChild: {\n ofRule: {\n kind: 'import_statement',\n },\n position: 1,\n reverse: true,\n },\n },\n });\n\n const insertPos =\n extensionVersion?.range().end.index ??\n lastImport?.range().end.index ??\n astRoot.range().start.index;\n\n edits.push({\n startPos: insertPos,\n endPos: insertPos,\n insertedText: 'const DATADOG_NODE_LAYER_VERSION = 126;\\n',\n });\n\n edits.push({\n startPos: datadogSettings.range().end.index - 1,\n endPos: datadogSettings.range().end.index - 1,\n insertedText:\n '\\nnodeLayerVersion: DATADOG_NODE_LAYER_VERSION,\\n',\n });\n }\n }\n }\n\n if (!edits.length) {\n return null;\n }\n\n return {\n file,\n contents: astRoot.commitEdits(edits),\n };\n }),\n )\n ).filter((file) => file !== null);\n\nconst migrateServerlessLambdas = async (\n serverlessFiles: Array<{ file: string; contents: string }>,\n containsDatadogLambdaImport: boolean,\n) => {\n registerAstGrepLanguages();\n return (\n await Promise.all(\n serverlessFiles.map(async ({ file, contents }) => {\n if (!contents.includes('esbuild')) {\n return null;\n }\n\n const edits: Edit[] = [];\n\n const astRoot = (await parseAsync('yaml', contents)).root();\n\n const esbuildAst = astRoot.find({\n rule: {\n kind: 'block_node',\n inside: {\n kind: 'block_mapping_pair',\n regex: '^esbuild:',\n },\n },\n });\n\n if (!esbuildAst) {\n return null;\n }\n\n const conditions = esbuildAst.find({\n rule: {\n kind: 'block_node',\n inside: {\n kind: 'block_mapping_pair',\n regex: '^conditions:',\n },\n },\n });\n\n if (conditions) {\n const indent = conditions.range().start.column;\n edits.push({\n startPos: conditions.range().end.index,\n endPos: conditions.range().end.index,\n insertedText: `\\n${' '.repeat(indent)}- module`,\n });\n } else {\n const indent = esbuildAst.range().start.column;\n edits.push({\n startPos: esbuildAst.range().end.index,\n endPos: esbuildAst.range().end.index,\n insertedText: `\\n${' '.repeat(indent)}conditions:\\n${' '.repeat(\n indent + 2,\n )}- module\\n`,\n });\n }\n\n const external = esbuildAst.find({\n rule: {\n kind: 'block_node',\n inside: {\n kind: 'block_mapping_pair',\n regex: '^external:',\n },\n },\n });\n\n if (external) {\n const indent = external.range().start.column;\n if (!external.text().includes('pino')) {\n edits.push({\n startPos: external.range().start.index,\n endPos: external.range().start.index,\n insertedText: `- pino\\n${' '.repeat(indent)}`,\n });\n }\n } else {\n const indent = esbuildAst.range().start.column;\n edits.push({\n startPos: esbuildAst.range().end.index,\n endPos: esbuildAst.range().end.index,\n insertedText: `\\n${' '.repeat(indent)}external:\\n${' '.repeat(\n indent + 2,\n )}- pino\\n`,\n });\n }\n\n const mainFields = esbuildAst.find({\n rule: {\n kind: 'block_node',\n inside: {\n kind: 'block_mapping_pair',\n regex: '^mainFields:',\n },\n },\n });\n\n if (!mainFields) {\n const indent = esbuildAst.range().start.column;\n edits.push({\n startPos: esbuildAst.range().end.index,\n endPos: esbuildAst.range().end.index,\n insertedText: `\\n${' '.repeat(indent)}mainFields:\\n${' '.repeat(\n indent + 2,\n )}- module\\n${' '.repeat(indent + 2)}- main\\n`,\n });\n } else {\n edits.push(mainFields.replace('mainFields:\\n - module\\n - main\\n'));\n }\n\n const datadogSettings = astRoot.find({\n rule: {\n kind: 'block_node',\n inside: {\n kind: 'block_mapping_pair',\n regex: '^datadog:',\n },\n },\n });\n\n if (datadogSettings) {\n const addLayers = datadogSettings.find({\n rule: {\n kind: 'block_mapping_pair',\n regex: '^addLayers:',\n },\n });\n\n const addLayersDisabled = addLayers?.text().includes('false');\n\n if (addLayersDisabled && containsDatadogLambdaImport) {\n const redirectHandlers = datadogSettings.find({\n rule: {\n kind: 'block_node',\n inside: {\n kind: 'block_mapping_pair',\n regex: '^redirectHandlers:',\n },\n },\n });\n\n if (!redirectHandlers) {\n const indent = datadogSettings.range().start.column;\n edits.push({\n startPos: datadogSettings.range().end.index,\n endPos: datadogSettings.range().end.index,\n insertedText: `\\n${' '.repeat(indent)}redirectHandlers: false\\n`,\n });\n }\n }\n }\n\n if (edits.length === 0) {\n return null;\n }\n\n return {\n file,\n contents: astRoot.commitEdits(edits),\n };\n }),\n )\n ).filter((file) => file !== null);\n};\n\nexport const migrateLambdas: PatchFunction = async ({ mode }) => {\n const [tsFilePaths, serverlessFilePaths] = await Promise.all([\n fg(['**/*.ts'], {\n ignore: ['**/.git', '**/node_modules'],\n }),\n fg(['**/serverless*.{yml,yaml}'], {\n ignore: ['**/.git', '**/node_modules'],\n }),\n ]);\n\n const [tsFiles, serverlessFiles] = await Promise.all([\n Promise.all(\n tsFilePaths.map(async (file) => {\n const contents = await fs.promises.readFile(file, 'utf8');\n\n return {\n file,\n contents,\n };\n }),\n ),\n Promise.all(\n serverlessFilePaths.map(async (file) => {\n const contents = await fs.promises.readFile(file, 'utf8');\n\n return {\n file,\n contents,\n };\n }),\n ),\n ]);\n\n const containsDatadogLambdaImport = tsFiles.some(\n ({ contents }) =>\n contents.includes('datadog-lambda-js') ||\n contents.includes('withLambdaExtension'),\n );\n\n const [patchedTsFiles, patchedServerlessFiles] = await Promise.all([\n migrateCdkLambdas(tsFiles, containsDatadogLambdaImport),\n migrateServerlessLambdas(serverlessFiles, containsDatadogLambdaImport),\n ]);\n\n if (!patchedTsFiles.length && !patchedServerlessFiles.length) {\n return {\n result: 'skip',\n reason: 'no lambdas to migrate',\n };\n }\n\n if (mode === 'lint') {\n return {\n result: 'apply',\n };\n }\n\n await Promise.all(\n [...patchedTsFiles, ...patchedServerlessFiles].map(\n async ({ file, contents }) => {\n await fs.promises.writeFile(file, contents, 'utf8');\n },\n ),\n );\n\n return {\n result: 'apply',\n };\n};\n\nexport const tryMigrateLambdas: PatchFunction = async (opts) => {\n try {\n return await migrateLambdas(opts);\n } catch (err) {\n // Don't fail the entire lint/format if this fails since it's a non-critical part of the upgrade\n // and can be retried later by the user\n log.warn('Failed to migrate lambdas, skipping');\n log.subtle(inspect(err));\n return { result: 'skip', reason: 'due to an error' };\n }\n};\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { inspect } from 'util';\n\nimport { type Edit, parseAsync } from '@ast-grep/napi';\nimport fg from 'fast-glob';\nimport fs from 'fs-extra';\n\nimport { log } from '../../../utils/logging.js';\nimport { getCustomConditions } from '../../build/tsc.js';\nimport { registerAstGrepLanguages } from '../../lint/internalLints/registerAstGrepLanguages.js';\nimport type { PatchFunction } from '../../lint/internalLints/upgrade/index.js';\n\nconst migrateCdkLambdas = async (\n tsFiles: Array<{ file: string; contents: string }>,\n containsDatadogLambdaImport: boolean,\n) =>\n (\n await Promise.all(\n tsFiles.map(async ({ file, contents }) => {\n if (!contents.includes('NodejsFunction')) {\n return null;\n }\n\n const edits: Edit[] = [];\n\n const astRoot = (await parseAsync('TypeScript', contents)).root();\n\n const workerAst = astRoot.find({\n rule: {\n kind: 'new_expression',\n regex: '^new (aws_lambda_nodejs.NodejsFunction|NodejsFunction)',\n },\n });\n\n if (!workerAst) {\n return null;\n }\n\n const bundlingObject = workerAst.find({\n rule: {\n kind: 'object',\n inside: {\n kind: 'pair',\n regex: '^bundling',\n },\n },\n });\n\n if (!bundlingObject) {\n return null;\n }\n\n const format = bundlingObject.find({\n rule: {\n kind: 'pair',\n regex: '^format',\n },\n });\n\n const containsAwsLambdaNodeJsImport = astRoot.find({\n rule: {\n kind: 'import_specifier',\n regex: 'aws_lambda_nodejs',\n },\n });\n\n if (!format) {\n edits.push({\n startPos: bundlingObject.range().end.index - 1,\n endPos: bundlingObject.range().end.index - 1,\n insertedText: `\\nformat: ${containsAwsLambdaNodeJsImport ? 'aws_lambda_nodejs.' : ''}OutputFormat.ESM,\\n`,\n });\n if (!containsAwsLambdaNodeJsImport) {\n const lastImport = astRoot.find({\n rule: {\n kind: 'import_statement',\n inside: {\n kind: 'program',\n },\n nthChild: {\n ofRule: {\n kind: 'import_statement',\n },\n position: 1,\n reverse: true,\n },\n },\n });\n\n const insertPos = lastImport\n ? lastImport.range().end.index\n : astRoot.range().start.index;\n\n edits.push({\n startPos: insertPos,\n endPos: insertPos,\n insertedText:\n \"import { OutputFormat } from 'aws-cdk-lib/aws-lambda-nodejs';\\n\",\n });\n }\n } else {\n edits.push(format.replace(format.text().replace('CJS', 'ESM')));\n }\n\n const mainFields = bundlingObject.find({\n rule: {\n kind: 'pair',\n regex: '^mainFields',\n },\n });\n\n if (!mainFields) {\n edits.push({\n startPos: bundlingObject.range().end.index - 1,\n endPos: bundlingObject.range().end.index - 1,\n insertedText: \"\\nmainFields: ['module', 'main'],\\n\",\n });\n } else {\n edits.push(mainFields.replace(\"mainFields: ['module', 'main']\"));\n }\n\n const nodeModules = bundlingObject.find({\n rule: {\n kind: 'pair',\n regex: '^nodeModules',\n },\n });\n\n if (!nodeModules) {\n edits.push({\n startPos: bundlingObject.range().end.index - 1,\n endPos: bundlingObject.range().end.index - 1,\n insertedText: \"\\nnodeModules: ['pino'],\\n\",\n });\n } else {\n const nodeModulesArray = nodeModules.find({\n rule: {\n kind: 'array',\n },\n });\n\n if (nodeModulesArray && !nodeModules.text().includes('pino')) {\n edits.push({\n startPos: nodeModulesArray.range().end.index - 1,\n endPos: nodeModulesArray.range().end.index - 1,\n insertedText: `${nodeModules.text().includes('[') ? ',' : ''} 'pino'`,\n });\n }\n }\n\n const esbuildArgs = bundlingObject.find({\n rule: {\n kind: 'pair',\n regex: '^esbuildArgs',\n },\n });\n\n if (!esbuildArgs) {\n const customCondition = getCustomConditions();\n edits.push({\n startPos: bundlingObject.range().end.index - 1,\n endPos: bundlingObject.range().end.index - 1,\n insertedText: `\\nesbuildArgs: {\\n '--conditions': '${customCondition.join(',')},module',\\n},\\n`,\n });\n } else {\n const conditions = esbuildArgs.find({\n rule: {\n kind: 'pair',\n regex: \"^'--conditions'\",\n },\n });\n\n if (!conditions) {\n const customCondition = getCustomConditions();\n edits.push({\n startPos: esbuildArgs.range().end.index - 1,\n endPos: esbuildArgs.range().end.index - 1,\n insertedText: `\\n'--conditions': '${customCondition.join(',')},module',\\n`,\n });\n } else {\n const conditionsValue = conditions.field('value');\n if (conditionsValue && !conditionsValue.text().includes('module')) {\n edits.push({\n startPos: conditionsValue.range().end.index - 1,\n endPos: conditionsValue.range().end.index - 1,\n insertedText: ',module',\n });\n }\n }\n\n const datadogSettings = astRoot.find({\n rule: {\n kind: 'object',\n inside: {\n kind: 'arguments',\n inside: {\n kind: 'new_expression',\n regex: '^new DatadogLambda',\n },\n },\n },\n });\n\n const nodeLayerVersion = datadogSettings?.find({\n rule: {\n kind: 'pair',\n regex: '^nodeLayerVersion',\n },\n });\n\n const redirectHandler = datadogSettings?.find({\n rule: {\n kind: 'pair',\n regex: '^redirectHandler',\n },\n });\n\n if (datadogSettings && !nodeLayerVersion && !redirectHandler) {\n if (containsDatadogLambdaImport) {\n edits.push({\n startPos: datadogSettings.range().end.index - 1,\n endPos: datadogSettings.range().end.index - 1,\n insertedText: '\\nredirectHandler: false,\\n',\n });\n } else {\n const extensionVersion = datadogSettings.find({\n rule: {\n kind: 'lexical_declaration',\n regex: '^const DATADOG_EXTENSION_LAYER_VERSION ',\n },\n });\n\n const lastImport = astRoot.find({\n rule: {\n kind: 'import_statement',\n inside: {\n kind: 'program',\n },\n nthChild: {\n ofRule: {\n kind: 'import_statement',\n },\n position: 1,\n reverse: true,\n },\n },\n });\n\n const insertPos =\n extensionVersion?.range().end.index ??\n lastImport?.range().end.index ??\n astRoot.range().start.index;\n\n edits.push({\n startPos: insertPos,\n endPos: insertPos,\n insertedText: 'const DATADOG_NODE_LAYER_VERSION = 126;\\n',\n });\n\n edits.push({\n startPos: datadogSettings.range().end.index - 1,\n endPos: datadogSettings.range().end.index - 1,\n insertedText:\n '\\nnodeLayerVersion: DATADOG_NODE_LAYER_VERSION,\\n',\n });\n }\n }\n }\n\n if (!edits.length) {\n return null;\n }\n\n return {\n file,\n contents: astRoot.commitEdits(edits),\n };\n }),\n )\n ).filter((file) => file !== null);\n\nconst migrateServerlessLambdas = async (\n serverlessFiles: Array<{ file: string; contents: string }>,\n containsDatadogLambdaImport: boolean,\n) => {\n registerAstGrepLanguages();\n return (\n await Promise.all(\n serverlessFiles.map(async ({ file, contents }) => {\n const astRoot = (await parseAsync('yaml', contents)).root();\n\n const edits: Edit[] = [];\n const datadogSettings = astRoot.find({\n rule: {\n kind: 'block_node',\n inside: {\n kind: 'block_mapping_pair',\n regex: '^datadog:',\n },\n },\n });\n\n if (datadogSettings) {\n const addLayers = datadogSettings.find({\n rule: {\n kind: 'block_mapping_pair',\n regex: '^addLayers:',\n },\n });\n\n const addLayersDisabled = addLayers?.text().includes('false');\n\n if (addLayersDisabled) {\n const redirectHandlers = datadogSettings.find({\n rule: {\n kind: 'block_node',\n inside: {\n kind: 'block_mapping_pair',\n regex: '^redirectHandlers:',\n },\n },\n });\n\n if (!redirectHandlers) {\n const indent = datadogSettings.range().start.column;\n edits.push({\n startPos: datadogSettings.range().end.index,\n endPos: datadogSettings.range().end.index,\n insertedText: `\\n${' '.repeat(indent)}redirectHandlers: false${!containsDatadogLambdaImport ? ' # TODO: Wrap your handler with the `datadog` function wrapper from `datadog-lambda-js` or the `withLambdaExtension` function wrapper from `seek-datadog-custom-metrics/lambda`. Alternatively, remove this setting and enable addLayers: true' : ''}\\n`,\n });\n }\n }\n }\n\n if (!contents.includes('esbuild')) {\n if (edits.length === 0) {\n return null;\n }\n return {\n contents: astRoot.commitEdits(edits),\n file,\n };\n }\n\n const esbuildAst = astRoot.find({\n rule: {\n kind: 'block_node',\n inside: {\n kind: 'block_mapping_pair',\n regex: '^esbuild:',\n },\n },\n });\n\n if (!esbuildAst) {\n return null;\n }\n\n const conditions = esbuildAst.find({\n rule: {\n kind: 'block_node',\n inside: {\n kind: 'block_mapping_pair',\n regex: '^conditions:',\n },\n },\n });\n\n if (conditions) {\n const indent = conditions.range().start.column;\n edits.push({\n startPos: conditions.range().end.index,\n endPos: conditions.range().end.index,\n insertedText: `\\n${' '.repeat(indent)}- module`,\n });\n } else {\n const indent = esbuildAst.range().start.column;\n edits.push({\n startPos: esbuildAst.range().end.index,\n endPos: esbuildAst.range().end.index,\n insertedText: `\\n${' '.repeat(indent)}conditions:\\n${' '.repeat(\n indent + 2,\n )}- module\\n`,\n });\n }\n\n const external = esbuildAst.find({\n rule: {\n kind: 'block_node',\n inside: {\n kind: 'block_mapping_pair',\n regex: '^external:',\n },\n },\n });\n\n if (external) {\n const indent = external.range().start.column;\n if (!external.text().includes('pino')) {\n edits.push({\n startPos: external.range().start.index,\n endPos: external.range().start.index,\n insertedText: `- pino\\n${' '.repeat(indent)}`,\n });\n }\n } else {\n const indent = esbuildAst.range().start.column;\n edits.push({\n startPos: esbuildAst.range().end.index,\n endPos: esbuildAst.range().end.index,\n insertedText: `\\n${' '.repeat(indent)}external:\\n${' '.repeat(\n indent + 2,\n )}- pino\\n`,\n });\n }\n\n const mainFields = esbuildAst.find({\n rule: {\n kind: 'block_node',\n inside: {\n kind: 'block_mapping_pair',\n regex: '^mainFields:',\n },\n },\n });\n\n if (!mainFields) {\n const indent = esbuildAst.range().start.column;\n edits.push({\n startPos: esbuildAst.range().end.index,\n endPos: esbuildAst.range().end.index,\n insertedText: `\\n${' '.repeat(indent)}mainFields:\\n${' '.repeat(\n indent + 2,\n )}- module\\n${' '.repeat(indent + 2)}- main\\n`,\n });\n } else {\n edits.push(mainFields.replace('mainFields:\\n - module\\n - main\\n'));\n }\n\n if (edits.length === 0) {\n return null;\n }\n\n return {\n file,\n contents: astRoot.commitEdits(edits),\n };\n }),\n )\n ).filter((file) => file !== null);\n};\n\nexport const migrateLambdas: PatchFunction = async ({ mode }) => {\n const [tsFilePaths, serverlessFilePaths] = await Promise.all([\n fg(['**/*.ts'], {\n ignore: ['**/.git', '**/node_modules'],\n }),\n fg(['**/serverless*.{yml,yaml}'], {\n ignore: ['**/.git', '**/node_modules'],\n }),\n ]);\n\n const [tsFiles, serverlessFiles] = await Promise.all([\n Promise.all(\n tsFilePaths.map(async (file) => {\n const contents = await fs.promises.readFile(file, 'utf8');\n\n return {\n file,\n contents,\n };\n }),\n ),\n Promise.all(\n serverlessFilePaths.map(async (file) => {\n const contents = await fs.promises.readFile(file, 'utf8');\n\n return {\n file,\n contents,\n };\n }),\n ),\n ]);\n\n const containsDatadogLambdaImport = tsFiles.some(\n ({ contents }) =>\n contents.includes('datadog-lambda-js') ||\n contents.includes('withLambdaExtension'),\n );\n\n const [patchedTsFiles, patchedServerlessFiles] = await Promise.all([\n migrateCdkLambdas(tsFiles, containsDatadogLambdaImport),\n migrateServerlessLambdas(serverlessFiles, containsDatadogLambdaImport),\n ]);\n\n if (!patchedTsFiles.length && !patchedServerlessFiles.length) {\n return {\n result: 'skip',\n reason: 'no lambdas to migrate',\n };\n }\n\n if (mode === 'lint') {\n return {\n result: 'apply',\n };\n }\n\n await Promise.all(\n [...patchedTsFiles, ...patchedServerlessFiles].map(\n async ({ file, contents }) => {\n await fs.promises.writeFile(file, contents, 'utf8');\n },\n ),\n );\n\n return {\n result: 'apply',\n };\n};\n\nexport const tryMigrateLambdas: PatchFunction = async (opts) => {\n try {\n return await migrateLambdas(opts);\n } catch (err) {\n // Don't fail the entire lint/format if this fails since it's a non-critical part of the upgrade\n // and can be retried later by the user\n log.warn('Failed to migrate lambdas, skipping');\n log.subtle(inspect(err));\n return { result: 'skip', reason: 'due to an error' };\n }\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -43,32 +43,35 @@ export const patchInstrumentation = async ({
|
|
|
43
43
|
const hasDDTraceImport = tsFiles.some(
|
|
44
44
|
({ content }) => /from\s+['"]dd-trace['"]/.test(content)
|
|
45
45
|
);
|
|
46
|
+
const hasDDTraceInitImport = tsFiles.some(
|
|
47
|
+
({ content }) => /from\s+['"]dd-trace\/init['"]/.test(content)
|
|
48
|
+
);
|
|
46
49
|
const otelImports = tsFiles.filter(
|
|
47
50
|
({ content }) => /from\s+['"]@opentelemetry\/api['"]/.test(content)
|
|
48
51
|
);
|
|
49
52
|
const hasOpenTelemetryImport = otelImports.length > 0;
|
|
50
|
-
if (!hasDDTraceImport && !hasOpenTelemetryImport) {
|
|
53
|
+
if (!hasDDTraceImport && !hasDDTraceInitImport && !hasOpenTelemetryImport) {
|
|
51
54
|
return {
|
|
52
55
|
result: "skip",
|
|
53
56
|
reason: "no imports for Datadog or OpenTelemetry instrumentation found in source files"
|
|
54
57
|
};
|
|
55
58
|
}
|
|
56
|
-
const confused = hasDDTraceImport && hasOpenTelemetryImport;
|
|
59
|
+
const confused = (hasDDTraceImport || hasDDTraceInitImport) && hasOpenTelemetryImport;
|
|
57
60
|
if (confused) {
|
|
58
61
|
log.warn(
|
|
59
62
|
"Found imports for both Datadog and OpenTelemetry instrumentation in source files, unsure which to patch"
|
|
60
63
|
);
|
|
61
64
|
}
|
|
62
|
-
const warning =
|
|
65
|
+
const warning = confused ? "TODO: skuba failed to determine whether to add dd-trace or OpenTelemetry flags, please choose the appropriate flags to add to your Dockerfile " : "";
|
|
63
66
|
const commandsToAdd = [
|
|
64
|
-
hasDDTraceImport ? "--import dd-trace/
|
|
67
|
+
hasDDTraceImport ? "--import dd-trace/register.js" : "",
|
|
65
68
|
hasOpenTelemetryImport ? "--experimental-loader @opentelemetry/instrumentation/hook.mjs" : ""
|
|
66
69
|
].filter(Boolean);
|
|
67
70
|
const patched = dockerFiles.map(({ filePath, content }) => {
|
|
68
71
|
if (filePath.includes("dev-deps")) {
|
|
69
72
|
return null;
|
|
70
73
|
}
|
|
71
|
-
if (content.includes("dd-trace/initialize.mjs") || content.includes("@opentelemetry/instrumentation/hook.mjs")) {
|
|
74
|
+
if (content.includes("dd-trace/initialize.mjs") || content.includes("dd-trace/register.js") || content.includes("@opentelemetry/instrumentation/hook.mjs")) {
|
|
72
75
|
return null;
|
|
73
76
|
}
|
|
74
77
|
const cmd = /^CMD\s+(.+)$/m.exec(content)?.[1];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cli/migrate/esm/patchInstrumentation.ts"],
|
|
4
|
-
"sourcesContent": ["import { dirname } from 'path';\nimport { inspect } from 'util';\n\nimport fg from 'fast-glob';\nimport fs from 'fs-extra';\nimport latestVersion from 'latest-version';\n\nimport { createExec } from '../../../utils/exec.js';\nimport { log } from '../../../utils/logging.js';\nimport { getConsumerManifest } from '../../../utils/manifest.js';\nimport type { PatchFunction } from '../../lint/internalLints/upgrade/index.js';\n\nimport { Git } from '@skuba-lib/api';\n\nexport const patchInstrumentation: PatchFunction = async ({\n mode,\n packageManager,\n}) => {\n const [dockerfilePaths, tsPaths] = await Promise.all([\n fg(['**/Dockerfile*'], {\n ignore: ['**/.git', '**/node_modules'],\n }),\n fg(['**/*.ts'], {\n ignore: ['**/.git', '**/node_modules'],\n }),\n ]);\n\n if (!dockerfilePaths.length) {\n return {\n result: 'skip',\n reason: 'no Dockerfile files found',\n };\n }\n\n const [dockerFiles, tsFiles] = await Promise.all([\n Promise.all(\n dockerfilePaths.map(async (filePath) => ({\n filePath,\n content: await fs.promises.readFile(filePath, 'utf-8'),\n })),\n ),\n Promise.all(\n tsPaths.map(async (filePath) => ({\n filePath,\n content: await fs.promises.readFile(filePath, 'utf-8'),\n })),\n ),\n ]);\n\n const hasDDTraceImport = tsFiles.some(({ content }) =>\n /from\\s+['\"]dd-trace['\"]/.test(content),\n );\n const otelImports = tsFiles.filter(({ content }) =>\n /from\\s+['\"]@opentelemetry\\/api['\"]/.test(content),\n );\n\n const hasOpenTelemetryImport = otelImports.length > 0;\n\n if (!hasDDTraceImport && !hasOpenTelemetryImport) {\n return {\n result: 'skip',\n reason:\n 'no imports for Datadog or OpenTelemetry instrumentation found in source files',\n };\n }\n\n const confused
|
|
5
|
-
"mappings": ";AAAA,SAAS,eAAe;AACxB,SAAS,eAAe;AAExB,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf,OAAO,mBAAmB;AAE1B,SAAS,kBAAkB;AAC3B,SAAS,WAAW;AACpB,SAAS,2BAA2B;AAGpC,SAAS,WAAW;AAEb,aAAM,uBAAsC,OAAO;AAAA,EACxD;AAAA,EACA;AACF,MAAM;AACJ,QAAM,CAAC,iBAAiB,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,IACnD,GAAG,CAAC,gBAAgB,GAAG;AAAA,MACrB,QAAQ,CAAC,WAAW,iBAAiB;AAAA,IACvC,CAAC;AAAA,IACD,GAAG,CAAC,SAAS,GAAG;AAAA,MACd,QAAQ,CAAC,WAAW,iBAAiB;AAAA,IACvC,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,gBAAgB,QAAQ;AAC3B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,CAAC,aAAa,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC/C,QAAQ;AAAA,MACN,gBAAgB,IAAI,OAAO,cAAc;AAAA,QACvC;AAAA,QACA,SAAS,MAAM,GAAG,SAAS,SAAS,UAAU,OAAO;AAAA,MACvD,EAAE;AAAA,IACJ;AAAA,IACA,QAAQ;AAAA,MACN,QAAQ,IAAI,OAAO,cAAc;AAAA,QAC/B;AAAA,QACA,SAAS,MAAM,GAAG,SAAS,SAAS,UAAU,OAAO;AAAA,MACvD,EAAE;AAAA,IACJ;AAAA,EACF,CAAC;AAED,QAAM,mBAAmB,QAAQ;AAAA,IAAK,CAAC,EAAE,QAAQ,MAC/C,0BAA0B,KAAK,OAAO;AAAA,EACxC;AACA,QAAM,cAAc,QAAQ;AAAA,IAAO,CAAC,EAAE,QAAQ,MAC5C,qCAAqC,KAAK,OAAO;AAAA,EACnD;AAEA,QAAM,yBAAyB,YAAY,SAAS;AAEpD,MAAI,CAAC,oBAAoB,CAAC,wBAAwB;
|
|
4
|
+
"sourcesContent": ["import { dirname } from 'path';\nimport { inspect } from 'util';\n\nimport fg from 'fast-glob';\nimport fs from 'fs-extra';\nimport latestVersion from 'latest-version';\n\nimport { createExec } from '../../../utils/exec.js';\nimport { log } from '../../../utils/logging.js';\nimport { getConsumerManifest } from '../../../utils/manifest.js';\nimport type { PatchFunction } from '../../lint/internalLints/upgrade/index.js';\n\nimport { Git } from '@skuba-lib/api';\n\nexport const patchInstrumentation: PatchFunction = async ({\n mode,\n packageManager,\n}) => {\n const [dockerfilePaths, tsPaths] = await Promise.all([\n fg(['**/Dockerfile*'], {\n ignore: ['**/.git', '**/node_modules'],\n }),\n fg(['**/*.ts'], {\n ignore: ['**/.git', '**/node_modules'],\n }),\n ]);\n\n if (!dockerfilePaths.length) {\n return {\n result: 'skip',\n reason: 'no Dockerfile files found',\n };\n }\n\n const [dockerFiles, tsFiles] = await Promise.all([\n Promise.all(\n dockerfilePaths.map(async (filePath) => ({\n filePath,\n content: await fs.promises.readFile(filePath, 'utf-8'),\n })),\n ),\n Promise.all(\n tsPaths.map(async (filePath) => ({\n filePath,\n content: await fs.promises.readFile(filePath, 'utf-8'),\n })),\n ),\n ]);\n\n const hasDDTraceImport = tsFiles.some(({ content }) =>\n /from\\s+['\"]dd-trace['\"]/.test(content),\n );\n const hasDDTraceInitImport = tsFiles.some(({ content }) =>\n /from\\s+['\"]dd-trace\\/init['\"]/.test(content),\n );\n const otelImports = tsFiles.filter(({ content }) =>\n /from\\s+['\"]@opentelemetry\\/api['\"]/.test(content),\n );\n\n const hasOpenTelemetryImport = otelImports.length > 0;\n\n if (!hasDDTraceImport && !hasDDTraceInitImport && !hasOpenTelemetryImport) {\n return {\n result: 'skip',\n reason:\n 'no imports for Datadog or OpenTelemetry instrumentation found in source files',\n };\n }\n\n const confused =\n (hasDDTraceImport || hasDDTraceInitImport) && hasOpenTelemetryImport;\n\n if (confused) {\n log.warn(\n 'Found imports for both Datadog and OpenTelemetry instrumentation in source files, unsure which to patch',\n );\n }\n\n const warning = confused\n ? 'TODO: skuba failed to determine whether to add dd-trace or OpenTelemetry flags, please choose the appropriate flags to add to your Dockerfile '\n : '';\n\n const commandsToAdd = [\n hasDDTraceImport ? '--import dd-trace/register.js' : '',\n hasOpenTelemetryImport\n ? '--experimental-loader @opentelemetry/instrumentation/hook.mjs'\n : '',\n ].filter(Boolean);\n\n const patched = dockerFiles\n .map(({ filePath, content }) => {\n if (filePath.includes('dev-deps')) {\n return null;\n }\n\n if (\n content.includes('dd-trace/initialize.mjs') ||\n content.includes('dd-trace/register.js') ||\n content.includes('@opentelemetry/instrumentation/hook.mjs')\n ) {\n return null;\n }\n\n const cmd = /^CMD\\s+(.+)$/m.exec(content)?.[1];\n\n if (!cmd) {\n return null;\n }\n\n // check if CMD is in shell or exec form\n const isShellForm = !cmd.startsWith('[');\n\n if (isShellForm) {\n if (cmd.startsWith('node ')) {\n const patchedCmd = cmd.replace(\n 'node ',\n `node ${warning}${commandsToAdd.join(' ')} `,\n );\n return { filePath, content: content.replace(cmd, patchedCmd) };\n }\n\n return {\n filePath,\n content: content.replace(\n cmd,\n `${warning}${commandsToAdd.join(' ')} ${cmd}`,\n ),\n };\n }\n\n const flags = commandsToAdd\n .map((f) => f.split(' '))\n .flat()\n .map((f) => `\"${f}\"`)\n .join(', ');\n\n if (/^\\s*\\[\\s*\"node\"\\s*[,\\]]/.test(cmd)) {\n const patchedCmd = cmd.replace(\n /^(\\s*\\[\\s*\"node\"\\s*)([,\\]])/,\n `$1, ${warning}${flags}$2`,\n );\n\n return { filePath, content: content.replace(cmd, patchedCmd) };\n }\n\n const patchedCmd = cmd.replace(/^\\s*\\[/, `[${warning}${flags}, `);\n return { filePath, content: content.replace(cmd, patchedCmd) };\n })\n .filter((patch) => patch !== null);\n\n if (!patched.length) {\n return {\n result: 'skip',\n reason: 'no CMD instructions found in Dockerfiles to patch',\n };\n }\n\n if (mode === 'lint') {\n return {\n result: 'apply',\n };\n }\n\n if (hasOpenTelemetryImport) {\n const packageJsons = await Promise.all(\n otelImports.map(async ({ filePath }) =>\n getConsumerManifest(dirname(filePath)),\n ),\n );\n\n const filteredPackageJsons = packageJsons.filter(\n (pkg) => pkg !== undefined,\n );\n await Promise.all(\n filteredPackageJsons.map(async (pkg) => {\n const { packageJson, path } = pkg;\n\n if (\n packageJson.dependencies?.['@opentelemetry/instrumentation'] ||\n packageJson.devDependencies?.['@opentelemetry/instrumentation']\n ) {\n return;\n }\n\n const fallbackVersion = '0.216.0';\n\n const existingVersion =\n packageJson.dependencies?.['@opentelemetry/instrumentation-http'] ??\n packageJson.dependencies?.['@opentelemetry/sdk-node'];\n\n const versionToUse =\n existingVersion?.startsWith('catalog:') ||\n existingVersion === undefined\n ? fallbackVersion\n : await latestVersion('@opentelemetry/instrumentation', {\n version: `<=${existingVersion}`,\n });\n\n packageJson.dependencies ??= {};\n\n packageJson.dependencies['@opentelemetry/instrumentation'] =\n versionToUse;\n\n await fs.promises.writeFile(\n path,\n JSON.stringify(packageJson, null, 2),\n 'utf-8',\n );\n }),\n );\n\n const gitRoot =\n (await Git.findRoot({ dir: process.cwd() })) ?? process.cwd();\n\n const rootExec = createExec({ cwd: gitRoot });\n\n try {\n await rootExec(\n packageManager.command,\n 'install',\n ...(packageManager.command === 'pnpm'\n ? ['--frozen-lockfile=false']\n : []),\n '--prefer-offline',\n '--ignore-scripts',\n );\n } catch (error) {\n log.warn('Failed to install dependencies after OpenTelemetry patch');\n log.subtle(inspect(error));\n }\n }\n\n await Promise.all(\n patched.map(({ filePath, content }) =>\n fs.promises.writeFile(filePath, content, 'utf-8'),\n ),\n );\n\n return {\n result: 'apply',\n };\n};\n\nexport const tryPatchInstrumentation: PatchFunction = async (opts) => {\n try {\n return await patchInstrumentation(opts);\n } catch (err) {\n log.warn(\n 'Failed to patch Datadog or OpenTelemetry instrumentation, skipping',\n );\n log.subtle(inspect(err));\n return { result: 'skip', reason: 'due to an error' };\n }\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["patchedCmd"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skuba",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "SEEK development toolkit for backend applications and packages",
|
|
6
6
|
"homepage": "https://github.com/seek-oss/skuba#readme",
|
|
@@ -106,9 +106,9 @@
|
|
|
106
106
|
"typescript": "~5.9.0",
|
|
107
107
|
"vitest": "^4.1.4",
|
|
108
108
|
"zod": "^4.3.5",
|
|
109
|
-
"
|
|
109
|
+
"eslint-config-skuba": "9.0.0",
|
|
110
110
|
"pnpm-plugin-skuba": "3.0.0",
|
|
111
|
-
"
|
|
111
|
+
"@skuba-lib/api": "^2.1.2"
|
|
112
112
|
},
|
|
113
113
|
"devDependencies": {
|
|
114
114
|
"@changesets/cli": "2.31.0",
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"@types/picomatch": "4.0.3",
|
|
128
128
|
"@types/semver": "7.7.1",
|
|
129
129
|
"@types/supertest": "7.2.0",
|
|
130
|
-
"enhanced-resolve": "5.21.
|
|
130
|
+
"enhanced-resolve": "5.21.3",
|
|
131
131
|
"express": "5.2.1",
|
|
132
132
|
"fastify": "5.8.5",
|
|
133
133
|
"jsonfile": "6.2.1",
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
"memfs": "4.57.2",
|
|
136
136
|
"remark-cli": "12.0.1",
|
|
137
137
|
"remark-preset-lint-recommended": "7.0.1",
|
|
138
|
-
"semver": "7.
|
|
138
|
+
"semver": "7.8.0",
|
|
139
139
|
"supertest": "7.2.2",
|
|
140
140
|
"type-fest": "2.19.0",
|
|
141
141
|
"@skuba-lib/changesets-changelog": "^1.0.1"
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@opentelemetry/api": "^1.9.0",
|
|
24
24
|
"@opentelemetry/core": "~2.7.0",
|
|
25
|
-
"@opentelemetry/exporter-trace-otlp-grpc": "~0.
|
|
26
|
-
"@opentelemetry/instrumentation": "~0.
|
|
27
|
-
"@opentelemetry/instrumentation-aws-sdk": "^0.
|
|
28
|
-
"@opentelemetry/instrumentation-http": "~0.
|
|
25
|
+
"@opentelemetry/exporter-trace-otlp-grpc": "~0.218.0",
|
|
26
|
+
"@opentelemetry/instrumentation": "~0.218.0",
|
|
27
|
+
"@opentelemetry/instrumentation-aws-sdk": "^0.73.0",
|
|
28
|
+
"@opentelemetry/instrumentation-http": "~0.218.0",
|
|
29
29
|
"@opentelemetry/propagator-b3": "^2.0.0",
|
|
30
|
-
"@opentelemetry/sdk-node": "~0.
|
|
30
|
+
"@opentelemetry/sdk-node": "~0.218.0",
|
|
31
31
|
"@seek/logger": "^12.0.0",
|
|
32
32
|
"express": "^5.0.0",
|
|
33
33
|
"hot-shots": "^14.3.1",
|
|
@@ -29,7 +29,7 @@ or serve as a starting point for a backend project if the other built-in templat
|
|
|
29
29
|
It's a barebones Node.js application that comprises:
|
|
30
30
|
|
|
31
31
|
- A [src/app.ts](src/app.ts) that can be run locally to greet the user
|
|
32
|
-
- A [src/app.test.ts](src/app.test.ts) that demonstrates rudimentary
|
|
32
|
+
- A [src/app.test.ts](src/app.test.ts) that demonstrates rudimentary Vitest usage
|
|
33
33
|
|
|
34
34
|
## Development
|
|
35
35
|
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
"@koa/router": "15.5.0",
|
|
25
25
|
"@opentelemetry/api": "^1.9.0",
|
|
26
26
|
"@opentelemetry/core": "~2.7.0",
|
|
27
|
-
"@opentelemetry/exporter-trace-otlp-grpc": "~0.
|
|
28
|
-
"@opentelemetry/instrumentation": "~0.
|
|
29
|
-
"@opentelemetry/instrumentation-aws-sdk": "^0.
|
|
30
|
-
"@opentelemetry/instrumentation-http": "~0.
|
|
27
|
+
"@opentelemetry/exporter-trace-otlp-grpc": "~0.218.0",
|
|
28
|
+
"@opentelemetry/instrumentation": "~0.218.0",
|
|
29
|
+
"@opentelemetry/instrumentation-aws-sdk": "^0.73.0",
|
|
30
|
+
"@opentelemetry/instrumentation-http": "~0.218.0",
|
|
31
31
|
"@opentelemetry/propagator-b3": "^2.0.0",
|
|
32
|
-
"@opentelemetry/sdk-node": "~0.
|
|
32
|
+
"@opentelemetry/sdk-node": "~0.218.0",
|
|
33
33
|
"@seek/logger": "^12.0.0",
|
|
34
34
|
"hot-shots": "^14.3.1",
|
|
35
35
|
"koa": "^3.0.1",
|
|
@@ -23,23 +23,23 @@
|
|
|
23
23
|
"@aws-sdk/client-lambda": "^3.363.0",
|
|
24
24
|
"@aws-sdk/client-secrets-manager": "^3.363.0",
|
|
25
25
|
"@aws-sdk/client-sns": "^3.363.0",
|
|
26
|
-
"@seek/aws-codedeploy-hooks": "^
|
|
26
|
+
"@seek/aws-codedeploy-hooks": "^4.0.0",
|
|
27
27
|
"@seek/logger": "^12.0.0",
|
|
28
28
|
"skuba-dive": "^4.1.0",
|
|
29
29
|
"zod": "^4.3.5"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@seek/aws-codedeploy-infra": "^
|
|
32
|
+
"@seek/aws-codedeploy-infra": "^5.0.0",
|
|
33
33
|
"@types/aws-lambda": "^8.10.82",
|
|
34
34
|
"@types/chance": "^1.1.3",
|
|
35
35
|
"@types/node": "^24.10.2",
|
|
36
36
|
"aws-cdk": "^2.1010.0",
|
|
37
|
-
"aws-cdk-lib": "
|
|
37
|
+
"aws-cdk-lib": "^2.253.0",
|
|
38
38
|
"aws-sdk-client-mock": "^4.0.0",
|
|
39
39
|
"aws-sdk-client-mock-vitest": "^7.0.0",
|
|
40
40
|
"chance": "^1.1.8",
|
|
41
41
|
"constructs": "^10.0.17",
|
|
42
|
-
"datadog-cdk-constructs-v2": "^
|
|
42
|
+
"datadog-cdk-constructs-v2": "^4.0.0",
|
|
43
43
|
"datadog-lambda-js": "^12.0.0",
|
|
44
44
|
"dd-trace": "^5.0.0",
|
|
45
45
|
"pino-pretty": "^13.0.0",
|
|
@@ -23,7 +23,7 @@ jobs:
|
|
|
23
23
|
fetch-depth: 0
|
|
24
24
|
|
|
25
25
|
- name: Set up pnpm
|
|
26
|
-
uses: pnpm/action-setup@
|
|
26
|
+
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
|
27
27
|
|
|
28
28
|
- name: Set up Node.js
|
|
29
29
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
@@ -19,7 +19,7 @@ jobs:
|
|
|
19
19
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
20
20
|
|
|
21
21
|
- name: Set up pnpm
|
|
22
|
-
uses: pnpm/action-setup@
|
|
22
|
+
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
|
23
23
|
|
|
24
24
|
- name: Set up Node.js
|
|
25
25
|
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
2
|
-
type Props = ts.NodeArray<ts.ObjectLiteralElementLike>;
|
|
3
|
-
type Transformer<T> = (context: ts.TransformationContext | null, props: T) => T;
|
|
4
|
-
/**
|
|
5
|
-
* Create a transformer to filter out unspecified props from an object literal.
|
|
6
|
-
*/
|
|
7
|
-
export declare const createPropFilter: (names: string[]) => Transformer<Props>;
|
|
8
|
-
export declare const createPropAppender: (appendingProps: Props) => Transformer<Props>;
|
|
9
|
-
/**
|
|
10
|
-
* Read out `export default` or `module.exports` props from a source file.
|
|
11
|
-
*
|
|
12
|
-
* The props can then be used when transforming another source file.
|
|
13
|
-
*/
|
|
14
|
-
export declare const readModuleExports: (inputFile: string) => Promise<Props | undefined>;
|
|
15
|
-
/**
|
|
16
|
-
* Mutate imports and exports in a source file:
|
|
17
|
-
*
|
|
18
|
-
* - Convert `const x = require('')` into `import x from ''`
|
|
19
|
-
* - Convert `module.exports =` into `export default`
|
|
20
|
-
* - Run a transformer over the exported props
|
|
21
|
-
*/
|
|
22
|
-
export declare const transformModuleImportsAndExports: (inputFile: string, transformProps: Transformer<Props>) => Promise<string>;
|
|
23
|
-
export {};
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
import ts from "typescript";
|
|
3
|
-
import { formatPrettier } from "./prettier.js";
|
|
4
|
-
const BLANK_LINE_PLACEHOLDER = " __BLANK_LINE_PLACEHOLDER__";
|
|
5
|
-
const BLANK_LINE_REGEXP = new RegExp(`//${BLANK_LINE_PLACEHOLDER}`, "g");
|
|
6
|
-
const withLeadingBlankLinePlaceholder = (node) => ts.addSyntheticLeadingComment(
|
|
7
|
-
node,
|
|
8
|
-
ts.SyntaxKind.SingleLineCommentTrivia,
|
|
9
|
-
BLANK_LINE_PLACEHOLDER,
|
|
10
|
-
true
|
|
11
|
-
);
|
|
12
|
-
const createExportDefaultObjectLiteralExpression = (factory, props, callExpression) => factory.createExportAssignment(
|
|
13
|
-
void 0,
|
|
14
|
-
void 0,
|
|
15
|
-
callExpression === void 0 ? factory.createObjectLiteralExpression(props, true) : factory.createCallExpression(callExpression, void 0, [
|
|
16
|
-
factory.createObjectLiteralExpression(props, true)
|
|
17
|
-
])
|
|
18
|
-
);
|
|
19
|
-
const createImportFromExpression = (factory, moduleName, importNames) => {
|
|
20
|
-
const importClause = typeof importNames === "string" ? factory.createImportClause(
|
|
21
|
-
false,
|
|
22
|
-
factory.createIdentifier(importNames),
|
|
23
|
-
void 0
|
|
24
|
-
) : factory.createImportClause(
|
|
25
|
-
false,
|
|
26
|
-
void 0,
|
|
27
|
-
factory.createNamedImports(
|
|
28
|
-
importNames.map(
|
|
29
|
-
(importName) => factory.createImportSpecifier(
|
|
30
|
-
false,
|
|
31
|
-
void 0,
|
|
32
|
-
factory.createIdentifier(importName)
|
|
33
|
-
)
|
|
34
|
-
)
|
|
35
|
-
)
|
|
36
|
-
);
|
|
37
|
-
return factory.createImportDeclaration(
|
|
38
|
-
void 0,
|
|
39
|
-
importClause,
|
|
40
|
-
factory.createStringLiteral(moduleName)
|
|
41
|
-
);
|
|
42
|
-
};
|
|
43
|
-
const getPropName = (prop) => ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) ? prop.name.escapedText.toString() : void 0;
|
|
44
|
-
const expressionAsDefaultExport = (context, transformProps, expression) => withLeadingBlankLinePlaceholder(
|
|
45
|
-
(() => {
|
|
46
|
-
if (ts.isObjectLiteralExpression(expression)) {
|
|
47
|
-
const props = transformProps(context, expression.properties);
|
|
48
|
-
return createExportDefaultObjectLiteralExpression(
|
|
49
|
-
context.factory,
|
|
50
|
-
props
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
if (ts.isCallExpression(expression) && expression.arguments.length === 1 && expression.arguments[0]) {
|
|
54
|
-
const [firstArgument] = expression.arguments;
|
|
55
|
-
if (ts.isObjectLiteralExpression(firstArgument)) {
|
|
56
|
-
const props = transformProps(context, firstArgument.properties);
|
|
57
|
-
return createExportDefaultObjectLiteralExpression(
|
|
58
|
-
context.factory,
|
|
59
|
-
props,
|
|
60
|
-
expression.expression
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return context.factory.createExportAssignment(
|
|
65
|
-
void 0,
|
|
66
|
-
void 0,
|
|
67
|
-
expression
|
|
68
|
-
);
|
|
69
|
-
})()
|
|
70
|
-
);
|
|
71
|
-
const requireImportsTransformer = (context) => (rootNode) => ts.visitEachChild(
|
|
72
|
-
rootNode,
|
|
73
|
-
(node) => {
|
|
74
|
-
let declaration, moduleName;
|
|
75
|
-
if (ts.isVariableStatement(node) && node.declarationList.declarations.length === 1 && node.declarationList.declarations[0] && ts.isVariableDeclaration(
|
|
76
|
-
declaration = node.declarationList.declarations[0]
|
|
77
|
-
) && declaration.initializer && ts.isCallExpression(declaration.initializer) && declaration.initializer.arguments.length === 1 && declaration.initializer.arguments[0] && ts.isStringLiteral(
|
|
78
|
-
moduleName = declaration.initializer.arguments[0]
|
|
79
|
-
) && ts.isIdentifier(declaration.initializer.expression) && declaration.initializer.expression.text === "require") {
|
|
80
|
-
if (ts.isIdentifier(declaration.name)) {
|
|
81
|
-
return createImportFromExpression(
|
|
82
|
-
context.factory,
|
|
83
|
-
moduleName.text,
|
|
84
|
-
declaration.name.text
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
if (ts.isObjectBindingPattern(declaration.name)) {
|
|
88
|
-
return createImportFromExpression(
|
|
89
|
-
context.factory,
|
|
90
|
-
moduleName.text,
|
|
91
|
-
declaration.name.elements.flatMap(
|
|
92
|
-
(element) => ts.isIdentifier(element.name) ? [element.name.text] : []
|
|
93
|
-
)
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return node;
|
|
98
|
-
},
|
|
99
|
-
context
|
|
100
|
-
);
|
|
101
|
-
const createModuleExportsTransformer = (transformProps) => (context) => (rootNode) => ts.visitEachChild(
|
|
102
|
-
rootNode,
|
|
103
|
-
(node) => {
|
|
104
|
-
if (ts.isExpressionStatement(node) && ts.isBinaryExpression(node.expression) && ts.isPropertyAccessExpression(node.expression.left) && ts.isIdentifier(node.expression.left.expression) && node.expression.left.expression.escapedText.toString() === "module" && node.expression.left.name.text === "exports" && node.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
105
|
-
return expressionAsDefaultExport(
|
|
106
|
-
context,
|
|
107
|
-
transformProps,
|
|
108
|
-
node.expression.right
|
|
109
|
-
) ?? node;
|
|
110
|
-
}
|
|
111
|
-
if (ts.isExportAssignment(node)) {
|
|
112
|
-
return expressionAsDefaultExport(
|
|
113
|
-
context,
|
|
114
|
-
transformProps,
|
|
115
|
-
node.expression
|
|
116
|
-
) ?? node;
|
|
117
|
-
}
|
|
118
|
-
return node;
|
|
119
|
-
},
|
|
120
|
-
context
|
|
121
|
-
);
|
|
122
|
-
export const createPropFilter = (names) => (context, props) => {
|
|
123
|
-
const nameSet = new Set(names);
|
|
124
|
-
const factory = context?.factory ?? ts.factory;
|
|
125
|
-
return factory.createNodeArray(
|
|
126
|
-
props.filter((prop) => nameSet.has(getPropName(prop)))
|
|
127
|
-
);
|
|
128
|
-
};
|
|
129
|
-
export const createPropAppender = (appendingProps) => (context, props) => {
|
|
130
|
-
const nameSet = new Set(
|
|
131
|
-
props.map(getPropName).filter((prop) => typeof prop === "string")
|
|
132
|
-
);
|
|
133
|
-
const factory = context?.factory ?? ts.factory;
|
|
134
|
-
return factory.createNodeArray([
|
|
135
|
-
...props,
|
|
136
|
-
...appendingProps.filter((prop) => !nameSet.has(getPropName(prop)))
|
|
137
|
-
]);
|
|
138
|
-
};
|
|
139
|
-
export const readModuleExports = async (inputFile) => {
|
|
140
|
-
let result;
|
|
141
|
-
await transformModuleImportsAndExports(
|
|
142
|
-
inputFile,
|
|
143
|
-
(_, props) => result = props
|
|
144
|
-
);
|
|
145
|
-
return result;
|
|
146
|
-
};
|
|
147
|
-
export const transformModuleImportsAndExports = async (inputFile, transformProps) => {
|
|
148
|
-
const sourceFile = ts.createSourceFile("", inputFile, ts.ScriptTarget.Latest);
|
|
149
|
-
const moduleExportsTransformer = createModuleExportsTransformer(transformProps);
|
|
150
|
-
const result = ts.transform(sourceFile, [
|
|
151
|
-
requireImportsTransformer,
|
|
152
|
-
moduleExportsTransformer
|
|
153
|
-
]);
|
|
154
|
-
const [transformedFile] = result.transformed;
|
|
155
|
-
if (!transformedFile) {
|
|
156
|
-
throw new Error(
|
|
157
|
-
`Could not get transformed result for ${JSON.stringify(result)}`
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
const text = ts.createPrinter().printNode(ts.EmitHint.SourceFile, transformedFile, sourceFile).replace(BLANK_LINE_REGEXP, "");
|
|
161
|
-
return formatPrettier(text, { parser: "typescript" });
|
|
162
|
-
};
|
|
163
|
-
//# sourceMappingURL=typescript.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../src/cli/configure/processing/typescript.ts"],
|
|
4
|
-
"sourcesContent": ["import ts from 'typescript';\n\nimport { formatPrettier } from './prettier.js';\n\ntype Props = ts.NodeArray<ts.ObjectLiteralElementLike>;\n\ntype Transformer<T> = (context: ts.TransformationContext | null, props: T) => T;\n\nconst BLANK_LINE_PLACEHOLDER = ' __BLANK_LINE_PLACEHOLDER__';\nconst BLANK_LINE_REGEXP = new RegExp(`//${BLANK_LINE_PLACEHOLDER}`, 'g');\n\n/**\n * Append a placeholder comment to the start of a node.\n *\n * Blank lines can be annotated and preserved through the TypeScript printer\n * when this is paired with a dodgy `String.prototype.replace` post-processor.\n */\nconst withLeadingBlankLinePlaceholder = <T extends ts.Node>(node: T) =>\n ts.addSyntheticLeadingComment(\n node,\n ts.SyntaxKind.SingleLineCommentTrivia,\n BLANK_LINE_PLACEHOLDER,\n true,\n );\n\n/**\n * Create the following expression:\n *\n * ```javascript\n * export default {};\n * ```\n */\nconst createExportDefaultObjectLiteralExpression = (\n factory: ts.NodeFactory,\n props: Props,\n callExpression?: ts.Expression,\n): ts.ExportAssignment =>\n factory.createExportAssignment(\n undefined,\n undefined,\n callExpression === undefined\n ? factory.createObjectLiteralExpression(props, true)\n : factory.createCallExpression(callExpression, undefined, [\n factory.createObjectLiteralExpression(props, true),\n ]),\n );\n\nconst createImportFromExpression = (\n factory: ts.NodeFactory,\n moduleName: string,\n importNames: string | string[],\n) => {\n const importClause =\n typeof importNames === 'string'\n ? factory.createImportClause(\n false,\n factory.createIdentifier(importNames),\n undefined,\n )\n : factory.createImportClause(\n false,\n undefined,\n factory.createNamedImports(\n importNames.map((importName) =>\n factory.createImportSpecifier(\n false,\n undefined,\n factory.createIdentifier(importName),\n ),\n ),\n ),\n );\n\n return factory.createImportDeclaration(\n undefined,\n importClause,\n factory.createStringLiteral(moduleName),\n );\n};\n\nconst getPropName = (prop: ts.ObjectLiteralElementLike) =>\n ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)\n ? prop.name.escapedText.toString()\n : undefined;\n\nconst expressionAsDefaultExport = (\n context: ts.TransformationContext,\n transformProps: Transformer<Props>,\n expression: ts.Expression,\n): ts.ExportAssignment | null =>\n withLeadingBlankLinePlaceholder(\n (() => {\n // {}\n if (ts.isObjectLiteralExpression(expression)) {\n const props = transformProps(context, expression.properties);\n\n return createExportDefaultObjectLiteralExpression(\n context.factory,\n props,\n );\n }\n\n // fn({})\n if (\n ts.isCallExpression(expression) &&\n expression.arguments.length === 1 &&\n expression.arguments[0]\n ) {\n const [firstArgument] = expression.arguments;\n\n if (ts.isObjectLiteralExpression(firstArgument)) {\n const props = transformProps(context, firstArgument.properties);\n\n return createExportDefaultObjectLiteralExpression(\n context.factory,\n props,\n expression.expression,\n );\n }\n }\n\n // Anything else\n return context.factory.createExportAssignment(\n undefined,\n undefined,\n expression,\n );\n })(),\n );\n\n/**\n * Mutate `const x = require('')` into `import x from ''`:\n *\n * ```javascript\n * const x = require('');\n *\n * const { x } = require('');\n * ```\n *\n * There's no recursion needed here as we expect the import statement to be a\n * top-level node and therefore an immediate child of the source file.\n */\nconst requireImportsTransformer: ts.TransformerFactory<ts.Node> =\n (context) => (rootNode) =>\n ts.visitEachChild(\n rootNode,\n (node) => {\n let declaration, moduleName;\n\n if (\n ts.isVariableStatement(node) &&\n node.declarationList.declarations.length === 1 &&\n node.declarationList.declarations[0] &&\n ts.isVariableDeclaration(\n (declaration = node.declarationList.declarations[0]),\n ) &&\n declaration.initializer &&\n ts.isCallExpression(declaration.initializer) &&\n declaration.initializer.arguments.length === 1 &&\n declaration.initializer.arguments[0] &&\n ts.isStringLiteral(\n (moduleName = declaration.initializer.arguments[0]),\n ) &&\n ts.isIdentifier(declaration.initializer.expression) &&\n declaration.initializer.expression.text === 'require'\n ) {\n // const x\n if (ts.isIdentifier(declaration.name)) {\n return createImportFromExpression(\n context.factory,\n moduleName.text,\n declaration.name.text,\n );\n }\n\n // const { x }\n if (ts.isObjectBindingPattern(declaration.name)) {\n return createImportFromExpression(\n context.factory,\n moduleName.text,\n declaration.name.elements.flatMap((element) =>\n ts.isIdentifier(element.name) ? [element.name.text] : [],\n ),\n );\n }\n }\n\n return node;\n },\n context,\n );\n\n/**\n * Create a transformer to mutate `module.exports` and `export default`:\n *\n * ```javascript\n * export default {};\n *\n * module.exports = {};\n * ```\n *\n * If the export is a call expression with a single argument, it will try to\n * transform the props of that argument.\n *\n * ```javascript\n * module.exports = fn({});\n * ```\n *\n * There's no recursion needed here as we expect the export statement to be a\n * top-level node and therefore an immediate child of the source file.\n */\nconst createModuleExportsTransformer =\n (transformProps: Transformer<Props>): ts.TransformerFactory<ts.Node> =>\n (context) =>\n (rootNode) =>\n ts.visitEachChild(\n rootNode,\n (node) => {\n // module.exports =\n if (\n ts.isExpressionStatement(node) &&\n ts.isBinaryExpression(node.expression) &&\n ts.isPropertyAccessExpression(node.expression.left) &&\n ts.isIdentifier(node.expression.left.expression) &&\n node.expression.left.expression.escapedText.toString() === 'module' &&\n node.expression.left.name.text === 'exports' &&\n node.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken\n ) {\n return (\n expressionAsDefaultExport(\n context,\n transformProps,\n node.expression.right,\n ) ?? node\n );\n }\n\n // export default\n if (ts.isExportAssignment(node)) {\n return (\n expressionAsDefaultExport(\n context,\n transformProps,\n node.expression,\n ) ?? node\n );\n }\n\n return node;\n },\n context,\n );\n\n/**\n * Create a transformer to filter out unspecified props from an object literal.\n */\nexport const createPropFilter =\n (names: string[]): Transformer<Props> =>\n (context, props) => {\n const nameSet = new Set<unknown>(names);\n\n const factory = context?.factory ?? ts.factory;\n\n return factory.createNodeArray(\n props.filter((prop) => nameSet.has(getPropName(prop))),\n );\n };\n\nexport const createPropAppender =\n (appendingProps: Props): Transformer<Props> =>\n (context, props) => {\n const nameSet = new Set<unknown>(\n props.map(getPropName).filter((prop) => typeof prop === 'string'),\n );\n\n const factory = context?.factory ?? ts.factory;\n\n return factory.createNodeArray([\n ...props,\n ...appendingProps.filter((prop) => !nameSet.has(getPropName(prop))),\n ]);\n };\n\n/**\n * Read out `export default` or `module.exports` props from a source file.\n *\n * The props can then be used when transforming another source file.\n */\nexport const readModuleExports = async (\n inputFile: string,\n): Promise<Props | undefined> => {\n let result: Props | undefined;\n\n await transformModuleImportsAndExports(\n inputFile,\n (_, props) => (result = props),\n );\n\n return result;\n};\n\n/**\n * Mutate imports and exports in a source file:\n *\n * - Convert `const x = require('')` into `import x from ''`\n * - Convert `module.exports =` into `export default`\n * - Run a transformer over the exported props\n */\nexport const transformModuleImportsAndExports = async (\n inputFile: string,\n transformProps: Transformer<Props>,\n): Promise<string> => {\n const sourceFile = ts.createSourceFile('', inputFile, ts.ScriptTarget.Latest);\n\n const moduleExportsTransformer =\n createModuleExportsTransformer(transformProps);\n\n const result = ts.transform(sourceFile, [\n requireImportsTransformer,\n moduleExportsTransformer,\n ]);\n\n const [transformedFile] = result.transformed;\n\n if (!transformedFile) {\n throw new Error(\n `Could not get transformed result for ${JSON.stringify(result)}`,\n );\n }\n\n const text = ts\n .createPrinter()\n .printNode(ts.EmitHint.SourceFile, transformedFile, sourceFile)\n .replace(BLANK_LINE_REGEXP, '');\n\n return formatPrettier(text, { parser: 'typescript' });\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|