@gaganref/confect-cli 0.0.0-stage → 10.3.1-fork.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/CHANGELOG.md +1824 -0
  2. package/LICENSE +7 -0
  3. package/README.md +16 -2
  4. package/bin/confect.mjs +26 -0
  5. package/dist/Ansi.mjs +18 -0
  6. package/dist/Ansi.mjs.map +1 -0
  7. package/dist/BuildError.mjs +30 -0
  8. package/dist/BuildError.mjs.map +1 -0
  9. package/dist/Bundler.mjs +426 -0
  10. package/dist/Bundler.mjs.map +1 -0
  11. package/dist/CodeBlockWriter.mjs +55 -0
  12. package/dist/CodeBlockWriter.mjs.map +1 -0
  13. package/dist/CodegenError.mjs +194 -0
  14. package/dist/CodegenError.mjs.map +1 -0
  15. package/dist/ConfectDirectory.mjs +35 -0
  16. package/dist/ConfectDirectory.mjs.map +1 -0
  17. package/dist/ConvexConfig.mjs +198 -0
  18. package/dist/ConvexConfig.mjs.map +1 -0
  19. package/dist/ConvexDirectory.mjs +54 -0
  20. package/dist/ConvexDirectory.mjs.map +1 -0
  21. package/dist/Declaration.mjs +258 -0
  22. package/dist/Declaration.mjs.map +1 -0
  23. package/dist/DirectoryOptions.mjs +42 -0
  24. package/dist/DirectoryOptions.mjs.map +1 -0
  25. package/dist/DocName.mjs +25 -0
  26. package/dist/DocName.mjs.map +1 -0
  27. package/dist/EntryPoint.mjs +111 -0
  28. package/dist/EntryPoint.mjs.map +1 -0
  29. package/dist/Evaluation.mjs +117 -0
  30. package/dist/Evaluation.mjs.map +1 -0
  31. package/dist/EvaluationWorker.mjs +46 -0
  32. package/dist/EvaluationWorker.mjs.map +1 -0
  33. package/dist/FunctionModule.mjs +137 -0
  34. package/dist/FunctionModule.mjs.map +1 -0
  35. package/dist/FunctionPath.mjs +18 -0
  36. package/dist/FunctionPath.mjs.map +1 -0
  37. package/dist/FunctionPaths.mjs +45 -0
  38. package/dist/FunctionPaths.mjs.map +1 -0
  39. package/dist/GenerationSnapshot.mjs +183 -0
  40. package/dist/GenerationSnapshot.mjs.map +1 -0
  41. package/dist/GroupPath.mjs +51 -0
  42. package/dist/GroupPath.mjs.map +1 -0
  43. package/dist/GroupPaths.mjs +8 -0
  44. package/dist/GroupPaths.mjs.map +1 -0
  45. package/dist/ImplModulePath.mjs +8 -0
  46. package/dist/ImplModulePath.mjs.map +1 -0
  47. package/dist/LeafModule.mjs +285 -0
  48. package/dist/LeafModule.mjs.map +1 -0
  49. package/dist/ProjectRoot.mjs +38 -0
  50. package/dist/ProjectRoot.mjs.map +1 -0
  51. package/dist/RelativeModulePath.mjs +13 -0
  52. package/dist/RelativeModulePath.mjs.map +1 -0
  53. package/dist/Remove.mjs +24 -0
  54. package/dist/Remove.mjs.map +1 -0
  55. package/dist/RestoreWatcher.mjs +31 -0
  56. package/dist/RestoreWatcher.mjs.map +1 -0
  57. package/dist/Rollback.mjs +50 -0
  58. package/dist/Rollback.mjs.map +1 -0
  59. package/dist/SnapshotError.mjs +21 -0
  60. package/dist/SnapshotError.mjs.map +1 -0
  61. package/dist/SpecAssemblyNode.mjs +91 -0
  62. package/dist/SpecAssemblyNode.mjs.map +1 -0
  63. package/dist/SpecModulePath.mjs +10 -0
  64. package/dist/SpecModulePath.mjs.map +1 -0
  65. package/dist/SyncState.mjs +122 -0
  66. package/dist/SyncState.mjs.map +1 -0
  67. package/dist/TableModule.mjs +97 -0
  68. package/dist/TableModule.mjs.map +1 -0
  69. package/dist/TableModulePath.mjs +8 -0
  70. package/dist/TableModulePath.mjs.map +1 -0
  71. package/dist/WatchBuild.mjs +190 -0
  72. package/dist/WatchBuild.mjs.map +1 -0
  73. package/dist/WatchGraph.mjs +35 -0
  74. package/dist/WatchGraph.mjs.map +1 -0
  75. package/dist/WatchTopology.mjs +55 -0
  76. package/dist/WatchTopology.mjs.map +1 -0
  77. package/dist/Watcher.mjs +377 -0
  78. package/dist/Watcher.mjs.map +1 -0
  79. package/dist/cliApp.mjs +9 -0
  80. package/dist/cliApp.mjs.map +1 -0
  81. package/dist/confect/codegen.mjs +570 -0
  82. package/dist/confect/codegen.mjs.map +1 -0
  83. package/dist/confect/declaration.mjs +219 -0
  84. package/dist/confect/declaration.mjs.map +1 -0
  85. package/dist/confect/dev.mjs +182 -0
  86. package/dist/confect/dev.mjs.map +1 -0
  87. package/dist/confect.mjs +9 -0
  88. package/dist/confect.mjs.map +1 -0
  89. package/dist/index.mjs +19 -0
  90. package/dist/index.mjs.map +1 -0
  91. package/dist/log.mjs +107 -0
  92. package/dist/log.mjs.map +1 -0
  93. package/dist/package.mjs +6 -0
  94. package/dist/package.mjs.map +1 -0
  95. package/dist/templates.mjs +448 -0
  96. package/dist/templates.mjs.map +1 -0
  97. package/dist/utils.mjs +105 -0
  98. package/dist/utils.mjs.map +1 -0
  99. 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
- # Temporary Holding Version
1
+ # Confect 🧁
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
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)!
@@ -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"}
@@ -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.js\";\nimport { logCoalescedBuildWarnings } from \"./log.js\";\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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"}