@ecopages/core 0.2.0-alpha.46 → 0.2.0-alpha.48

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ecopages/core",
3
- "version": "0.2.0-alpha.46",
3
+ "version": "0.2.0-alpha.48",
4
4
  "description": "Core package for Ecopages",
5
5
  "keywords": [
6
6
  "ecopages",
@@ -17,7 +17,7 @@
17
17
  "directory": "packages/core"
18
18
  },
19
19
  "dependencies": {
20
- "@ecopages/file-system": "0.2.0-alpha.46",
20
+ "@ecopages/file-system": "0.2.0-alpha.48",
21
21
  "@ecopages/logger": "^0.2.3",
22
22
  "@ecopages/scripts-injector": "^0.1.5",
23
23
  "@worker-tools/html-rewriter": "0.1.0-pre.19",
@@ -12,8 +12,8 @@ export interface NodeBootstrapResolutionOptions {
12
12
  */
13
13
  projectDir: string;
14
14
  /**
15
- * Runtime-local node_modules directory that receives symlinks to resolved
16
- * package roots so transpiled Node imports share one package graph.
15
+ * Runtime-local node_modules directory retained for backwards-compatible
16
+ * option shape. Third-party packages now resolve through native Node lookup.
17
17
  */
18
18
  runtimeNodeModulesDir: string;
19
19
  }
@@ -26,17 +26,13 @@ export declare function resolveNodeBootstrapDependency(args: Pick<EcoBuildOnReso
26
26
  /**
27
27
  * Creates the Node bootstrap plugin used by app-owned server module loads.
28
28
  *
29
- * The resolver anchors third-party imports to the nearest package boundary for
30
- * the importing file, then mirrors the resolved package root into the runtime
31
- * node_modules directory. That keeps transpiled Node execution aligned with the
32
- * package graph each source file was authored against.
29
+ * The resolver keeps third-party imports external so native Node package
30
+ * semantics decide exports, subpaths, and CommonJS interop at runtime.
33
31
  */
34
32
  export declare function createNodeBootstrapPlugin(options: NodeBootstrapResolutionOptions): EcoBuildPlugin;
35
33
  /**
36
34
  * Creates the default Node bootstrap plugin for one Ecopages app runtime.
37
35
  *
38
- * This binds the shared resolution policy to the app's internal execution
39
- * directory so transpiled server modules can externalize packages into one
40
- * stable runtime node_modules graph.
36
+ * This binds the shared resolution policy to one Ecopages app runtime.
41
37
  */
42
38
  export declare function createAppNodeBootstrapPlugin(appConfig: Pick<EcoPagesAppConfig, 'rootDir' | 'workDir' | 'absolutePaths'>): EcoBuildPlugin;
@@ -1,5 +1,5 @@
1
1
  import path from "node:path";
2
- import { existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, rmSync, symlinkSync, unlinkSync } from "node:fs";
2
+ import { existsSync, readFileSync } from "node:fs";
3
3
  import { createRequire } from "node:module";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
5
5
  import { resolveInternalExecutionDir } from "../../utils/resolve-work-dir.js";
@@ -13,123 +13,6 @@ function getPackageNameFromSpecifier(specifier) {
13
13
  }
14
14
  return specifier.split("/")[0] ?? specifier;
15
15
  }
16
- function findPackageRoot(resolvedPath) {
17
- let currentPath = path.dirname(resolvedPath);
18
- while (true) {
19
- const packageJsonPath = path.join(currentPath, "package.json");
20
- if (existsSync(packageJsonPath)) {
21
- return currentPath;
22
- }
23
- const parentPath = path.dirname(currentPath);
24
- if (parentPath === currentPath) {
25
- throw new Error(`Could not find package root for resolved dependency path: ${resolvedPath}`);
26
- }
27
- currentPath = parentPath;
28
- }
29
- }
30
- function pathEntryExists(filePath) {
31
- try {
32
- lstatSync(filePath);
33
- return true;
34
- } catch {
35
- return false;
36
- }
37
- }
38
- function linkPointsToPackage(linkPath, packageRoot) {
39
- try {
40
- return realpathSync(linkPath) === realpathSync(packageRoot);
41
- } catch {
42
- return false;
43
- }
44
- }
45
- function resolveRuntimePackageRoot(specifier, resolvedPath, parentPath) {
46
- const packageName = getPackageNameFromSpecifier(specifier);
47
- return findInstalledPackageDir(packageName, parentPath) ?? findPackageRoot(resolvedPath);
48
- }
49
- function getNodeExternalSpecifier(specifier, resolvedPath, parentPath) {
50
- const packageName = getPackageNameFromSpecifier(specifier);
51
- if (specifier === packageName) {
52
- return specifier;
53
- }
54
- if (path.extname(specifier)) {
55
- return specifier;
56
- }
57
- for (const extension of [".js", ".mjs", ".cjs", ".json"]) {
58
- const candidateSpecifier = `${specifier}${extension}`;
59
- try {
60
- const candidateResolvedPath = resolveSpecifier(candidateSpecifier, parentPath);
61
- if (existsSync(candidateResolvedPath)) {
62
- return candidateSpecifier;
63
- }
64
- } catch {
65
- }
66
- }
67
- for (const candidatePath of [
68
- resolvedPath,
69
- ...[".js", ".mjs", ".cjs", ".json"].map((extension) => `${specifier}${extension}`)
70
- ]) {
71
- const candidateResolvedPath = candidatePath === resolvedPath ? resolvedPath : (() => {
72
- try {
73
- return resolveSpecifier(candidatePath, parentPath);
74
- } catch {
75
- return void 0;
76
- }
77
- })();
78
- if (!candidateResolvedPath) {
79
- continue;
80
- }
81
- if (!existsSync(candidateResolvedPath)) {
82
- continue;
83
- }
84
- const resolvedExtension = path.extname(candidateResolvedPath);
85
- if (![".js", ".mjs", ".cjs", ".json"].includes(resolvedExtension)) {
86
- continue;
87
- }
88
- const packageRoot = resolveRuntimePackageRoot(specifier, candidateResolvedPath, parentPath);
89
- const requestedSubpath = specifier.slice(packageName.length + 1);
90
- const resolvedSubpath = path.relative(packageRoot, candidateResolvedPath);
91
- if (resolvedSubpath === `${requestedSubpath}${resolvedExtension}`) {
92
- return `${specifier}${resolvedExtension}`;
93
- }
94
- }
95
- return specifier;
96
- }
97
- function ensureRuntimePackageLink(nodeModulesDir, specifier, resolvedPath, parentPath) {
98
- const packageName = getPackageNameFromSpecifier(specifier);
99
- const packageRoot = resolveRuntimePackageRoot(specifier, resolvedPath, parentPath);
100
- const linkPath = path.join(nodeModulesDir, packageName);
101
- mkdirSync(path.dirname(linkPath), { recursive: true });
102
- if (pathEntryExists(linkPath)) {
103
- if (linkPointsToPackage(linkPath, packageRoot)) {
104
- return;
105
- }
106
- removeRuntimePackageLink(linkPath);
107
- }
108
- try {
109
- symlinkSync(packageRoot, linkPath, "dir");
110
- } catch (error) {
111
- if (error.code !== "EEXIST") {
112
- throw error;
113
- }
114
- if (linkPointsToPackage(linkPath, packageRoot)) {
115
- return;
116
- }
117
- removeRuntimePackageLink(linkPath);
118
- symlinkSync(packageRoot, linkPath, "dir");
119
- }
120
- }
121
- function removeRuntimePackageLink(linkPath) {
122
- try {
123
- const stats = lstatSync(linkPath);
124
- if (stats.isSymbolicLink()) {
125
- unlinkSync(linkPath);
126
- return;
127
- }
128
- } catch {
129
- return;
130
- }
131
- rmSync(linkPath, { recursive: true, force: true });
132
- }
133
16
  function getNodeUnsupportedBuiltinError(specifier, importer) {
134
17
  return `Node bootstrap transpilation does not support Bun builtin specifier ${JSON.stringify(specifier)}${importer ? ` imported from ${importer}` : ""}.`;
135
18
  }
@@ -232,27 +115,6 @@ function findResolutionParent(importer, projectDir) {
232
115
  currentPath = parentPath;
233
116
  }
234
117
  }
235
- function getBootstrapBuildLoaderForPath(filePath) {
236
- switch (path.extname(filePath).toLowerCase()) {
237
- case ".ts":
238
- case ".mts":
239
- case ".cts":
240
- return "ts";
241
- case ".tsx":
242
- return "tsx";
243
- case ".jsx":
244
- return "jsx";
245
- case ".json":
246
- return "json";
247
- default:
248
- return "js";
249
- }
250
- }
251
- function shouldRewriteBootstrapSource(filePath, projectDir) {
252
- const normalizedPath = path.resolve(filePath);
253
- const normalizedProjectDir = path.resolve(projectDir);
254
- return normalizedPath.startsWith(`${normalizedProjectDir}${path.sep}`) && !normalizedPath.includes(`${path.sep}node_modules${path.sep}`);
255
- }
256
118
  function resolveNodeBootstrapDependency(args, options) {
257
119
  if (args.path.startsWith("./") || args.path.startsWith("../") || args.path.startsWith("@/") || args.path.startsWith("/") || args.path.startsWith("node:")) {
258
120
  return void 0;
@@ -269,70 +131,43 @@ function resolveNodeBootstrapDependency(args, options) {
269
131
  const resolvedSubpath = resolveSpecifier(args.path, resolveParent);
270
132
  return { path: resolvedSubpath };
271
133
  }
272
- let resolvedPath2;
134
+ let resolvedPath;
273
135
  try {
274
- resolvedPath2 = resolveFromCore(args.path);
136
+ resolvedPath = resolveFromCore(args.path);
275
137
  } catch {
276
138
  try {
277
- resolvedPath2 = resolveSpecifier(args.path, resolveParent);
139
+ resolvedPath = resolveSpecifier(args.path, resolveParent);
278
140
  } catch {
279
141
  const candidatePath = path.join(options.projectDir, "node_modules", packageName);
280
142
  const candidatePackageJson = path.join(candidatePath, "package.json");
281
143
  if (existsSync(candidatePackageJson)) {
282
- ensureRuntimePackageLink(
283
- options.runtimeNodeModulesDir,
284
- args.path,
285
- candidatePackageJson,
286
- resolveParent
287
- );
288
144
  return { path: args.path, external: true };
289
145
  }
290
146
  }
291
147
  }
292
- if (!resolvedPath2) {
148
+ if (!resolvedPath) {
293
149
  return void 0;
294
150
  }
295
- if (resolvedPath2.includes(`${path.sep}node_modules${path.sep}`)) {
296
- ensureRuntimePackageLink(options.runtimeNodeModulesDir, args.path, resolvedPath2, resolveParent);
151
+ if (resolvedPath.includes(`${path.sep}node_modules${path.sep}`)) {
297
152
  return {
298
153
  path: args.path,
299
154
  external: true
300
155
  };
301
156
  }
302
- return { path: resolvedPath2 };
157
+ return { path: resolvedPath };
303
158
  }
304
- const resolvedPath = resolveSpecifier(args.path, resolveParent);
305
- ensureRuntimePackageLink(options.runtimeNodeModulesDir, args.path, resolvedPath, resolveParent);
306
159
  return {
307
- path: getNodeExternalSpecifier(args.path, resolvedPath, resolveParent),
160
+ path: args.path,
308
161
  external: true
309
162
  };
310
163
  }
311
164
  function createNodeBootstrapPlugin(options) {
312
- const projectDir = path.resolve(options.projectDir);
313
165
  return {
314
166
  name: "node-bootstrap-plugin",
315
167
  setup(build) {
316
168
  build.onResolve({ filter: /^bun:/ }, (args) => {
317
169
  throw new Error(getNodeUnsupportedBuiltinError(args.path, args.importer));
318
170
  });
319
- build.onLoad({ filter: /\.[cm]?[jt]sx?$/ }, async (args) => {
320
- const absolutePath = path.resolve(args.path);
321
- const shouldRewriteImportMeta = shouldRewriteBootstrapSource(absolutePath, projectDir);
322
- if (!shouldRewriteImportMeta) {
323
- return void 0;
324
- }
325
- const originalContents = readFileSync(args.path, "utf8");
326
- const contents = originalContents.replaceAll("import.meta.env", "process.env").replaceAll("import.meta.dirname", JSON.stringify(path.dirname(args.path))).replaceAll("import.meta.filename", JSON.stringify(args.path)).replaceAll("import.meta.dir", JSON.stringify(path.dirname(args.path))).replaceAll("import.meta.path", JSON.stringify(args.path));
327
- if (contents === originalContents) {
328
- return void 0;
329
- }
330
- return {
331
- contents,
332
- loader: getBootstrapBuildLoaderForPath(args.path),
333
- resolveDir: path.dirname(args.path)
334
- };
335
- });
336
171
  build.onResolve({ filter: /^[@A-Za-z0-9][^:]*$/ }, (args) => {
337
172
  return resolveNodeBootstrapDependency(args, options);
338
173
  });