veryfront 0.1.216 → 0.1.217
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/esm/cli/commands/generate/integration-generator-helpers.d.ts +35 -0
- package/esm/cli/commands/generate/integration-generator-helpers.d.ts.map +1 -0
- package/esm/cli/commands/generate/integration-generator-helpers.js +123 -0
- package/esm/cli/commands/generate/integration-generator.d.ts +1 -2
- package/esm/cli/commands/generate/integration-generator.d.ts.map +1 -1
- package/esm/cli/commands/generate/integration-generator.js +1 -123
- package/esm/cli/commands/knowledge/command-helpers.d.ts +48 -0
- package/esm/cli/commands/knowledge/command-helpers.d.ts.map +1 -0
- package/esm/cli/commands/knowledge/command-helpers.js +216 -0
- package/esm/cli/commands/knowledge/command.d.ts +11 -16
- package/esm/cli/commands/knowledge/command.d.ts.map +1 -1
- package/esm/cli/commands/knowledge/command.js +25 -212
- package/esm/cli/mcp/remote-file-tool-helpers.d.ts +5 -0
- package/esm/cli/mcp/remote-file-tool-helpers.d.ts.map +1 -0
- package/esm/cli/mcp/remote-file-tool-helpers.js +22 -0
- package/esm/cli/mcp/remote-file-tools.d.ts.map +1 -1
- package/esm/cli/mcp/remote-file-tools.js +1 -22
- package/esm/cli/templates/integration-loader-helpers.d.ts +8 -0
- package/esm/cli/templates/integration-loader-helpers.d.ts.map +1 -0
- package/esm/cli/templates/integration-loader-helpers.js +29 -0
- package/esm/cli/templates/integration-loader.d.ts.map +1 -1
- package/esm/cli/templates/integration-loader.js +5 -21
- package/esm/cli/templates/manifest.d.ts +1 -0
- package/esm/cli/templates/manifest.js +2 -1
- package/esm/deno.js +2 -2
- package/esm/src/agent/runtime/index.d.ts.map +1 -1
- package/esm/src/agent/runtime/index.js +48 -90
- package/esm/src/chat/ag-ui-helpers.d.ts +17 -0
- package/esm/src/chat/ag-ui-helpers.d.ts.map +1 -0
- package/esm/src/chat/ag-ui-helpers.js +111 -0
- package/esm/src/chat/ag-ui.d.ts.map +1 -1
- package/esm/src/chat/ag-ui.js +1 -111
- package/esm/src/config/schemas/config.schema.d.ts +1 -0
- package/esm/src/config/schemas/config.schema.d.ts.map +1 -1
- package/esm/src/config/schemas/config.schema.js +11 -0
- package/esm/src/config/schemas/index.d.ts +11 -1
- package/esm/src/config/schemas/index.d.ts.map +1 -1
- package/esm/src/errors/error-registry-helpers.d.ts +6 -0
- package/esm/src/errors/error-registry-helpers.d.ts.map +1 -0
- package/esm/src/errors/error-registry-helpers.js +9 -0
- package/esm/src/errors/error-registry.d.ts.map +1 -1
- package/esm/src/errors/error-registry.js +4 -3
- package/esm/src/extensions/factory-loader.d.ts +29 -0
- package/esm/src/extensions/factory-loader.d.ts.map +1 -0
- package/esm/src/extensions/factory-loader.js +63 -0
- package/esm/src/extensions/index.d.ts +16 -0
- package/esm/src/extensions/index.d.ts.map +1 -1
- package/esm/src/extensions/index.js +16 -0
- package/esm/src/extensions/orchestrate.d.ts +54 -0
- package/esm/src/extensions/orchestrate.d.ts.map +1 -0
- package/esm/src/extensions/orchestrate.js +116 -0
- package/esm/src/html/styles-builder/plugin-loader.d.ts.map +1 -1
- package/esm/src/html/styles-builder/plugin-loader.js +23 -0
- package/esm/src/html/styles-builder/tailwind-plugin-allowlist.d.ts +29 -0
- package/esm/src/html/styles-builder/tailwind-plugin-allowlist.d.ts.map +1 -0
- package/esm/src/html/styles-builder/tailwind-plugin-allowlist.js +48 -0
- package/esm/src/modules/react-loader/ssr-module-loader/loader-helpers.d.ts +15 -0
- package/esm/src/modules/react-loader/ssr-module-loader/loader-helpers.d.ts.map +1 -0
- package/esm/src/modules/react-loader/ssr-module-loader/loader-helpers.js +22 -0
- package/esm/src/modules/react-loader/ssr-module-loader/loader.d.ts +0 -2
- package/esm/src/modules/react-loader/ssr-module-loader/loader.d.ts.map +1 -1
- package/esm/src/modules/react-loader/ssr-module-loader/loader.js +4 -24
- package/esm/src/platform/adapters/fs/veryfront/adapter-helpers.d.ts +19 -0
- package/esm/src/platform/adapters/fs/veryfront/adapter-helpers.d.ts.map +1 -0
- package/esm/src/platform/adapters/fs/veryfront/adapter-helpers.js +26 -0
- package/esm/src/platform/adapters/fs/veryfront/adapter.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/adapter.js +4 -20
- package/esm/src/platform/adapters/fs/veryfront/read-operations-helpers.d.ts +1 -0
- package/esm/src/platform/adapters/fs/veryfront/read-operations-helpers.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/read-operations-helpers.js +3 -0
- package/esm/src/platform/adapters/fs/veryfront/read-operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/read-operations.js +4 -7
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager-helpers.d.ts +28 -0
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager-helpers.d.ts.map +1 -0
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager-helpers.js +41 -0
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager.d.ts +1 -4
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager.d.ts.map +1 -1
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager.js +7 -40
- package/esm/src/provider/runtime-loader/tool-input-status.d.ts +17 -0
- package/esm/src/provider/runtime-loader/tool-input-status.d.ts.map +1 -0
- package/esm/src/provider/runtime-loader/tool-input-status.js +155 -0
- package/esm/src/provider/runtime-loader.d.ts +2 -3
- package/esm/src/provider/runtime-loader.d.ts.map +1 -1
- package/esm/src/provider/runtime-loader.js +2 -155
- package/esm/src/rendering/orchestrator/pipeline-helpers.d.ts +8 -0
- package/esm/src/rendering/orchestrator/pipeline-helpers.d.ts.map +1 -0
- package/esm/src/rendering/orchestrator/pipeline-helpers.js +20 -0
- package/esm/src/rendering/orchestrator/pipeline.d.ts +0 -3
- package/esm/src/rendering/orchestrator/pipeline.d.ts.map +1 -1
- package/esm/src/rendering/orchestrator/pipeline.js +4 -22
- package/esm/src/routing/api/module-loader/loader-helpers.d.ts +10 -0
- package/esm/src/routing/api/module-loader/loader-helpers.d.ts.map +1 -0
- package/esm/src/routing/api/module-loader/loader-helpers.js +62 -0
- package/esm/src/routing/api/module-loader/loader.d.ts +1 -1
- package/esm/src/routing/api/module-loader/loader.d.ts.map +1 -1
- package/esm/src/routing/api/module-loader/loader.js +2 -60
- package/esm/src/server/bootstrap.d.ts +22 -2
- package/esm/src/server/bootstrap.d.ts.map +1 -1
- package/esm/src/server/bootstrap.js +67 -5
- package/esm/src/server/dev-ui/manifest.d.ts +2 -0
- package/esm/src/server/dev-ui/manifest.js +3 -1
- package/esm/src/server/handlers/request/api/project-discovery.d.ts.map +1 -1
- package/esm/src/server/handlers/request/api/project-discovery.js +14 -8
- package/esm/src/server/production-server.js +1 -1
- package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.d.ts.map +1 -1
- package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.js +2 -2
- package/esm/src/studio/bridge/bridge-bundle.generated.d.ts.map +1 -1
- package/esm/src/studio/bridge/bridge-bundle.generated.js +1 -1
- package/esm/src/tool/index.d.ts +1 -1
- package/esm/src/tool/index.d.ts.map +1 -1
- package/esm/src/tool/types.d.ts +20 -0
- package/esm/src/tool/types.d.ts.map +1 -1
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
- package/src/cli/commands/generate/integration-generator-helpers.ts +185 -0
- package/src/cli/commands/generate/integration-generator.ts +12 -168
- package/src/cli/commands/knowledge/command-helpers.ts +295 -0
- package/src/cli/commands/knowledge/command.ts +33 -259
- package/src/cli/mcp/remote-file-tool-helpers.ts +27 -0
- package/src/cli/mcp/remote-file-tools.ts +6 -28
- package/src/cli/templates/integration-loader-helpers.ts +49 -0
- package/src/cli/templates/integration-loader.ts +10 -28
- package/src/cli/templates/manifest.js +2 -1
- package/src/deno.js +2 -2
- package/src/src/agent/runtime/index.ts +77 -94
- package/src/src/chat/ag-ui-helpers.ts +139 -0
- package/src/src/chat/ag-ui.ts +11 -139
- package/src/src/config/schemas/config.schema.ts +11 -0
- package/src/src/config/schemas/index.ts +15 -1
- package/src/src/errors/error-registry-helpers.ts +23 -0
- package/src/src/errors/error-registry.ts +8 -3
- package/src/src/extensions/factory-loader.ts +76 -0
- package/src/src/extensions/index.ts +20 -0
- package/src/src/extensions/orchestrate.ts +184 -0
- package/src/src/html/styles-builder/plugin-loader.ts +32 -0
- package/src/src/html/styles-builder/tailwind-plugin-allowlist.ts +51 -0
- package/src/src/modules/react-loader/ssr-module-loader/loader-helpers.ts +37 -0
- package/src/src/modules/react-loader/ssr-module-loader/loader.ts +8 -39
- package/src/src/platform/adapters/fs/veryfront/adapter-helpers.ts +43 -0
- package/src/src/platform/adapters/fs/veryfront/adapter.ts +8 -22
- package/src/src/platform/adapters/fs/veryfront/read-operations-helpers.ts +4 -0
- package/src/src/platform/adapters/fs/veryfront/read-operations.ts +4 -7
- package/src/src/platform/adapters/fs/veryfront/websocket-manager-helpers.ts +73 -0
- package/src/src/platform/adapters/fs/veryfront/websocket-manager.ts +29 -44
- package/src/src/provider/runtime-loader/tool-input-status.ts +210 -0
- package/src/src/provider/runtime-loader.ts +6 -203
- package/src/src/rendering/orchestrator/pipeline-helpers.ts +35 -0
- package/src/src/rendering/orchestrator/pipeline.ts +8 -35
- package/src/src/routing/api/module-loader/loader-helpers.ts +68 -0
- package/src/src/routing/api/module-loader/loader.ts +8 -65
- package/src/src/server/bootstrap.ts +88 -7
- package/src/src/server/dev-ui/manifest.js +3 -1
- package/src/src/server/handlers/request/api/project-discovery.ts +19 -8
- package/src/src/server/production-server.ts +1 -1
- package/src/src/server/services/rsc/endpoints/rsc-bundles.generated.ts +2 -2
- package/src/src/studio/bridge/bridge-bundle.generated.ts +1 -1
- package/src/src/tool/index.ts +1 -0
- package/src/src/tool/types.ts +21 -0
- package/src/src/utils/version-constant.ts +1 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic factory loader.
|
|
3
|
+
*
|
|
4
|
+
* Loads an extension factory from a filesystem path by dynamic import,
|
|
5
|
+
* invokes it, and wraps the result as a `ResolvedExtension`.
|
|
6
|
+
*
|
|
7
|
+
* @module extensions/factory-loader
|
|
8
|
+
*/
|
|
9
|
+
import { isAbsolute, toFileUrl } from "../../deps/jsr.io/@std/path/1.1.4/mod.js";
|
|
10
|
+
import { EXTENSION_VALIDATION_ERROR } from "./errors.js";
|
|
11
|
+
/**
|
|
12
|
+
* Dynamically import an extension factory from `path` and resolve it.
|
|
13
|
+
*
|
|
14
|
+
* `path` may be either an absolute filesystem path (for project and
|
|
15
|
+
* local-file sources) or a bare module specifier (for `package` source).
|
|
16
|
+
* Absolute paths are converted to `file://` URLs; bare specifiers are
|
|
17
|
+
* passed through so the runtime's module resolver can find them.
|
|
18
|
+
*
|
|
19
|
+
* The module must `export default` an `ExtensionFactory` (a function that
|
|
20
|
+
* returns an `Extension`). On any error — missing default export, default
|
|
21
|
+
* export that is not a function, factory throw, or import failure — this
|
|
22
|
+
* throws `EXTENSION_VALIDATION_ERROR` with a `detail` field that names the
|
|
23
|
+
* path and what went wrong.
|
|
24
|
+
*
|
|
25
|
+
* @param path Absolute filesystem path or bare module specifier.
|
|
26
|
+
* @param source Where the extension was discovered (drives merge priority).
|
|
27
|
+
* @param config Optional config forwarded to the factory.
|
|
28
|
+
*/
|
|
29
|
+
export async function loadExtensionFactory(path, source, config) {
|
|
30
|
+
const specifier = isAbsolute(path) ? toFileUrl(path).href : path;
|
|
31
|
+
let mod;
|
|
32
|
+
try {
|
|
33
|
+
mod = await import(specifier);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
throw EXTENSION_VALIDATION_ERROR.create({
|
|
37
|
+
detail: `Failed to import extension at "${path}": ${err instanceof Error ? err.message : String(err)}`,
|
|
38
|
+
cause: err,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const factory = mod.default;
|
|
42
|
+
if (factory === undefined || factory === null) {
|
|
43
|
+
throw EXTENSION_VALIDATION_ERROR.create({
|
|
44
|
+
detail: `Extension at "${path}" has no default export`,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (typeof factory !== "function") {
|
|
48
|
+
throw EXTENSION_VALIDATION_ERROR.create({
|
|
49
|
+
detail: `Extension at "${path}" default export is not a function (got ${typeof factory})`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
let extension;
|
|
53
|
+
try {
|
|
54
|
+
extension = factory(config);
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
throw EXTENSION_VALIDATION_ERROR.create({
|
|
58
|
+
detail: `Extension factory at "${path}" threw during invocation: ${err instanceof Error ? err.message : String(err)}`,
|
|
59
|
+
cause: err,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return { extension, source, origin: path };
|
|
63
|
+
}
|
|
@@ -6,6 +6,19 @@
|
|
|
6
6
|
* helpers consumers need to load, validate, and orchestrate extensions.
|
|
7
7
|
*
|
|
8
8
|
* @module extensions
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { orchestrateExtensions } from "veryfront/extensions";
|
|
12
|
+
*
|
|
13
|
+
* const loader = await orchestrateExtensions({
|
|
14
|
+
* projectDir: Deno.cwd(),
|
|
15
|
+
* config,
|
|
16
|
+
* logger,
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Later, on shutdown:
|
|
20
|
+
* await loader.teardownAll();
|
|
21
|
+
* ```
|
|
9
22
|
*/
|
|
10
23
|
import "../../_dnt.polyfills.js";
|
|
11
24
|
export type { Capability, Extension, ExtensionConfigEntry, ExtensionContext, ExtensionFactory, ExtensionLogger, ExtensionSource, ResolvedExtension, } from "./types.js";
|
|
@@ -13,6 +26,9 @@ export { resolve, tryResolve } from "./contracts.js";
|
|
|
13
26
|
export type { PackageMetadata } from "./discovery.js";
|
|
14
27
|
export { discoverLocalExtensions, discoverPackageExtensions, discoverProjectExtensions, mergeExtensions, parsePackageMetadata, } from "./discovery.js";
|
|
15
28
|
export { ExtensionLoader } from "./loader.js";
|
|
29
|
+
export { loadExtensionFactory } from "./factory-loader.js";
|
|
30
|
+
export type { OrchestrateOptions } from "./orchestrate.js";
|
|
31
|
+
export { orchestrateExtensions } from "./orchestrate.js";
|
|
16
32
|
export type { ConflictInfo } from "./validation.js";
|
|
17
33
|
export { detectConflicts, validateExtension } from "./validation.js";
|
|
18
34
|
export { auditCapabilities, formatCapabilities, mapToDenoPermissions } from "./capabilities.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,yBAAyB,CAAC;AAEjC,YAAY,EACV,UAAU,EACV,SAAS,EACT,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAKpB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGrD,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAGhG,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,aAAa,CAAC"}
|
|
@@ -6,6 +6,19 @@
|
|
|
6
6
|
* helpers consumers need to load, validate, and orchestrate extensions.
|
|
7
7
|
*
|
|
8
8
|
* @module extensions
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { orchestrateExtensions } from "veryfront/extensions";
|
|
12
|
+
*
|
|
13
|
+
* const loader = await orchestrateExtensions({
|
|
14
|
+
* projectDir: Deno.cwd(),
|
|
15
|
+
* config,
|
|
16
|
+
* logger,
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Later, on shutdown:
|
|
20
|
+
* await loader.teardownAll();
|
|
21
|
+
* ```
|
|
9
22
|
*/
|
|
10
23
|
// Core types
|
|
11
24
|
import "../../_dnt.polyfills.js";
|
|
@@ -16,6 +29,9 @@ export { resolve, tryResolve } from "./contracts.js";
|
|
|
16
29
|
export { discoverLocalExtensions, discoverPackageExtensions, discoverProjectExtensions, mergeExtensions, parsePackageMetadata, } from "./discovery.js";
|
|
17
30
|
// Loader
|
|
18
31
|
export { ExtensionLoader } from "./loader.js";
|
|
32
|
+
// Factory loader (dynamic-import of an extension factory)
|
|
33
|
+
export { loadExtensionFactory } from "./factory-loader.js";
|
|
34
|
+
export { orchestrateExtensions } from "./orchestrate.js";
|
|
19
35
|
export { detectConflicts, validateExtension } from "./validation.js";
|
|
20
36
|
// Capabilities
|
|
21
37
|
export { auditCapabilities, formatCapabilities, mapToDenoPermissions } from "./capabilities.js";
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension orchestration pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Discovers, loads, merges, sorts, and runs setup for every extension
|
|
5
|
+
* contributed by the four sources (config, package, project, local-file).
|
|
6
|
+
* Invoked once by `bootstrap()` after config resolution.
|
|
7
|
+
*
|
|
8
|
+
* @module extensions/orchestrate
|
|
9
|
+
*/
|
|
10
|
+
import * as defaultDiscovery from "./discovery.js";
|
|
11
|
+
import { loadExtensionFactory as defaultLoadFactory } from "./factory-loader.js";
|
|
12
|
+
import { ExtensionLoader } from "./loader.js";
|
|
13
|
+
import type { ExtensionConfigEntry, ExtensionLogger } from "./types.js";
|
|
14
|
+
/**
|
|
15
|
+
* Options for `orchestrateExtensions`.
|
|
16
|
+
*
|
|
17
|
+
* The `discovery` and `loadFactory` fields are test seams — they are not
|
|
18
|
+
* part of the stable public API and default to the real implementations.
|
|
19
|
+
*/
|
|
20
|
+
export interface OrchestrateOptions {
|
|
21
|
+
projectDir: string;
|
|
22
|
+
config: {
|
|
23
|
+
extensions?: ExtensionConfigEntry[];
|
|
24
|
+
};
|
|
25
|
+
logger: ExtensionLogger;
|
|
26
|
+
/** @internal Override discovery functions in tests. */
|
|
27
|
+
discovery?: {
|
|
28
|
+
discoverPackageExtensions: typeof defaultDiscovery.discoverPackageExtensions;
|
|
29
|
+
discoverProjectExtensions: typeof defaultDiscovery.discoverProjectExtensions;
|
|
30
|
+
discoverLocalExtensions: typeof defaultDiscovery.discoverLocalExtensions;
|
|
31
|
+
mergeExtensions: typeof defaultDiscovery.mergeExtensions;
|
|
32
|
+
};
|
|
33
|
+
/** @internal Override factory loading in tests. */
|
|
34
|
+
loadFactory?: typeof defaultLoadFactory;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Run the full extension pipeline against a resolved project config.
|
|
38
|
+
*
|
|
39
|
+
* Pipeline:
|
|
40
|
+
* 1. Split `config.extensions` into resolved entries and disable directives.
|
|
41
|
+
* 2. Discover extensions from package, project, and local sources.
|
|
42
|
+
* 3. Skip loading factories for package- and project-source extensions whose
|
|
43
|
+
* names appear in the disable set (local-file names are not reliable
|
|
44
|
+
* pre-load and are filtered after `mergeExtensions`).
|
|
45
|
+
* 4. Dynamic-import factories for every remaining discovered path.
|
|
46
|
+
* 5. Merge sources honoring priority `config > package > project > local-file`.
|
|
47
|
+
* 6. Construct an `ExtensionLoader` and run `setupAll`.
|
|
48
|
+
*
|
|
49
|
+
* On factory error during `setup()`, `ExtensionLoader.setupAll` performs
|
|
50
|
+
* partial rollback internally. The error is re-thrown unchanged so callers
|
|
51
|
+
* can surface the extension name to the user.
|
|
52
|
+
*/
|
|
53
|
+
export declare function orchestrateExtensions(options: OrchestrateOptions): Promise<ExtensionLoader>;
|
|
54
|
+
//# sourceMappingURL=orchestrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrate.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/orchestrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,gBAAgB,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,oBAAoB,IAAI,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAEV,oBAAoB,EACpB,eAAe,EAGhB,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE;QAAE,UAAU,CAAC,EAAE,oBAAoB,EAAE,CAAA;KAAE,CAAC;IAChD,MAAM,EAAE,eAAe,CAAC;IACxB,uDAAuD;IACvD,SAAS,CAAC,EAAE;QACV,yBAAyB,EAAE,OAAO,gBAAgB,CAAC,yBAAyB,CAAC;QAC7E,yBAAyB,EAAE,OAAO,gBAAgB,CAAC,yBAAyB,CAAC;QAC7E,uBAAuB,EAAE,OAAO,gBAAgB,CAAC,uBAAuB,CAAC;QACzE,eAAe,EAAE,OAAO,gBAAgB,CAAC,eAAe,CAAC;KAC1D,CAAC;IACF,mDAAmD;IACnD,WAAW,CAAC,EAAE,OAAO,kBAAkB,CAAC;CACzC;AAmCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,eAAe,CAAC,CA4E1B"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension orchestration pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Discovers, loads, merges, sorts, and runs setup for every extension
|
|
5
|
+
* contributed by the four sources (config, package, project, local-file).
|
|
6
|
+
* Invoked once by `bootstrap()` after config resolution.
|
|
7
|
+
*
|
|
8
|
+
* @module extensions/orchestrate
|
|
9
|
+
*/
|
|
10
|
+
import { basename, dirname } from "../../deps/jsr.io/@std/path/1.1.4/mod.js";
|
|
11
|
+
import * as defaultDiscovery from "./discovery.js";
|
|
12
|
+
import { loadExtensionFactory as defaultLoadFactory } from "./factory-loader.js";
|
|
13
|
+
import { ExtensionLoader } from "./loader.js";
|
|
14
|
+
function isDisableDirective(entry) {
|
|
15
|
+
return (typeof entry === "object" &&
|
|
16
|
+
entry !== null &&
|
|
17
|
+
"enabled" in entry &&
|
|
18
|
+
entry.enabled === false);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Extract the extension name from a project-extension path.
|
|
22
|
+
*
|
|
23
|
+
* Project extensions live under `<baseDir>/extensions/<name>/...`. Discovery
|
|
24
|
+
* emits either `<baseDir>/extensions/<name>/src/index.ts` or
|
|
25
|
+
* `<baseDir>/extensions/<name>/index.ts`. This walks parent directories until
|
|
26
|
+
* it finds the ancestor whose parent is `extensions/`.
|
|
27
|
+
*/
|
|
28
|
+
function projectExtensionNameFromPath(path) {
|
|
29
|
+
let current = dirname(path);
|
|
30
|
+
// Safety limit in case of a malformed path that never reaches a root.
|
|
31
|
+
for (let i = 0; i < 8; i++) {
|
|
32
|
+
const parent = dirname(current);
|
|
33
|
+
if (basename(parent) === "extensions") {
|
|
34
|
+
return basename(current);
|
|
35
|
+
}
|
|
36
|
+
if (parent === current)
|
|
37
|
+
return undefined;
|
|
38
|
+
current = parent;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Run the full extension pipeline against a resolved project config.
|
|
44
|
+
*
|
|
45
|
+
* Pipeline:
|
|
46
|
+
* 1. Split `config.extensions` into resolved entries and disable directives.
|
|
47
|
+
* 2. Discover extensions from package, project, and local sources.
|
|
48
|
+
* 3. Skip loading factories for package- and project-source extensions whose
|
|
49
|
+
* names appear in the disable set (local-file names are not reliable
|
|
50
|
+
* pre-load and are filtered after `mergeExtensions`).
|
|
51
|
+
* 4. Dynamic-import factories for every remaining discovered path.
|
|
52
|
+
* 5. Merge sources honoring priority `config > package > project > local-file`.
|
|
53
|
+
* 6. Construct an `ExtensionLoader` and run `setupAll`.
|
|
54
|
+
*
|
|
55
|
+
* On factory error during `setup()`, `ExtensionLoader.setupAll` performs
|
|
56
|
+
* partial rollback internally. The error is re-thrown unchanged so callers
|
|
57
|
+
* can surface the extension name to the user.
|
|
58
|
+
*/
|
|
59
|
+
export async function orchestrateExtensions(options) {
|
|
60
|
+
const { projectDir, config, logger } = options;
|
|
61
|
+
const disc = options.discovery ?? defaultDiscovery;
|
|
62
|
+
const loadFactory = options.loadFactory ?? defaultLoadFactory;
|
|
63
|
+
const configEntries = Array.isArray(config.extensions) ? config.extensions : [];
|
|
64
|
+
const disables = [];
|
|
65
|
+
const configResolved = [];
|
|
66
|
+
for (const entry of configEntries) {
|
|
67
|
+
if (isDisableDirective(entry)) {
|
|
68
|
+
disables.push(entry);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
configResolved.push({
|
|
72
|
+
extension: entry,
|
|
73
|
+
source: "config",
|
|
74
|
+
origin: "veryfront.config",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Build the disabled-names set early so we can skip dynamic imports for
|
|
79
|
+
// extensions the user has explicitly turned off. A factory whose module
|
|
80
|
+
// fails to import or invoke would otherwise take down bootstrap even
|
|
81
|
+
// though the user asked for it to be disabled.
|
|
82
|
+
const disabledNames = new Set(disables.map((d) => d.name));
|
|
83
|
+
const [packageHits, projectPaths, localPaths] = await Promise.all([
|
|
84
|
+
disc.discoverPackageExtensions(projectDir),
|
|
85
|
+
disc.discoverProjectExtensions(projectDir),
|
|
86
|
+
disc.discoverLocalExtensions(projectDir),
|
|
87
|
+
]);
|
|
88
|
+
// Package hits carry the package name directly — filter before loading.
|
|
89
|
+
const enabledPackageNames = packageHits
|
|
90
|
+
.map((hit) => hit.packageName)
|
|
91
|
+
.filter((name) => !disabledNames.has(name));
|
|
92
|
+
// Project paths have the shape `<projectDir>/extensions/<name>/src/index.ts`
|
|
93
|
+
// (or `<projectDir>/extensions/<name>/index.ts`). `mergeExtensions` is the
|
|
94
|
+
// safety net for any path whose name cannot be derived.
|
|
95
|
+
const enabledProjectPaths = projectPaths.filter((path) => {
|
|
96
|
+
const name = projectExtensionNameFromPath(path);
|
|
97
|
+
return name === undefined || !disabledNames.has(name);
|
|
98
|
+
});
|
|
99
|
+
// Local-file paths cannot be reliably filtered pre-load: the filename
|
|
100
|
+
// (`foo.extension.ts`) is not guaranteed to match the extension name
|
|
101
|
+
// declared by the factory. `mergeExtensions` applies the post-hoc filter.
|
|
102
|
+
const packageResolved = await loadAllFactories(enabledPackageNames, "package", loadFactory);
|
|
103
|
+
const projectResolved = await loadAllFactories(enabledProjectPaths, "project", loadFactory);
|
|
104
|
+
const localResolved = await loadAllFactories(localPaths, "local-file", loadFactory);
|
|
105
|
+
const merged = disc.mergeExtensions(configResolved, packageResolved, projectResolved, localResolved, disables);
|
|
106
|
+
const loader = new ExtensionLoader(logger);
|
|
107
|
+
await loader.setupAll(merged, config);
|
|
108
|
+
return loader;
|
|
109
|
+
}
|
|
110
|
+
async function loadAllFactories(paths, source, loadFactory) {
|
|
111
|
+
const resolved = [];
|
|
112
|
+
for (const path of paths) {
|
|
113
|
+
resolved.push(await loadFactory(path, source));
|
|
114
|
+
}
|
|
115
|
+
return resolved;
|
|
116
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-loader.d.ts","sourceRoot":"","sources":["../../../../src/src/html/styles-builder/plugin-loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin-loader.d.ts","sourceRoot":"","sources":["../../../../src/src/html/styles-builder/plugin-loader.ts"],"names":[],"mappings":"AAiIA;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA4D/E;AAED,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAC/B,OAAO,CAAC,OAAO,CAAC,CAwClB"}
|
|
@@ -13,7 +13,25 @@ import colors from "tailwindcss/colors";
|
|
|
13
13
|
import { serverLogger } from "../../utils/index.js";
|
|
14
14
|
import { getErrorBySlug, IMPORT_RESOLUTION_ERROR, NETWORK_ERROR, VeryfrontError, } from "../../errors/index.js";
|
|
15
15
|
import { getTailwindPluginBundleUrl } from "../../build/binary-plugin-includes.js";
|
|
16
|
+
import { bareName, PACKAGE_SPEC_RE, TAILWIND_PLUGIN_ALLOWLIST, } from "./tailwind-plugin-allowlist.js";
|
|
16
17
|
const logger = serverLogger.component("tailwind");
|
|
18
|
+
/**
|
|
19
|
+
* Enforce the Tailwind plugin allowlist (VULN-FS-1).
|
|
20
|
+
*
|
|
21
|
+
* Called at the top of every entry point that can load third-party plugin
|
|
22
|
+
* code. Rejects anything that is not a syntactically valid npm package
|
|
23
|
+
* specifier, and anything whose bare name is not on the allowlist.
|
|
24
|
+
*/
|
|
25
|
+
function assertPluginAllowed(spec) {
|
|
26
|
+
if (!PACKAGE_SPEC_RE.test(spec)) {
|
|
27
|
+
throw new Error(`Invalid Tailwind plugin specifier: ${spec}`);
|
|
28
|
+
}
|
|
29
|
+
const name = bareName(spec);
|
|
30
|
+
if (!TAILWIND_PLUGIN_ALLOWLIST.has(name)) {
|
|
31
|
+
throw new Error(`Package "${name}" is not on the Tailwind plugin allowlist. ` +
|
|
32
|
+
`See src/html/styles-builder/tailwind-plugin-allowlist.ts.`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
17
35
|
// Provide localStorage shim for plugins that use util-deprecate (which checks localStorage)
|
|
18
36
|
// This prevents "LocalStorage is not supported in this context" errors in Deno.
|
|
19
37
|
try {
|
|
@@ -89,6 +107,7 @@ async function importBundledModule(code) {
|
|
|
89
107
|
* dynamic imports from URLs. Fetches bundled code, rewrites imports, loads via temp file.
|
|
90
108
|
*/
|
|
91
109
|
export async function loadModuleFromEsmSh(packageName) {
|
|
110
|
+
assertPluginAllowed(packageName);
|
|
92
111
|
const stubUrl = getTailwindPluginBundleUrl(packageName);
|
|
93
112
|
logger.debug("Fetching esm.sh stub", { url: stubUrl });
|
|
94
113
|
const stubResponse = await fetch(stubUrl);
|
|
@@ -133,6 +152,10 @@ export async function loadModuleFromEsmSh(packageName) {
|
|
|
133
152
|
return await importBundledModule(code);
|
|
134
153
|
}
|
|
135
154
|
export async function loadPlugin(id, pluginCache, pluginErrors) {
|
|
155
|
+
// Enforce the allowlist before consulting any caches so a disallowed id can
|
|
156
|
+
// never be served from a pre-seeded or stale cache entry — defence-in-depth
|
|
157
|
+
// against future changes that might pre-populate these maps.
|
|
158
|
+
assertPluginAllowed(id);
|
|
136
159
|
const cachedError = pluginErrors.get(id);
|
|
137
160
|
if (cachedError)
|
|
138
161
|
throw cachedError;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Allowlist of Tailwind CSS plugin package names that may be dynamically loaded
|
|
3
|
+
* via `loadPlugin` / `loadModuleFromEsmSh`.
|
|
4
|
+
*
|
|
5
|
+
* Tailwind v4 stylesheets can request plugins through the `@plugin "..."`
|
|
6
|
+
* directive. Without restriction, this turns arbitrary project CSS into a
|
|
7
|
+
* remote-code-execution vector because the loader fetches and imports code
|
|
8
|
+
* from https://esm.sh. Only the packages listed here may be loaded.
|
|
9
|
+
*
|
|
10
|
+
* @module html/styles-builder/tailwind-plugin-allowlist
|
|
11
|
+
*/
|
|
12
|
+
export declare const TAILWIND_PLUGIN_ALLOWLIST: ReadonlySet<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Matches npm package specifiers, optionally scoped and optionally suffixed
|
|
15
|
+
* with an `@version` range. Deliberately restrictive: ASCII only, no path
|
|
16
|
+
* separators, no whitespace, no control characters.
|
|
17
|
+
*/
|
|
18
|
+
export declare const PACKAGE_SPEC_RE: RegExp;
|
|
19
|
+
/**
|
|
20
|
+
* Return the bare package name (without any `@version` suffix) for a spec.
|
|
21
|
+
*
|
|
22
|
+
* Examples:
|
|
23
|
+
* bareName("pkg") -> "pkg"
|
|
24
|
+
* bareName("pkg@1.0.0") -> "pkg"
|
|
25
|
+
* bareName("@scope/pkg") -> "@scope/pkg"
|
|
26
|
+
* bareName("@scope/pkg@1.0") -> "@scope/pkg"
|
|
27
|
+
*/
|
|
28
|
+
export declare function bareName(spec: string): string;
|
|
29
|
+
//# sourceMappingURL=tailwind-plugin-allowlist.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tailwind-plugin-allowlist.d.ts","sourceRoot":"","sources":["../../../../src/src/html/styles-builder/tailwind-plugin-allowlist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAaxD,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,eAAe,QAA4D,CAAC;AAEzF;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO7C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Allowlist of Tailwind CSS plugin package names that may be dynamically loaded
|
|
3
|
+
* via `loadPlugin` / `loadModuleFromEsmSh`.
|
|
4
|
+
*
|
|
5
|
+
* Tailwind v4 stylesheets can request plugins through the `@plugin "..."`
|
|
6
|
+
* directive. Without restriction, this turns arbitrary project CSS into a
|
|
7
|
+
* remote-code-execution vector because the loader fetches and imports code
|
|
8
|
+
* from https://esm.sh. Only the packages listed here may be loaded.
|
|
9
|
+
*
|
|
10
|
+
* @module html/styles-builder/tailwind-plugin-allowlist
|
|
11
|
+
*/
|
|
12
|
+
export const TAILWIND_PLUGIN_ALLOWLIST = new Set([
|
|
13
|
+
// Bundled into the compiled binary (see src/build/binary-plugin-includes.ts).
|
|
14
|
+
// Must stay in sync with BINARY_TAILWIND_PLUGIN_PACKAGES — an invariant
|
|
15
|
+
// enforced by tailwind-plugin-allowlist.test.ts.
|
|
16
|
+
"@tailwindcss/typography",
|
|
17
|
+
"@tailwindcss/forms",
|
|
18
|
+
"tailwindcss-animate",
|
|
19
|
+
"tailwind-scrollbar-hide",
|
|
20
|
+
"daisyui",
|
|
21
|
+
// Allowlisted but NOT bundled: loaded from esm.sh on first use. Adding an
|
|
22
|
+
// entry here is arbitrary-code-exec surface; review each one explicitly.
|
|
23
|
+
"@tailwindcss/aspect-ratio",
|
|
24
|
+
"@tailwindcss/container-queries",
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* Matches npm package specifiers, optionally scoped and optionally suffixed
|
|
28
|
+
* with an `@version` range. Deliberately restrictive: ASCII only, no path
|
|
29
|
+
* separators, no whitespace, no control characters.
|
|
30
|
+
*/
|
|
31
|
+
export const PACKAGE_SPEC_RE = /^(?:@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*(?:@[\w.+-]+)?$/i;
|
|
32
|
+
/**
|
|
33
|
+
* Return the bare package name (without any `@version` suffix) for a spec.
|
|
34
|
+
*
|
|
35
|
+
* Examples:
|
|
36
|
+
* bareName("pkg") -> "pkg"
|
|
37
|
+
* bareName("pkg@1.0.0") -> "pkg"
|
|
38
|
+
* bareName("@scope/pkg") -> "@scope/pkg"
|
|
39
|
+
* bareName("@scope/pkg@1.0") -> "@scope/pkg"
|
|
40
|
+
*/
|
|
41
|
+
export function bareName(spec) {
|
|
42
|
+
if (spec.startsWith("@")) {
|
|
43
|
+
const idx = spec.indexOf("@", 1);
|
|
44
|
+
return idx === -1 ? spec : spec.slice(0, idx);
|
|
45
|
+
}
|
|
46
|
+
const idx = spec.indexOf("@");
|
|
47
|
+
return idx === -1 ? spec : spec.slice(0, idx);
|
|
48
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type TransformCapacityErrorMode = "plain" | "build";
|
|
2
|
+
export type ImportErrorClassification = {
|
|
3
|
+
type: "http-bundle-missing";
|
|
4
|
+
hash: string;
|
|
5
|
+
message: string;
|
|
6
|
+
} | {
|
|
7
|
+
type: "module-not-found";
|
|
8
|
+
message: string;
|
|
9
|
+
} | {
|
|
10
|
+
type: "unknown";
|
|
11
|
+
message: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function classifyImportError(importError: unknown): ImportErrorClassification;
|
|
14
|
+
export declare function createTransformCapacityError(mode: TransformCapacityErrorMode, message: string, filePath: string): Error;
|
|
15
|
+
//# sourceMappingURL=loader-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader-helpers.d.ts","sourceRoot":"","sources":["../../../../../src/src/modules/react-loader/ssr-module-loader/loader-helpers.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,0BAA0B,GAAG,OAAO,GAAG,OAAO,CAAC;AAE3D,MAAM,MAAM,yBAAyB,GACjC;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,OAAO,GAAG,yBAAyB,CAUnF;AAED,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,0BAA0B,EAChC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,KAAK,CASP"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createError, toError } from "../../../errors/veryfront-error.js";
|
|
2
|
+
const MISSING_HTTP_BUNDLE_PATTERN = /veryfront-http-bundle\/http-([a-f0-9]+)\.mjs/;
|
|
3
|
+
export function classifyImportError(importError) {
|
|
4
|
+
const message = importError instanceof Error ? importError.message : String(importError);
|
|
5
|
+
const bundleMatch = message.match(MISSING_HTTP_BUNDLE_PATTERN);
|
|
6
|
+
if (bundleMatch?.[1]) {
|
|
7
|
+
return { type: "http-bundle-missing", hash: bundleMatch[1], message };
|
|
8
|
+
}
|
|
9
|
+
if (message.includes("Cannot find module") || message.includes("Module not found")) {
|
|
10
|
+
return { type: "module-not-found", message };
|
|
11
|
+
}
|
|
12
|
+
return { type: "unknown", message };
|
|
13
|
+
}
|
|
14
|
+
export function createTransformCapacityError(mode, message, filePath) {
|
|
15
|
+
if (mode === "plain")
|
|
16
|
+
return new Error(message);
|
|
17
|
+
return toError(createError({
|
|
18
|
+
type: "build",
|
|
19
|
+
message,
|
|
20
|
+
context: { file: filePath, phase: "transform" },
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
@@ -19,8 +19,6 @@ export declare class SSRModuleLoader {
|
|
|
19
19
|
private circuitBreaker;
|
|
20
20
|
private depValidator;
|
|
21
21
|
constructor(options: SSRModuleLoaderOptions);
|
|
22
|
-
private classifyImportError;
|
|
23
|
-
private createTransformCapacityError;
|
|
24
22
|
private withTransformCapacity;
|
|
25
23
|
private importModuleFromCacheEntry;
|
|
26
24
|
loadRawModule(filePath: string, source: string): Promise<Record<string, unknown>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../../src/src/modules/react-loader/ssr-module-loader/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../../../src/src/modules/react-loader/ssr-module-loader/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAsCpC,OAAO,KAAK,EAAoB,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAkB3E;;;;;GAKG;AACH,qBAAa,eAAe;IAKd,OAAO,CAAC,OAAO;IAJ3B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,cAAc,CAA2B;IACjD,OAAO,CAAC,YAAY,CAAyB;gBAEzB,OAAO,EAAE,sBAAsB;YAWrC,qBAAqB;YAuCrB,0BAA0B;IAwHxC,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IA+C7B,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;YAK1C,2BAA2B;IAYzC,OAAO,CAAC,yBAAyB;YAiBnB,2BAA2B;CA+V1C"}
|
|
@@ -16,6 +16,7 @@ import { rendererLogger } from "../../../utils/index.js";
|
|
|
16
16
|
import { withSpan } from "../../../observability/tracing/otlp-setup.js";
|
|
17
17
|
import { SpanNames } from "../../../observability/tracing/span-names.js";
|
|
18
18
|
import { extractComponent } from "../extract-component.js";
|
|
19
|
+
import { classifyImportError, createTransformCapacityError, } from "./loader-helpers.js";
|
|
19
20
|
import { getMaxConcurrentTransforms, IN_PROGRESS_WAIT_TIMEOUT_MS, MAX_TRANSFORM_DEPTH, TRANSFORM_ACQUIRE_TIMEOUT_MS, TRANSFORM_BATCH_SIZE, } from "./constants.js";
|
|
20
21
|
import { withTimeoutThrow } from "../../../rendering/utils/stream-utils.js";
|
|
21
22
|
import { getFromRedis, getTransformSemaphore, globalInProgress, globalModuleCache, isSSRDistributedCacheEnabled, releaseTransformSlot, setInRedis, tryAcquireTransformSlot, } from "./cache/index.js";
|
|
@@ -34,7 +35,6 @@ import { registerCSSImport } from "../css-import-collector.js";
|
|
|
34
35
|
import { injectNodePositions } from "../../../transforms/plugins/babel-node-positions.js";
|
|
35
36
|
import { ensureMdxModuleDependencies } from "../../../transforms/mdx/esm-module-loader/module-fetcher/dependency-recovery.js";
|
|
36
37
|
const logger = rendererLogger.component("ssr-module-loader");
|
|
37
|
-
const MISSING_HTTP_BUNDLE_PATTERN = /veryfront-http-bundle\/http-([a-f0-9]+)\.mjs/;
|
|
38
38
|
/**
|
|
39
39
|
* SSR Module Loader with Redis Support.
|
|
40
40
|
*
|
|
@@ -51,39 +51,19 @@ export class SSRModuleLoader {
|
|
|
51
51
|
this.cache = new SSRCacheManager(options);
|
|
52
52
|
this.depValidator = new SSRDependencyValidator((filePath) => this.cache.getCacheKey(filePath), (filePath, source, depth) => this.transformWithDependencies(filePath, source, depth), (crossImport) => this.transformCrossProjectImport(crossImport), options.adapter, options.projectDir);
|
|
53
53
|
}
|
|
54
|
-
classifyImportError(importError) {
|
|
55
|
-
const message = importError instanceof Error ? importError.message : String(importError);
|
|
56
|
-
const bundleMatch = message.match(MISSING_HTTP_BUNDLE_PATTERN);
|
|
57
|
-
if (bundleMatch?.[1]) {
|
|
58
|
-
return { type: "http-bundle-missing", hash: bundleMatch[1], message };
|
|
59
|
-
}
|
|
60
|
-
if (message.includes("Cannot find module") || message.includes("Module not found")) {
|
|
61
|
-
return { type: "module-not-found", message };
|
|
62
|
-
}
|
|
63
|
-
return { type: "unknown", message };
|
|
64
|
-
}
|
|
65
|
-
createTransformCapacityError(mode, message, filePath) {
|
|
66
|
-
if (mode === "plain")
|
|
67
|
-
return new Error(message);
|
|
68
|
-
return toError(createError({
|
|
69
|
-
type: "build",
|
|
70
|
-
message,
|
|
71
|
-
context: { file: filePath, phase: "transform" },
|
|
72
|
-
}));
|
|
73
|
-
}
|
|
74
54
|
async withTransformCapacity(filePath, mode, operation) {
|
|
75
55
|
const useSemaphore = getMaxConcurrentTransforms() > 0;
|
|
76
56
|
const projectId = this.options.projectId;
|
|
77
57
|
const semaphore = useSemaphore ? getTransformSemaphore() : undefined;
|
|
78
58
|
let semaphoreAcquired = false;
|
|
79
59
|
if (!await tryAcquireTransformSlot(projectId, TRANSFORM_ACQUIRE_TIMEOUT_MS)) {
|
|
80
|
-
throw
|
|
60
|
+
throw createTransformCapacityError(mode, `Project ${projectId} at transform capacity. Consider reducing page complexity or request rate.`, filePath);
|
|
81
61
|
}
|
|
82
62
|
try {
|
|
83
63
|
if (semaphore) {
|
|
84
64
|
semaphoreAcquired = await semaphore.tryAcquire(TRANSFORM_ACQUIRE_TIMEOUT_MS);
|
|
85
65
|
if (!semaphoreAcquired) {
|
|
86
|
-
throw
|
|
66
|
+
throw createTransformCapacityError(mode, `Transform capacity exceeded (${semaphore.waiting} waiting). Service is overloaded.`, filePath);
|
|
87
67
|
}
|
|
88
68
|
}
|
|
89
69
|
return await operation();
|
|
@@ -115,7 +95,7 @@ export class SSRModuleLoader {
|
|
|
115
95
|
return (await withSpan(SpanNames.SSR_DYNAMIC_IMPORT, () => import(`file://${cacheEntry.tempPath}?v=${cacheEntry.contentHash}`), { "ssr.file": fileName }));
|
|
116
96
|
}
|
|
117
97
|
catch (importError) {
|
|
118
|
-
const classifiedError =
|
|
98
|
+
const classifiedError = classifyImportError(importError);
|
|
119
99
|
if (classifiedError.type === "http-bundle-missing") {
|
|
120
100
|
const hash = classifiedError.hash;
|
|
121
101
|
const cacheDir = getHttpBundleCacheDir();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { VeryfrontAPIConfig } from "../../veryfront-api-client/types.js";
|
|
2
|
+
import type { FileCacheOptions } from "../cache/types.js";
|
|
3
|
+
import type { ContentSource, FSAdapterConfig } from "./types.js";
|
|
4
|
+
export declare const DEFAULT_MAX_RETRIES = 3;
|
|
5
|
+
export declare const DEFAULT_INITIAL_RETRY_DELAY_MS = 1000;
|
|
6
|
+
export declare const DEFAULT_MAX_RETRY_DELAY_MS = 10000;
|
|
7
|
+
export declare const DEFAULT_CACHE_TTL_MS = 60000;
|
|
8
|
+
export declare const DEFAULT_CACHE_MAX_ENTRIES = 1000;
|
|
9
|
+
export declare const DEFAULT_CACHE_MAX_MEMORY_BYTES: number;
|
|
10
|
+
type VeryfrontConfigOverrides = NonNullable<FSAdapterConfig["veryfront"]>;
|
|
11
|
+
type RetryOverrides = VeryfrontConfigOverrides["retry"];
|
|
12
|
+
type CacheOverrides = VeryfrontConfigOverrides["cache"];
|
|
13
|
+
export declare function buildRetryConfig(retry?: RetryOverrides): NonNullable<VeryfrontAPIConfig["retry"]>;
|
|
14
|
+
export declare function buildFileCacheOptions(cache?: CacheOverrides): FileCacheOptions;
|
|
15
|
+
export declare function shouldBackgroundPregenerateStyles(contentContext: {
|
|
16
|
+
sourceType: ContentSource["type"];
|
|
17
|
+
} | null): boolean;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=adapter-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-helpers.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/adapter-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEjE,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,8BAA8B,OAAQ,CAAC;AACpD,eAAO,MAAM,0BAA0B,QAAS,CAAC;AACjD,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAC3C,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAC/C,eAAO,MAAM,8BAA8B,QAAoB,CAAC;AAEhE,KAAK,wBAAwB,GAAG,WAAW,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;AAC1E,KAAK,cAAc,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;AACxD,KAAK,cAAc,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAExD,wBAAgB,gBAAgB,CAC9B,KAAK,CAAC,EAAE,cAAc,GACrB,WAAW,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAO1C;AAED,wBAAgB,qBAAqB,CACnC,KAAK,CAAC,EAAE,cAAc,GACrB,gBAAgB,CAQlB;AAED,wBAAgB,iCAAiC,CAC/C,cAAc,EAAE;IAAE,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,GAC3D,OAAO,CAET"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const DEFAULT_MAX_RETRIES = 3;
|
|
2
|
+
export const DEFAULT_INITIAL_RETRY_DELAY_MS = 1_000;
|
|
3
|
+
export const DEFAULT_MAX_RETRY_DELAY_MS = 10_000;
|
|
4
|
+
export const DEFAULT_CACHE_TTL_MS = 60_000;
|
|
5
|
+
export const DEFAULT_CACHE_MAX_ENTRIES = 1_000;
|
|
6
|
+
export const DEFAULT_CACHE_MAX_MEMORY_BYTES = 100 * 1024 * 1024;
|
|
7
|
+
export function buildRetryConfig(retry) {
|
|
8
|
+
return {
|
|
9
|
+
maxRetries: DEFAULT_MAX_RETRIES,
|
|
10
|
+
initialDelay: DEFAULT_INITIAL_RETRY_DELAY_MS,
|
|
11
|
+
maxDelay: DEFAULT_MAX_RETRY_DELAY_MS,
|
|
12
|
+
...retry,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export function buildFileCacheOptions(cache) {
|
|
16
|
+
return {
|
|
17
|
+
enabled: true,
|
|
18
|
+
ttl: DEFAULT_CACHE_TTL_MS,
|
|
19
|
+
maxSize: DEFAULT_CACHE_MAX_ENTRIES,
|
|
20
|
+
maxMemory: DEFAULT_CACHE_MAX_MEMORY_BYTES,
|
|
21
|
+
...cache,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function shouldBackgroundPregenerateStyles(contentContext) {
|
|
25
|
+
return contentContext?.sourceType !== "branch";
|
|
26
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/adapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EAEV,cAAc,EACd,SAAS,EACT,eAAe,EAEf,sBAAsB,EACvB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../../../../src/src/platform/adapters/fs/veryfront/adapter.ts"],"names":[],"mappings":"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"}
|