@checkdigit/typescript-config 3.3.0-PR.30-064b → 3.3.0-PR.30-3a83

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/bin/builder.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // src/builder/index.mts
3
3
  import { strict as assert2 } from "node:assert";
4
+ import path2 from "node:path";
4
5
  import { parseArgs } from "node:util";
5
6
 
6
7
  // src/builder/builder.mts
@@ -36,7 +37,8 @@ function setup(pluginBuild) {
36
37
  });
37
38
  }
38
39
  async function builder_default({ inDir: inDir2, outDir: outDir2 }) {
39
- const sourceDirectory = path.join(process.cwd(), inDir2);
40
+ const messages2 = [];
41
+ const sourceDirectory = inDir2;
40
42
  const allSourceFiles = await getFiles(sourceDirectory);
41
43
  const productionSourceFiles = allSourceFiles.filter(
42
44
  // && !file.endsWith('.test.ts') && !file.endsWith('.spec.ts')
@@ -58,15 +60,15 @@ async function builder_default({ inDir: inDir2, outDir: outDir2 }) {
58
60
  assert.ok(diagnostic.start !== void 0);
59
61
  const { line, character } = typescript.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
60
62
  const message = typescript.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
61
- console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
63
+ messages2.push(`tsc: ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
62
64
  } else {
63
- console.log(typescript.flattenDiagnosticMessageText(diagnostic.messageText, "\n"));
65
+ messages2.push(`tsc: ${typescript.flattenDiagnosticMessageText(diagnostic.messageText, "\n")}`);
64
66
  }
65
67
  }
66
68
  if (emitResult.emitSkipped) {
67
69
  throw new Error("TypeScript compilation failed");
68
70
  }
69
- await build({
71
+ const buildResult = await build({
70
72
  entryPoints: productionSourceFiles,
71
73
  bundle: true,
72
74
  platform: "node",
@@ -82,6 +84,9 @@ async function builder_default({ inDir: inDir2, outDir: outDir2 }) {
82
84
  }
83
85
  ]
84
86
  });
87
+ messages2.push(...buildResult.errors.map((error) => `esbuild error: ${error.text}`));
88
+ messages2.push(...buildResult.warnings.map((warning) => `esbuild warning: ${warning.text}`));
89
+ return messages2;
85
90
  }
86
91
 
87
92
  // src/builder/index.mts
@@ -95,4 +100,8 @@ var {
95
100
  });
96
101
  assert2.ok(inDir !== void 0, "inDir is required");
97
102
  assert2.ok(outDir !== void 0, "outDir is required");
98
- await builder_default({ inDir, outDir });
103
+ var messages = await builder_default({ inDir: path2.join(process.cwd(), inDir), outDir: path2.join(process.cwd(), outDir) });
104
+ if (messages.length > 0) {
105
+ console.warn(JSON.stringify(messages, void 0, 2));
106
+ process.exit(1);
107
+ }
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@checkdigit/typescript-config","version":"3.3.0-PR.30-064b","description":"Check Digit standard Typescript configuration","prettier":"@checkdigit/prettier-config","engines":{"node":">=16"},"bin":{"builder":"./bin/builder.mjs"},"peerDependencies":{"@types/node":">=16","typescript":">=5.0.4 <5.1","esbuild":"0.17.18"},"repository":{"type":"git","url":"git+https://github.com/checkdigit/typescript-config.git"},"author":"Check Digit, LLC","license":"MIT","bugs":{"url":"https://github.com/checkdigit/typescript-config/issues"},"homepage":"https://github.com/checkdigit/typescript-config#readme","scripts":{"preversion":"npm test","postversion":"git push && git push --tags","prepare":"npm run build-builder","lint:fix":"eslint -f unix --ext .ts,.mts src --fix","lint":"eslint -f unix --ext .ts,.mts src","prettier":"prettier --ignore-path .gitignore --list-different .","prettier:fix":"prettier --ignore-path .gitignore --write .","test":"npm run ci:compile && npm run ci:test && npm run ci:lint && npm run ci:style","build-builder":"esbuild src/builder/index.mts --bundle --platform=node --format=esm --external:typescript --external:esbuild --outfile=build-builder/builder.mjs && mkdir -p bin && { echo '#!/usr/bin/env node'; cat build-builder/builder.mjs; } > bin/builder.mjs && chmod +x bin/builder.mjs","build-tsc-cjs":"rimraf build-tsc-cjs && tsc --outDir build-tsc-cjs","build-esbuild-cjs":"rimraf build-esbuild-cjs && esbuild ./src/*.ts ./src/*/*.ts --platform=node --bundle --format=cjs --sourcemap=inline --sources-content=false --outdir=build-esbuild-cjs","build-esbuild-cjs-bundle":"rimraf build-esbuild-cjs-bundle && esbuild src/test/index.test.ts --bundle --platform=node --format=cjs --sourcemap=inline --sources-content=false --outfile=build-esbuild-cjs-bundle/test/index.test.cjs","build-esbuild-esm":"rimraf build-esbuild-esm && node bin/builder.mjs --outDir=build-esbuild-esm","build-esbuild-esm-bundle":"rimraf build-esbuild-esm-bundle && esbuild src/test/index.test.ts --bundle --platform=node --format=esm --sourcemap=inline --sources-content=false --outfile=build-esbuild-esm-bundle/test/index.test.mjs","test-jest-esm":"NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage=false src/*.mts src/*/*.mts src/*/*/*.mts","test-jest-cjs":"jest --coverage=false src/*.ts src/*/*.ts src/*/*/*.ts","test-tsc-cjs":"node --test build-tsc-cjs/test/index.test.js","test-esbuild-cjs":"node --test build-esbuild-cjs/test/index.test.js","test-esbuild-cjs-bundle":"node --test build-esbuild-cjs-bundle/test/index.test.cjs","test-esbuild-esm":"node --test build-esbuild-esm/test/index.test.mjs","test-esbuild-esm-bundle":"echo 'node -test build-esbuild-esm-bundle/test/index.test.mjs'","ci:test":"npm run test-jest-cjs && npm run test-jest-esm &&npm run test-tsc-cjs && npm run test-esbuild-cjs && npm run test-esbuild-cjs-bundle && npm run test-esbuild-esm && npm run test-esbuild-esm-bundle","ci:compile":"npm run build-builder && npm run build-tsc-cjs && npm run build-esbuild-cjs && npm run build-esbuild-cjs-bundle && npm run build-esbuild-esm && npm run build-esbuild-esm-bundle","ci:lint":"npm run lint","ci:style":"npm run prettier"},"devDependencies":{"@checkdigit/prettier-config":"^3.4.0","@types/debug":"^4.1.7","@types/jest":"^29.5.1","@typescript-eslint/eslint-plugin":"^5.59.5","@typescript-eslint/parser":"^5.59.5","debug":"^4.3.4","eslint":"^8.40.0","eslint-config-prettier":"^8.8.0","get-port":"^6.1.2","got":"^11.8.6","jest":"^29.5.0","rimraf":"^5.0.0","ts-jest":"^29.1.0"},"eslintConfig":{"parser":"@typescript-eslint/parser","plugins":["@typescript-eslint"],"parserOptions":{"project":"./tsconfig.json"},"extends":["eslint:all","plugin:@typescript-eslint/recommended","plugin:@typescript-eslint/recommended-requiring-type-checking","plugin:@typescript-eslint/strict","prettier"],"rules":{"@typescript-eslint/non-nullable-type-assertion-style":"error","capitalized-comments":"off","one-var":"off","sort-keys":"off","sort-imports":"off","func-style":["error","declaration",{"allowArrowFunctions":true}],"no-magic-numbers":["error",{"ignore":[1]}],"no-undefined":"off","no-ternary":"off"},"overrides":[{"files":["*.spec.mts","*.test.mts","*.spec.ts","*.test.ts"],"rules":{"@typescript-eslint/non-nullable-type-assertion-style":"off","@typescript-eslint/ban-types":"off","@typescript-eslint/require-await":"off","@typescript-eslint/consistent-type-definitions":"off","@typescript-eslint/ban-ts-comment":"off","@typescript-eslint/no-unnecessary-condition":"off","@typescript-eslint/consistent-indexed-object-style":"off","@typescript-eslint/no-unused-vars":"off","@typescript-eslint/no-unsafe-member-access":"off","line-comment-position":"off","no-inline-comments":"off","no-param-reassign":"off","id-length":"off","no-magic-numbers":"off","func-names":"off","no-duplicate-imports":"off","symbol-description":"off","no-invalid-this":"off"}}]},"jest":{"moduleFileExtensions":["js","mjs","cjs","ts","mts","json","node"],"extensionsToTreatAsEsm":[".mts"],"transform":{"^.+\\.mts$":["ts-jest",{"isolatedModules":true,"diagnostics":false,"useESM":true}],"^.+\\.ts$":["ts-jest",{"isolatedModules":true,"diagnostics":false,"useESM":false}]},"collectCoverageFrom":["<rootDir>/src/**","!<rootDir>/src/**/*.spec.mts","!<rootDir>/src/**/*.test.mts","!<rootDir>/src/**/*.spec.ts","!<rootDir>/src/**/*.test.ts"],"testMatch":["<rootDir>/src/**/*.spec.ts","<rootDir>/src/**/*.spec.mts"]},"files":["tsconfig.json","SECURITY.md","/src/"]}
1
+ {"name":"@checkdigit/typescript-config","version":"3.3.0-PR.30-3a83","description":"Check Digit standard Typescript configuration","prettier":"@checkdigit/prettier-config","engines":{"node":">=16"},"bin":{"builder":"./bin/builder.mjs"},"peerDependencies":{"@types/node":">=16","esbuild":"0.17.18","typescript":">=5.0.4 <5.1"},"repository":{"type":"git","url":"git+https://github.com/checkdigit/typescript-config.git"},"author":"Check Digit, LLC","license":"MIT","bugs":{"url":"https://github.com/checkdigit/typescript-config/issues"},"homepage":"https://github.com/checkdigit/typescript-config#readme","scripts":{"preversion":"npm test","postversion":"git push && git push --tags","prepare":"npm run build-builder","lint:fix":"eslint -f unix --ext .ts,.mts src --fix","lint":"eslint -f unix --ext .ts,.mts src","prettier":"prettier --ignore-path .gitignore --list-different .","prettier:fix":"prettier --ignore-path .gitignore --write .","test":"npm run ci:compile && npm run ci:test && npm run ci:lint && npm run ci:style","build-builder":"esbuild src/builder/index.mts --bundle --platform=node --format=esm --external:typescript --external:esbuild --outfile=build-builder/builder.mjs && mkdir -p bin && { echo '#!/usr/bin/env node'; cat build-builder/builder.mjs; } > bin/builder.mjs && chmod +x bin/builder.mjs","build-tsc-cjs":"rimraf build-tsc-cjs && tsc --outDir build-tsc-cjs","build-esbuild-cjs":"rimraf build-esbuild-cjs && esbuild ./src/*.ts ./src/*/*.ts --platform=node --bundle --format=cjs --sourcemap=inline --sources-content=false --outdir=build-esbuild-cjs","build-esbuild-cjs-bundle":"rimraf build-esbuild-cjs-bundle && esbuild src/test/index.test.ts --bundle --platform=node --format=cjs --sourcemap=inline --sources-content=false --outfile=build-esbuild-cjs-bundle/test/index.test.cjs","build-esbuild-esm":"rimraf build-esbuild-esm && node bin/builder.mjs --outDir=build-esbuild-esm","build-esbuild-esm-bundle":"rimraf build-esbuild-esm-bundle && esbuild src/test/index.test.ts --bundle --platform=node --format=esm --sourcemap=inline --sources-content=false --outfile=build-esbuild-esm-bundle/test/index.test.mjs","test-jest-esm":"NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage=false src/*.mts src/*/*.mts src/*/*/*.mts","test-jest-cjs":"jest --coverage=false src/*.ts src/*/*.ts src/*/*/*.ts","test-tsc-cjs":"node --test build-tsc-cjs/test/index.test.js","test-esbuild-cjs":"node --test build-esbuild-cjs/test/index.test.js","test-esbuild-cjs-bundle":"node --test build-esbuild-cjs-bundle/test/index.test.cjs","test-esbuild-esm":"node --test build-esbuild-esm/test/index.test.mjs","test-esbuild-esm-bundle":"echo 'node -test build-esbuild-esm-bundle/test/index.test.mjs'","ci:test":"npm run test-jest-cjs && npm run test-jest-esm &&npm run test-tsc-cjs && npm run test-esbuild-cjs && npm run test-esbuild-cjs-bundle && npm run test-esbuild-esm && npm run test-esbuild-esm-bundle","ci:compile":"npm run build-builder && npm run build-tsc-cjs && npm run build-esbuild-cjs && npm run build-esbuild-cjs-bundle && npm run build-esbuild-esm && npm run build-esbuild-esm-bundle","ci:lint":"npm run lint","ci:style":"npm run prettier"},"devDependencies":{"@checkdigit/prettier-config":"^3.4.0","@types/debug":"^4.1.7","@types/jest":"^29.5.1","@types/uuid":"^9.0.1","@typescript-eslint/eslint-plugin":"^5.59.5","@typescript-eslint/parser":"^5.59.5","debug":"^4.3.4","eslint":"^8.40.0","eslint-config-prettier":"^8.8.0","get-port":"^6.1.2","got":"^11.8.6","jest":"^29.5.0","rimraf":"^5.0.0","ts-jest":"^29.1.0","uuid":"^9.0.0"},"eslintConfig":{"parser":"@typescript-eslint/parser","plugins":["@typescript-eslint"],"parserOptions":{"project":"./tsconfig.json"},"extends":["eslint:all","plugin:@typescript-eslint/recommended","plugin:@typescript-eslint/recommended-requiring-type-checking","plugin:@typescript-eslint/strict","prettier"],"rules":{"@typescript-eslint/non-nullable-type-assertion-style":"error","capitalized-comments":"off","one-var":"off","sort-keys":"off","sort-imports":"off","func-style":["error","declaration",{"allowArrowFunctions":true}],"no-magic-numbers":["error",{"ignore":[0,1,2]}],"no-undefined":"off","no-ternary":"off"},"overrides":[{"files":["*.spec.mts","*.test.mts","*.spec.ts","*.test.ts"],"rules":{"@typescript-eslint/non-nullable-type-assertion-style":"off","@typescript-eslint/ban-types":"off","@typescript-eslint/require-await":"off","@typescript-eslint/consistent-type-definitions":"off","@typescript-eslint/ban-ts-comment":"off","@typescript-eslint/no-unnecessary-condition":"off","@typescript-eslint/consistent-indexed-object-style":"off","@typescript-eslint/no-unused-vars":"off","@typescript-eslint/no-unsafe-member-access":"off","line-comment-position":"off","no-inline-comments":"off","no-param-reassign":"off","id-length":"off","no-magic-numbers":"off","func-names":"off","no-duplicate-imports":"off","symbol-description":"off","no-invalid-this":"off"}}]},"jest":{"moduleFileExtensions":["js","mjs","cjs","ts","mts","json","node"],"extensionsToTreatAsEsm":[".mts"],"transform":{"^.+\\.mts$":["ts-jest",{"isolatedModules":true,"diagnostics":false,"useESM":true}],"^.+\\.ts$":["ts-jest",{"isolatedModules":true,"diagnostics":false,"useESM":false}]},"collectCoverageFrom":["<rootDir>/src/**","!<rootDir>/src/**/*.spec.mts","!<rootDir>/src/**/*.test.mts","!<rootDir>/src/**/*.spec.ts","!<rootDir>/src/**/*.test.ts"],"testMatch":["<rootDir>/src/**/*.spec.ts","<rootDir>/src/**/*.spec.mts"]},"files":["tsconfig.json","SECURITY.md","/src/"]}
@@ -47,11 +47,13 @@ function setup(pluginBuild: PluginBuild) {
47
47
  }
48
48
 
49
49
  // eslint-disable-next-line func-names,max-lines-per-function,max-statements
50
- export default async function ({ inDir, outDir }: BuilderOptions): Promise<void> {
50
+ export default async function ({ inDir, outDir }: BuilderOptions): Promise<string[]> {
51
+ const messages: string[] = [];
52
+
51
53
  /**
52
54
  * Emit declarations using typescript compiler
53
55
  */
54
- const sourceDirectory = path.join(process.cwd(), inDir);
56
+ const sourceDirectory = inDir;
55
57
  const allSourceFiles = await getFiles(sourceDirectory);
56
58
  const productionSourceFiles = allSourceFiles.filter(
57
59
  // && !file.endsWith('.test.ts') && !file.endsWith('.spec.ts')
@@ -75,11 +77,10 @@ export default async function ({ inDir, outDir }: BuilderOptions): Promise<void>
75
77
  assert.ok(diagnostic.start !== undefined);
76
78
  const { line, character } = typescript.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
77
79
  const message = typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
78
- // eslint-disable-next-line no-console
79
- console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
80
+ messages.push(`tsc: ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
80
81
  } else {
81
82
  // eslint-disable-next-line no-console
82
- console.log(typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n'));
83
+ messages.push(`tsc: ${typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n')}`);
83
84
  }
84
85
  }
85
86
  if (emitResult.emitSkipped) {
@@ -89,7 +90,7 @@ export default async function ({ inDir, outDir }: BuilderOptions): Promise<void>
89
90
  /**
90
91
  * Emit ESM javascript using esbuild
91
92
  */
92
- await build({
93
+ const buildResult = await build({
93
94
  entryPoints: productionSourceFiles,
94
95
  bundle: true,
95
96
  platform: 'node',
@@ -105,4 +106,8 @@ export default async function ({ inDir, outDir }: BuilderOptions): Promise<void>
105
106
  },
106
107
  ],
107
108
  });
109
+
110
+ messages.push(...buildResult.errors.map((error) => `esbuild error: ${error.text}`));
111
+ messages.push(...buildResult.warnings.map((warning) => `esbuild warning: ${warning.text}`));
112
+ return messages;
108
113
  }
@@ -1,12 +1,85 @@
1
1
  // builder/builder.spec.mts
2
2
 
3
3
  import { strict as assert } from 'node:assert';
4
+ import { promises as fs } from 'node:fs';
5
+ import os from 'node:os';
6
+ import path from 'node:path';
7
+
8
+ import { v4 as uuid } from 'uuid';
4
9
 
5
10
  // @ts-expect-error
6
11
  import builder from './builder.mts';
7
12
 
13
+ const singleModule = {
14
+ [`index.ts`]: `export const hello = 'world';`,
15
+ };
16
+
17
+ async function write(dir: string, files: Record<string, string>): Promise<void> {
18
+ await fs.mkdir(dir, { recursive: true });
19
+ await Promise.all(Object.entries(files).map(([name, content]) => fs.writeFile(path.join(dir, name), content)));
20
+ }
21
+
22
+ async function read(dir: string): Promise<Record<string, string>> {
23
+ const files = await fs.readdir(dir);
24
+ return Object.fromEntries(
25
+ await Promise.all(
26
+ files.map(async (name) => [
27
+ name,
28
+ (
29
+ await fs.readFile(path.join(dir, name), 'utf-8')
30
+ )
31
+ .split('\n')
32
+ .filter((line) => !line.startsWith('//'))
33
+ .join('\n'),
34
+ ])
35
+ )
36
+ ) as Record<string, string>;
37
+ }
38
+
8
39
  describe('test builder', () => {
9
- it('should build', async () => {
10
- await assert.rejects(builder({ inDir: '../test/lib', outDir: 'hello' }));
40
+ it('should not build bad code', async () => {
41
+ const id = uuid();
42
+ const inDir = path.join(os.tmpdir(), `in-dir-${id}`);
43
+ const outDir = path.join(os.tmpdir(), `out-dir-${id}`);
44
+ await write(inDir, { 'index.ts': 'bad code' });
45
+ await assert.rejects(builder({ inDir, outDir }), { message: 'TypeScript compilation failed' });
46
+ await assert.rejects(read(outDir), {
47
+ message: `ENOENT: no such file or directory, scandir '${outDir}'`,
48
+ });
49
+ });
50
+
51
+ it('should not build from bad directory', async () => {
52
+ const id = uuid();
53
+ const inDir = path.join(os.tmpdir(), `in-dir-${id}`);
54
+ const outDir = path.join(os.tmpdir(), `out-dir-${id}`);
55
+ await assert.rejects(builder({ inDir, outDir }), {
56
+ message: `ENOENT: no such file or directory, scandir '${inDir}'`,
57
+ });
58
+ await assert.rejects(read(outDir), {
59
+ message: `ENOENT: no such file or directory, scandir '${outDir}'`,
60
+ });
61
+ });
62
+
63
+ it('should build from empty directory, but not create output directory', async () => {
64
+ const id = uuid();
65
+ const inDir = path.join(os.tmpdir(), `in-dir-${id}`);
66
+ const outDir = path.join(os.tmpdir(), `out-dir-${id}`);
67
+ await write(inDir, {});
68
+ assert.deepEqual(await builder({ inDir, outDir }), []);
69
+ await assert.rejects(read(outDir), {
70
+ message: `ENOENT: no such file or directory, scandir '${outDir}'`,
71
+ });
72
+ });
73
+
74
+ it('should build a single ESM module', async () => {
75
+ const id = uuid();
76
+ const inDir = path.join(os.tmpdir(), `in-dir-${id}`);
77
+ const outDir = path.join(os.tmpdir(), `out-dir-${id}`);
78
+ await write(inDir, singleModule);
79
+ assert.deepEqual(await builder({ inDir, outDir }), []);
80
+ assert.deepEqual(await read(outDir), {
81
+ 'index.d.ts': 'export declare const hello = "world";\n',
82
+ 'index.mjs': 'var hello = "world";\nexport {\n hello\n};\n',
83
+ });
11
84
  });
12
85
  });
@@ -1,6 +1,7 @@
1
1
  // builder/index.mts
2
2
 
3
3
  import { strict as assert } from 'node:assert';
4
+ import path from 'node:path';
4
5
  import { parseArgs } from 'node:util';
5
6
 
6
7
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -19,4 +20,9 @@ const {
19
20
  assert.ok(inDir !== undefined, 'inDir is required');
20
21
  assert.ok(outDir !== undefined, 'outDir is required');
21
22
 
22
- await builder({ inDir, outDir });
23
+ const messages = await builder({ inDir: path.join(process.cwd(), inDir), outDir: path.join(process.cwd(), outDir) });
24
+ if (messages.length > 0) {
25
+ // eslint-disable-next-line no-console
26
+ console.warn(JSON.stringify(messages, undefined, 2));
27
+ process.exit(1);
28
+ }