veryfront 0.1.738 → 0.1.742

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.
Files changed (78) hide show
  1. package/esm/cli/templates/manifest.js +3 -3
  2. package/esm/deno.js +1 -1
  3. package/esm/src/agent/ag-ui/sse-parser.d.ts.map +1 -1
  4. package/esm/src/agent/ag-ui/sse-parser.js +20 -12
  5. package/esm/src/agent/hosted/child-tool-input.js +1 -1
  6. package/esm/src/agent/react/use-chat/streaming/handler.d.ts.map +1 -1
  7. package/esm/src/agent/react/use-chat/streaming/handler.js +53 -39
  8. package/esm/src/fs/index.d.ts +1 -1
  9. package/esm/src/fs/index.d.ts.map +1 -1
  10. package/esm/src/fs/index.js +1 -1
  11. package/esm/src/mcp/http-transport.js +1 -1
  12. package/esm/src/mcp/server.d.ts.map +1 -1
  13. package/esm/src/mcp/server.js +1 -4
  14. package/esm/src/mcp/session.d.ts +23 -0
  15. package/esm/src/mcp/session.d.ts.map +1 -1
  16. package/esm/src/mcp/session.js +46 -3
  17. package/esm/src/modules/manifest/route-module-manifest.d.ts.map +1 -1
  18. package/esm/src/modules/manifest/route-module-manifest.js +12 -4
  19. package/esm/src/modules/react-loader/ssr-module-loader/cross-project-import-loader.d.ts.map +1 -1
  20. package/esm/src/modules/react-loader/ssr-module-loader/cross-project-import-loader.js +2 -1
  21. package/esm/src/modules/server/cross-project-source-limit.d.ts +7 -0
  22. package/esm/src/modules/server/cross-project-source-limit.d.ts.map +1 -0
  23. package/esm/src/modules/server/cross-project-source-limit.js +46 -0
  24. package/esm/src/modules/server/module-batch-handler.d.ts.map +1 -1
  25. package/esm/src/modules/server/module-batch-handler.js +3 -4
  26. package/esm/src/modules/server/module-server.d.ts.map +1 -1
  27. package/esm/src/modules/server/module-server.js +11 -1
  28. package/esm/src/oauth/handlers/init-handler.js +6 -6
  29. package/esm/src/oauth/providers/base.d.ts +3 -0
  30. package/esm/src/oauth/providers/base.d.ts.map +1 -1
  31. package/esm/src/oauth/providers/base.js +24 -2
  32. package/esm/src/platform/compat/fs.d.ts +6 -0
  33. package/esm/src/platform/compat/fs.d.ts.map +1 -1
  34. package/esm/src/platform/compat/fs.js +12 -0
  35. package/esm/src/provider/runtime-loader/tool-input-status.d.ts.map +1 -1
  36. package/esm/src/provider/runtime-loader/tool-input-status.js +16 -8
  37. package/esm/src/rendering/orchestrator/module-loader/dependency-resolver.d.ts +2 -0
  38. package/esm/src/rendering/orchestrator/module-loader/dependency-resolver.d.ts.map +1 -1
  39. package/esm/src/rendering/orchestrator/module-loader/dependency-resolver.js +23 -10
  40. package/esm/src/rendering/renderer-concurrency.d.ts.map +1 -1
  41. package/esm/src/rendering/renderer-concurrency.js +9 -2
  42. package/esm/src/security/sandbox/worker-permissions.d.ts +10 -7
  43. package/esm/src/security/sandbox/worker-permissions.d.ts.map +1 -1
  44. package/esm/src/security/sandbox/worker-permissions.js +32 -12
  45. package/esm/src/security/utils/constant-time.d.ts.map +1 -1
  46. package/esm/src/security/utils/constant-time.js +4 -1
  47. package/esm/src/server/services/rendering/ssr.service.d.ts.map +1 -1
  48. package/esm/src/server/services/rendering/ssr.service.js +6 -3
  49. package/esm/src/transforms/mdx/esm-module-loader/loader-helpers.d.ts +4 -0
  50. package/esm/src/transforms/mdx/esm-module-loader/loader-helpers.d.ts.map +1 -1
  51. package/esm/src/transforms/mdx/esm-module-loader/loader-helpers.js +22 -18
  52. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/http-fetcher.d.ts.map +1 -1
  53. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/http-fetcher.js +27 -8
  54. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/import-rewriter.d.ts.map +1 -1
  55. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/import-rewriter.js +24 -14
  56. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.d.ts +1 -1
  57. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.d.ts.map +1 -1
  58. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.js +1 -1
  59. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/nested-imports.d.ts +4 -0
  60. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/nested-imports.d.ts.map +1 -1
  61. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/nested-imports.js +45 -37
  62. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/path-cache-lookup.d.ts.map +1 -1
  63. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/path-cache-lookup.js +6 -1
  64. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.d.ts +5 -0
  65. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.d.ts.map +1 -1
  66. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/render-sessions.js +27 -2
  67. package/esm/src/transforms/mdx/esm-module-loader/types.d.ts +2 -0
  68. package/esm/src/transforms/mdx/esm-module-loader/types.d.ts.map +1 -1
  69. package/esm/src/transforms/mdx/esm-module-loader/utils/source-spans.d.ts +23 -0
  70. package/esm/src/transforms/mdx/esm-module-loader/utils/source-spans.d.ts.map +1 -0
  71. package/esm/src/transforms/mdx/esm-module-loader/utils/source-spans.js +188 -0
  72. package/esm/src/utils/version-constant.d.ts +1 -1
  73. package/esm/src/utils/version-constant.js +1 -1
  74. package/esm/src/workflow/executor/dag/index.d.ts.map +1 -1
  75. package/esm/src/workflow/executor/dag/index.js +9 -8
  76. package/esm/src/workflow/worker/workflow-worker.d.ts.map +1 -1
  77. package/esm/src/workflow/worker/workflow-worker.js +9 -1
  78. package/package.json +1 -1
@@ -41,11 +41,11 @@ function createNotConfiguredResponse(config) {
41
41
  });
42
42
  return Response.json({ error: `${config.displayName} OAuth not configured` }, { status: 503 });
43
43
  }
44
- function createInitErrorResponse(error) {
45
- return Response.json({
46
- error: "Failed to initiate OAuth flow",
47
- details: error instanceof Error ? error.message : "Unknown error",
48
- }, { status: 500 });
44
+ function createInitErrorResponse() {
45
+ // SEC-009: do NOT leak internal error details (file paths, library
46
+ // internals) to the client. The caller already logs the full error
47
+ // server-side; return a generic message here.
48
+ return Response.json({ error: "Failed to initiate OAuth flow" }, { status: 500 });
49
49
  }
50
50
  /** Handler for create oauth init. */
51
51
  export function createOAuthInitHandler(config, options) {
@@ -78,7 +78,7 @@ export function createOAuthInitHandler(config, options) {
78
78
  }
79
79
  catch (error) {
80
80
  logger.error("Init error", { serviceId: config.serviceId }, error);
81
- return createInitErrorResponse(error);
81
+ return createInitErrorResponse();
82
82
  }
83
83
  };
84
84
  }
@@ -36,9 +36,11 @@ export declare class OAuthProvider {
36
36
  export declare class OAuthService extends OAuthProvider {
37
37
  protected serviceConfig: OAuthServiceConfig;
38
38
  protected tokenStore?: TokenStore;
39
+ private refreshPromises;
39
40
  constructor(config: OAuthServiceConfig, tokenStore?: TokenStore, envReader?: EnvReader);
40
41
  get serviceId(): string;
41
42
  get apiBaseUrl(): string;
43
+ private refreshKey;
42
44
  createAuthorizationUrl(options?: AuthorizationUrlOptions): Promise<{
43
45
  url: string;
44
46
  state: OAuthState;
@@ -51,6 +53,7 @@ export declare class OAuthService extends OAuthProvider {
51
53
  * tokens. See VULN-AUTH-2.
52
54
  */
53
55
  getAccessToken(userId: string): Promise<string | null>;
56
+ private refreshAndStoreAccessToken;
54
57
  /**
55
58
  * Resolve `endpoint` against `apiBaseUrl`, validating that absolute URLs
56
59
  * share the configured origin.
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/src/oauth/providers/base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EAEV,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACX,MAAM,aAAa,CAAC;AAarB,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAuB5D,gCAAgC;AAChC,qBAAa,aAAa;IACxB,SAAS,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACtC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC;gBAEnB,MAAM,EAAE,mBAAmB,EAAE,SAAS,GAAE,SAAkB;IAKtE,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC,YAAY,IAAI,OAAO;IAIjB,sBAAsB,CAC1B,OAAO,GAAE,uBAAuB,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;KAAO,GACnE,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;IA0C9C,OAAO,CAAC,iBAAiB;IAazB;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;YA0CZ,gBAAgB;IAe9B,OAAO,CAAC,4BAA4B;YAQtB,aAAa;IAyCrB,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA+BzE,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAwBjE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAiBnD;AAED,+BAA+B;AAC/B,qBAAa,YAAa,SAAQ,aAAa;IAC7C,SAAS,CAAC,aAAa,EAAE,kBAAkB,CAAC;IAC5C,SAAS,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;gBAEtB,MAAM,EAAE,kBAAkB,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,SAAS;IAMtF,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAEQ,sBAAsB,CAC7B,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;IAO9C;;;;;;OAMG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmB5D;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAuBpB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,CAAC,CAAC;CA+BxF"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/src/oauth/providers/base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EAEV,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACX,MAAM,aAAa,CAAC;AAarB,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAuB5D,gCAAgC;AAChC,qBAAa,aAAa;IACxB,SAAS,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACtC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC;gBAEnB,MAAM,EAAE,mBAAmB,EAAE,SAAS,GAAE,SAAkB;IAKtE,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC,YAAY,IAAI,OAAO;IAIjB,sBAAsB,CAC1B,OAAO,GAAE,uBAAuB,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;KAAO,GACnE,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;IA0C9C,OAAO,CAAC,iBAAiB;IAazB;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;YA0CZ,gBAAgB;IAe9B,OAAO,CAAC,4BAA4B;YAQtB,aAAa;IAyCrB,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAgCzE,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAwBjE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAiBnD;AAED,+BAA+B;AAC/B,qBAAa,YAAa,SAAQ,aAAa;IAC7C,SAAS,CAAC,aAAa,EAAE,kBAAkB,CAAC;IAC5C,SAAS,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IAClC,OAAO,CAAC,eAAe,CAA6C;gBAExD,MAAM,EAAE,kBAAkB,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,SAAS;IAMtF,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,OAAO,CAAC,UAAU;IAIT,sBAAsB,CAC7B,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;IAO9C;;;;;;OAMG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;YAyB9C,0BAA0B;IAcxC;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAuBpB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,CAAC,CAAC;CA+BxF"}
@@ -183,7 +183,9 @@ export class OAuthProvider {
183
183
  return {
184
184
  success: false,
185
185
  error: "OAuth not configured",
186
- errorDescription: `Missing ${this.config.clientIdEnvVar} or ${this.config.clientSecretEnvVar}`,
186
+ // Don't leak internal env var names to the caller; this result can
187
+ // propagate to HTTP responses via OAuthService.
188
+ errorDescription: "OAuth provider credentials are not configured",
187
189
  };
188
190
  }
189
191
  const body = new URLSearchParams({
@@ -231,6 +233,7 @@ export class OAuthProvider {
231
233
  export class OAuthService extends OAuthProvider {
232
234
  serviceConfig;
233
235
  tokenStore;
236
+ refreshPromises = new Map();
234
237
  constructor(config, tokenStore, envReader) {
235
238
  super(config, envReader);
236
239
  this.serviceConfig = config;
@@ -242,6 +245,9 @@ export class OAuthService extends OAuthProvider {
242
245
  get apiBaseUrl() {
243
246
  return this.serviceConfig.apiBaseUrl;
244
247
  }
248
+ refreshKey(userId) {
249
+ return JSON.stringify([this.serviceId, userId]);
250
+ }
245
251
  createAuthorizationUrl(options = {}) {
246
252
  return super.createAuthorizationUrl({
247
253
  ...options,
@@ -264,7 +270,23 @@ export class OAuthService extends OAuthProvider {
264
270
  return tokens.accessToken;
265
271
  if (!tokens.refreshToken)
266
272
  return null;
267
- const result = await this.refreshTokens(tokens.refreshToken);
273
+ const key = this.refreshKey(userId);
274
+ const existingRefresh = this.refreshPromises.get(key);
275
+ if (existingRefresh)
276
+ return existingRefresh;
277
+ const refreshPromise = this.refreshAndStoreAccessToken(userId, tokens.refreshToken);
278
+ this.refreshPromises.set(key, refreshPromise);
279
+ try {
280
+ return await refreshPromise;
281
+ }
282
+ finally {
283
+ if (this.refreshPromises.get(key) === refreshPromise) {
284
+ this.refreshPromises.delete(key);
285
+ }
286
+ }
287
+ }
288
+ async refreshAndStoreAccessToken(userId, refreshToken) {
289
+ const result = await this.refreshTokens(refreshToken);
268
290
  if (!result.success || !result.tokens)
269
291
  return null;
270
292
  if (!this.tokenStore) {
@@ -58,6 +58,12 @@ export declare function makeTempDir(options?: {
58
58
  /** Change file permissions. */
59
59
  export declare function chmod(path: string, mode: number): Promise<void>;
60
60
  export declare function symlink(target: string, path: string): Promise<void>;
61
+ /**
62
+ * Resolve a path to its canonical absolute form, following symlinks.
63
+ * Throws if the path does not exist. Useful for containment checks where a
64
+ * symlink could otherwise escape an intended directory.
65
+ */
66
+ export declare function realPath(path: string): Promise<string>;
61
67
  /** Error shape for is not found. */
62
68
  export declare function isNotFoundError(error: unknown): boolean;
63
69
  /** Error shape for is already exists. */
@@ -1 +1 @@
1
- {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../../../src/src/platform/compat/fs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../../../src/src/platform/compat/fs.ts"],"names":[],"mappings":"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"}
@@ -243,6 +243,18 @@ export async function symlink(target, path) {
243
243
  const fs = await import("node:fs/promises");
244
244
  await fs.symlink(target, path);
245
245
  }
246
+ /**
247
+ * Resolve a path to its canonical absolute form, following symlinks.
248
+ * Throws if the path does not exist. Useful for containment checks where a
249
+ * symlink could otherwise escape an intended directory.
250
+ */
251
+ export async function realPath(path) {
252
+ if (isDeno) {
253
+ return await denoGlobal().realPath(path);
254
+ }
255
+ const fs = await import("node:fs/promises");
256
+ return await fs.realpath(path);
257
+ }
246
258
  /** Error shape for is not found. */
247
259
  export function isNotFoundError(error) {
248
260
  const NotFound = dntShim.dntGlobalThis.Deno?.errors?.NotFound;
@@ -1 +1 @@
1
- {"version":3,"file":"tool-input-status.d.ts","sourceRoot":"","sources":["../../../../src/src/provider/runtime-loader/tool-input-status.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,+BAA+B,OAAQ,CAAC;AAErD,KAAK,uBAAuB,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAEnE,KAAK,oBAAoB,GAAG;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAAC;CAC5C,CAAC;AAOF,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAexE;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAC7C,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,GAClB,KAAK,CAAC;IAAE,IAAI,EAAE,uBAAuB,CAAC;IAAC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,eAAe,CAAA;KAAE,CAAA;CAAE,CAAC,CAsBjG;AAED,6CAA6C;AAC7C,wBAAuB,8BAA8B,CACnD,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,EAC9B,WAAW,SAAkC,GAC5C,aAAa,CAAC,OAAO,CAAC,CAkLxB"}
1
+ {"version":3,"file":"tool-input-status.d.ts","sourceRoot":"","sources":["../../../../src/src/provider/runtime-loader/tool-input-status.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,+BAA+B,OAAQ,CAAC;AAErD,KAAK,uBAAuB,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAEnE,KAAK,oBAAoB,GAAG;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAAC;CAC5C,CAAC;AAOF,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAexE;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAC7C,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,GAClB,KAAK,CAAC;IAAE,IAAI,EAAE,uBAAuB,CAAC;IAAC,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,eAAe,CAAA;KAAE,CAAA;CAAE,CAAC,CAsBjG;AAED,6CAA6C;AAC7C,wBAAuB,8BAA8B,CACnD,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,EAC9B,WAAW,SAAkC,GAC5C,aAAa,CAAC,OAAO,CAAC,CA2LxB"}
@@ -137,14 +137,22 @@ export async function* withToolInputStatusTransitions(stream, thresholdMs = TOOL
137
137
  .sort((left, right) => left - right)[0] ?? null;
138
138
  if (nextDueAt !== null) {
139
139
  let timeoutId = null;
140
- const timeoutResult = await Promise.race([
141
- nextPartPromise.then((result) => ({ kind: "part", result })),
142
- new Promise((resolve) => {
143
- timeoutId = dntShim.setTimeout(() => resolve({ kind: "timeout" }), Math.max(0, nextDueAt - Date.now()));
144
- }),
145
- ]);
146
- if (timeoutId !== null) {
147
- clearTimeout(timeoutId);
140
+ // Clear the timer in finally so it is released even when the race
141
+ // rejects (iterator error) or the generator is abandoned mid-await
142
+ // (consumer break/return), not just on the happy path.
143
+ let timeoutResult;
144
+ try {
145
+ timeoutResult = await Promise.race([
146
+ nextPartPromise.then((result) => ({ kind: "part", result })),
147
+ new Promise((resolve) => {
148
+ timeoutId = dntShim.setTimeout(() => resolve({ kind: "timeout" }), Math.max(0, nextDueAt - Date.now()));
149
+ }),
150
+ ]);
151
+ }
152
+ finally {
153
+ if (timeoutId !== null) {
154
+ clearTimeout(timeoutId);
155
+ }
148
156
  }
149
157
  if (timeoutResult.kind === "timeout") {
150
158
  const readyResult = await readPartIfReady();
@@ -3,6 +3,8 @@ import type { RuntimeAdapter } from "../../../platform/adapters/base.js";
3
3
  export type ResolvedModuleDependency = {
4
4
  full: string;
5
5
  path: string;
6
+ start: number;
7
+ end: number;
6
8
  relativePath: string;
7
9
  depFilePath: string | null;
8
10
  isLocalLib: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"dependency-resolver.d.ts","sourceRoot":"","sources":["../../../../../src/src/rendering/orchestrator/module-loader/dependency-resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AASzE,sEAAsE;AACtE,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,uFAAuF;AACvF,MAAM,MAAM,2BAA2B,GAAG,wBAAwB,GAAG;IACnE,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,sEAAsE;AACtE,MAAM,WAAW,8BAA8B;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;CACzB;AAgFD,yEAAyE;AACzE,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAuBrC;AAED,2EAA2E;AAC3E,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,2BAA2B,EAAE,GAC7C,MAAM,CAMR"}
1
+ {"version":3,"file":"dependency-resolver.d.ts","sourceRoot":"","sources":["../../../../../src/src/rendering/orchestrator/module-loader/dependency-resolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAczE,sEAAsE;AACtE,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,uFAAuF;AACvF,MAAM,MAAM,2BAA2B,GAAG,wBAAwB,GAAG;IACnE,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,sEAAsE;AACtE,MAAM,WAAW,8BAA8B;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;CACzB;AAgGD,yEAAyE;AACzE,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAuBrC;AAED,2EAA2E;AAC3E,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,2BAA2B,EAAE,GAC7C,MAAM,CAQR"}
@@ -1,16 +1,25 @@
1
1
  import { dirname, join, normalize } from "../../../platform/compat/path/index.js";
2
2
  import { parallelMap, rendererLogger } from "../../../utils/index.js";
3
+ import { findStaticImportFromSpans, replaceSourceSpans, } from "../../../transforms/mdx/esm-module-loader/utils/source-spans.js";
3
4
  import { findSourceFile } from "../file-resolver/index.js";
4
5
  const logger = rendererLogger.component("module-loader");
5
6
  function collectAliasImports(fileContent) {
6
- return [...fileContent.matchAll(/from\s+["'](@\/[^"']+)["']/g)].map((m) => ({
7
- full: m[0],
8
- path: m[1] ?? "",
7
+ return findStaticImportFromSpans(fileContent, (specifier) => specifier.startsWith("@/") ? specifier : null).map(({ original, path, start, end }) => ({
8
+ full: original,
9
+ path,
10
+ start,
11
+ end,
9
12
  }));
10
13
  }
11
14
  function collectRelativeImports(fileContent, fileDir) {
12
- return [...fileContent.matchAll(/from\s+["'](\.\.?\/[^"']+)["']/g)]
13
- .map((m) => ({ full: m[0], path: m[1] ?? "", fromDir: fileDir }))
15
+ return findStaticImportFromSpans(fileContent, (specifier) => specifier.match(/^(\.\.?\/[^?]+)(?:\?.*)?$/)?.[1])
16
+ .map(({ original, path, start, end }) => ({
17
+ full: original,
18
+ path,
19
+ fromDir: fileDir,
20
+ start,
21
+ end,
22
+ }))
14
23
  // Ignore already-transformed file:// imports.
15
24
  .filter((imp) => !imp.path.includes("file://"));
16
25
  }
@@ -56,6 +65,8 @@ async function resolveRelativeImport(imp, adapter) {
56
65
  return {
57
66
  full: imp.full,
58
67
  path: imp.path,
68
+ start: imp.start,
69
+ end: imp.end,
59
70
  relativePath: imp.path,
60
71
  depFilePath,
61
72
  isLocalLib: false,
@@ -79,9 +90,11 @@ export async function resolveModuleDependencies(input) {
79
90
  }
80
91
  /** Rewrites resolved local imports to their transformed temp file URLs. */
81
92
  export function rewriteResolvedDependencyImports(fileContent, transformedDeps) {
82
- let rewritten = fileContent;
83
- for (const dep of transformedDeps) {
84
- rewritten = rewritten.replace(dep.full, `from "file://${dep.depTempPath}"`);
85
- }
86
- return rewritten;
93
+ const replacements = transformedDeps.map((dep) => ({
94
+ start: dep.start,
95
+ end: dep.end,
96
+ expected: dep.full,
97
+ replacement: `from "file://${dep.depTempPath}"`,
98
+ }));
99
+ return replaceSourceSpans(fileContent, replacements);
87
100
  }
@@ -1 +1 @@
1
- {"version":3,"file":"renderer-concurrency.d.ts","sourceRoot":"","sources":["../../../src/src/rendering/renderer-concurrency.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,SAAS,EAAE,MAAM,oEAAoE,CAAC;AAQ/F;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAA8C,CAAC;AAEjF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,QACC,CAAC;AAEvC;;;GAGG;AACH,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAS/C;;;;GAIG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAA4C;IACzD,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC;IA+BhD,OAAO,CAAC,OAAO;IASf,IAAI,OAAO,IAAI,MAAM,CAEpB;CACF;AAYD,eAAO,MAAM,eAAe,WAE1B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,qBAA4B,CAAC;AA8B7D;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAalB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAef"}
1
+ {"version":3,"file":"renderer-concurrency.d.ts","sourceRoot":"","sources":["../../../src/src/rendering/renderer-concurrency.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,SAAS,EAAE,MAAM,oEAAoE,CAAC;AAQ/F;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAA8C,CAAC;AAEjF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,QACC,CAAC;AAEvC;;;GAGG;AACH,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAS/C;;;;GAIG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAA4C;IACzD,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC;IA+BhD,OAAO,CAAC,OAAO;IASf,IAAI,OAAO,IAAI,MAAM,CAEpB;CACF;AAYD,eAAO,MAAM,eAAe,WAE1B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,qBAA4B,CAAC;AA8B7D;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAalB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAwBf"}
@@ -154,17 +154,24 @@ export async function acquireProjectSlot(projectId) {
154
154
  export async function releaseProjectSlot(projectId) {
155
155
  if (RENDER_PER_PROJECT_LIMIT <= 0)
156
156
  return;
157
- const release = await acquireProjectLock(projectId);
157
+ const mutex = getProjectMutex(projectId);
158
+ const release = await mutex.acquire(LOCK_TIMEOUT_MS);
159
+ let deleteIdleMutex = false;
158
160
  try {
159
161
  const current = projectRenderCounts.get(projectId) ?? 0;
160
162
  if (current <= 1) {
161
163
  projectRenderCounts.delete(projectId);
162
- projectMutexes.delete(projectId);
164
+ deleteIdleMutex = mutex.waiting === 0;
163
165
  return;
164
166
  }
165
167
  projectRenderCounts.set(projectId, current - 1);
166
168
  }
167
169
  finally {
168
170
  release();
171
+ if (deleteIdleMutex &&
172
+ !projectRenderCounts.has(projectId) &&
173
+ projectMutexes.get(projectId) === mutex) {
174
+ projectMutexes.delete(projectId);
175
+ }
169
176
  }
170
177
  }
@@ -1,10 +1,6 @@
1
1
  /**
2
- * Worker Permission Builder
3
- *
4
- * Builds scoped Deno Worker permissions for per-project isolation.
5
- * Each project worker gets the minimum required permissions.
6
- *
7
- * @module security/sandbox/worker-permissions
2
+ * Deno Worker permission object.
3
+ * See: https://docs.deno.com/runtime/fundamentals/permissions/
8
4
  */
9
5
  export interface WorkerPermissions {
10
6
  read: string[] | boolean;
@@ -15,6 +11,12 @@ export interface WorkerPermissions {
15
11
  ffi: boolean;
16
12
  sys: boolean;
17
13
  }
14
+ interface WorkerPermissionOptions {
15
+ /** Override for tests that need to exercise compiled-binary behavior. */
16
+ isCompiledBinary?: boolean;
17
+ /** Override for tests that need deterministic compiled-binary support paths. */
18
+ compiledReadPaths?: string[];
19
+ }
18
20
  /**
19
21
  * Build scoped permissions for a project worker.
20
22
  *
@@ -26,5 +28,6 @@ export interface WorkerPermissions {
26
28
  * - ffi: denied (no native code from user code)
27
29
  * - sys: denied (no system info access from user code)
28
30
  */
29
- export declare function buildWorkerPermissions(readPaths: string[]): WorkerPermissions;
31
+ export declare function buildWorkerPermissions(readPaths: string[], options?: WorkerPermissionOptions): WorkerPermissions;
32
+ export {};
30
33
  //# sourceMappingURL=worker-permissions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker-permissions.d.ts","sourceRoot":"","sources":["../../../../src/src/security/sandbox/worker-permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;CACd;AAcD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EAAE,GAClB,iBAAiB,CA0BnB"}
1
+ {"version":3,"file":"worker-permissions.d.ts","sourceRoot":"","sources":["../../../../src/src/security/sandbox/worker-permissions.ts"],"names":[],"mappings":"AAmBA;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;CACd;AAED,UAAU,uBAAuB;IAC/B,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gFAAgF;IAChF,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAmCD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,GAAE,uBAA4B,GACpC,iBAAiB,CA2BnB"}
@@ -6,11 +6,10 @@
6
6
  *
7
7
  * @module security/sandbox/worker-permissions
8
8
  */
9
- /**
10
- * Deno Worker permission object.
11
- * See: https://docs.deno.com/runtime/fundamentals/permissions/
12
- */
13
9
  import * as dntShim from "../../../_dnt.shims.js";
10
+ import { getFrameworkRootFromMeta } from "../../platform/compat/vfs-paths.js";
11
+ import { getHostEnv } from "../../platform/compat/process.js";
12
+ import { getCacheBaseDir, getHttpBundleCacheDir, getMdxEsmCacheDir, } from "../../utils/cache-dir.js";
14
13
  // Cache compiled binary check — Deno.execPath() is a syscall that never changes at runtime
15
14
  const _isCompiledBinary = (() => {
16
15
  try {
@@ -24,6 +23,27 @@ const _isCompiledBinary = (() => {
24
23
  return false;
25
24
  }
26
25
  })();
26
+ function normalizeReadPaths(paths) {
27
+ const unique = new Set();
28
+ for (const path of paths) {
29
+ if (!path)
30
+ continue;
31
+ const trimmed = path.trim();
32
+ if (!trimmed)
33
+ continue;
34
+ unique.add(trimmed);
35
+ }
36
+ return [...unique];
37
+ }
38
+ function getDefaultCompiledReadPaths() {
39
+ return normalizeReadPaths([
40
+ getFrameworkRootFromMeta(globalThis[Symbol.for("import-meta-ponyfill-esmodule")](import.meta).url),
41
+ getCacheBaseDir(),
42
+ getMdxEsmCacheDir(),
43
+ getHttpBundleCacheDir(),
44
+ getHostEnv("DENO_DIR"),
45
+ ]);
46
+ }
27
47
  /**
28
48
  * Build scoped permissions for a project worker.
29
49
  *
@@ -35,14 +55,14 @@ const _isCompiledBinary = (() => {
35
55
  * - ffi: denied (no native code from user code)
36
56
  * - sys: denied (no system info access from user code)
37
57
  */
38
- export function buildWorkerPermissions(readPaths) {
39
- // In compiled binaries, user modules import from the VFS temp dir which
40
- // is outside the project directory. Rather than trying to enumerate all
41
- // read paths, grant full read access — the security boundary is enforced
42
- // by denying write/run/ffi/sys, not by restricting reads.
43
- if (_isCompiledBinary) {
58
+ export function buildWorkerPermissions(readPaths, options = {}) {
59
+ const isCompiledBinary = options.isCompiledBinary ?? _isCompiledBinary;
60
+ const normalizedReadPaths = normalizeReadPaths(readPaths);
61
+ if (isCompiledBinary) {
62
+ const compiledReadPaths = options.compiledReadPaths ?? getDefaultCompiledReadPaths();
63
+ const scopedReadPaths = normalizeReadPaths([...normalizedReadPaths, ...compiledReadPaths]);
44
64
  return {
45
- read: true,
65
+ read: scopedReadPaths.length > 0 ? scopedReadPaths : false,
46
66
  write: false,
47
67
  net: true,
48
68
  env: true,
@@ -52,7 +72,7 @@ export function buildWorkerPermissions(readPaths) {
52
72
  };
53
73
  }
54
74
  return {
55
- read: readPaths.length > 0 ? readPaths : false,
75
+ read: normalizedReadPaths.length > 0 ? normalizedReadPaths : false,
56
76
  write: false,
57
77
  net: true,
58
78
  env: true,
@@ -1 +1 @@
1
- {"version":3,"file":"constant-time.d.ts","sourceRoot":"","sources":["../../../../src/src/security/utils/constant-time.ts"],"names":[],"mappings":"AAEA,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAY/D"}
1
+ {"version":3,"file":"constant-time.d.ts","sourceRoot":"","sources":["../../../../src/src/security/utils/constant-time.ts"],"names":[],"mappings":"AAEA,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAe/D"}
@@ -4,8 +4,11 @@ export function constantTimeEqual(a, b) {
4
4
  const bBuf = encoder.encode(b);
5
5
  const len = Math.max(aBuf.length, bBuf.length);
6
6
  let xor = aBuf.length ^ bBuf.length;
7
+ // Pad out-of-range positions with 0xff (not 0x00) so a padded slot can
8
+ // never coincide with a real 0x00 byte on the other side and read as a
9
+ // match. Matches the CSRF comparison in src/security/csrf/helpers.ts.
7
10
  for (let i = 0; i < len; i++) {
8
- xor |= (aBuf[i] ?? 0) ^ (bBuf[i] ?? 0);
11
+ xor |= (aBuf[i] ?? 0xff) ^ (bBuf[i] ?? 0xff);
9
12
  }
10
13
  return xor === 0;
11
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ssr.service.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/services/rendering/ssr.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,kCAAkC,CAAC;AAsB1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAItE;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC5D;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,mBAAmB,IAAI,YAAY,CAAC;IACpC,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACrF,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAC;CAC3D;AAUD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACpC,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,UAAU,GAAG,OAAO,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,cAAc,GAAG,SAAS,CAAC;IACjF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAqBD,qBAAa,UAAW,YAAW,cAAc;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAA0B;IACrD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;gBAExC,OAAO,CAAC,EAAE;QACpB,SAAS,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;QACpC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACrC;IAKD,mBAAmB,IAAI,YAAY;IAW7B,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAI1D,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IA2G1F,OAAO,CAAC,iBAAiB;IAyHzB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;CAS1D"}
1
+ {"version":3,"file":"ssr.service.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/services/rendering/ssr.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,kCAAkC,CAAC;AAuB1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAItE;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC5D;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,mBAAmB,IAAI,YAAY,CAAC;IACpC,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACrF,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAC;CAC3D;AAUD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACpC,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,UAAU,GAAG,OAAO,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,cAAc,GAAG,SAAS,CAAC;IACjF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAqBD,qBAAa,UAAW,YAAW,cAAc;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAA0B;IACrD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;gBAExC,OAAO,CAAC,EAAE;QACpB,SAAS,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;QACpC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACrC;IAKD,mBAAmB,IAAI,YAAY;IAW7B,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAI1D,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IA+G1F,OAAO,CAAC,iBAAiB;IAyHzB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;CAS1D"}
@@ -4,7 +4,7 @@ import { serverLogger, timeAsync } from "../../../utils/index.js";
4
4
  import { computeSSRETag } from "../../handlers/request/ssr/etag-handler.js";
5
5
  import { VeryfrontError } from "../../../errors/index.js";
6
6
  import { getColorSchemeFromRequest } from "../../../security/http/client-hints.js";
7
- import { endRenderSession, hasRenderSession, startRenderSession, } from "../../../transforms/mdx/esm-module-loader/module-fetcher/index.js";
7
+ import { endRenderSession, hasRenderSession, runInRenderSession, startRenderSession, } from "../../../transforms/mdx/esm-module-loader/module-fetcher/index.js";
8
8
  import { getErrorCollector } from "../../../observability/error-collector.js";
9
9
  import { profilePhase } from "../../../observability/request-profiler.js";
10
10
  import { ErrorOverlay, parseErrorLocation } from "../../dev-server/error-overlay/index.js";
@@ -68,7 +68,10 @@ export class SSRService {
68
68
  slug,
69
69
  });
70
70
  const renderStartTime = performance.now();
71
- const result = await profilePhase("ssr.render_page", () => timeAsync("render-page", () => renderer.renderPage(slug, {
71
+ // Bind the render session to this async context so modules fetched
72
+ // during the render are attributed to THIS render, not whichever
73
+ // concurrent session started first.
74
+ const result = await runInRenderSession(renderSessionId, () => profilePhase("ssr.render_page", () => timeAsync("render-page", () => renderer.renderPage(slug, {
72
75
  delivery: "stream",
73
76
  request,
74
77
  url,
@@ -84,7 +87,7 @@ export class SSRService {
84
87
  noHmr,
85
88
  forceProductionScripts: options.forceProductionScripts,
86
89
  renderSessionId,
87
- })));
90
+ }))));
88
91
  logger.debug("renderPage DONE", {
89
92
  projectSlug: ctx.projectSlug,
90
93
  slug,
@@ -25,6 +25,8 @@ export declare function initializeCacheDir(context: ESMLoaderContext): Promise<s
25
25
  export declare function findVfModuleImports(code: string): Array<{
26
26
  original: string;
27
27
  path: string;
28
+ start: number;
29
+ end: number;
28
30
  }>;
29
31
  /**
30
32
  * Process /_vf_modules/ imports and replace them with file:// paths.
@@ -32,5 +34,7 @@ export declare function findVfModuleImports(code: string): Array<{
32
34
  export declare function processVfModuleImports(code: string, imports: Array<{
33
35
  original: string;
34
36
  path: string;
37
+ start: number;
38
+ end: number;
35
39
  }>, context: ESMLoaderContext, projectDir: string, strictMissingModules: boolean): Promise<string>;
36
40
  //# sourceMappingURL=loader-helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader-helpers.d.ts","sourceRoot":"","sources":["../../../../../src/src/transforms/mdx/esm-module-loader/loader-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;GAGG;AACH,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAapF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAWnE;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgCnF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAW3F;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,OAAO,EAAE,gBAAgB,EACzB,UAAU,EAAE,MAAM,EAClB,oBAAoB,EAAE,OAAO,GAC5B,OAAO,CAAC,MAAM,CAAC,CAwGjB"}
1
+ {"version":3,"file":"loader-helpers.d.ts","sourceRoot":"","sources":["../../../../../src/src/transforms/mdx/esm-module-loader/loader-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmBH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;GAGG;AACH,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAapF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAWnE;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgCnF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,GACX,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAKvE;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,EAC9E,OAAO,EAAE,gBAAgB,EACzB,UAAU,EAAE,MAAM,EAClB,oBAAoB,EAAE,OAAO,GAC5B,OAAO,CAAC,MAAM,CAAC,CAoHjB"}
@@ -17,6 +17,7 @@ import { exists as fsExists } from "../../../platform/compat/fs.js";
17
17
  import { LOG_PREFIX_MDX_LOADER } from "./constants.js";
18
18
  import { getLocalFs } from "./cache/index.js";
19
19
  import { createStubModule } from "./utils/stub-module.js";
20
+ import { findStaticImportFromSpans, replaceSourceSpans, } from "./utils/source-spans.js";
20
21
  import { createModuleFetcherContext, fetchAndCacheModule } from "./module-fetcher/index.js";
21
22
  import { buildMissingModuleError } from "./missing-module.js";
22
23
  /**
@@ -89,15 +90,7 @@ export async function initializeCacheDir(context) {
89
90
  * Find /_vf_modules/ imports in code.
90
91
  */
91
92
  export function findVfModuleImports(code) {
92
- const imports = [];
93
- const pattern = /from\s*["'](\/?)(_vf_modules\/[^"']+)["']/g;
94
- let match;
95
- while ((match = pattern.exec(code)) !== null) {
96
- const [original, , path] = match;
97
- if (path)
98
- imports.push({ original, path });
99
- }
100
- return imports;
93
+ return findStaticImportFromSpans(code, (specifier) => specifier.match(/^\/?(_vf_modules\/[^?]+)(?:\?.*)?$/)?.[1]);
101
94
  }
102
95
  /**
103
96
  * Process /_vf_modules/ imports and replace them with file:// paths.
@@ -136,7 +129,7 @@ export async function processVfModuleImports(code, imports, context, projectDir,
136
129
  strictMissingModules,
137
130
  });
138
131
  const fetchStart = performance.now();
139
- const results = await Promise.all(imports.map(async ({ original, path }, index) => {
132
+ const results = await Promise.all(imports.map(async ({ original, path, start, end }, index) => {
140
133
  return await withSpan(SpanNames.MDX_FETCH_MODULE, async () => {
141
134
  const moduleStart = performance.now();
142
135
  logger.debug(`${LOG_PREFIX_MDX_LOADER} Fetching module START`, {
@@ -151,7 +144,7 @@ export async function processVfModuleImports(code, imports, context, projectDir,
151
144
  path,
152
145
  durationMs: (performance.now() - moduleStart).toFixed(1),
153
146
  });
154
- return { original, filePath, path };
147
+ return { original, start, end, filePath, path };
155
148
  }, {
156
149
  "mdx.module_path": path,
157
150
  "mdx.module_index": index,
@@ -163,10 +156,15 @@ export async function processVfModuleImports(code, imports, context, projectDir,
163
156
  moduleCount: imports.length,
164
157
  durationMs: (performance.now() - fetchStart).toFixed(1),
165
158
  });
166
- let result = code;
167
- for (const { original, filePath, path } of results) {
159
+ const replacements = [];
160
+ for (const { original, start, end, filePath, path } of results) {
168
161
  if (filePath) {
169
- result = result.replace(original, `from "file://${filePath}"`);
162
+ replacements.push({
163
+ start,
164
+ end,
165
+ expected: original,
166
+ replacement: `from "file://${filePath}"`,
167
+ });
170
168
  continue;
171
169
  }
172
170
  if (strictMissingModules) {
@@ -178,9 +176,15 @@ export async function processVfModuleImports(code, imports, context, projectDir,
178
176
  projectSlug,
179
177
  });
180
178
  }
181
- const stubPath = await createStubModule(path, result, original, context.esmCacheDir);
182
- if (stubPath)
183
- result = result.replace(original, `from "file://${stubPath}"`);
179
+ const stubPath = await createStubModule(path, code, original, context.esmCacheDir);
180
+ if (stubPath) {
181
+ replacements.push({
182
+ start,
183
+ end,
184
+ expected: original,
185
+ replacement: `from "file://${stubPath}"`,
186
+ });
187
+ }
184
188
  }
185
- return result;
189
+ return replaceSourceSpans(code, replacements);
186
190
  }
@@ -1 +1 @@
1
- {"version":3,"file":"http-fetcher.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/mdx/esm-module-loader/module-fetcher/http-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAGjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAK5E;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,cAAc,EACvB,qBAAqB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,EAChF,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,MAAM,EACpB,cAAc,CAAC,EAAE,OAAO,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqDxB"}
1
+ {"version":3,"file":"http-fetcher.d.ts","sourceRoot":"","sources":["../../../../../../src/src/transforms/mdx/esm-module-loader/module-fetcher/http-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAGjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAM5E;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,cAAc,EACvB,qBAAqB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,EAChF,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,MAAM,EACpB,cAAc,CAAC,EAAE,OAAO,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuExB"}