@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.
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 +378 -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 +548 -0
  82. package/dist/confect/codegen.mjs.map +1 -0
  83. package/dist/confect/declaration.mjs +218 -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
@@ -0,0 +1,9 @@
1
+ import { codegen } from "./confect/codegen.mjs";
2
+ import { dev } from "./confect/dev.mjs";
3
+ import * as Command from "effect/cli/Command";
4
+ //#region src/confect.ts
5
+ const confect = Command.make("confect").pipe(Command.withDescription("Generate and sync Confect files with Convex"), Command.withSubcommands([codegen, dev]));
6
+ //#endregion
7
+ export { confect };
8
+
9
+ //# sourceMappingURL=confect.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confect.mjs","names":[],"sources":["../src/confect.ts"],"sourcesContent":["import * as Command from \"effect/cli/Command\";\nimport { codegen } from \"./confect/codegen\";\nimport { dev } from \"./confect/dev\";\n\nexport const confect = Command.make(\"confect\").pipe(\n Command.withDescription(\"Generate and sync Confect files with Convex\"),\n Command.withSubcommands([codegen, dev]),\n);\n"],"mappings":";;;;AAIA,MAAa,UAAU,QAAQ,KAAK,SAAS,CAAC,CAAC,KAC7C,QAAQ,gBAAgB,6CAA6C,GACrE,QAAQ,gBAAgB,CAAC,SAAS,GAAG,CAAC,CACxC"}
package/dist/index.mjs ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import { cliApp } from "./cliApp.mjs";
3
+ import * as NodeServices from "@effect/platform-node/NodeServices";
4
+ import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
5
+ import * as Effect from "effect/Effect";
6
+ //#region src/index.ts
7
+ const canReRaiseSignals = process.platform !== "win32";
8
+ let interrupted = false;
9
+ process.prependListener("SIGINT", () => {
10
+ interrupted = true;
11
+ });
12
+ process.on("exit", () => {
13
+ if (interrupted && canReRaiseSignals) process.kill(process.pid, "SIGINT");
14
+ });
15
+ cliApp.pipe(Effect.provide(NodeServices.layer), NodeRuntime.runMain);
16
+ //#endregion
17
+ export {};
18
+
19
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport * as NodeServices from \"@effect/platform-node/NodeServices\";\nimport * as NodeRuntime from \"@effect/platform-node/NodeRuntime\";\nimport * as Effect from \"effect/Effect\";\nimport { cliApp } from \"./cliApp\";\n\n// Track if we received SIGINT so we can re-raise it after cleanup.\n// This ensures proper terminal state restoration when run via e.g. `pnpm`.\nconst canReRaiseSignals = process.platform !== \"win32\";\n\nlet interrupted = false;\nprocess.prependListener(\"SIGINT\", () => {\n interrupted = true;\n});\nprocess.on(\"exit\", () => {\n if (interrupted && canReRaiseSignals) {\n process.kill(process.pid, \"SIGINT\");\n }\n});\n\ncliApp.pipe(Effect.provide(NodeServices.layer), NodeRuntime.runMain);\n"],"mappings":";;;;;;AASA,MAAM,oBAAoB,QAAQ,aAAa;AAE/C,IAAI,cAAc;AAClB,QAAQ,gBAAgB,gBAAgB;CACtC,cAAc;AAChB,CAAC;AACD,QAAQ,GAAG,cAAc;CACvB,IAAI,eAAe,mBACjB,QAAQ,KAAK,QAAQ,KAAK,QAAQ;AAEtC,CAAC;AAED,OAAO,KAAK,OAAO,QAAQ,aAAa,KAAK,GAAG,YAAY,OAAO"}
package/dist/log.mjs ADDED
@@ -0,0 +1,107 @@
1
+ import { blackBright, green, red, yellow } from "./Ansi.mjs";
2
+ import { toString } from "./GroupPath.mjs";
3
+ import { ProjectRoot } from "./ProjectRoot.mjs";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Path from "effect/Path";
6
+ import * as Array from "effect/Array";
7
+ import { pipe } from "effect/Function";
8
+ import * as Match from "effect/Match";
9
+ import * as Option from "effect/Option";
10
+ import * as String from "effect/String";
11
+ import * as esbuild from "esbuild";
12
+ import * as Console from "effect/Console";
13
+ import * as Predicate from "effect/Predicate";
14
+ //#region src/log.ts
15
+ /**
16
+ * Render a relative path with the directory portion dimmed (`Ansi.blackBright`)
17
+ * and the file leaf rendered in the default terminal color.
18
+ */
19
+ const formatPath = (relativePath) => {
20
+ const lastSep = Math.max(relativePath.lastIndexOf("/"), relativePath.lastIndexOf("\\"));
21
+ const dir = lastSep < 0 ? "" : relativePath.slice(0, lastSep + 1);
22
+ const leaf = lastSep < 0 ? relativePath : relativePath.slice(lastSep + 1);
23
+ return blackBright(dir) + leaf;
24
+ };
25
+ const logFile = (char, color) => Effect.fnUntraced(function* (fullPath) {
26
+ const prefix = (yield* ProjectRoot.get) + (yield* Path.Path).sep;
27
+ const suffix = pipe(fullPath, String.startsWith(prefix)) ? pipe(fullPath, String.slice(prefix.length)) : fullPath;
28
+ yield* Console.log(`${color(char)} ${blackBright(prefix)}${color(suffix)}`);
29
+ });
30
+ const logFileAdded = logFile("+", green);
31
+ const logFileRemoved = logFile("-", red);
32
+ const logFileModified = logFile("~", yellow);
33
+ const logFunction = (char, color) => (functionPath) => Console.log(` ${color(char)} ${blackBright(toString(functionPath.groupPath) + ".")}${color(functionPath.name)}`);
34
+ const logFunctionAdded = logFunction("+", green);
35
+ const logFunctionRemoved = logFunction("-", red);
36
+ const logStatus = (char, charColor) => (message) => Console.log(`${charColor(char)} ${message}`);
37
+ const logSuccess = logStatus("✔︎", green);
38
+ const logPending = logStatus("⭘", yellow);
39
+ const logWarn = logStatus("⚠", yellow);
40
+ const cross = red("✘");
41
+ const warningSign = yellow("⚠");
42
+ const gutter = (color) => color("│");
43
+ const errorGutter = gutter(red);
44
+ const withGutterBlock = (gutterChar) => (output) => pipe(String.split(output, "\n"), Array.map((line) => pipe(line, String.trim) === "" ? gutterChar : `${gutterChar} ${line}`), Array.join("\n"), (guttered) => `${gutterChar}\n${guttered}\n${gutterChar}`);
45
+ const withErrorGutterBlock = withGutterBlock(errorGutter);
46
+ const formatBuildMessage = (error, formattedMessage) => {
47
+ const lines = String.split(formattedMessage, "\n");
48
+ const redErrorText = red(error?.text ?? "");
49
+ const replaced = pipe(Array.findFirstIndex(lines, (l) => pipe(l, String.trim, String.isNonEmpty)), Option.flatMap((index) => Array.modify(lines, index, () => redErrorText)), Option.getOrElse(() => lines));
50
+ return pipe(replaced, Array.join("\n"));
51
+ };
52
+ /**
53
+ * Render a list of esbuild messages into a styled, gutter-prefixed block.
54
+ */
55
+ const formatEsbuildMessages = (errors, formattedMessages) => pipe(formattedMessages, Array.map((message, i) => formatBuildMessage(errors[i], message)), Array.join(""), String.trimEnd, withErrorGutterBlock);
56
+ const renderImportFailedError = (error) => {
57
+ const causeMessage = Predicate.isError(error.cause) ? error.cause.message : Predicate.isString(error.cause) ? error.cause : globalThis.String(error.cause);
58
+ const oneLineCause = pipe(String.split(causeMessage, "\n"), Array.findFirst((line) => pipe(line, String.trim, String.isNonEmpty)), Option.map(String.trim), Option.getOrElse(() => "unknown error"));
59
+ return `${cross} Failed to load bundled module ${formatPath(error.file)}: ${oneLineCause}; check the file's top-level imports and side effects.`;
60
+ };
61
+ /**
62
+ * Render a {@link BundleFailedError} as a multi-line, ANSI-styled string: a
63
+ * one-line `✘ <file>: build errors` header followed by the gutter-prefixed
64
+ * esbuild diagnostic block. Multi-line is appropriate here because a single
65
+ * `BundleFailedError` carries an array of distinct esbuild messages.
66
+ */
67
+ const renderBundleFailedError = (error) => {
68
+ const messages = error.errors;
69
+ const formatted = esbuild.formatMessagesSync(messages, {
70
+ kind: "error",
71
+ color: true,
72
+ terminalWidth: 80
73
+ });
74
+ return `${`${cross} ${formatPath(error.file)}: build errors`}\n${formatEsbuildMessages(messages, formatted)}`;
75
+ };
76
+ /**
77
+ * Render any {@link BuildError} into a styled, ready-to-print string.
78
+ * `ImportFailedError` collapses to a single line; `BundleFailedError` expands
79
+ * to a header plus one diagnostic block per esbuild message.
80
+ */
81
+ const renderBuildError = (error) => Match.value(error).pipe(Match.tag("BundleFailedError", renderBundleFailedError), Match.tag("ImportFailedError", renderImportFailedError), Match.exhaustive);
82
+ /**
83
+ * Render a flat list of esbuild messages as a single error block with a generic
84
+ * `✘ Build errors` header.
85
+ */
86
+ const renderCoalescedBuildErrors = (messages) => {
87
+ const formatted = esbuild.formatMessagesSync(messages, {
88
+ kind: "error",
89
+ color: true,
90
+ terminalWidth: 80
91
+ });
92
+ return `${`${cross} Build errors`}\n${formatEsbuildMessages(messages, formatted)}`;
93
+ };
94
+ const logCoalescedBuildErrors = (messages) => messages.length === 0 ? Effect.void : Console.error(renderCoalescedBuildErrors(messages));
95
+ const renderCoalescedBuildWarnings = (messages) => {
96
+ const formatted = esbuild.formatMessagesSync(messages, {
97
+ kind: "warning",
98
+ color: true,
99
+ terminalWidth: 80
100
+ });
101
+ return `${`${warningSign} Build warnings`}\n${pipe(formatted, Array.join(""), String.trimEnd, withGutterBlock(gutter(yellow)))}`;
102
+ };
103
+ const logCoalescedBuildWarnings = (messages) => messages.length === 0 ? Effect.void : Console.error(renderCoalescedBuildWarnings(messages));
104
+ //#endregion
105
+ export { formatEsbuildMessages, formatPath, logCoalescedBuildErrors, logCoalescedBuildWarnings, logFileAdded, logFileModified, logFileRemoved, logFunctionAdded, logFunctionRemoved, logPending, logSuccess, logWarn, renderBuildError };
106
+
107
+ //# sourceMappingURL=log.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.mjs","names":["Ansi.blackBright","Ansi.green","Ansi.red","Ansi.yellow","GroupPath.toString"],"sources":["../src/log.ts"],"sourcesContent":["import { pipe } from \"effect/Function\";\nimport * as Array from \"effect/Array\";\nimport * as Console from \"effect/Console\";\nimport * as Effect from \"effect/Effect\";\nimport * as Match from \"effect/Match\";\nimport * as Option from \"effect/Option\";\nimport * as Path from \"effect/Path\";\nimport * as Predicate from \"effect/Predicate\";\nimport * as String from \"effect/String\";\nimport * as esbuild from \"esbuild\";\nimport type {\n BuildError,\n BundleFailedError,\n ImportFailedError,\n} from \"./BuildError\";\nimport * as Ansi from \"./Ansi\";\nimport type * as FunctionPath from \"./FunctionPath\";\nimport * as GroupPath from \"./GroupPath\";\nimport { ProjectRoot } from \"./ProjectRoot\";\n\n// --- Path styling ---\n\n/**\n * Render a relative path with the directory portion dimmed (`Ansi.blackBright`)\n * and the file leaf rendered in the default terminal color.\n */\nexport const formatPath = (relativePath: string): string => {\n const lastSep = Math.max(\n relativePath.lastIndexOf(\"/\"),\n relativePath.lastIndexOf(\"\\\\\"),\n );\n const dir = lastSep < 0 ? \"\" : relativePath.slice(0, lastSep + 1);\n const leaf = lastSep < 0 ? relativePath : relativePath.slice(lastSep + 1);\n return Ansi.blackBright(dir) + leaf;\n};\n\n// --- File operation logs ---\n\nconst logFile = (char: string, color: Ansi.Style) =>\n Effect.fnUntraced(function* (fullPath: string) {\n const projectRoot = yield* ProjectRoot.get;\n const path = yield* Path.Path;\n\n const prefix = projectRoot + path.sep;\n const suffix = pipe(fullPath, String.startsWith(prefix))\n ? pipe(fullPath, String.slice(prefix.length))\n : fullPath;\n\n yield* Console.log(\n `${color(char)} ${Ansi.blackBright(prefix)}${color(suffix)}`,\n );\n });\n\nexport const logFileAdded = logFile(\"+\", Ansi.green);\n\nexport const logFileRemoved = logFile(\"-\", Ansi.red);\n\nexport const logFileModified = logFile(\"~\", Ansi.yellow);\n\n// --- Function subline logs ---\n\nconst logFunction =\n (char: string, color: Ansi.Style) =>\n (functionPath: FunctionPath.FunctionPath) =>\n Console.log(\n ` ${color(char)} ${Ansi.blackBright(\n GroupPath.toString(functionPath.groupPath) + \".\",\n )}${color(functionPath.name)}`,\n );\n\nexport const logFunctionAdded = logFunction(\"+\", Ansi.green);\n\nexport const logFunctionRemoved = logFunction(\"-\", Ansi.red);\n\n// --- Process status logs ---\n\nconst logStatus = (char: string, charColor: Ansi.Style) => (message: string) =>\n Console.log(`${charColor(char)} ${message}`);\n\nexport const logSuccess = logStatus(\"✔︎\", Ansi.green);\n\nexport const logFailure = logStatus(\"✘\", Ansi.red);\n\nexport const logPending = logStatus(\"⭘\", Ansi.yellow);\n\nexport const logWarn = logStatus(\"⚠\", Ansi.yellow);\n\n// --- Build message rendering ---\n\nconst cross = Ansi.red(\"✘\");\n\nconst warningSign = Ansi.yellow(\"⚠\");\n\nconst gutter = (color: Ansi.Style): string => color(\"│\");\n\nconst errorGutter = gutter(Ansi.red);\n\nconst withGutterBlock =\n (gutterChar: string) =>\n (output: string): string =>\n pipe(\n String.split(output, \"\\n\"),\n Array.map((line) =>\n pipe(line, String.trim) === \"\" ? gutterChar : `${gutterChar} ${line}`,\n ),\n Array.join(\"\\n\"),\n (guttered) => `${gutterChar}\\n${guttered}\\n${gutterChar}`,\n );\n\nconst withErrorGutterBlock = withGutterBlock(errorGutter);\n\nconst formatBuildMessage = (\n error: esbuild.Message | undefined,\n formattedMessage: string,\n): string => {\n const lines = String.split(formattedMessage, \"\\n\");\n const redErrorText = Ansi.red(error?.text ?? \"\");\n const replaced = pipe(\n Array.findFirstIndex(lines, (l) => pipe(l, String.trim, String.isNonEmpty)),\n Option.flatMap((index) => Array.modify(lines, index, () => redErrorText)),\n Option.getOrElse(() => lines),\n );\n return pipe(replaced, Array.join(\"\\n\"));\n};\n\n/**\n * Render a list of esbuild messages into a styled, gutter-prefixed block.\n */\nexport const formatEsbuildMessages = (\n errors: readonly esbuild.Message[],\n formattedMessages: readonly string[],\n): string =>\n pipe(\n formattedMessages,\n Array.map((message, i) => formatBuildMessage(errors[i], message)),\n Array.join(\"\"),\n String.trimEnd,\n withErrorGutterBlock,\n );\n\nconst renderImportFailedError = (error: ImportFailedError): string => {\n const causeMessage = Predicate.isError(error.cause)\n ? error.cause.message\n : Predicate.isString(error.cause)\n ? error.cause\n : globalThis.String(error.cause);\n const oneLineCause = pipe(\n String.split(causeMessage, \"\\n\"),\n Array.findFirst((line) => pipe(line, String.trim, String.isNonEmpty)),\n Option.map(String.trim),\n Option.getOrElse(() => \"unknown error\"),\n );\n return `${cross} Failed to load bundled module ${formatPath(\n error.file,\n )}: ${oneLineCause}; check the file's top-level imports and side effects.`;\n};\n\n/**\n * Render a {@link BundleFailedError} as a multi-line, ANSI-styled string: a\n * one-line `✘ <file>: build errors` header followed by the gutter-prefixed\n * esbuild diagnostic block. Multi-line is appropriate here because a single\n * `BundleFailedError` carries an array of distinct esbuild messages.\n */\nconst renderBundleFailedError = (error: BundleFailedError): string => {\n const messages = error.errors as readonly esbuild.Message[];\n const formatted = esbuild.formatMessagesSync(messages as esbuild.Message[], {\n kind: \"error\",\n color: true,\n terminalWidth: 80,\n });\n const header = `${cross} ${formatPath(error.file)}: build errors`;\n return `${header}\\n${formatEsbuildMessages(messages, formatted)}`;\n};\n\n/**\n * Render any {@link BuildError} into a styled, ready-to-print string.\n * `ImportFailedError` collapses to a single line; `BundleFailedError` expands\n * to a header plus one diagnostic block per esbuild message.\n */\nexport const renderBuildError = (error: BuildError): string =>\n Match.value(error).pipe(\n Match.tag(\"BundleFailedError\", renderBundleFailedError),\n Match.tag(\"ImportFailedError\", renderImportFailedError),\n Match.exhaustive,\n );\n\nexport const logBuildError = (error: BuildError) =>\n Console.error(renderBuildError(error));\n\n/**\n * Render a flat list of esbuild messages as a single error block with a generic\n * `✘ Build errors` header.\n */\nconst renderCoalescedBuildErrors = (\n messages: readonly esbuild.Message[],\n): string => {\n const formatted = esbuild.formatMessagesSync(messages as esbuild.Message[], {\n kind: \"error\",\n color: true,\n terminalWidth: 80,\n });\n const header = `${cross} Build errors`;\n return `${header}\\n${formatEsbuildMessages(messages, formatted)}`;\n};\n\nexport const logCoalescedBuildErrors = (\n messages: readonly esbuild.Message[],\n) =>\n messages.length === 0\n ? Effect.void\n : Console.error(renderCoalescedBuildErrors(messages));\n\nconst renderCoalescedBuildWarnings = (\n messages: readonly esbuild.Message[],\n): string => {\n const formatted = esbuild.formatMessagesSync(messages as esbuild.Message[], {\n kind: \"warning\",\n color: true,\n terminalWidth: 80,\n });\n const header = `${warningSign} Build warnings`;\n const body = pipe(\n formatted,\n Array.join(\"\"),\n String.trimEnd,\n withGutterBlock(gutter(Ansi.yellow)),\n );\n return `${header}\\n${body}`;\n};\n\nexport const logCoalescedBuildWarnings = (\n messages: readonly esbuild.Message[],\n) =>\n messages.length === 0\n ? Effect.void\n : Console.error(renderCoalescedBuildWarnings(messages));\n"],"mappings":";;;;;;;;;;;;;;;;;;AA0BA,MAAa,cAAc,iBAAiC;CAC1D,MAAM,UAAU,KAAK,IACnB,aAAa,YAAY,GAAG,GAC5B,aAAa,YAAY,IAAI,CAC/B;CACA,MAAM,MAAM,UAAU,IAAI,KAAK,aAAa,MAAM,GAAG,UAAU,CAAC;CAChE,MAAM,OAAO,UAAU,IAAI,eAAe,aAAa,MAAM,UAAU,CAAC;CACxE,OAAOA,YAAiB,GAAG,IAAI;AACjC;AAIA,MAAM,WAAW,MAAc,UAC7B,OAAO,WAAW,WAAW,UAAkB;CAI7C,MAAM,UAAS,OAHY,YAAY,QAGV,OAFT,KAAK,KAAA,CAES;CAClC,MAAM,SAAS,KAAK,UAAU,OAAO,WAAW,MAAM,CAAC,IACnD,KAAK,UAAU,OAAO,MAAM,OAAO,MAAM,CAAC,IAC1C;CAEJ,OAAO,QAAQ,IACb,GAAG,MAAM,IAAI,EAAE,GAAGA,YAAiB,MAAM,IAAI,MAAM,MAAM,GAC3D;AACF,CAAC;AAEH,MAAa,eAAe,QAAQ,KAAKC,KAAU;AAEnD,MAAa,iBAAiB,QAAQ,KAAKC,GAAQ;AAEnD,MAAa,kBAAkB,QAAQ,KAAKC,MAAW;AAIvD,MAAM,eACH,MAAc,WACd,iBACC,QAAQ,IACN,KAAK,MAAM,IAAI,EAAE,GAAGH,YAClBI,SAAmB,aAAa,SAAS,IAAI,GAC/C,IAAI,MAAM,aAAa,IAAI,GAC7B;AAEJ,MAAa,mBAAmB,YAAY,KAAKH,KAAU;AAE3D,MAAa,qBAAqB,YAAY,KAAKC,GAAQ;AAI3D,MAAM,aAAa,MAAc,eAA2B,YAC1D,QAAQ,IAAI,GAAG,UAAU,IAAI,EAAE,GAAG,SAAS;AAE7C,MAAa,aAAa,UAAU,MAAMD,KAAU;AAIpD,MAAa,aAAa,UAAU,KAAKE,MAAW;AAEpD,MAAa,UAAU,UAAU,KAAKA,MAAW;AAIjD,MAAM,QAAQD,IAAS,GAAG;AAE1B,MAAM,cAAcC,OAAY,GAAG;AAEnC,MAAM,UAAU,UAA8B,MAAM,GAAG;AAEvD,MAAM,cAAc,OAAOD,GAAQ;AAEnC,MAAM,mBACH,gBACA,WACC,KACE,OAAO,MAAM,QAAQ,IAAI,GACzB,MAAM,KAAK,SACT,KAAK,MAAM,OAAO,IAAI,MAAM,KAAK,aAAa,GAAG,WAAW,GAAG,MACjE,GACA,MAAM,KAAK,IAAI,IACd,aAAa,GAAG,WAAW,IAAI,SAAS,IAAI,YAC/C;AAEJ,MAAM,uBAAuB,gBAAgB,WAAW;AAExD,MAAM,sBACJ,OACA,qBACW;CACX,MAAM,QAAQ,OAAO,MAAM,kBAAkB,IAAI;CACjD,MAAM,eAAeA,IAAS,OAAO,QAAQ,EAAE;CAC/C,MAAM,WAAW,KACf,MAAM,eAAe,QAAQ,MAAM,KAAK,GAAG,OAAO,MAAM,OAAO,UAAU,CAAC,GAC1E,OAAO,SAAS,UAAU,MAAM,OAAO,OAAO,aAAa,YAAY,CAAC,GACxE,OAAO,gBAAgB,KAAK,CAC9B;CACA,OAAO,KAAK,UAAU,MAAM,KAAK,IAAI,CAAC;AACxC;;;;AAKA,MAAa,yBACX,QACA,sBAEA,KACE,mBACA,MAAM,KAAK,SAAS,MAAM,mBAAmB,OAAO,IAAI,OAAO,CAAC,GAChE,MAAM,KAAK,EAAE,GACb,OAAO,SACP,oBACF;AAEF,MAAM,2BAA2B,UAAqC;CACpE,MAAM,eAAe,UAAU,QAAQ,MAAM,KAAK,IAC9C,MAAM,MAAM,UACZ,UAAU,SAAS,MAAM,KAAK,IAC5B,MAAM,QACN,WAAW,OAAO,MAAM,KAAK;CACnC,MAAM,eAAe,KACnB,OAAO,MAAM,cAAc,IAAI,GAC/B,MAAM,WAAW,SAAS,KAAK,MAAM,OAAO,MAAM,OAAO,UAAU,CAAC,GACpE,OAAO,IAAI,OAAO,IAAI,GACtB,OAAO,gBAAgB,eAAe,CACxC;CACA,OAAO,GAAG,MAAM,iCAAiC,WAC/C,MAAM,IACR,EAAE,IAAI,aAAa;AACrB;;;;;;;AAQA,MAAM,2BAA2B,UAAqC;CACpE,MAAM,WAAW,MAAM;CACvB,MAAM,YAAY,QAAQ,mBAAmB,UAA+B;EAC1E,MAAM;EACN,OAAO;EACP,eAAe;CACjB,CAAC;CAED,OAAO,GAAG,GADQ,MAAM,GAAG,WAAW,MAAM,IAAI,EAAE,gBACjC,IAAI,sBAAsB,UAAU,SAAS;AAChE;;;;;;AAOA,MAAa,oBAAoB,UAC/B,MAAM,MAAM,KAAK,CAAC,CAAC,KACjB,MAAM,IAAI,qBAAqB,uBAAuB,GACtD,MAAM,IAAI,qBAAqB,uBAAuB,GACtD,MAAM,UACR;;;;;AASF,MAAM,8BACJ,aACW;CACX,MAAM,YAAY,QAAQ,mBAAmB,UAA+B;EAC1E,MAAM;EACN,OAAO;EACP,eAAe;CACjB,CAAC;CAED,OAAO,GAAG,GADQ,MAAM,eACP,IAAI,sBAAsB,UAAU,SAAS;AAChE;AAEA,MAAa,2BACX,aAEA,SAAS,WAAW,IAChB,OAAO,OACP,QAAQ,MAAM,2BAA2B,QAAQ,CAAC;AAExD,MAAM,gCACJ,aACW;CACX,MAAM,YAAY,QAAQ,mBAAmB,UAA+B;EAC1E,MAAM;EACN,OAAO;EACP,eAAe;CACjB,CAAC;CAQD,OAAO,GAAG,GAPQ,YAAY,iBAOb,IANJ,KACX,WACA,MAAM,KAAK,EAAE,GACb,OAAO,SACP,gBAAgB,OAAOC,MAAW,CAAC,CAEb;AAC1B;AAEA,MAAa,6BACX,aAEA,SAAS,WAAW,IAChB,OAAO,OACP,QAAQ,MAAM,6BAA6B,QAAQ,CAAC"}
@@ -0,0 +1,6 @@
1
+ //#region package.json
2
+ var version = "10.3.1";
3
+ //#endregion
4
+ export { version };
5
+
6
+ //# sourceMappingURL=package.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.mjs","names":[],"sources":["../package.json"],"sourcesContent":[""],"mappings":""}
@@ -0,0 +1,448 @@
1
+ import { CodeBlockWriter } from "./CodeBlockWriter.mjs";
2
+ import { render } from "./SpecAssemblyNode.mjs";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Array from "effect/Array";
5
+ //#region src/templates.ts
6
+ /**
7
+ * Emit `convex/schema.ts` as a one-line re-export of the codegen-emitted deploy
8
+ * schema in `confect/_generated/convexSchema.ts`. Deploy-time consumers (the
9
+ * Convex CLI, `convex-test`) keep reading `convex/schema.ts`; the runtime
10
+ * `DatabaseSchema` in `confect/_generated/schema.ts` is untouched by this
11
+ * file.
12
+ */
13
+ const schema = ({ convexSchemaImportPath }) => schemaEffect({ convexSchemaImportPath });
14
+ const schemaEffect = Effect.fnUntraced(function* ({ convexSchemaImportPath }) {
15
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
16
+ yield* cbw.writeLine(`export { default } from "${convexSchemaImportPath}";`);
17
+ return yield* cbw.toString();
18
+ });
19
+ /**
20
+ * Emit `confect/_generated/schema.ts`—the runtime `DatabaseSchema` used by
21
+ * impls and the per-group registries (and downstream by per-function bundles
22
+ * for codec lookup). Every table wrapper at
23
+ * `confect/_generated/tables/<name>.ts` is imported statically and registered
24
+ * as a value entry on the `DatabaseSchema.make({...})` call. Per-table laziness
25
+ * lives inside each `Table`: its `Fields` and `Doc` are lazy memoised getters
26
+ * that only evaluate the user-supplied field-schema callback on first access,
27
+ * so unused tables in a function bundle never pay schema-construction cost
28
+ * despite the static import.
29
+ *
30
+ * The `DatabaseSchema` import is aliased to `$DatabaseSchema` because each
31
+ * table is imported under its own (filename-derived) name; a table named
32
+ * `DatabaseSchema` would otherwise collide with the library import and emit a
33
+ * duplicate-binding file. The leading `$` makes the alias collision-proof:
34
+ * `validateConfectTableIdentifier` requires names to match
35
+ * `/^[a-zA-Z][a-zA-Z0-9_]*$/`, which forbids `$`, so no valid table import can
36
+ * ever shadow it.
37
+ */
38
+ const runtimeSchema = ({ tableModules, component = false }) => runtimeSchemaEffect({
39
+ tableModules,
40
+ component
41
+ });
42
+ const runtimeSchemaEffect = Effect.fnUntraced(function* ({ tableModules, component = false }) {
43
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
44
+ yield* cbw.writeLine(`import { DatabaseSchema as $DatabaseSchema } from "@confect/server";`);
45
+ if (tableModules.length > 0) {
46
+ yield* cbw.blankLine();
47
+ yield* Effect.forEach(tableModules, ({ tableName, importPath }) => cbw.writeLine(`import ${tableName} from "${importPath}";`));
48
+ }
49
+ yield* cbw.blankLine();
50
+ if (component) yield* cbw.writeLine(`import { target as $target } from "./id";`);
51
+ if (tableModules.length === 0) yield* cbw.writeLine(`const databaseSchema: $DatabaseSchema.DatabaseSchema${component ? "<{}, typeof $target>" : ""} = $DatabaseSchema.make({}${component ? ", $target" : ""});`);
52
+ else {
53
+ yield* cbw.writeLine(`const databaseSchema: $DatabaseSchema.DatabaseSchema<{`);
54
+ yield* cbw.indent(Effect.forEach(tableModules, ({ tableName }) => cbw.writeLine(`readonly ${tableName}: typeof ${tableName};`), { discard: true }));
55
+ yield* cbw.writeLine(`}${component ? ", typeof $target" : ""}> = $DatabaseSchema.make({`);
56
+ yield* cbw.indent(Effect.gen(function* () {
57
+ for (const { tableName } of tableModules) yield* cbw.writeLine(`${tableName},`);
58
+ }));
59
+ yield* cbw.writeLine(`}${component ? ", $target" : ""});`);
60
+ }
61
+ yield* cbw.blankLine();
62
+ yield* cbw.writeLine(`export default databaseSchema;`);
63
+ return yield* cbw.toString();
64
+ });
65
+ /**
66
+ * Emit `confect/_generated/convexSchema.ts`—the Convex deploy-time
67
+ * `SchemaDefinition`. Imports every table from its generated wrapper at
68
+ * `_generated/tables/<name>` and calls `defineSchema({...})` exactly once.
69
+ * `Table.tableDefinition` lives in `@confect/server` because it is the
70
+ * `defineTable` binding; the generated table wrappers themselves stay
71
+ * client-safe (`Fields`/`Doc` from `@confect/core`).
72
+ *
73
+ * The `defineSchema` and `Table` imports are aliased with a leading `$` because
74
+ * each table is imported under its own (filename-derived) name; a table named
75
+ * `defineSchema` or `Table` would otherwise collide with the library import and
76
+ * emit a duplicate-binding file. `validateConfectTableIdentifier` requires
77
+ * names to match `/^[a-zA-Z][a-zA-Z0-9_]*$/`, which forbids `$`, so no valid
78
+ * table import can ever shadow them.
79
+ */
80
+ const convexSchema = ({ tableModules }) => convexSchemaEffect({ tableModules });
81
+ const convexSchemaEffect = Effect.fnUntraced(function* ({ tableModules }) {
82
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
83
+ yield* cbw.writeLine(`import { defineSchema as $defineSchema } from "convex/server";`);
84
+ if (tableModules.length > 0) {
85
+ yield* cbw.writeLine(`import { Table as $Table } from "@confect/server";`);
86
+ yield* cbw.blankLine();
87
+ yield* Effect.forEach(tableModules, ({ tableName, importPath }) => cbw.writeLine(`import ${tableName} from "${importPath}";`));
88
+ }
89
+ yield* cbw.blankLine();
90
+ if (tableModules.length === 0) yield* cbw.writeLine(`export default $defineSchema({});`);
91
+ else {
92
+ yield* cbw.writeLine(`export default $defineSchema({`);
93
+ yield* cbw.indent(Effect.gen(function* () {
94
+ for (const { tableName } of tableModules) yield* cbw.writeLine(`${tableName}: $Table.tableDefinition(${tableName}),`);
95
+ }));
96
+ yield* cbw.writeLine(`});`);
97
+ }
98
+ return yield* cbw.toString();
99
+ });
100
+ /**
101
+ * Emit `confect/_generated/id.ts`—a type-constrained `Id` constructor and a
102
+ * `TableNames` union derived from the user's `confect/tables/*.ts` filenames.
103
+ * User-authored table modules import `Id` from this file to declare cross-table
104
+ * id references without typing the destination name as a free string (and
105
+ * without ever importing each other transitively).
106
+ *
107
+ * `Id` also accepts Convex system tables, with the component scope when
108
+ * present. `TableNames` includes only user tables and resolves to `never` for
109
+ * an empty table directory.
110
+ */
111
+ const id = ({ tableNames, scope }) => idEffect({
112
+ tableNames,
113
+ scope
114
+ });
115
+ const idEffect = Effect.fnUntraced(function* ({ tableNames, scope }) {
116
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
117
+ yield* cbw.writeLine(`import { GenericId${scope === void 0 ? "" : ", IdScope"} } from "@confect/core";`);
118
+ yield* cbw.writeLine(`import type { SystemTableNames } from "convex/server";`);
119
+ yield* cbw.blankLine();
120
+ if (scope !== void 0) {
121
+ yield* cbw.writeLine(`export const scope = IdScope.component(${JSON.stringify(scope.slice(10))});`);
122
+ yield* cbw.writeLine(`export const target = { kind: "component", scope } as const;`);
123
+ }
124
+ const union = tableNames.length === 0 ? "never" : tableNames.map((n) => `"${n}"`).join(" | ");
125
+ yield* cbw.writeLine(`export type TableNames = ${union};`);
126
+ yield* cbw.blankLine();
127
+ yield* cbw.writeLine(`export type Id<TableName extends TableNames | SystemTableNames> = GenericId.GenericId<TableName${scope === void 0 ? "" : ", typeof scope"}>;`);
128
+ yield* cbw.blankLine();
129
+ yield* cbw.writeLine(`export const Id = <const TableName extends TableNames | SystemTableNames>(`);
130
+ yield* cbw.indent(cbw.writeLine(`tableName: TableName,`));
131
+ yield* cbw.writeLine(`) => GenericId.GenericId(tableName${scope === void 0 ? "" : ", scope"});`);
132
+ return yield* cbw.toString();
133
+ });
134
+ /**
135
+ * Emit `confect/_generated/tables/<tableName>.ts`—a two-line wrapper that
136
+ * imports the user-authored `UnnamedTable` and binds the file basename to it,
137
+ * producing the fully-named `Table` value that downstream consumers (schema,
138
+ * specs, impls) read.
139
+ */
140
+ const tableWrapper = ({ tableName, unnamedImportPath, component = false }) => tableWrapperEffect({
141
+ tableName,
142
+ unnamedImportPath,
143
+ component
144
+ });
145
+ const tableWrapperEffect = Effect.fnUntraced(function* ({ tableName, unnamedImportPath, component = false }) {
146
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
147
+ yield* cbw.writeLine(`import unnamed from "${unnamedImportPath}";`);
148
+ if (component) yield* cbw.writeLine(`import { scope } from "../id";`);
149
+ yield* cbw.blankLine();
150
+ yield* cbw.writeLine(`export default unnamed("${tableName}"${component ? ", scope" : ""});`);
151
+ return yield* cbw.toString();
152
+ });
153
+ const http = ({ httpImportPath }) => httpEffect({ httpImportPath });
154
+ const httpEffect = Effect.fnUntraced(function* ({ httpImportPath }) {
155
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
156
+ yield* cbw.writeLine(`import http from "${httpImportPath}";`);
157
+ yield* cbw.newLine();
158
+ yield* cbw.writeLine(`export default http;`);
159
+ return yield* cbw.toString();
160
+ });
161
+ /**
162
+ * Emit `convex/http.ts` for a declared backend: the Convex router serving
163
+ * `confect/http.ts`'s routes, typed by the generated database schema.
164
+ */
165
+ const declaredHttp = Effect.fnUntraced(function* ({ schemaImportPath, httpImportPath }) {
166
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
167
+ yield* cbw.writeLine("// Generated by `confect codegen` from confect/http.ts. Do not edit.");
168
+ yield* cbw.writeLine(`import { HttpRouter } from "@confect/server";`);
169
+ yield* cbw.writeLine(`import schema from "${schemaImportPath}";`);
170
+ yield* cbw.writeLine(`import http from "${httpImportPath}";`);
171
+ yield* cbw.newLine();
172
+ yield* cbw.writeLine(`export default HttpRouter.forSchema(schema)(http.routes, { api: http.api });`);
173
+ return yield* cbw.toString();
174
+ });
175
+ const crons = ({ cronsImportPath }) => cronsEffect({ cronsImportPath });
176
+ const cronsEffect = Effect.fnUntraced(function* ({ cronsImportPath }) {
177
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
178
+ yield* cbw.writeLine(`import crons from "${cronsImportPath}";`);
179
+ yield* cbw.newLine();
180
+ yield* cbw.writeLine(`export default crons.convexCronJobs;`);
181
+ return yield* cbw.toString();
182
+ });
183
+ const authConfig = ({ authImportPath }) => authConfigEffect({ authImportPath });
184
+ const authConfigEffect = Effect.fnUntraced(function* ({ authImportPath }) {
185
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
186
+ yield* cbw.writeLine(`import auth from "${authImportPath}";`);
187
+ yield* cbw.newLine();
188
+ yield* cbw.writeLine(`export default auth;`);
189
+ return yield* cbw.toString();
190
+ });
191
+ /**
192
+ * Emit `confect/_generated/components.ts`—a typed registry of the Convex
193
+ * components installed via `app.use(...)` in `convex/convex.config.ts`. Mirrors
194
+ * the `components` export of Convex's generated `convex/_generated/api`: the
195
+ * runtime value is `componentsGeneric()` (a name-preserving proxy), and each
196
+ * entry is typed with the `ComponentApi` that component packages export from
197
+ * `_generated/component.js`. Unlike `convex/_generated/api`, this file exists
198
+ * before `convex codegen` ever runs, so impl modules can import it
199
+ * safely—`confect codegen` bundles and evaluates each impl's import graph, and
200
+ * `convex/_generated/api` doesn't exist yet at that point.
201
+ *
202
+ * The `as any` cast is confined here: `componentsGeneric()` is typed
203
+ * `AnyChildComponents`, which deliberately doesn't overlap the precise registry
204
+ * type; the `Components` annotation on the const supplies the real type.
205
+ */
206
+ const components = ({ components: installedComponents }) => componentsEffect({ components: installedComponents });
207
+ const componentsEffect = Effect.fnUntraced(function* ({ components: installedComponents }) {
208
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
209
+ yield* cbw.writeLine(`import { componentsGeneric } from "convex/server";`);
210
+ yield* cbw.blankLine();
211
+ if (installedComponents.length === 0) yield* cbw.writeLine(`export type Components = {};`);
212
+ else {
213
+ yield* cbw.writeLine(`export type Components = {`);
214
+ yield* cbw.indent(Effect.forEach(installedComponents, ({ name, typeImportPath }) => cbw.writeLine(`"${name}": import("${typeImportPath}/_generated/component.js").ComponentApi<"${name}">;`), { discard: true }));
215
+ yield* cbw.writeLine(`};`);
216
+ }
217
+ yield* cbw.blankLine();
218
+ yield* cbw.writeLine(`export const components: Components = componentsGeneric() as any;`);
219
+ return yield* cbw.toString();
220
+ });
221
+ const refs = ({ specImportPath }) => refsEffect({ specImportPath });
222
+ const refsEffect = Effect.fnUntraced(function* ({ specImportPath }) {
223
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
224
+ yield* cbw.writeLine(`import { Refs } from "@confect/core";`);
225
+ yield* cbw.writeLine(`import spec from "${specImportPath}";`);
226
+ yield* cbw.blankLine();
227
+ yield* cbw.writeLine(`const refs: Refs.FromSpec<typeof spec> = Refs.make(spec);`);
228
+ yield* cbw.blankLine();
229
+ yield* cbw.writeLine(`export default refs;`);
230
+ return yield* cbw.toString();
231
+ });
232
+ const componentContract = Effect.fnUntraced(function* ({ tableNames }) {
233
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
234
+ yield* cbw.writeLine("import { Component } from \"@confect/core\";");
235
+ yield* cbw.writeLine("import spec from \"./spec\";");
236
+ yield* cbw.writeLine("import { scope } from \"./id\";");
237
+ yield* cbw.blankLine();
238
+ const names = Array.map([
239
+ ...tableNames,
240
+ "_storage",
241
+ "_scheduled_functions"
242
+ ], (name) => `"${name}"`);
243
+ yield* cbw.writeLine(`const component: Component.Component<typeof spec, typeof scope, ${names.join(" | ")}> = Component.make(spec, scope, [${names.join(", ")}]);`);
244
+ yield* cbw.writeLine("export default component;");
245
+ return yield* cbw.toString();
246
+ });
247
+ /**
248
+ * Emit `_generated/docs.ts`: one named `type <table>` alias per table plus a
249
+ * `Docs` registry. Each alias is `Document.Document<typeof schemaDefinition,
250
+ * "<table>">`, so it stays structurally exact while giving the document a
251
+ * _name_—declaration emit then prints e.g. `NotesDoc` instead of expanding the
252
+ * row structure. A `type` alias (rather than an extending `interface`) is used
253
+ * so it works for every document shape: object tables, but also union schemas
254
+ * (`Schema.Union`) and other non-object documents, which an `interface …
255
+ * extends` cannot represent (TS2312). The registry is threaded into the
256
+ * generated `DatabaseReader`/`DatabaseWriter` tags so query/mutation helpers
257
+ * print named documents with no user annotations.
258
+ */
259
+ const docs = ({ schemaImportPath, tables }) => docsEffect({
260
+ schemaImportPath,
261
+ tables
262
+ });
263
+ const docsEffect = Effect.fnUntraced(function* ({ schemaImportPath, tables }) {
264
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
265
+ if (tables.length === 0) {
266
+ yield* cbw.writeLine(`export interface Docs {}`);
267
+ return yield* cbw.toString();
268
+ }
269
+ yield* cbw.writeLine(`import type { Document } from "@confect/server";`);
270
+ yield* cbw.writeLine(`import type schemaDefinition from "${schemaImportPath}";`);
271
+ yield* cbw.blankLine();
272
+ for (const { tableName, docName } of tables) yield* cbw.writeLine(`export type ${docName} = Document.Document<typeof schemaDefinition, "${tableName}">;`);
273
+ yield* cbw.blankLine();
274
+ yield* cbw.writeLine(`export interface Docs {`);
275
+ yield* cbw.indent(Effect.gen(function* () {
276
+ for (const { tableName, docName } of tables) yield* cbw.writeLine(`${tableName}: ${docName};`);
277
+ }));
278
+ yield* cbw.writeLine(`}`);
279
+ return yield* cbw.toString();
280
+ });
281
+ const registeredFunctionsForGroup = ({ spec, schemaImportPath, specImportPath, implImportPath }) => registeredFunctionsForGroupEffect({
282
+ spec,
283
+ schemaImportPath,
284
+ specImportPath,
285
+ implImportPath
286
+ });
287
+ const registeredFunctionsForGroupEffect = Effect.fnUntraced(function* ({ spec, schemaImportPath, specImportPath, implImportPath }) {
288
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
289
+ const useNode = spec.runtime === "Node";
290
+ const hasConfectFunctions = (group) => Object.values(group.functions).some((functionSpec) => functionSpec.functionProvenance._tag === "Confect") || Object.values(group.groups).some(hasConfectFunctions);
291
+ const forwarding = !useNode && hasConfectFunctions(spec);
292
+ if (useNode) yield* cbw.writeLine(`import { RegisteredNodeFunction } from "@confect/server/node";`);
293
+ else if (!forwarding) yield* cbw.writeLine(`import { RegisteredFunctions } from "@confect/server";`);
294
+ else yield* cbw.writeLine(`import { ConvexFunctionDefinitions, RegisteredConvexFunction, type RegisteredFunctions } from "@confect/server";`);
295
+ yield* cbw.writeLine(`import databaseSchema from "${schemaImportPath}";`);
296
+ yield* cbw.writeLine(`import groupLayer from "${implImportPath}";`);
297
+ yield* cbw.blankLine();
298
+ const specType = `typeof import("${specImportPath}")["default"]`;
299
+ if (useNode) yield* cbw.writeLine(`export default RegisteredNodeFunction.buildForGroup<${specType}>(databaseSchema, groupLayer);`);
300
+ else if (!forwarding) yield* cbw.writeLine(`export default RegisteredFunctions.buildForGroup<${specType}>(databaseSchema, groupLayer);`);
301
+ else {
302
+ const bindings = (group, path) => `{
303
+ ${[...Object.entries(group.functions).map(([name, functionSpec]) => {
304
+ const key = JSON.stringify(name);
305
+ const definition = `${path}[${key}]`;
306
+ return `[${key}]: ${functionSpec.functionProvenance._tag === "Convex" ? `${definition}.handler` : `RegisteredConvexFunction.register({ ...${definition}, handler: forward(${definition}.handler) })`},`;
307
+ }), ...Object.entries(group.groups).map(([name, child]) => {
308
+ const key = JSON.stringify(name);
309
+ return `[${key}]: ${bindings(child, `${path}[${key}]`)},`;
310
+ })].join("\n")}
311
+ }`;
312
+ yield* cbw.writeLine(`const forward = <Ctx, Args, Returns>(handler: (ctx: Ctx, args: Args) => Promise<Returns>) => (ctx: Ctx, args: Args) => handler(ctx, args);
313
+
314
+ const definitions = ConvexFunctionDefinitions.buildForGroup<${specType}>(databaseSchema, groupLayer);
315
+
316
+ export default ${bindings(spec, "definitions")} as RegisteredFunctions.RegisteredFunctionsForGroupSpec<${specType}>;`);
317
+ }
318
+ return yield* cbw.toString();
319
+ });
320
+ const services = ({ schemaImportPath, component = false }) => servicesEffect({
321
+ schemaImportPath,
322
+ component
323
+ });
324
+ const servicesEffect = Effect.fnUntraced(function* ({ schemaImportPath, component = false }) {
325
+ const cbw = new CodeBlockWriter({ indentNumberOfSpaces: 2 });
326
+ yield* cbw.writeLine("import {");
327
+ yield* cbw.indent(Effect.gen(function* () {
328
+ yield* cbw.writeLine("ActionCtx as ActionCtx_,");
329
+ yield* cbw.writeLine("ActionRunner as ActionRunner_,");
330
+ if (!component) yield* cbw.writeLine("Auth as Auth_,");
331
+ yield* cbw.writeLine("type DataModel,");
332
+ yield* cbw.writeLine("DatabaseReader as DatabaseReader_,");
333
+ yield* cbw.writeLine("DatabaseWriter as DatabaseWriter_,");
334
+ yield* cbw.writeLine("ExecutionMetadata as ExecutionMetadata_,");
335
+ yield* cbw.writeLine("MutationCtx as MutationCtx_,");
336
+ yield* cbw.writeLine("MutationRunner as MutationRunner_,");
337
+ yield* cbw.writeLine("MutationTransactionContext as MutationTransactionContext_,");
338
+ yield* cbw.writeLine("QueryCtx as QueryCtx_,");
339
+ yield* cbw.writeLine("QueryRunner as QueryRunner_,");
340
+ yield* cbw.writeLine("QueryTransactionContext as QueryTransactionContext_,");
341
+ yield* cbw.writeLine("RequestMetadata as RequestMetadata_,");
342
+ yield* cbw.writeLine("Scheduler as Scheduler_,");
343
+ if (!component) yield* cbw.writeLine("Storage as Storage_,");
344
+ yield* cbw.writeLine("StorageActionWriter as StorageActionWriter_,");
345
+ yield* cbw.writeLine("StorageReader as StorageReader_,");
346
+ yield* cbw.writeLine("StorageWriter as StorageWriter_,");
347
+ yield* cbw.writeLine("TransactionMetadata as TransactionMetadata_,");
348
+ yield* cbw.writeLine("VectorSearch as VectorSearch_,");
349
+ }));
350
+ yield* cbw.writeLine(`} from "@confect/server";`);
351
+ yield* cbw.writeLine(`import type schemaDefinition from "${schemaImportPath}";`);
352
+ yield* cbw.writeLine(`import type { Docs } from "./docs";`);
353
+ if (component) yield* cbw.writeLine(`import type { scope } from "./id";`);
354
+ yield* cbw.blankLine();
355
+ if (!component) {
356
+ yield* cbw.writeLine("export const Auth = Auth_.Auth;");
357
+ yield* cbw.writeLine("export type Auth = typeof Auth.Identifier;");
358
+ }
359
+ yield* cbw.blankLine();
360
+ yield* cbw.writeLine("export const ExecutionMetadata = ExecutionMetadata_.ExecutionMetadata;");
361
+ yield* cbw.writeLine("export type ExecutionMetadata = typeof ExecutionMetadata.Identifier;");
362
+ yield* cbw.blankLine();
363
+ yield* cbw.writeLine("export const RequestMetadata = RequestMetadata_.RequestMetadata;");
364
+ yield* cbw.writeLine("export type RequestMetadata = typeof RequestMetadata.Identifier;");
365
+ yield* cbw.blankLine();
366
+ yield* cbw.writeLine("export const TransactionMetadata = TransactionMetadata_.TransactionMetadata;");
367
+ yield* cbw.writeLine("export type TransactionMetadata = typeof TransactionMetadata.Identifier;");
368
+ yield* cbw.blankLine();
369
+ yield* cbw.writeLine(component ? "export const Scheduler = Scheduler_.forScope<typeof scope>();" : "export const Scheduler = Scheduler_.Scheduler;");
370
+ yield* cbw.writeLine("export type Scheduler = typeof Scheduler.Identifier;");
371
+ yield* cbw.blankLine();
372
+ if (!component) {
373
+ yield* cbw.writeLine("export const Storage = Storage_.Storage;");
374
+ yield* cbw.writeLine("export type Storage = typeof Storage.Identifier;");
375
+ yield* cbw.blankLine();
376
+ }
377
+ yield* cbw.writeLine(`export const StorageReader = StorageReader_.StorageReader${component ? ".forScope<typeof scope>()" : ""};`);
378
+ yield* cbw.writeLine("export type StorageReader = typeof StorageReader.Identifier;");
379
+ yield* cbw.blankLine();
380
+ yield* cbw.writeLine(`export const StorageWriter = StorageWriter_.StorageWriter${component ? ".forScope<typeof scope>()" : ""};`);
381
+ yield* cbw.writeLine("export type StorageWriter = typeof StorageWriter.Identifier;");
382
+ yield* cbw.blankLine();
383
+ yield* cbw.writeLine(`export const StorageActionWriter = StorageActionWriter_.StorageActionWriter${component ? ".forScope<typeof scope>()" : ""};`);
384
+ yield* cbw.writeLine("export type StorageActionWriter = typeof StorageActionWriter.Identifier;");
385
+ yield* cbw.blankLine();
386
+ yield* cbw.writeLine("export const VectorSearch: VectorSearch_.VectorSearchTag<");
387
+ yield* cbw.indent(cbw.writeLine("DataModel.FromSchema<typeof schemaDefinition>"));
388
+ yield* cbw.writeLine("> = VectorSearch_.VectorSearch<DataModel.FromSchema<typeof schemaDefinition>>();");
389
+ yield* cbw.writeLine("export type VectorSearch = typeof VectorSearch.Identifier;");
390
+ yield* cbw.blankLine();
391
+ yield* cbw.writeLine("export const DatabaseReader: DatabaseReader_.DatabaseReaderTag<");
392
+ yield* cbw.indent(Effect.gen(function* () {
393
+ yield* cbw.writeLine("typeof schemaDefinition,");
394
+ yield* cbw.writeLine("Docs");
395
+ }));
396
+ yield* cbw.writeLine("> = DatabaseReader_.DatabaseReader<typeof schemaDefinition, Docs>();");
397
+ yield* cbw.writeLine("export type DatabaseReader = typeof DatabaseReader.Identifier;");
398
+ yield* cbw.blankLine();
399
+ yield* cbw.writeLine("export const DatabaseWriter: DatabaseWriter_.DatabaseWriterTag<");
400
+ yield* cbw.indent(Effect.gen(function* () {
401
+ yield* cbw.writeLine("typeof schemaDefinition,");
402
+ yield* cbw.writeLine("Docs");
403
+ }));
404
+ yield* cbw.writeLine("> = DatabaseWriter_.DatabaseWriter<typeof schemaDefinition, Docs>();");
405
+ yield* cbw.writeLine("export type DatabaseWriter = typeof DatabaseWriter.Identifier;");
406
+ yield* cbw.blankLine();
407
+ yield* cbw.writeLine("export const QueryTransactionContext = QueryTransactionContext_.QueryTransactionContext;");
408
+ yield* cbw.writeLine("export type QueryTransactionContext = typeof QueryTransactionContext.Identifier;");
409
+ yield* cbw.blankLine();
410
+ yield* cbw.writeLine("export const MutationTransactionContext = MutationTransactionContext_.MutationTransactionContext;");
411
+ yield* cbw.writeLine("export type MutationTransactionContext = typeof MutationTransactionContext.Identifier;");
412
+ yield* cbw.blankLine();
413
+ yield* cbw.writeLine("export const QueryRunner = QueryRunner_.QueryRunner;");
414
+ yield* cbw.writeLine("export type QueryRunner = typeof QueryRunner.Identifier;");
415
+ yield* cbw.blankLine();
416
+ yield* cbw.writeLine("export const MutationRunner = MutationRunner_.MutationRunner;");
417
+ yield* cbw.writeLine("export type MutationRunner = typeof MutationRunner.Identifier;");
418
+ yield* cbw.blankLine();
419
+ yield* cbw.writeLine("export const ActionRunner = ActionRunner_.ActionRunner;");
420
+ yield* cbw.writeLine("export type ActionRunner = typeof ActionRunner.Identifier;");
421
+ yield* cbw.blankLine();
422
+ yield* cbw.writeLine("export const QueryCtx: QueryCtx_.QueryCtxTag<");
423
+ yield* cbw.indent(cbw.writeLine(`DataModel.ToConvex<DataModel.FromSchema<typeof schemaDefinition>>${component ? ", typeof scope" : ""}`));
424
+ yield* cbw.writeLine("> = QueryCtx_.QueryCtx<");
425
+ yield* cbw.indent(cbw.writeLine(`DataModel.ToConvex<DataModel.FromSchema<typeof schemaDefinition>>${component ? ", typeof scope" : ""}`));
426
+ yield* cbw.writeLine(">();");
427
+ yield* cbw.writeLine("export type QueryCtx = typeof QueryCtx.Identifier;");
428
+ yield* cbw.blankLine();
429
+ yield* cbw.writeLine("export const MutationCtx: MutationCtx_.MutationCtxTag<");
430
+ yield* cbw.indent(cbw.writeLine(`DataModel.ToConvex<DataModel.FromSchema<typeof schemaDefinition>>${component ? ", typeof scope" : ""}`));
431
+ yield* cbw.writeLine("> = MutationCtx_.MutationCtx<");
432
+ yield* cbw.indent(cbw.writeLine(`DataModel.ToConvex<DataModel.FromSchema<typeof schemaDefinition>>${component ? ", typeof scope" : ""}`));
433
+ yield* cbw.writeLine(">();");
434
+ yield* cbw.writeLine("export type MutationCtx = typeof MutationCtx.Identifier;");
435
+ yield* cbw.blankLine();
436
+ yield* cbw.writeLine("export const ActionCtx: ActionCtx_.ActionCtxTag<");
437
+ yield* cbw.indent(cbw.writeLine(`DataModel.ToConvex<DataModel.FromSchema<typeof schemaDefinition>>${component ? ", typeof scope" : ""}`));
438
+ yield* cbw.writeLine("> = ActionCtx_.ActionCtx<");
439
+ yield* cbw.indent(cbw.writeLine(`DataModel.ToConvex<DataModel.FromSchema<typeof schemaDefinition>>${component ? ", typeof scope" : ""}`));
440
+ yield* cbw.writeLine(">();");
441
+ yield* cbw.writeLine("export type ActionCtx = typeof ActionCtx.Identifier;");
442
+ return yield* cbw.toString();
443
+ });
444
+ const assembledSpec = ({ nodes }) => render(nodes);
445
+ //#endregion
446
+ export { assembledSpec, authConfig, componentContract, components, convexSchema, crons, declaredHttp, docs, http, id, refs, registeredFunctionsForGroup, runtimeSchema, schema, services, tableWrapper };
447
+
448
+ //# sourceMappingURL=templates.mjs.map