Skip to content

Commit fe50319

Browse files
authored
Create seperate testLoader and testCached for Node v22 compatibility with JSON assertions (#1149)
* Add test loader * Change exec to testCached * cleanup pathing for execution * bump version * lint * fix failing test * Fix rootEsm tests for JSON compat with 22
1 parent 6f7f893 commit fe50319

File tree

10 files changed

+125
-21
lines changed

10 files changed

+125
-21
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# CHANGELOG
22

3+
## 0.82.1
4+
5+
- Create seperate testLoader and testCached for Node v22 compatibility with JSON assertions
6+
7+
38
## 0.81.1
49

510
- Duplicate .d.ts files into cjs

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
},
1515
"sideEffects": false,
1616
"type": "module",
17-
"version": "0.81.2",
17+
"version": "0.82.0",
1818
"versions": {
1919
"git": "0.81.2",
2020
"npm": "0.81.2"

packages/dev-test/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
},
1616
"sideEffects": false,
1717
"type": "module",
18-
"version": "0.81.2",
18+
"version": "0.82.0",
1919
"main": "./index.js",
2020
"exports": {
2121
"./globals.d.ts": "./src/globals.d.ts"

packages/dev-ts/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
},
1616
"sideEffects": false,
1717
"type": "module",
18-
"version": "0.81.2",
18+
"version": "0.82.0",
1919
"main": "./index.js",
2020
"exports": {
2121
"./globals.d.ts": "./src/globals.d.ts"

packages/dev-ts/src/testCached.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2017-2024 @polkadot/dev-ts authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
// Adapted from: https://nodejs.org/api/esm.html#esm_transpiler_loader
5+
//
6+
// NOTE: This assumes the loader implementation for Node.js >= 18
7+
8+
import { loaderOptions } from './common.js';
9+
10+
loaderOptions.isCached = true;
11+
12+
export { resolve } from './resolver.js';
13+
export { load } from './testLoader.js';

packages/dev-ts/src/testLoader.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright 2017-2024 @polkadot/dev-ts authors & contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
import crypto from 'node:crypto';
5+
import fs from 'node:fs';
6+
import path from 'node:path';
7+
import { fileURLToPath } from 'node:url';
8+
import ts from 'typescript';
9+
10+
import { EXT_TS_REGEX, loaderOptions } from './common.js';
11+
12+
interface Loaded {
13+
format: 'commonjs' | 'module';
14+
shortCircuit?: boolean;
15+
source: string;
16+
}
17+
18+
type NexLoad = (url: string, context: Record<string, unknown>) => Promise<Loaded>;
19+
20+
/**
21+
* Load all TypeScript files, compile via tsc on-the-fly
22+
**/
23+
export async function load (url: string, context: Record<string, unknown>, nextLoad: NexLoad): Promise<Loaded> {
24+
if (EXT_TS_REGEX.test(url)) {
25+
// used the chained loaders to retrieve
26+
const { source } = await nextLoad(url, {
27+
...context,
28+
format: 'module'
29+
});
30+
31+
// This ensures there is support for Node v22 while also maintaining backwards compatibility for testing.
32+
const modifiedSrc = Buffer.from(source.toString().replace(/assert\s*\{\s*type:\s*'json'\s*\}/g, 'with { type: \'json\' }'), 'utf-8');
33+
34+
// we use a hash of the source to determine caching
35+
const sourceHash = `//# sourceHash=${crypto.createHash('sha256').update(modifiedSrc as unknown as string).digest('hex')}`;
36+
const compiledFile = url.includes('/src/')
37+
? fileURLToPath(
38+
url
39+
.replace(/\.tsx?$/, '.js')
40+
.replace('/src/', '/build-loader/')
41+
)
42+
: null;
43+
44+
if (loaderOptions.isCached && compiledFile && fs.existsSync(compiledFile)) {
45+
const compiled = fs.readFileSync(compiledFile, 'utf-8');
46+
47+
if (compiled.includes(sourceHash)) {
48+
return {
49+
format: 'module',
50+
source: compiled
51+
};
52+
}
53+
}
54+
55+
// compile via typescript
56+
const { outputText } = ts.transpileModule(modifiedSrc.toString(), {
57+
compilerOptions: {
58+
...(
59+
url.endsWith('.tsx')
60+
? { jsx: ts.JsxEmit.ReactJSX }
61+
: {}
62+
),
63+
esModuleInterop: true,
64+
importHelpers: true,
65+
inlineSourceMap: true,
66+
module: ts.ModuleKind.ESNext,
67+
moduleResolution: ts.ModuleResolutionKind.NodeNext,
68+
skipLibCheck: true,
69+
// Aligns with packages/dev/scripts/polkadot-dev-build-ts & packages/dev/config/tsconfig
70+
target: ts.ScriptTarget.ES2022
71+
},
72+
fileName: fileURLToPath(url)
73+
});
74+
75+
if (loaderOptions.isCached && compiledFile) {
76+
const compiledDir = path.dirname(compiledFile);
77+
78+
if (!fs.existsSync(compiledDir)) {
79+
fs.mkdirSync(compiledDir, { recursive: true });
80+
}
81+
82+
fs.writeFileSync(compiledFile, `${outputText}\n${sourceHash}`, 'utf-8');
83+
}
84+
85+
return {
86+
format: 'module',
87+
source: outputText
88+
};
89+
}
90+
91+
return nextLoad(url, context);
92+
}

packages/dev/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
},
1616
"sideEffects": false,
1717
"type": "module",
18-
"version": "0.81.2",
18+
"version": "0.82.0",
1919
"bin": {
2020
"polkadot-ci-ghact-build": "./scripts/polkadot-ci-ghact-build.mjs",
2121
"polkadot-ci-ghact-docs": "./scripts/polkadot-ci-ghact-docs.mjs",
@@ -50,8 +50,8 @@
5050
},
5151
"dependencies": {
5252
"@eslint/js": "^8.56.0",
53-
"@polkadot/dev-test": "^0.81.2",
54-
"@polkadot/dev-ts": "^0.81.2",
53+
"@polkadot/dev-test": "^0.82.0",
54+
"@polkadot/dev-ts": "^0.82.0",
5555
"@rollup/plugin-alias": "^5.1.0",
5656
"@rollup/plugin-commonjs": "^25.0.7",
5757
"@rollup/plugin-dynamic-import-vars": "^2.1.2",

packages/dev/scripts/polkadot-dev-run-test.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ try {
157157
: `@polkadot/dev-test/${testEnv}`
158158
);
159159

160-
execNodeTs(allFlags, nodeFlags, false, isDev ? './packages/dev-ts/build/cached.js' : undefined);
160+
execNodeTs(allFlags, nodeFlags, false, isDev ? './packages/dev-ts/build/testCached.js' : '@polkadot/dev-ts/testCached');
161161
} catch {
162162
process.exit(1);
163163
}

packages/dev/src/rootEsm.spec.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,13 @@
33

44
/// <reference types="@polkadot/dev-test/globals.d.ts" />
55

6-
import type * as testRoot from './root.js';
7-
86
import fs from 'node:fs';
97
import path from 'node:path';
108

11-
// NOTE We don't use ts-expect-error here since the build folder may or may
12-
// not exist (so the error may or may not be there)
13-
//
14-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
15-
// @ts-ignore This should only run against the compiled ouput, where this should exist
16-
import * as testRootBuild from '../build/root.js';
9+
import * as testRoot from './root.js';
1710
import { runTests } from './rootTests.js';
1811

19-
runTests(testRootBuild as unknown as typeof testRoot);
12+
runTests(testRoot);
2013

2114
describe('as-built output checks', (): void => {
2215
const buildRoot = path.join(process.cwd(), 'packages/dev/build');
@@ -94,7 +87,8 @@ describe('as-built output checks', (): void => {
9487
jsIdx[type].includes(
9588
type === 'cjs'
9689
? 'require("@polkadot/dev/rootJs/testJson.json")'
97-
: "import testJson from '@polkadot/dev/rootJs/testJson.json' assert { type: 'json' };"
90+
// eslint-disable-next-line no-useless-escape
91+
: "import testJson from '@polkadot/dev/rootJs/testJson.json' assert { type: \'json\' };"
9892
)
9993
).toBe(true);
10094
})

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ __metadata:
433433
languageName: node
434434
linkType: hard
435435

436-
"@polkadot/dev-test@npm:^0.81.2, @polkadot/dev-test@workspace:packages/dev-test":
436+
"@polkadot/dev-test@npm:^0.82.0, @polkadot/dev-test@workspace:packages/dev-test":
437437
version: 0.0.0-use.local
438438
resolution: "@polkadot/dev-test@workspace:packages/dev-test"
439439
dependencies:
@@ -443,7 +443,7 @@ __metadata:
443443
languageName: unknown
444444
linkType: soft
445445

446-
"@polkadot/dev-ts@npm:^0.81.2, @polkadot/dev-ts@workspace:packages/dev-ts":
446+
"@polkadot/dev-ts@npm:^0.82.0, @polkadot/dev-ts@workspace:packages/dev-ts":
447447
version: 0.0.0-use.local
448448
resolution: "@polkadot/dev-ts@workspace:packages/dev-ts"
449449
dependencies:
@@ -458,8 +458,8 @@ __metadata:
458458
resolution: "@polkadot/dev@workspace:packages/dev"
459459
dependencies:
460460
"@eslint/js": "npm:^8.56.0"
461-
"@polkadot/dev-test": "npm:^0.81.2"
462-
"@polkadot/dev-ts": "npm:^0.81.2"
461+
"@polkadot/dev-test": "npm:^0.82.0"
462+
"@polkadot/dev-ts": "npm:^0.82.0"
463463
"@rollup/plugin-alias": "npm:^5.1.0"
464464
"@rollup/plugin-commonjs": "npm:^25.0.7"
465465
"@rollup/plugin-dynamic-import-vars": "npm:^2.1.2"

0 commit comments

Comments
 (0)