Skip to content

Commit d3cf198

Browse files
Merge pull request #569 from szegheo/fix-node22-compatibility-remove-esm
fix: v2 remove unmaintained esm dependency to fix Node22 compatibility
2 parents 0d07199 + 1c15995 commit d3cf198

File tree

6 files changed

+171
-22
lines changed

6 files changed

+171
-22
lines changed

lib/middleware/createTemplate.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { stripDefaultsAndDevProps } = require("esm")(module)('../../runtime/utils/normalizeNode')
1+
const { stripDefaultsAndDevProps } = require('../utils/normalizeNode')
22

33
const { name, version } = require('../../package.json')
44

lib/utils/middleware.js

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,108 @@
1-
require = require("esm")(module/*, options*/)
2-
module.exports = require("../../runtime/middleware")
1+
/**
2+
* CommonJS implementation of the node middleware helpers.
3+
*
4+
* This used to proxy the ESM implementation in `runtime/middleware.js` via the
5+
* unmaintained `esm` package. Keeping a CJS copy here avoids loaders and works
6+
* on Node 22+, while still supporting older Node versions.
7+
*/
8+
9+
/**
10+
* Node middleware
11+
* @description Walks through the nodes of a tree
12+
* @example middleware = createNodeMiddleware(payload => {payload.file.name = 'hello'})(treePayload))
13+
* @param {(payload: any) => any} fn
14+
*/
15+
function createNodeMiddleware(fn) {
16+
/**
17+
* NodeMiddleware payload receiver
18+
* @param {TreePayload} payload
19+
*/
20+
const inner = async function execute(payload) {
21+
return await nodeMiddleware(fn, {
22+
file: payload.tree,
23+
state: { treePayload: payload },
24+
scope: {},
25+
})
26+
}
27+
28+
/**
29+
* NodeMiddleware sync payload receiver
30+
* @param {TreePayload} payload
31+
*/
32+
inner.sync = function executeSync(payload) {
33+
return nodeMiddlewareSync(fn, {
34+
file: payload.tree,
35+
state: { treePayload: payload },
36+
scope: {},
37+
})
38+
}
39+
40+
return inner
41+
}
42+
43+
/**
44+
* Node walker
45+
* @param {(payload: any) => any} fn function to be called for each file
46+
* @param {any=} payload
47+
*/
48+
async function nodeMiddleware(fn, payload) {
49+
const _file = await fn(payload)
50+
if (_file === false) return false
51+
const file = _file || payload.file
52+
53+
if (file.children) {
54+
const children = await Promise.all(
55+
file.children.map(async _child =>
56+
nodeMiddleware(fn, {
57+
state: payload.state,
58+
scope: clone(payload.scope || {}),
59+
parent: payload.file,
60+
file: await _child,
61+
})
62+
)
63+
)
64+
file.children = children.filter(Boolean)
65+
}
66+
67+
return file
68+
}
69+
70+
/**
71+
* Node walker (sync version)
72+
* @param {(payload: any) => any} fn function to be called for each file
73+
* @param {any=} payload
74+
*/
75+
function nodeMiddlewareSync(fn, payload) {
76+
const _file = fn(payload)
77+
if (_file === false) return false
78+
79+
const file = _file || payload.file
80+
81+
if (file.children) {
82+
const children = file.children.map(_child =>
83+
nodeMiddlewareSync(fn, {
84+
state: payload.state,
85+
scope: clone(payload.scope || {}),
86+
parent: payload.file,
87+
file: _child,
88+
})
89+
)
90+
file.children = children.filter(Boolean)
91+
}
92+
93+
return file
94+
}
95+
96+
/**
97+
* Clone with JSON
98+
* @param {any} obj
99+
*/
100+
function clone(obj) {
101+
return JSON.parse(JSON.stringify(obj))
102+
}
103+
104+
module.exports = {
105+
nodeMiddleware,
106+
nodeMiddlewareSync,
107+
createNodeMiddleware,
108+
}

lib/utils/normalizeNode.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
const defaultNode = {
2+
isDir: false,
3+
ext: 'svelte',
4+
isLayout: false,
5+
isReset: false,
6+
isIndex: false,
7+
isFallback: false,
8+
isPage: false,
9+
ownMeta: {},
10+
meta: {
11+
recursive: true,
12+
preload: false,
13+
prerender: true,
14+
},
15+
id: '__fallback',
16+
}
17+
18+
const devProps = [
19+
'file',
20+
'filepath',
21+
'name',
22+
'badExt',
23+
'relativeDir',
24+
'absolutePath',
25+
'importPath',
26+
'isFile',
27+
]
28+
29+
/** @param {TreePayload} node */
30+
function stripDefaultsAndDevProps(node) {
31+
const strippedNode = {}
32+
33+
Object.entries(node)
34+
.filter(([key]) => !devProps.includes(key))
35+
.filter(
36+
([key, value]) =>
37+
JSON.stringify(defaultNode[key]) !== JSON.stringify(value)
38+
)
39+
.forEach(([key, value]) => (strippedNode[key] = value))
40+
41+
if (node.children)
42+
strippedNode.children = [...node.children.map(stripDefaultsAndDevProps)]
43+
44+
return strippedNode
45+
}
46+
47+
function restoreDefaults(node) {
48+
Object.entries(defaultNode).forEach(([key, value]) => {
49+
if (typeof node[key] === 'undefined') node[key] = value
50+
})
51+
52+
if (node.children) node.children = node.children.map(restoreDefaults)
53+
54+
return node
55+
}
56+
57+
module.exports = {
58+
defaultNode,
59+
stripDefaultsAndDevProps,
60+
restoreDefaults,
61+
}

package-lock.json

Lines changed: 0 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
"./plugins/*": "./plugins/*",
3434
"./hmr": "./hmr.js",
3535
"./lib/utils/config": "./lib/utils/config.js"
36-
3736
},
3837
"dependencies": {
3938
"@roxi/ssr": "^0.2.1",
@@ -42,7 +41,6 @@
4241
"cheap-watch": "^1.0.4",
4342
"commander": "^7.2.0",
4443
"configent": "^2.2.0",
45-
"esm": "^3.2.25",
4644
"fs-extra": "^9.1.0",
4745
"log-symbols": "^3.0.0",
4846
"picomatch": "^2.3.1",

typings/lib/utils/middleware.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
declare const _exports: typeof import("../middleware");
1+
declare const _exports: typeof import("../../runtime/middleware");
22
export = _exports;

0 commit comments

Comments
 (0)