@gaganref/confect-cli 0.0.0-stage → 10.3.1-fork.2
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/CHANGELOG.md +1824 -0
- package/LICENSE +7 -0
- package/README.md +16 -2
- package/bin/confect.mjs +26 -0
- package/dist/Ansi.mjs +18 -0
- package/dist/Ansi.mjs.map +1 -0
- package/dist/BuildError.mjs +30 -0
- package/dist/BuildError.mjs.map +1 -0
- package/dist/Bundler.mjs +426 -0
- package/dist/Bundler.mjs.map +1 -0
- package/dist/CodeBlockWriter.mjs +55 -0
- package/dist/CodeBlockWriter.mjs.map +1 -0
- package/dist/CodegenError.mjs +194 -0
- package/dist/CodegenError.mjs.map +1 -0
- package/dist/ConfectDirectory.mjs +35 -0
- package/dist/ConfectDirectory.mjs.map +1 -0
- package/dist/ConvexConfig.mjs +198 -0
- package/dist/ConvexConfig.mjs.map +1 -0
- package/dist/ConvexDirectory.mjs +54 -0
- package/dist/ConvexDirectory.mjs.map +1 -0
- package/dist/Declaration.mjs +258 -0
- package/dist/Declaration.mjs.map +1 -0
- package/dist/DirectoryOptions.mjs +42 -0
- package/dist/DirectoryOptions.mjs.map +1 -0
- package/dist/DocName.mjs +25 -0
- package/dist/DocName.mjs.map +1 -0
- package/dist/EntryPoint.mjs +111 -0
- package/dist/EntryPoint.mjs.map +1 -0
- package/dist/Evaluation.mjs +117 -0
- package/dist/Evaluation.mjs.map +1 -0
- package/dist/EvaluationWorker.mjs +46 -0
- package/dist/EvaluationWorker.mjs.map +1 -0
- package/dist/FunctionModule.mjs +137 -0
- package/dist/FunctionModule.mjs.map +1 -0
- package/dist/FunctionPath.mjs +18 -0
- package/dist/FunctionPath.mjs.map +1 -0
- package/dist/FunctionPaths.mjs +45 -0
- package/dist/FunctionPaths.mjs.map +1 -0
- package/dist/GenerationSnapshot.mjs +183 -0
- package/dist/GenerationSnapshot.mjs.map +1 -0
- package/dist/GroupPath.mjs +51 -0
- package/dist/GroupPath.mjs.map +1 -0
- package/dist/GroupPaths.mjs +8 -0
- package/dist/GroupPaths.mjs.map +1 -0
- package/dist/ImplModulePath.mjs +8 -0
- package/dist/ImplModulePath.mjs.map +1 -0
- package/dist/LeafModule.mjs +285 -0
- package/dist/LeafModule.mjs.map +1 -0
- package/dist/ProjectRoot.mjs +38 -0
- package/dist/ProjectRoot.mjs.map +1 -0
- package/dist/RelativeModulePath.mjs +13 -0
- package/dist/RelativeModulePath.mjs.map +1 -0
- package/dist/Remove.mjs +24 -0
- package/dist/Remove.mjs.map +1 -0
- package/dist/RestoreWatcher.mjs +31 -0
- package/dist/RestoreWatcher.mjs.map +1 -0
- package/dist/Rollback.mjs +50 -0
- package/dist/Rollback.mjs.map +1 -0
- package/dist/SnapshotError.mjs +21 -0
- package/dist/SnapshotError.mjs.map +1 -0
- package/dist/SpecAssemblyNode.mjs +91 -0
- package/dist/SpecAssemblyNode.mjs.map +1 -0
- package/dist/SpecModulePath.mjs +10 -0
- package/dist/SpecModulePath.mjs.map +1 -0
- package/dist/SyncState.mjs +122 -0
- package/dist/SyncState.mjs.map +1 -0
- package/dist/TableModule.mjs +97 -0
- package/dist/TableModule.mjs.map +1 -0
- package/dist/TableModulePath.mjs +8 -0
- package/dist/TableModulePath.mjs.map +1 -0
- package/dist/WatchBuild.mjs +190 -0
- package/dist/WatchBuild.mjs.map +1 -0
- package/dist/WatchGraph.mjs +35 -0
- package/dist/WatchGraph.mjs.map +1 -0
- package/dist/WatchTopology.mjs +55 -0
- package/dist/WatchTopology.mjs.map +1 -0
- package/dist/Watcher.mjs +378 -0
- package/dist/Watcher.mjs.map +1 -0
- package/dist/cliApp.mjs +9 -0
- package/dist/cliApp.mjs.map +1 -0
- package/dist/confect/codegen.mjs +548 -0
- package/dist/confect/codegen.mjs.map +1 -0
- package/dist/confect/declaration.mjs +218 -0
- package/dist/confect/declaration.mjs.map +1 -0
- package/dist/confect/dev.mjs +182 -0
- package/dist/confect/dev.mjs.map +1 -0
- package/dist/confect.mjs +9 -0
- package/dist/confect.mjs.map +1 -0
- package/dist/index.mjs +19 -0
- package/dist/index.mjs.map +1 -0
- package/dist/log.mjs +107 -0
- package/dist/log.mjs.map +1 -0
- package/dist/package.mjs +6 -0
- package/dist/package.mjs.map +1 -0
- package/dist/templates.mjs +448 -0
- package/dist/templates.mjs.map +1 -0
- package/dist/utils.mjs +105 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +51 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright 2024 RJ Dellecese
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Confect 🧁
|
|
2
2
|
|
|
3
|
-
This
|
|
3
|
+
This is a fork of [Confect](https://github.com/rjdellecese/confect). See [FORK.md](FORK.md) for builds, installation, and maintenance, and [CHANGES.md](CHANGES.md) for the fork additions.
|
|
4
|
+
|
|
5
|
+
## About Confect
|
|
6
|
+
|
|
7
|
+
Confect is a framework that deeply integrates Effect with Convex. It's more than just Effect bindings! Confect allows you to:
|
|
8
|
+
|
|
9
|
+
- Define your Convex database schema using Effect schemas.
|
|
10
|
+
- Write Convex function args and returns validators using Effect's schema library.
|
|
11
|
+
- Use Confect functions to automatically decode and encode your data according to your Effect schema definitions for end-to-end rich types, from client to function to database (and back).
|
|
12
|
+
- Add reusable, type-safe middleware to function groups or individual functions to provide Effect services and run logic around handlers.
|
|
13
|
+
- Declare typed errors on functions and middleware using Effect schemas, then handle the decoded errors at every call site.
|
|
14
|
+
- Use Effect's native HTTP API modules to define your HTTP API.
|
|
15
|
+
- Access Convex platform capabilities via Effect services.
|
|
16
|
+
|
|
17
|
+
Want to learn more? Read the [docs](https://confect.dev)!
|
package/bin/confect.mjs
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The `confect` bin points at this committed shim rather than at the tsdown
|
|
5
|
+
* output directly: pnpm only creates command shims for bin targets that exist
|
|
6
|
+
* at install time, and in a fresh checkout `pnpm install` runs before `dist/`
|
|
7
|
+
* is built, which would otherwise leave the bin missing until a re-install.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// oxlint-disable-next-line effecttsgo/node-builtin-import -- The pre-build shim cannot import the CLI's Effect runtime before dist exists.
|
|
13
|
+
import { existsSync } from "node:fs";
|
|
14
|
+
|
|
15
|
+
const entry = new URL("../dist/index.mjs", import.meta.url);
|
|
16
|
+
|
|
17
|
+
if (!existsSync(entry)) {
|
|
18
|
+
// oxlint-disable-next-line effecttsgo/global-console -- The pre-build shim cannot use the CLI's Effect logger before dist exists.
|
|
19
|
+
console.error(
|
|
20
|
+
"@confect/cli's build output is missing. Run `pnpm build` from the repo root " +
|
|
21
|
+
"(or `vp run --filter @confect/cli dev` for a watcher) first.",
|
|
22
|
+
);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
await import(entry.href);
|
package/dist/Ansi.mjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/Ansi.ts
|
|
2
|
+
/**
|
|
3
|
+
* Minimal ANSI styling helpers for CLI output (Effect's own ANSI helpers in
|
|
4
|
+
* `effect/cli` are internal). Styles are functions from text to a styled string
|
|
5
|
+
* with a trailing reset.
|
|
6
|
+
*/
|
|
7
|
+
const ESC = "\x1B[";
|
|
8
|
+
const RESET = `${ESC}0m`;
|
|
9
|
+
const style = (code) => (text) => `${ESC}${code}m${text}${RESET}`;
|
|
10
|
+
const red = style(31);
|
|
11
|
+
const green = style(32);
|
|
12
|
+
const yellow = style(33);
|
|
13
|
+
const magenta = style(35);
|
|
14
|
+
const blackBright = style(90);
|
|
15
|
+
//#endregion
|
|
16
|
+
export { blackBright, green, magenta, red, yellow };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=Ansi.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Ansi.mjs","names":[],"sources":["../src/Ansi.ts"],"sourcesContent":["/**\n * Minimal ANSI styling helpers for CLI output (Effect's own ANSI helpers in\n * `effect/cli` are internal). Styles are functions from text to a styled string\n * with a trailing reset.\n */\n\nconst ESC = \"\\x1B[\";\n\nconst RESET = `${ESC}0m`;\n\nconst style =\n (code: number) =>\n (text: string): string =>\n `${ESC}${code}m${text}${RESET}`;\n\nexport type Style = (text: string) => string;\n\nexport const red: Style = style(31);\n\nexport const green: Style = style(32);\n\nexport const yellow: Style = style(33);\n\nexport const magenta: Style = style(35);\n\nexport const blackBright: Style = style(90);\n"],"mappings":";;;;;;AAMA,MAAM,MAAM;AAEZ,MAAM,QAAQ,GAAG,IAAI;AAErB,MAAM,SACH,UACA,SACC,GAAG,MAAM,KAAK,GAAG,OAAO;AAI5B,MAAa,MAAa,MAAM,EAAE;AAElC,MAAa,QAAe,MAAM,EAAE;AAEpC,MAAa,SAAgB,MAAM,EAAE;AAErC,MAAa,UAAiB,MAAM,EAAE;AAEtC,MAAa,cAAqB,MAAM,EAAE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
//#region src/BuildError.ts
|
|
3
|
+
var BundleFailedError = class extends Schema.TaggedError()("BundleFailedError", {
|
|
4
|
+
file: Schema.String,
|
|
5
|
+
errors: Schema.Array(Schema.Unknown)
|
|
6
|
+
}) {};
|
|
7
|
+
var ImportFailedError = class extends Schema.TaggedError()("ImportFailedError", {
|
|
8
|
+
file: Schema.String,
|
|
9
|
+
cause: Schema.Unknown
|
|
10
|
+
}) {};
|
|
11
|
+
const BuildError = Schema.Union([BundleFailedError, ImportFailedError]);
|
|
12
|
+
const isBuildError = (error) => Schema.is(BuildError)(error);
|
|
13
|
+
/**
|
|
14
|
+
* Internal failure produced by the esbuild bundle/import pipeline. Always
|
|
15
|
+
* remapped to a {@link BuildError} (which carries enough context for the CLI to
|
|
16
|
+
* render it) before reaching a user-surface boundary.
|
|
17
|
+
*/
|
|
18
|
+
var BundlerError = class extends Schema.TaggedError()("BundlerError", { cause: Schema.Unknown }) {};
|
|
19
|
+
const isEsbuildBuildFailure = (error) => typeof error === "object" && error !== null && "errors" in error && globalThis.Array.isArray(error.errors);
|
|
20
|
+
const fromBundlerError = (file, error) => isEsbuildBuildFailure(error.cause) ? new BundleFailedError({
|
|
21
|
+
file,
|
|
22
|
+
errors: error.cause.errors
|
|
23
|
+
}) : new ImportFailedError({
|
|
24
|
+
file,
|
|
25
|
+
cause: error.cause
|
|
26
|
+
});
|
|
27
|
+
//#endregion
|
|
28
|
+
export { BuildError, BundleFailedError, BundlerError, ImportFailedError, fromBundlerError, isBuildError };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=BuildError.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildError.mjs","names":[],"sources":["../src/BuildError.ts"],"sourcesContent":["import * as Schema from \"effect/Schema\";\nimport type * as esbuild from \"esbuild\";\n\n// --- Variants ---\n\nexport class BundleFailedError extends Schema.TaggedError<BundleFailedError>()(\n \"BundleFailedError\",\n {\n file: Schema.String,\n errors: Schema.Array(Schema.Unknown),\n },\n) {}\n\nexport class ImportFailedError extends Schema.TaggedError<ImportFailedError>()(\n \"ImportFailedError\",\n {\n file: Schema.String,\n cause: Schema.Unknown,\n },\n) {}\n\nexport const BuildError = Schema.Union([BundleFailedError, ImportFailedError]);\nexport type BuildError = typeof BuildError.Type;\n\nexport const isBuildError = (error: unknown): error is BuildError =>\n Schema.is(BuildError)(error);\n\n// --- Bundler adapter ---\n\n/**\n * Internal failure produced by the esbuild bundle/import pipeline. Always\n * remapped to a {@link BuildError} (which carries enough context for the CLI to\n * render it) before reaching a user-surface boundary.\n */\nexport class BundlerError extends Schema.TaggedError<BundlerError>()(\n \"BundlerError\",\n {\n cause: Schema.Unknown,\n },\n) {}\n\nconst isEsbuildBuildFailure = (error: unknown): error is esbuild.BuildFailure =>\n typeof error === \"object\" &&\n error !== null &&\n \"errors\" in error &&\n globalThis.Array.isArray((error as esbuild.BuildFailure).errors);\n\nexport const fromBundlerError = (\n file: string,\n error: BundlerError,\n): BuildError =>\n isEsbuildBuildFailure(error.cause)\n ? new BundleFailedError({ file, errors: error.cause.errors })\n : new ImportFailedError({ file, cause: error.cause });\n"],"mappings":";;AAKA,IAAa,oBAAb,cAAuC,OAAO,YAA+B,CAAC,CAC5E,qBACA;CACE,MAAM,OAAO;CACb,QAAQ,OAAO,MAAM,OAAO,OAAO;AACrC,CACF,CAAC,CAAC,CAAC;AAEH,IAAa,oBAAb,cAAuC,OAAO,YAA+B,CAAC,CAC5E,qBACA;CACE,MAAM,OAAO;CACb,OAAO,OAAO;AAChB,CACF,CAAC,CAAC,CAAC;AAEH,MAAa,aAAa,OAAO,MAAM,CAAC,mBAAmB,iBAAiB,CAAC;AAG7E,MAAa,gBAAgB,UAC3B,OAAO,GAAG,UAAU,CAAC,CAAC,KAAK;;;;;;AAS7B,IAAa,eAAb,cAAkC,OAAO,YAA0B,CAAC,CAClE,gBACA,EACE,OAAO,OAAO,QAChB,CACF,CAAC,CAAC,CAAC;AAEH,MAAM,yBAAyB,UAC7B,OAAO,UAAU,YACjB,UAAU,QACV,YAAY,SACZ,WAAW,MAAM,QAAS,MAA+B,MAAM;AAEjE,MAAa,oBACX,MACA,UAEA,sBAAsB,MAAM,KAAK,IAC7B,IAAI,kBAAkB;CAAE;CAAM,QAAQ,MAAM,MAAM;AAAO,CAAC,IAC1D,IAAI,kBAAkB;CAAE;CAAM,OAAO,MAAM;AAAM,CAAC"}
|
package/dist/Bundler.mjs
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
import { BundlerError } from "./BuildError.mjs";
|
|
2
|
+
import { logCoalescedBuildWarnings } from "./log.mjs";
|
|
3
|
+
import { createRequire, isBuiltin } from "node:module";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
import * as FileSystem from "effect/FileSystem";
|
|
6
|
+
import * as Path from "effect/Path";
|
|
7
|
+
import * as Array from "effect/Array";
|
|
8
|
+
import { identity, pipe } from "effect/Function";
|
|
9
|
+
import * as HashSet from "effect/HashSet";
|
|
10
|
+
import * as Option from "effect/Option";
|
|
11
|
+
import * as Record from "effect/Record";
|
|
12
|
+
import { pathToFileURL } from "node:url";
|
|
13
|
+
import { parseArgs } from "node:util";
|
|
14
|
+
import { JS_EXT_RE, bundleRequire, dynamicImport, injectFileScopePlugin, loadTsConfig, tsconfigPathsToRegExp } from "bundle-require";
|
|
15
|
+
import { resolveModulePath } from "exsolve";
|
|
16
|
+
import * as Chunk from "effect/Chunk";
|
|
17
|
+
import * as Cause from "effect/Cause";
|
|
18
|
+
import * as Config from "effect/Config";
|
|
19
|
+
import * as Context from "effect/Context";
|
|
20
|
+
import * as HashMap from "effect/HashMap";
|
|
21
|
+
import * as Iterable from "effect/Iterable";
|
|
22
|
+
import * as Ref from "effect/Ref";
|
|
23
|
+
import * as Scope from "effect/Scope";
|
|
24
|
+
import * as Schema from "effect/Schema";
|
|
25
|
+
import * as String from "effect/String";
|
|
26
|
+
import * as esbuild from "esbuild";
|
|
27
|
+
//#region src/Bundler.ts
|
|
28
|
+
/**
|
|
29
|
+
* `bundle-require` sets `absWorkingDir: cwd` on the underlying esbuild build,
|
|
30
|
+
* so the metafile's input keys (and each input's `imports[].path`) are stored
|
|
31
|
+
* relative to that cwd. Callers reach for the metafile with absolute paths
|
|
32
|
+
* (e.g. {@link directlyImports}), so we normalize every key/import path to
|
|
33
|
+
* absolute up front. That way the lookup logic stays oblivious to whatever cwd
|
|
34
|
+
* was used during bundling.
|
|
35
|
+
*
|
|
36
|
+
* `original` (the specifier as written, before resolution) is filled in from
|
|
37
|
+
* `path` when esbuild omits it—esbuild only sets it when it differs from the
|
|
38
|
+
* resolved path, which is exactly the externalized-bare-specifier case that
|
|
39
|
+
* absolutizing `path` would otherwise mangle into `<cwd>/@confect/server`.
|
|
40
|
+
* {@link importersOfPackage} relies on `original` always being the raw
|
|
41
|
+
* specifier.
|
|
42
|
+
*/
|
|
43
|
+
const absolutizeMetafile = (path, metafile, cwd) => {
|
|
44
|
+
const absolutize = (p) => path.resolve(cwd, p);
|
|
45
|
+
return {
|
|
46
|
+
inputs: Record.mapEntries(metafile.inputs, (value, key) => [absolutize(key), {
|
|
47
|
+
...value,
|
|
48
|
+
imports: Array.map(value.imports, (i) => ({
|
|
49
|
+
...i,
|
|
50
|
+
path: absolutize(i.path),
|
|
51
|
+
original: i.original ?? i.path
|
|
52
|
+
}))
|
|
53
|
+
}]),
|
|
54
|
+
outputs: Record.mapEntries(metafile.outputs, (value, key) => [absolutize(key), {
|
|
55
|
+
...value,
|
|
56
|
+
...value.entryPoint ? { entryPoint: absolutize(value.entryPoint) } : {},
|
|
57
|
+
inputs: Record.mapKeys(value.inputs, absolutize),
|
|
58
|
+
imports: Array.map(value.imports, (imported) => imported.external ? imported : {
|
|
59
|
+
...imported,
|
|
60
|
+
path: absolutize(imported.path)
|
|
61
|
+
})
|
|
62
|
+
}])
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
const resolveEsm = Option.liftThrowable((specifier, importer) => resolveModulePath(specifier, {
|
|
66
|
+
from: importer,
|
|
67
|
+
conditions: ["node", "import"]
|
|
68
|
+
}));
|
|
69
|
+
const resolveCjs = Option.liftThrowable((specifier, importer) => createRequire(importer).resolve(specifier));
|
|
70
|
+
const resolveExternalEsm = Option.liftThrowable((specifier, importer, conditions) => resolveModulePath(specifier, {
|
|
71
|
+
from: importer,
|
|
72
|
+
conditions
|
|
73
|
+
}));
|
|
74
|
+
const resolveModule = (specifier, importer) => Option.orElse(resolveEsm(specifier, importer), () => resolveCjs(specifier, importer));
|
|
75
|
+
/**
|
|
76
|
+
* Bundles first-party workspace dependencies that `bundle-require` would
|
|
77
|
+
* otherwise externalize and hand to Node's native ESM resolver. Resolves each
|
|
78
|
+
* bare specifier and, following symlinks, bundles it when its real path lives
|
|
79
|
+
* outside `node_modules`—mirroring Vite's "linked dependencies are not
|
|
80
|
+
* externalized" heuristic. Registered ahead of `externalPlugin`, so deferring
|
|
81
|
+
* (returning `undefined`) leaves third-party externalization untouched.
|
|
82
|
+
* `skipPatterns` are the tsconfig `paths` regexes, which keep deferring to
|
|
83
|
+
* esbuild's own `paths` resolution.
|
|
84
|
+
*/
|
|
85
|
+
const bundleWorkspacePlugin = (path, fs, skipPatterns) => ({
|
|
86
|
+
name: "confect:bundle-workspace",
|
|
87
|
+
setup(build) {
|
|
88
|
+
build.onResolve({ filter: /^[^./]/ }, (args) => {
|
|
89
|
+
if (args.namespace !== "file" && args.namespace !== "") return void 0;
|
|
90
|
+
if (isBuiltin(args.path) || path.isAbsolute(args.path)) return void 0;
|
|
91
|
+
if (Array.some(skipPatterns, (pattern) => pattern.test(args.path))) return;
|
|
92
|
+
const importer = args.importer !== "" ? args.importer : path.join(args.resolveDir, "_");
|
|
93
|
+
return Option.match(resolveModule(args.path, importer), {
|
|
94
|
+
onNone: () => ({
|
|
95
|
+
path: args.path,
|
|
96
|
+
external: true,
|
|
97
|
+
warnings: [{ text: `Confect could not resolve workspace dependency "${args.path}" (imported from ${importer}) to bundle it; leaving it external.` }]
|
|
98
|
+
}),
|
|
99
|
+
onSome: (resolved) => Effect.runPromise(fs.realPath(resolved).pipe(Effect.orElseSucceed(() => resolved))).then((real) => pipe(real, String.split(path.sep), Array.contains("node_modules")) ? void 0 : { path: real })
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
const captureBuildResultPlugin = (ref) => ({
|
|
105
|
+
name: "confect:capture-build-result",
|
|
106
|
+
setup(build) {
|
|
107
|
+
build.onEnd((result) => {
|
|
108
|
+
Effect.runSync(Ref.set(ref, {
|
|
109
|
+
metafile: result.metafile,
|
|
110
|
+
warnings: result.warnings
|
|
111
|
+
}));
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
var BatchIncompatible = class extends Schema.TaggedError()("BatchIncompatible", {
|
|
116
|
+
reason: Schema.Literals([
|
|
117
|
+
"RuntimeConditions",
|
|
118
|
+
"UnsupportedEntries",
|
|
119
|
+
"MixedTsconfigs",
|
|
120
|
+
"UnattributedWarnings"
|
|
121
|
+
]),
|
|
122
|
+
message: Schema.String
|
|
123
|
+
}) {};
|
|
124
|
+
var Batch = class extends Context.Service()("@confect/cli/Bundler/Batch") {};
|
|
125
|
+
const batchResolutionPlugin = (path, fs, skipPatterns, conditions, externalImports) => ({
|
|
126
|
+
name: "confect:batch-resolution",
|
|
127
|
+
setup(build) {
|
|
128
|
+
const external = (args, resolved) => {
|
|
129
|
+
const importer = path.resolve(args.importer);
|
|
130
|
+
Effect.runSync(Ref.update(externalImports, HashMap.modifyAt(importer, (imports) => Option.some(Array.append(Option.getOrElse(imports, () => []), {
|
|
131
|
+
path: resolved,
|
|
132
|
+
original: args.path
|
|
133
|
+
})))));
|
|
134
|
+
return {
|
|
135
|
+
path: resolved,
|
|
136
|
+
external: true
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
build.onResolve({ filter: /.*/ }, (args) => {
|
|
140
|
+
if (args.kind === "entry-point") return void 0;
|
|
141
|
+
if (isBuiltin(args.path)) return {
|
|
142
|
+
path: args.path,
|
|
143
|
+
external: true
|
|
144
|
+
};
|
|
145
|
+
if (Array.some(skipPatterns, (pattern) => pattern.test(args.path))) return void 0;
|
|
146
|
+
if (/[\\/]node_modules[\\/]/.test(args.path)) return external(args, pathToFileURL(path.resolve(args.resolveDir, args.path)).href);
|
|
147
|
+
if (args.path.startsWith(".") || path.isAbsolute(args.path)) return void 0;
|
|
148
|
+
const resolved = resolveModule(args.path, args.importer);
|
|
149
|
+
if (Option.isNone(resolved)) return { errors: [{ text: `Could not resolve "${args.path}" from ${args.importer}` }] };
|
|
150
|
+
return Effect.runPromise(fs.realPath(resolved.value).pipe(Effect.orElseSucceed(() => resolved.value))).then((real) => {
|
|
151
|
+
if (!/[\\/]node_modules[\\/]/.test(real)) return { path: real };
|
|
152
|
+
if (args.kind === "require-call" || args.kind === "require-resolve") return external(args, createRequire(args.importer).resolve(args.path));
|
|
153
|
+
return external(args, Option.match(resolveExternalEsm(args.path, args.importer, conditions), {
|
|
154
|
+
onNone: () => args.path,
|
|
155
|
+
onSome: (resolvedPath) => pathToFileURL(resolvedPath).href
|
|
156
|
+
}));
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
const compileBatch = Effect.fn("Bundler.compileBatch")(function* (entryPoints) {
|
|
162
|
+
const path = yield* Path.Path;
|
|
163
|
+
const fs = yield* FileSystem.FileSystem;
|
|
164
|
+
const nodeOptions = yield* Config.String("NODE_OPTIONS").pipe(Config.withDefault(""));
|
|
165
|
+
if (/--conditions|-C|--(?:no-)?addons/.test(nodeOptions)) return yield* new BatchIncompatible({
|
|
166
|
+
reason: "RuntimeConditions",
|
|
167
|
+
message: "NODE_OPTIONS changes Node export conditions; individual builds preserve native resolution."
|
|
168
|
+
});
|
|
169
|
+
const runtimeOptions = yield* Effect.try({
|
|
170
|
+
try: () => parseArgs({
|
|
171
|
+
args: process.execArgv,
|
|
172
|
+
options: {
|
|
173
|
+
conditions: {
|
|
174
|
+
type: "string",
|
|
175
|
+
short: "C",
|
|
176
|
+
multiple: true
|
|
177
|
+
},
|
|
178
|
+
"no-addons": { type: "boolean" }
|
|
179
|
+
},
|
|
180
|
+
strict: false,
|
|
181
|
+
allowPositionals: true
|
|
182
|
+
}).values,
|
|
183
|
+
catch: (cause) => new BundlerError({ cause })
|
|
184
|
+
});
|
|
185
|
+
const conditions = [
|
|
186
|
+
"node",
|
|
187
|
+
"import",
|
|
188
|
+
...process.features.require_module ? ["module-sync"] : [],
|
|
189
|
+
...runtimeOptions["no-addons"] ? [] : ["node-addons"],
|
|
190
|
+
...(runtimeOptions.conditions ?? []).filter((condition) => typeof condition === "string")
|
|
191
|
+
];
|
|
192
|
+
const entries = Array.dedupe(entryPoints.map((entry) => path.resolve(entry)));
|
|
193
|
+
const first = entries[0];
|
|
194
|
+
if (first === void 0 || entries.some((entry) => !JS_EXT_RE.test(entry) || /[\\/]node_modules[\\/]/.test(entry))) return yield* new BatchIncompatible({
|
|
195
|
+
reason: "UnsupportedEntries",
|
|
196
|
+
message: "Shared builds require JavaScript or TypeScript entries outside node_modules."
|
|
197
|
+
});
|
|
198
|
+
const configs = yield* Effect.try({
|
|
199
|
+
try: () => entries.map((entry) => loadTsConfig(path.dirname(entry))),
|
|
200
|
+
catch: (cause) => new BundlerError({ cause })
|
|
201
|
+
});
|
|
202
|
+
const config = configs[0];
|
|
203
|
+
if (configs.some((other) => other?.path !== config?.path)) return yield* new BatchIncompatible({
|
|
204
|
+
reason: "MixedTsconfigs",
|
|
205
|
+
message: `Entries use different tsconfigs: ${Array.dedupe(configs.map((item) => item?.path ?? "(no tsconfig)")).join(", ")}`
|
|
206
|
+
});
|
|
207
|
+
const cwd = yield* fs.realPath(path.dirname(first));
|
|
208
|
+
const directory = yield* fs.makeTempDirectoryScoped({ prefix: "confect-batch-" }).pipe(Effect.flatMap((temporary) => fs.realPath(temporary)));
|
|
209
|
+
const artifacts = yield* Effect.forEach(entries, (entry, index) => Effect.map(fs.realPath(entry), (source) => [entry, {
|
|
210
|
+
source,
|
|
211
|
+
output: path.join(directory, `${index}.mjs`)
|
|
212
|
+
}]));
|
|
213
|
+
const externalImports = yield* Ref.make(HashMap.empty());
|
|
214
|
+
const result = yield* Effect.tryPromise({
|
|
215
|
+
try: () => esbuild.build({
|
|
216
|
+
entryPoints: entries.map((entry, index) => ({
|
|
217
|
+
in: entry,
|
|
218
|
+
out: `${index}`
|
|
219
|
+
})),
|
|
220
|
+
absWorkingDir: cwd,
|
|
221
|
+
outdir: directory,
|
|
222
|
+
outExtension: { ".js": ".mjs" },
|
|
223
|
+
chunkNames: "chunk-[hash]",
|
|
224
|
+
format: "esm",
|
|
225
|
+
platform: "node",
|
|
226
|
+
sourcemap: "inline",
|
|
227
|
+
bundle: true,
|
|
228
|
+
splitting: true,
|
|
229
|
+
metafile: true,
|
|
230
|
+
write: false,
|
|
231
|
+
logLevel: "silent",
|
|
232
|
+
...config?.path ? { tsconfig: config.path } : { tsconfigRaw: config?.data ?? {} },
|
|
233
|
+
plugins: [batchResolutionPlugin(path, fs, tsconfigPathsToRegExp(config?.data.compilerOptions?.paths ?? {}), conditions, externalImports), injectFileScopePlugin()]
|
|
234
|
+
}),
|
|
235
|
+
catch: (cause) => new BundlerError({ cause })
|
|
236
|
+
});
|
|
237
|
+
const inputPaths = HashSet.fromIterable(Object.keys(result.metafile.inputs).map((input) => path.resolve(cwd, input)));
|
|
238
|
+
const unattributedWarnings = result.warnings.filter((warning) => !warning.location || !HashSet.has(inputPaths, path.resolve(cwd, warning.location.file)));
|
|
239
|
+
if (unattributedWarnings.length > 0) return yield* new BatchIncompatible({
|
|
240
|
+
reason: "UnattributedWarnings",
|
|
241
|
+
message: `Cannot attribute build warnings to entries: ${unattributedWarnings.map((warning) => warning.text).join("; ")}`
|
|
242
|
+
});
|
|
243
|
+
yield* Effect.forEach(result.outputFiles, (output) => fs.writeFile(output.path, output.contents));
|
|
244
|
+
const capturedExternalImports = yield* Ref.get(externalImports);
|
|
245
|
+
const inputs = Object.fromEntries(Object.entries(result.metafile.inputs).map(([input, metadata]) => {
|
|
246
|
+
const originals = Option.getOrElse(HashMap.get(capturedExternalImports, path.resolve(cwd, input)), () => []);
|
|
247
|
+
return [input, {
|
|
248
|
+
...metadata,
|
|
249
|
+
imports: metadata.imports.flatMap((imported) => {
|
|
250
|
+
const matching = imported.external ? originals.filter((original) => original.path === imported.path) : [];
|
|
251
|
+
return matching.length === 0 ? [imported] : matching.map((original) => Object.assign({}, imported, { original: original.original }));
|
|
252
|
+
})
|
|
253
|
+
}];
|
|
254
|
+
}));
|
|
255
|
+
return {
|
|
256
|
+
entries: HashMap.fromIterable(artifacts),
|
|
257
|
+
metafile: absolutizeMetafile(path, {
|
|
258
|
+
...result.metafile,
|
|
259
|
+
inputs
|
|
260
|
+
}, cwd),
|
|
261
|
+
warnings: result.warnings,
|
|
262
|
+
cwd
|
|
263
|
+
};
|
|
264
|
+
});
|
|
265
|
+
/**
|
|
266
|
+
* Lazily shares one compilation across ordinary bundle calls in this effect.
|
|
267
|
+
* Different tsconfigs and failed compilations fall back to individual builds.
|
|
268
|
+
* Runtime conditions supplied through NODE_OPTIONS also use individual builds.
|
|
269
|
+
* Imports still run at each caller, and temporary chunks live until the effect
|
|
270
|
+
* finishes. The disposable evaluator, not this scope, owns Node's import
|
|
271
|
+
* cache.
|
|
272
|
+
*/
|
|
273
|
+
const withBatch = (entryPoints, effect) => Effect.scopedWith((scope) => Effect.gen(function* () {
|
|
274
|
+
const current = yield* Effect.serviceOption(Batch);
|
|
275
|
+
if (Option.isSome(current) && entryPoints.every((entry) => current.value.entryPoints.includes(entry))) return yield* effect;
|
|
276
|
+
const compilation = yield* Effect.cached(compileBatch(entryPoints).pipe(Effect.provideService(Scope.Scope, scope), Effect.asSome, Effect.catchTag("BatchIncompatible", (error) => Effect.logDebug("Shared build skipped; falling back to individual builds.", {
|
|
277
|
+
entryPoints,
|
|
278
|
+
reason: error.reason,
|
|
279
|
+
detail: error.message
|
|
280
|
+
}).pipe(Effect.as(Option.none()))), Effect.catch((error) => Effect.logDebug("Shared build failed; falling back to individual builds.", {
|
|
281
|
+
entryPoints,
|
|
282
|
+
reason: "CompileFailure"
|
|
283
|
+
}, Cause.fail(error)).pipe(Effect.as(Option.none())))));
|
|
284
|
+
return yield* Effect.provideService(effect, Batch, {
|
|
285
|
+
entryPoints,
|
|
286
|
+
compilation
|
|
287
|
+
});
|
|
288
|
+
}));
|
|
289
|
+
const reachableMetafileEntries = (entries, root, resolveImport) => Object.fromEntries(pipe(Iterable.unfold({
|
|
290
|
+
pending: Chunk.of(root),
|
|
291
|
+
visited: HashSet.empty()
|
|
292
|
+
}, ({ pending, visited }) => {
|
|
293
|
+
if (!Chunk.isNonEmpty(pending)) return Option.none();
|
|
294
|
+
const key = Chunk.headNonEmpty(pending);
|
|
295
|
+
const remaining = Chunk.tailNonEmpty(pending);
|
|
296
|
+
const metadata = entries[key];
|
|
297
|
+
if (HashSet.has(visited, key) || metadata === void 0) return Option.some([Option.none(), {
|
|
298
|
+
pending: remaining,
|
|
299
|
+
visited
|
|
300
|
+
}]);
|
|
301
|
+
return Option.some([Option.some([key, metadata]), {
|
|
302
|
+
pending: Array.reduce(metadata.imports, remaining, (queue, imported) => imported.external ? queue : Chunk.append(queue, resolveImport(imported.path))),
|
|
303
|
+
visited: HashSet.add(visited, key)
|
|
304
|
+
}]);
|
|
305
|
+
}), Iterable.getSomes));
|
|
306
|
+
const entryMetafile = (path, compilation, source, output) => ({
|
|
307
|
+
inputs: reachableMetafileEntries(compilation.metafile.inputs, source, identity),
|
|
308
|
+
outputs: reachableMetafileEntries(compilation.metafile.outputs, output, (key) => path.resolve(compilation.cwd, key))
|
|
309
|
+
});
|
|
310
|
+
/**
|
|
311
|
+
* Bundle a TypeScript entry point with esbuild via {@link bundleRequire} and
|
|
312
|
+
* import the result. `bundle-require` writes a temp `.mjs` next to the source,
|
|
313
|
+
* `import()`s it, and deletes it—so third-party `node_modules` externals
|
|
314
|
+
* resolve through the user's normal `node_modules` walk, while first-party
|
|
315
|
+
* workspace deps are bundled by {@link bundleWorkspacePlugin} and tsconfig
|
|
316
|
+
* `paths` aliases stay inside the bundle.
|
|
317
|
+
*
|
|
318
|
+
* `cwd` is set to the entry's directory so `bundle-require`'s `tsconfig.json`
|
|
319
|
+
* discovery (which walks upward from `cwd`) lands on the project's tsconfig
|
|
320
|
+
* regardless of where `confect codegen` was invoked from, and so esbuild
|
|
321
|
+
* resolves relative imports against the entry's location.
|
|
322
|
+
*
|
|
323
|
+
* The returned pair carries both the imported module and the esbuild metafile
|
|
324
|
+
* so callers can inspect the import graph (see {@link directlyImports}); the
|
|
325
|
+
* metafile is captured via a small `onEnd` plugin because `bundle-require`
|
|
326
|
+
* itself only exposes a flat `dependencies: string[]`.
|
|
327
|
+
*
|
|
328
|
+
* `options.plugins` are registered ahead of every other plugin—including
|
|
329
|
+
* `bundle-require`'s own `externalPlugin`—so a caller-supplied plugin can claim
|
|
330
|
+
* resolutions (e.g. `convex.config` imports) before the workspace and
|
|
331
|
+
* externalization heuristics see them.
|
|
332
|
+
*/
|
|
333
|
+
const bundle = Effect.fn("Bundler.bundle")(function* (entryPoint, options) {
|
|
334
|
+
const path = yield* Path.Path;
|
|
335
|
+
const fs = yield* FileSystem.FileSystem;
|
|
336
|
+
const batch = yield* Effect.serviceOption(Batch);
|
|
337
|
+
if (Option.isSome(batch) && !options?.plugins?.length && batch.value.entryPoints.some((entry) => path.resolve(entry) === path.resolve(entryPoint))) {
|
|
338
|
+
const compilation = yield* batch.value.compilation;
|
|
339
|
+
if (Option.isSome(compilation)) {
|
|
340
|
+
const entry = HashMap.get(compilation.value.entries, path.resolve(entryPoint));
|
|
341
|
+
if (Option.isSome(entry)) {
|
|
342
|
+
const metafile = entryMetafile(path, compilation.value, entry.value.source, entry.value.output);
|
|
343
|
+
return {
|
|
344
|
+
module: yield* Effect.tryPromise({
|
|
345
|
+
try: () => dynamicImport(pathToFileURL(entry.value.output).href, { format: "esm" }),
|
|
346
|
+
catch: (cause) => new BundlerError({ cause })
|
|
347
|
+
}).pipe(Effect.ensuring(logCoalescedBuildWarnings(compilation.value.warnings.filter((warning) => warning.location && metafile.inputs[path.resolve(compilation.value.cwd, warning.location.file)])))),
|
|
348
|
+
metafile
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
const buildResultRef = yield* Ref.make({
|
|
354
|
+
metafile: void 0,
|
|
355
|
+
warnings: []
|
|
356
|
+
});
|
|
357
|
+
const cwd = path.dirname(entryPoint);
|
|
358
|
+
const skipPatterns = yield* Effect.try({
|
|
359
|
+
try: () => tsconfigPathsToRegExp(loadTsConfig(cwd)?.data.compilerOptions?.paths ?? {}),
|
|
360
|
+
catch: (cause) => new BundlerError({ cause })
|
|
361
|
+
});
|
|
362
|
+
const result = yield* Effect.tryPromise({
|
|
363
|
+
try: () => bundleRequire({
|
|
364
|
+
filepath: entryPoint,
|
|
365
|
+
cwd,
|
|
366
|
+
format: "esm",
|
|
367
|
+
esbuildOptions: {
|
|
368
|
+
plugins: [
|
|
369
|
+
...options?.plugins ?? [],
|
|
370
|
+
bundleWorkspacePlugin(path, fs, skipPatterns),
|
|
371
|
+
captureBuildResultPlugin(buildResultRef)
|
|
372
|
+
],
|
|
373
|
+
logLevel: "silent"
|
|
374
|
+
}
|
|
375
|
+
}),
|
|
376
|
+
catch: (cause) => new BundlerError({ cause })
|
|
377
|
+
}).pipe(Effect.ensuring(Effect.andThen(Ref.get(buildResultRef), (captured) => logCoalescedBuildWarnings(captured.warnings))));
|
|
378
|
+
const { metafile } = yield* Ref.get(buildResultRef);
|
|
379
|
+
if (!metafile) return yield* Effect.die(/* @__PURE__ */ new Error("esbuild metafile missing"));
|
|
380
|
+
return {
|
|
381
|
+
module: result.mod,
|
|
382
|
+
metafile: absolutizeMetafile(path, metafile, cwd)
|
|
383
|
+
};
|
|
384
|
+
});
|
|
385
|
+
const findMetafileInputKey = Effect.fnUntraced(function* (metafile, absolutePath) {
|
|
386
|
+
const path = yield* Path.Path;
|
|
387
|
+
const resolved = path.resolve(absolutePath);
|
|
388
|
+
if (metafile.inputs[resolved] !== void 0) return Option.some(resolved);
|
|
389
|
+
const real = yield* (yield* FileSystem.FileSystem).realPath(resolved).pipe(Effect.orElseSucceed(() => resolved));
|
|
390
|
+
return Array.findFirst(Object.keys(metafile.inputs), (key) => path.resolve(key) === real);
|
|
391
|
+
});
|
|
392
|
+
/**
|
|
393
|
+
* Returns `true` when the module bundled from `sourceAbsolutePath` declares a
|
|
394
|
+
* direct import of `targetAbsolutePath` (according to the bundle's esbuild
|
|
395
|
+
* metafile). Returns `false` if either path is missing from the metafile.
|
|
396
|
+
*/
|
|
397
|
+
const directlyImports = Effect.fnUntraced(function* (bundled, sourceAbsolutePath, targetAbsolutePath) {
|
|
398
|
+
const path = yield* Path.Path;
|
|
399
|
+
const sourceKey = yield* findMetafileInputKey(bundled.metafile, sourceAbsolutePath);
|
|
400
|
+
const targetKey = yield* findMetafileInputKey(bundled.metafile, targetAbsolutePath);
|
|
401
|
+
return pipe(Option.all([sourceKey, targetKey]), Option.flatMap(([sourceKey_, targetKey_]) => Option.fromNullishOr(bundled.metafile.inputs[sourceKey_]).pipe(Option.map((sourceInput) => {
|
|
402
|
+
const targetResolved = path.resolve(targetKey_);
|
|
403
|
+
return sourceInput.imports.some((importedFile) => path.resolve(importedFile.path) === targetResolved);
|
|
404
|
+
}))), Option.getOrElse(() => false));
|
|
405
|
+
});
|
|
406
|
+
/**
|
|
407
|
+
* Returns the absolute paths of every module in the bundle that declares a
|
|
408
|
+
* direct import of `packageName` (the package itself or one of its subpaths)
|
|
409
|
+
* and satisfies `where`. Use `where` to restrict the search to the modules you
|
|
410
|
+
* care about—the bundle's inputs include every transitive dependency.
|
|
411
|
+
*
|
|
412
|
+
* Matching is on the specifier as written rather than the resolved path,
|
|
413
|
+
* because {@link bundleWorkspacePlugin} bundles first-party workspace
|
|
414
|
+
* dependencies (so `@confect/server` resolves to a path inside the monorepo)
|
|
415
|
+
* while a published install externalizes them (so it stays a bare specifier).
|
|
416
|
+
* esbuild erases `import type` before it produces the metafile, so type-only
|
|
417
|
+
* imports are not reported.
|
|
418
|
+
*/
|
|
419
|
+
const importersOfPackage = (bundled, packageName, where) => {
|
|
420
|
+
const subpathPrefix = `${packageName}/`;
|
|
421
|
+
return Object.entries(bundled.metafile.inputs).filter(([absolutePath, input]) => where(absolutePath) && input.imports.some((imported) => imported.original === packageName || imported.original?.startsWith(subpathPrefix) === true)).map(([absolutePath]) => absolutePath);
|
|
422
|
+
};
|
|
423
|
+
//#endregion
|
|
424
|
+
export { bundle, bundleWorkspacePlugin, directlyImports, importersOfPackage, resolveModule, withBatch };
|
|
425
|
+
|
|
426
|
+
//# sourceMappingURL=Bundler.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Bundler.mjs","names":[],"sources":["../src/Bundler.ts"],"sourcesContent":["import { createRequire, isBuiltin } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\nimport { parseArgs } from \"node:util\";\nimport {\n bundleRequire,\n dynamicImport,\n injectFileScopePlugin,\n JS_EXT_RE,\n loadTsConfig,\n tsconfigPathsToRegExp,\n} from \"bundle-require\";\nimport { resolveModulePath } from \"exsolve\";\nimport { identity, pipe } from \"effect/Function\";\nimport * as Array from \"effect/Array\";\nimport * as Chunk from \"effect/Chunk\";\nimport * as Cause from \"effect/Cause\";\nimport * as Config from \"effect/Config\";\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as HashMap from \"effect/HashMap\";\nimport * as HashSet from \"effect/HashSet\";\nimport * as Iterable from \"effect/Iterable\";\nimport * as Option from \"effect/Option\";\nimport * as Path from \"effect/Path\";\nimport * as Ref from \"effect/Ref\";\nimport * as Record from \"effect/Record\";\nimport * as Scope from \"effect/Scope\";\nimport * as Schema from \"effect/Schema\";\nimport * as String from \"effect/String\";\nimport * as esbuild from \"esbuild\";\nimport { BundlerError } from \"./BuildError\";\nimport { logCoalescedBuildWarnings } from \"./log\";\n\nexport interface Bundled {\n readonly module: any;\n readonly metafile: esbuild.Metafile;\n}\n\n/**\n * `bundle-require` sets `absWorkingDir: cwd` on the underlying esbuild build,\n * so the metafile's input keys (and each input's `imports[].path`) are stored\n * relative to that cwd. Callers reach for the metafile with absolute paths\n * (e.g. {@link directlyImports}), so we normalize every key/import path to\n * absolute up front. That way the lookup logic stays oblivious to whatever cwd\n * was used during bundling.\n *\n * `original` (the specifier as written, before resolution) is filled in from\n * `path` when esbuild omits it—esbuild only sets it when it differs from the\n * resolved path, which is exactly the externalized-bare-specifier case that\n * absolutizing `path` would otherwise mangle into `<cwd>/@confect/server`.\n * {@link importersOfPackage} relies on `original` always being the raw\n * specifier.\n */\nconst absolutizeMetafile = (\n path: Path.Path,\n metafile: esbuild.Metafile,\n cwd: string,\n): esbuild.Metafile => {\n const absolutize = (p: string) => path.resolve(cwd, p);\n const inputs = Record.mapEntries(metafile.inputs, (value, key) => [\n absolutize(key),\n {\n ...value,\n imports: Array.map(value.imports, (i) => ({\n ...i,\n path: absolutize(i.path),\n original: i.original ?? i.path,\n })),\n },\n ]);\n const outputs = Record.mapEntries(metafile.outputs, (value, key) => [\n absolutize(key),\n {\n ...value,\n ...(value.entryPoint ? { entryPoint: absolutize(value.entryPoint) } : {}),\n inputs: Record.mapKeys(value.inputs, absolutize),\n imports: Array.map(value.imports, (imported) =>\n imported.external\n ? imported\n : { ...imported, path: absolutize(imported.path) },\n ),\n },\n ]);\n return { inputs, outputs };\n};\n\nconst resolveEsm = Option.liftThrowable((specifier: string, importer: string) =>\n resolveModulePath(specifier, {\n from: importer,\n conditions: [\"node\", \"import\"],\n }),\n);\n\nconst resolveCjs = Option.liftThrowable((specifier: string, importer: string) =>\n createRequire(importer).resolve(specifier),\n);\n\nconst resolveExternalEsm = Option.liftThrowable(\n (specifier: string, importer: string, conditions: string[]) =>\n resolveModulePath(specifier, { from: importer, conditions }),\n);\n\nexport const resolveModule = (\n specifier: string,\n importer: string,\n): Option.Option<string> =>\n Option.orElse(resolveEsm(specifier, importer), () =>\n resolveCjs(specifier, importer),\n );\n\n/**\n * Bundles first-party workspace dependencies that `bundle-require` would\n * otherwise externalize and hand to Node's native ESM resolver. Resolves each\n * bare specifier and, following symlinks, bundles it when its real path lives\n * outside `node_modules`—mirroring Vite's \"linked dependencies are not\n * externalized\" heuristic. Registered ahead of `externalPlugin`, so deferring\n * (returning `undefined`) leaves third-party externalization untouched.\n * `skipPatterns` are the tsconfig `paths` regexes, which keep deferring to\n * esbuild's own `paths` resolution.\n */\nexport const bundleWorkspacePlugin = (\n path: Path.Path,\n fs: FileSystem.FileSystem,\n skipPatterns: ReadonlyArray<RegExp>,\n): esbuild.Plugin => ({\n name: \"confect:bundle-workspace\",\n setup(build) {\n build.onResolve({ filter: /^[^./]/ }, (args) => {\n if (args.namespace !== \"file\" && args.namespace !== \"\") return undefined;\n if (isBuiltin(args.path) || path.isAbsolute(args.path)) return undefined;\n if (Array.some(skipPatterns, (pattern) => pattern.test(args.path))) {\n return undefined;\n }\n\n const importer =\n args.importer !== \"\" ? args.importer : path.join(args.resolveDir, \"_\");\n\n return Option.match(resolveModule(args.path, importer), {\n onNone: () => ({\n path: args.path,\n external: true,\n warnings: [\n {\n text: `Confect could not resolve workspace dependency \"${args.path}\" (imported from ${importer}) to bundle it; leaving it external.`,\n },\n ],\n }),\n onSome: (resolved) =>\n Effect.runPromise(\n fs.realPath(resolved).pipe(Effect.orElseSucceed(() => resolved)),\n ).then((real) =>\n pipe(real, String.split(path.sep), Array.contains(\"node_modules\"))\n ? undefined\n : { path: real },\n ),\n });\n });\n },\n});\n\ninterface CapturedBuildResult {\n readonly metafile: esbuild.Metafile | undefined;\n readonly warnings: ReadonlyArray<esbuild.Message>;\n}\n\nconst captureBuildResultPlugin = (\n ref: Ref.Ref<CapturedBuildResult>,\n): esbuild.Plugin => ({\n name: \"confect:capture-build-result\",\n setup(build) {\n build.onEnd((result) => {\n Effect.runSync(\n Ref.set(ref, {\n metafile: result.metafile,\n warnings: result.warnings,\n }),\n );\n });\n },\n});\n\ninterface BatchCompilation {\n readonly entries: HashMap.HashMap<\n string,\n { readonly source: string; readonly output: string }\n >;\n readonly metafile: esbuild.Metafile;\n readonly warnings: ReadonlyArray<esbuild.Message>;\n readonly cwd: string;\n}\n\nclass BatchIncompatible extends Schema.TaggedError<BatchIncompatible>()(\n \"BatchIncompatible\",\n {\n reason: Schema.Literals([\n \"RuntimeConditions\",\n \"UnsupportedEntries\",\n \"MixedTsconfigs\",\n \"UnattributedWarnings\",\n ]),\n message: Schema.String,\n },\n) {}\n\nclass Batch extends Context.Service<\n Batch,\n {\n readonly entryPoints: ReadonlyArray<string>;\n readonly compilation: Effect.Effect<\n Option.Option<BatchCompilation>,\n never,\n Path.Path | FileSystem.FileSystem\n >;\n }\n>()(\"@confect/cli/Bundler/Batch\") {}\n\ninterface ExternalImport {\n readonly path: string;\n readonly original: string;\n}\n\nconst batchResolutionPlugin = (\n path: Path.Path,\n fs: FileSystem.FileSystem,\n skipPatterns: ReadonlyArray<RegExp>,\n conditions: string[],\n externalImports: Ref.Ref<\n HashMap.HashMap<string, ReadonlyArray<ExternalImport>>\n >,\n): esbuild.Plugin => ({\n name: \"confect:batch-resolution\",\n setup(build) {\n const external = (args: esbuild.OnResolveArgs, resolved: string) => {\n const importer = path.resolve(args.importer);\n Effect.runSync(\n Ref.update(\n externalImports,\n HashMap.modifyAt(importer, (imports) =>\n Option.some(\n Array.append(\n Option.getOrElse(imports, () => []),\n { path: resolved, original: args.path },\n ),\n ),\n ),\n ),\n );\n return { path: resolved, external: true };\n };\n build.onResolve({ filter: /.*/ }, (args) => {\n if (args.kind === \"entry-point\") return undefined;\n if (isBuiltin(args.path)) return { path: args.path, external: true };\n if (Array.some(skipPatterns, (pattern) => pattern.test(args.path)))\n return undefined;\n if (/[\\\\/]node_modules[\\\\/]/.test(args.path)) {\n return external(\n args,\n pathToFileURL(path.resolve(args.resolveDir, args.path)).href,\n );\n }\n if (args.path.startsWith(\".\") || path.isAbsolute(args.path))\n return undefined;\n\n const resolved = resolveModule(args.path, args.importer);\n if (Option.isNone(resolved)) {\n return {\n errors: [\n { text: `Could not resolve \"${args.path}\" from ${args.importer}` },\n ],\n };\n }\n return Effect.runPromise(\n fs\n .realPath(resolved.value)\n .pipe(Effect.orElseSucceed(() => resolved.value)),\n ).then((real) => {\n if (!/[\\\\/]node_modules[\\\\/]/.test(real)) return { path: real };\n if (args.kind === \"require-call\" || args.kind === \"require-resolve\") {\n return external(\n args,\n createRequire(args.importer).resolve(args.path),\n );\n }\n return external(\n args,\n Option.match(\n resolveExternalEsm(args.path, args.importer, conditions),\n {\n onNone: () => args.path,\n onSome: (resolvedPath) => pathToFileURL(resolvedPath).href,\n },\n ),\n );\n });\n });\n },\n});\n\nconst compileBatch = Effect.fn(\"Bundler.compileBatch\")(function* (\n entryPoints: ReadonlyArray<string>,\n) {\n const path = yield* Path.Path;\n const fs = yield* FileSystem.FileSystem;\n const nodeOptions = yield* Config.String(\"NODE_OPTIONS\").pipe(\n Config.withDefault(\"\"),\n );\n if (/--conditions|-C|--(?:no-)?addons/.test(nodeOptions))\n return yield* new BatchIncompatible({\n reason: \"RuntimeConditions\",\n message:\n \"NODE_OPTIONS changes Node export conditions; individual builds preserve native resolution.\",\n });\n const runtimeOptions = yield* Effect.try({\n try: () =>\n parseArgs({\n args: process.execArgv,\n options: {\n conditions: { type: \"string\", short: \"C\", multiple: true },\n \"no-addons\": { type: \"boolean\" },\n },\n strict: false,\n allowPositionals: true,\n }).values,\n catch: (cause) => new BundlerError({ cause }),\n });\n const conditions = [\n \"node\",\n \"import\",\n ...(process.features.require_module ? [\"module-sync\"] : []),\n ...(runtimeOptions[\"no-addons\"] ? [] : [\"node-addons\"]),\n ...(runtimeOptions.conditions ?? []).filter(\n (condition) => typeof condition === \"string\",\n ),\n ];\n const entries = Array.dedupe(entryPoints.map((entry) => path.resolve(entry)));\n const first = entries[0];\n if (\n first === undefined ||\n entries.some(\n (entry) => !JS_EXT_RE.test(entry) || /[\\\\/]node_modules[\\\\/]/.test(entry),\n )\n ) {\n return yield* new BatchIncompatible({\n reason: \"UnsupportedEntries\",\n message:\n \"Shared builds require JavaScript or TypeScript entries outside node_modules.\",\n });\n }\n const configs = yield* Effect.try({\n try: () => entries.map((entry) => loadTsConfig(path.dirname(entry))),\n catch: (cause) => new BundlerError({ cause }),\n });\n const config = configs[0];\n if (configs.some((other) => other?.path !== config?.path))\n return yield* new BatchIncompatible({\n reason: \"MixedTsconfigs\",\n message: `Entries use different tsconfigs: ${Array.dedupe(configs.map((item) => item?.path ?? \"(no tsconfig)\")).join(\", \")}`,\n });\n\n const cwd = yield* fs.realPath(path.dirname(first));\n const directory = yield* fs\n .makeTempDirectoryScoped({ prefix: \"confect-batch-\" })\n .pipe(Effect.flatMap((temporary) => fs.realPath(temporary)));\n const artifacts = yield* Effect.forEach(entries, (entry, index) =>\n Effect.map(\n fs.realPath(entry),\n (source) =>\n [\n entry,\n { source, output: path.join(directory, `${index}.mjs`) },\n ] as const,\n ),\n );\n const externalImports = yield* Ref.make(\n HashMap.empty<string, ReadonlyArray<ExternalImport>>(),\n );\n const result = yield* Effect.tryPromise({\n try: () =>\n esbuild.build({\n entryPoints: entries.map((entry, index) => ({\n in: entry,\n out: `${index}`,\n })),\n absWorkingDir: cwd,\n outdir: directory,\n outExtension: { \".js\": \".mjs\" },\n chunkNames: \"chunk-[hash]\",\n format: \"esm\",\n platform: \"node\",\n sourcemap: \"inline\",\n bundle: true,\n splitting: true,\n metafile: true,\n write: false,\n logLevel: \"silent\",\n ...(config?.path\n ? { tsconfig: config.path }\n : { tsconfigRaw: config?.data ?? {} }),\n plugins: [\n batchResolutionPlugin(\n path,\n fs,\n tsconfigPathsToRegExp(config?.data.compilerOptions?.paths ?? {}),\n conditions,\n externalImports,\n ),\n injectFileScopePlugin(),\n ],\n }),\n catch: (cause) => new BundlerError({ cause }),\n });\n const inputPaths = HashSet.fromIterable(\n Object.keys(result.metafile.inputs).map((input) =>\n path.resolve(cwd, input),\n ),\n );\n const unattributedWarnings = result.warnings.filter(\n (warning) =>\n !warning.location ||\n !HashSet.has(inputPaths, path.resolve(cwd, warning.location.file)),\n );\n if (unattributedWarnings.length > 0)\n return yield* new BatchIncompatible({\n reason: \"UnattributedWarnings\",\n message: `Cannot attribute build warnings to entries: ${unattributedWarnings.map((warning) => warning.text).join(\"; \")}`,\n });\n yield* Effect.forEach(result.outputFiles, (output) =>\n fs.writeFile(output.path, output.contents),\n );\n const capturedExternalImports = yield* Ref.get(externalImports);\n const inputs = Object.fromEntries(\n Object.entries(result.metafile.inputs).map(([input, metadata]) => {\n const originals = Option.getOrElse(\n HashMap.get(capturedExternalImports, path.resolve(cwd, input)),\n () => [],\n );\n return [\n input,\n {\n ...metadata,\n imports: metadata.imports.flatMap((imported) => {\n const matching = imported.external\n ? originals.filter((original) => original.path === imported.path)\n : [];\n return matching.length === 0\n ? [imported]\n : matching.map((original) =>\n Object.assign({}, imported, {\n original: original.original,\n }),\n );\n }),\n },\n ];\n }),\n );\n return {\n entries: HashMap.fromIterable(artifacts),\n metafile: absolutizeMetafile(path, { ...result.metafile, inputs }, cwd),\n warnings: result.warnings,\n cwd,\n } satisfies BatchCompilation;\n});\n\n/**\n * Lazily shares one compilation across ordinary bundle calls in this effect.\n * Different tsconfigs and failed compilations fall back to individual builds.\n * Runtime conditions supplied through NODE_OPTIONS also use individual builds.\n * Imports still run at each caller, and temporary chunks live until the effect\n * finishes. The disposable evaluator, not this scope, owns Node's import\n * cache.\n */\nexport const withBatch = <A, E, R>(\n entryPoints: ReadonlyArray<string>,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n Effect.scopedWith((scope) =>\n Effect.gen(function* () {\n const current = yield* Effect.serviceOption(Batch);\n if (\n Option.isSome(current) &&\n entryPoints.every((entry) => current.value.entryPoints.includes(entry))\n )\n return yield* effect;\n const compilation = yield* Effect.cached(\n compileBatch(entryPoints).pipe(\n Effect.provideService(Scope.Scope, scope),\n Effect.asSome,\n Effect.catchTag(\"BatchIncompatible\", (error) =>\n Effect.logDebug(\n \"Shared build skipped; falling back to individual builds.\",\n {\n entryPoints,\n reason: error.reason,\n detail: error.message,\n },\n ).pipe(Effect.as(Option.none<BatchCompilation>())),\n ),\n Effect.catch((error) =>\n Effect.logDebug(\n \"Shared build failed; falling back to individual builds.\",\n {\n entryPoints,\n reason: \"CompileFailure\",\n },\n Cause.fail(error),\n ).pipe(Effect.as(Option.none<BatchCompilation>())),\n ),\n ),\n );\n return yield* Effect.provideService(effect, Batch, {\n entryPoints,\n compilation,\n });\n }),\n );\n\ninterface MetafileTraversal {\n readonly pending: Chunk.Chunk<string>;\n readonly visited: HashSet.HashSet<string>;\n}\n\nconst reachableMetafileEntries = <\n Metadata extends {\n readonly imports: ReadonlyArray<{\n readonly path: string;\n readonly external?: boolean;\n }>;\n },\n>(\n entries: Readonly<Record<string, Metadata>>,\n root: string,\n resolveImport: (path: string) => string,\n): Record<string, Metadata> =>\n Object.fromEntries(\n pipe(\n Iterable.unfold<\n MetafileTraversal,\n Option.Option<readonly [string, Metadata]>\n >(\n { pending: Chunk.of(root), visited: HashSet.empty() },\n ({ pending, visited }) => {\n if (!Chunk.isNonEmpty(pending)) return Option.none();\n const key = Chunk.headNonEmpty(pending);\n const remaining = Chunk.tailNonEmpty(pending);\n const metadata = entries[key];\n if (HashSet.has(visited, key) || metadata === undefined)\n return Option.some([\n Option.none(),\n { pending: remaining, visited },\n ]);\n return Option.some([\n Option.some([key, metadata] as const),\n {\n pending: Array.reduce(\n metadata.imports,\n remaining,\n (queue, imported) =>\n imported.external\n ? queue\n : Chunk.append(queue, resolveImport(imported.path)),\n ),\n visited: HashSet.add(visited, key),\n },\n ]);\n },\n ),\n Iterable.getSomes,\n ),\n );\n\nconst entryMetafile = (\n path: Path.Path,\n compilation: BatchCompilation,\n source: string,\n output: string,\n): esbuild.Metafile => ({\n inputs: reachableMetafileEntries(\n compilation.metafile.inputs,\n source,\n identity,\n ),\n outputs: reachableMetafileEntries(\n compilation.metafile.outputs,\n output,\n (key) => path.resolve(compilation.cwd, key),\n ),\n});\n\n/**\n * Bundle a TypeScript entry point with esbuild via {@link bundleRequire} and\n * import the result. `bundle-require` writes a temp `.mjs` next to the source,\n * `import()`s it, and deletes it—so third-party `node_modules` externals\n * resolve through the user's normal `node_modules` walk, while first-party\n * workspace deps are bundled by {@link bundleWorkspacePlugin} and tsconfig\n * `paths` aliases stay inside the bundle.\n *\n * `cwd` is set to the entry's directory so `bundle-require`'s `tsconfig.json`\n * discovery (which walks upward from `cwd`) lands on the project's tsconfig\n * regardless of where `confect codegen` was invoked from, and so esbuild\n * resolves relative imports against the entry's location.\n *\n * The returned pair carries both the imported module and the esbuild metafile\n * so callers can inspect the import graph (see {@link directlyImports}); the\n * metafile is captured via a small `onEnd` plugin because `bundle-require`\n * itself only exposes a flat `dependencies: string[]`.\n *\n * `options.plugins` are registered ahead of every other plugin—including\n * `bundle-require`'s own `externalPlugin`—so a caller-supplied plugin can claim\n * resolutions (e.g. `convex.config` imports) before the workspace and\n * externalization heuristics see them.\n */\nexport const bundle = Effect.fn(\"Bundler.bundle\")(function* (\n entryPoint: string,\n options?: { readonly plugins?: ReadonlyArray<esbuild.Plugin> },\n): Effect.fn.Return<Bundled, BundlerError, Path.Path | FileSystem.FileSystem> {\n const path = yield* Path.Path;\n const fs = yield* FileSystem.FileSystem;\n\n const batch = yield* Effect.serviceOption(Batch);\n if (\n Option.isSome(batch) &&\n !options?.plugins?.length &&\n batch.value.entryPoints.some(\n (entry) => path.resolve(entry) === path.resolve(entryPoint),\n )\n ) {\n const compilation = yield* batch.value.compilation;\n if (Option.isSome(compilation)) {\n const entry = HashMap.get(\n compilation.value.entries,\n path.resolve(entryPoint),\n );\n if (Option.isSome(entry)) {\n const metafile = entryMetafile(\n path,\n compilation.value,\n entry.value.source,\n entry.value.output,\n );\n const module = yield* Effect.tryPromise({\n try: () =>\n dynamicImport(pathToFileURL(entry.value.output).href, {\n format: \"esm\",\n }),\n catch: (cause) => new BundlerError({ cause }),\n }).pipe(\n Effect.ensuring(\n logCoalescedBuildWarnings(\n compilation.value.warnings.filter(\n (warning) =>\n warning.location &&\n metafile.inputs[\n path.resolve(compilation.value.cwd, warning.location.file)\n ],\n ),\n ),\n ),\n );\n return { module, metafile };\n }\n }\n }\n\n const buildResultRef = yield* Ref.make<CapturedBuildResult>({\n metafile: undefined,\n warnings: [],\n });\n\n const cwd = path.dirname(entryPoint);\n const skipPatterns = yield* Effect.try({\n try: () =>\n tsconfigPathsToRegExp(\n loadTsConfig(cwd)?.data.compilerOptions?.paths ?? {},\n ),\n catch: (cause) => new BundlerError({ cause }),\n });\n const result = yield* Effect.tryPromise({\n try: () =>\n bundleRequire({\n filepath: entryPoint,\n cwd,\n format: \"esm\",\n esbuildOptions: {\n plugins: [\n ...(options?.plugins ?? []),\n bundleWorkspacePlugin(path, fs, skipPatterns),\n captureBuildResultPlugin(buildResultRef),\n ],\n logLevel: \"silent\",\n },\n }),\n catch: (cause) => new BundlerError({ cause }),\n }).pipe(\n Effect.ensuring(\n Effect.andThen(Ref.get(buildResultRef), (captured) =>\n logCoalescedBuildWarnings(captured.warnings),\n ),\n ),\n );\n\n const { metafile } = yield* Ref.get(buildResultRef);\n if (!metafile) {\n return yield* Effect.die(new Error(\"esbuild metafile missing\"));\n }\n\n return {\n module: result.mod,\n metafile: absolutizeMetafile(path, metafile, cwd),\n };\n});\n\nconst findMetafileInputKey = Effect.fnUntraced(function* (\n metafile: esbuild.Metafile,\n absolutePath: string,\n) {\n const path = yield* Path.Path;\n const resolved = path.resolve(absolutePath);\n if (metafile.inputs[resolved] !== undefined) return Option.some(resolved);\n const fs = yield* FileSystem.FileSystem;\n const real = yield* fs\n .realPath(resolved)\n .pipe(Effect.orElseSucceed(() => resolved));\n return Array.findFirst(\n Object.keys(metafile.inputs),\n (key) => path.resolve(key) === real,\n );\n});\n\n/**\n * Returns `true` when the module bundled from `sourceAbsolutePath` declares a\n * direct import of `targetAbsolutePath` (according to the bundle's esbuild\n * metafile). Returns `false` if either path is missing from the metafile.\n */\nexport const directlyImports = Effect.fnUntraced(function* (\n bundled: Bundled,\n sourceAbsolutePath: string,\n targetAbsolutePath: string,\n) {\n const path = yield* Path.Path;\n const sourceKey = yield* findMetafileInputKey(\n bundled.metafile,\n sourceAbsolutePath,\n );\n const targetKey = yield* findMetafileInputKey(\n bundled.metafile,\n targetAbsolutePath,\n );\n\n return pipe(\n Option.all([sourceKey, targetKey]),\n Option.flatMap(([sourceKey_, targetKey_]) =>\n Option.fromNullishOr(bundled.metafile.inputs[sourceKey_]).pipe(\n Option.map((sourceInput) => {\n const targetResolved = path.resolve(targetKey_);\n return sourceInput.imports.some(\n (importedFile) =>\n path.resolve(importedFile.path) === targetResolved,\n );\n }),\n ),\n ),\n Option.getOrElse(() => false),\n );\n});\n\n/**\n * Returns the absolute paths of every module in the bundle that declares a\n * direct import of `packageName` (the package itself or one of its subpaths)\n * and satisfies `where`. Use `where` to restrict the search to the modules you\n * care about—the bundle's inputs include every transitive dependency.\n *\n * Matching is on the specifier as written rather than the resolved path,\n * because {@link bundleWorkspacePlugin} bundles first-party workspace\n * dependencies (so `@confect/server` resolves to a path inside the monorepo)\n * while a published install externalizes them (so it stays a bare specifier).\n * esbuild erases `import type` before it produces the metafile, so type-only\n * imports are not reported.\n */\nexport const importersOfPackage = (\n bundled: Bundled,\n packageName: string,\n where: (absolutePath: string) => boolean,\n): ReadonlyArray<string> => {\n const subpathPrefix = `${packageName}/`;\n\n return Object.entries(bundled.metafile.inputs)\n .filter(\n ([absolutePath, input]) =>\n where(absolutePath) &&\n input.imports.some(\n (imported) =>\n imported.original === packageName ||\n imported.original?.startsWith(subpathPrefix) === true,\n ),\n )\n .map(([absolutePath]) => absolutePath);\n};\n"],"mappings":"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"}
|