@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,55 @@
1
+ import * as Effect from "effect/Effect";
2
+ import CodeBlockWriter_ from "code-block-writer";
3
+ //#region src/CodeBlockWriter.ts
4
+ const indentWriter = Effect.fnUntraced(function* (writer, effect) {
5
+ const indentationLevel = writer.getIndentationLevel();
6
+ writer.setIndentationLevel(indentationLevel + 1);
7
+ yield* effect;
8
+ writer.setIndentationLevel(indentationLevel);
9
+ });
10
+ var CodeBlockWriter = class {
11
+ writer;
12
+ constructor(opts) {
13
+ this.writer = new CodeBlockWriter_(opts);
14
+ }
15
+ indent(effect) {
16
+ return indentWriter(this.writer, effect);
17
+ }
18
+ writeLine(line) {
19
+ return Effect.sync(() => {
20
+ this.writer.writeLine(line);
21
+ });
22
+ }
23
+ write(text) {
24
+ return Effect.sync(() => {
25
+ this.writer.write(text);
26
+ });
27
+ }
28
+ quote(text) {
29
+ return Effect.sync(() => {
30
+ this.writer.quote(text);
31
+ });
32
+ }
33
+ conditionalWriteLine(condition, text) {
34
+ return Effect.sync(() => {
35
+ this.writer.conditionalWriteLine(condition, text);
36
+ });
37
+ }
38
+ newLine() {
39
+ return Effect.sync(() => {
40
+ this.writer.newLine();
41
+ });
42
+ }
43
+ blankLine() {
44
+ return Effect.sync(() => {
45
+ this.writer.blankLine();
46
+ });
47
+ }
48
+ toString() {
49
+ return Effect.sync(() => this.writer.toString());
50
+ }
51
+ };
52
+ //#endregion
53
+ export { CodeBlockWriter };
54
+
55
+ //# sourceMappingURL=CodeBlockWriter.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeBlockWriter.mjs","names":[],"sources":["../src/CodeBlockWriter.ts"],"sourcesContent":["import type { Options as CodeBlockWriterOptions } from \"code-block-writer\";\nimport CodeBlockWriter_ from \"code-block-writer\";\nimport * as Effect from \"effect/Effect\";\n\nconst indentWriter = Effect.fnUntraced(function* <E, R>(\n writer: CodeBlockWriter_,\n effect: Effect.Effect<void, E, R>,\n): Effect.fn.Return<void, E, R> {\n const indentationLevel = writer.getIndentationLevel();\n writer.setIndentationLevel(indentationLevel + 1);\n yield* effect;\n writer.setIndentationLevel(indentationLevel);\n});\n\nexport class CodeBlockWriter {\n private readonly writer: CodeBlockWriter_;\n\n constructor(opts?: Partial<CodeBlockWriterOptions>) {\n this.writer = new CodeBlockWriter_(opts);\n }\n\n indent<E = never, R = never>(\n effect: Effect.Effect<void, E, R>,\n ): Effect.Effect<void, E, R> {\n return indentWriter(this.writer, effect);\n }\n\n writeLine<E = never, R = never>(line: string): Effect.Effect<void, E, R> {\n return Effect.sync(() => {\n this.writer.writeLine(line);\n });\n }\n\n write<E = never, R = never>(text: string): Effect.Effect<void, E, R> {\n return Effect.sync(() => {\n this.writer.write(text);\n });\n }\n\n quote<E = never, R = never>(text: string): Effect.Effect<void, E, R> {\n return Effect.sync(() => {\n this.writer.quote(text);\n });\n }\n\n conditionalWriteLine<E = never, R = never>(\n condition: boolean,\n text: string,\n ): Effect.Effect<void, E, R> {\n return Effect.sync(() => {\n this.writer.conditionalWriteLine(condition, text);\n });\n }\n\n newLine<E = never, R = never>(): Effect.Effect<void, E, R> {\n return Effect.sync(() => {\n this.writer.newLine();\n });\n }\n\n blankLine<E = never, R = never>(): Effect.Effect<void, E, R> {\n return Effect.sync(() => {\n this.writer.blankLine();\n });\n }\n\n toString<E = never, R = never>(): Effect.Effect<string, E, R> {\n return Effect.sync(() => this.writer.toString());\n }\n}\n"],"mappings":";;;AAIA,MAAM,eAAe,OAAO,WAAW,WACrC,QACA,QAC8B;CAC9B,MAAM,mBAAmB,OAAO,oBAAoB;CACpD,OAAO,oBAAoB,mBAAmB,CAAC;CAC/C,OAAO;CACP,OAAO,oBAAoB,gBAAgB;AAC7C,CAAC;AAED,IAAa,kBAAb,MAA6B;CAC3B;CAEA,YAAY,MAAwC;EAClD,KAAK,SAAS,IAAI,iBAAiB,IAAI;CACzC;CAEA,OACE,QAC2B;EAC3B,OAAO,aAAa,KAAK,QAAQ,MAAM;CACzC;CAEA,UAAgC,MAAyC;EACvE,OAAO,OAAO,WAAW;GACvB,KAAK,OAAO,UAAU,IAAI;EAC5B,CAAC;CACH;CAEA,MAA4B,MAAyC;EACnE,OAAO,OAAO,WAAW;GACvB,KAAK,OAAO,MAAM,IAAI;EACxB,CAAC;CACH;CAEA,MAA4B,MAAyC;EACnE,OAAO,OAAO,WAAW;GACvB,KAAK,OAAO,MAAM,IAAI;EACxB,CAAC;CACH;CAEA,qBACE,WACA,MAC2B;EAC3B,OAAO,OAAO,WAAW;GACvB,KAAK,OAAO,qBAAqB,WAAW,IAAI;EAClD,CAAC;CACH;CAEA,UAA2D;EACzD,OAAO,OAAO,WAAW;GACvB,KAAK,OAAO,QAAQ;EACtB,CAAC;CACH;CAEA,YAA6D;EAC3D,OAAO,OAAO,WAAW;GACvB,KAAK,OAAO,UAAU;EACxB,CAAC;CACH;CAEA,WAA8D;EAC5D,OAAO,OAAO,WAAW,KAAK,OAAO,SAAS,CAAC;CACjD;AACF"}
@@ -0,0 +1,194 @@
1
+ import { BuildError, isBuildError } from "./BuildError.mjs";
2
+ import { red } from "./Ansi.mjs";
3
+ import { formatPath, renderBuildError } from "./log.mjs";
4
+ import { SnapshotError } from "./SnapshotError.mjs";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Array from "effect/Array";
7
+ import { pipe } from "effect/Function";
8
+ import * as Match from "effect/Match";
9
+ import "effect/Option";
10
+ import * as Schema from "effect/Schema";
11
+ import * as Console from "effect/Console";
12
+ //#region src/CodegenError.ts
13
+ var MissingImplFileError = class extends Schema.TaggedError()("MissingImplFileError", {
14
+ specPath: Schema.String,
15
+ expectedImplPath: Schema.String
16
+ }) {};
17
+ var MissingSpecFileError = class extends Schema.TaggedError()("MissingSpecFileError", {
18
+ implPath: Schema.String,
19
+ expectedSpecPath: Schema.String
20
+ }) {};
21
+ var SpecMissingDefaultGroupSpecError = class extends Schema.TaggedError()("SpecMissingDefaultGroupSpecError", { specPath: Schema.String }) {};
22
+ var RemoveBusyError = class extends Schema.TaggedError()("RemoveBusyError", {
23
+ path: Schema.String,
24
+ attempts: Schema.Finite,
25
+ cause: Schema.Unknown
26
+ }) {};
27
+ var ComponentNodeGroupError = class extends Schema.TaggedError()("ComponentNodeGroupError", {
28
+ specPath: Schema.String,
29
+ groupPath: Schema.String
30
+ }) {};
31
+ var SpecImportsServerError = class extends Schema.TaggedError()("SpecImportsServerError", {
32
+ specPath: Schema.String,
33
+ importerPaths: Schema.Array(Schema.String)
34
+ }) {};
35
+ var InvalidMiddlewareAttachmentError = class extends Schema.TaggedError()("InvalidMiddlewareAttachmentError", {
36
+ specPath: Schema.String,
37
+ message: Schema.String
38
+ }) {};
39
+ var ImplMissingSpecImportError = class extends Schema.TaggedError()("ImplMissingSpecImportError", {
40
+ implPath: Schema.String,
41
+ expectedSpecPath: Schema.String
42
+ }) {};
43
+ var ImplMissingDefaultLayerError = class extends Schema.TaggedError()("ImplMissingDefaultLayerError", { implPath: Schema.String }) {};
44
+ var ImplNotFinalizedError = class extends Schema.TaggedError()("ImplNotFinalizedError", { implPath: Schema.String }) {};
45
+ var ImplMissingFunctionsError = class extends Schema.TaggedError()("ImplMissingFunctionsError", {
46
+ implPath: Schema.String,
47
+ groupPath: Schema.String,
48
+ missingFunctionNames: Schema.Array(Schema.String)
49
+ }) {};
50
+ var ImplMissingMiddlewareError = class extends Schema.TaggedError()("ImplMissingMiddlewareError", {
51
+ implPath: Schema.String,
52
+ groupPath: Schema.String,
53
+ missingMiddlewareKeys: Schema.Array(Schema.String)
54
+ }) {};
55
+ var ParentChildNameCollisionError = class extends Schema.TaggedError()("ParentChildNameCollisionError", {
56
+ parentSpecPath: Schema.String,
57
+ childSpecPath: Schema.String,
58
+ collisionName: Schema.String,
59
+ collisionKind: Schema.Literals(["function", "group"])
60
+ }) {};
61
+ var InvalidTableDefaultExportError = class extends Schema.TaggedError()("InvalidTableDefaultExportError", { tablePath: Schema.String }) {};
62
+ var InvalidTableFilenameError = class extends Schema.TaggedError()("InvalidTableFilenameError", {
63
+ tablePath: Schema.String,
64
+ reason: Schema.String
65
+ }) {};
66
+ var DuplicateTableNameError = class extends Schema.TaggedError()("DuplicateTableNameError", { collisions: Schema.Array(Schema.Struct({
67
+ tableName: Schema.String,
68
+ tablePaths: Schema.Array(Schema.String)
69
+ })) }) {};
70
+ var LegacySchemaFileError = class extends Schema.TaggedError()("LegacySchemaFileError", { schemaPath: Schema.String }) {};
71
+ var ConflictingDocNameError = class extends Schema.TaggedError()("ConflictingDocNameError", { collisions: Schema.Array(Schema.Struct({
72
+ docName: Schema.String,
73
+ tableNames: Schema.Array(Schema.String)
74
+ })) }) {};
75
+ var InvalidConvexConfigError = class extends Schema.TaggedError()("InvalidConvexConfigError", {
76
+ configPath: Schema.String,
77
+ reason: Schema.String
78
+ }) {};
79
+ var InvalidDeclarationError = class extends Schema.TaggedError()("InvalidDeclarationError", {
80
+ declarationPath: Schema.String,
81
+ reason: Schema.String
82
+ }) {};
83
+ var HandWrittenConvexFileError = class extends Schema.TaggedError()("HandWrittenConvexFileError", {
84
+ convexPath: Schema.String,
85
+ declarationPath: Schema.String
86
+ }) {};
87
+ var DeclarationKindMismatchError = class extends Schema.TaggedError()("DeclarationKindMismatchError", {
88
+ declarationPath: Schema.String,
89
+ declaredKind: Schema.Literals(["app", "component"]),
90
+ targetKind: Schema.Literals(["app", "component"])
91
+ }) {};
92
+ var CallbackPrefixError = class extends Schema.TaggedError()("CallbackPrefixError", {
93
+ declarationPath: Schema.String,
94
+ contractId: Schema.String,
95
+ componentName: Schema.String
96
+ }) {};
97
+ const CodegenError = Schema.Union([
98
+ SnapshotError,
99
+ BuildError,
100
+ MissingImplFileError,
101
+ MissingSpecFileError,
102
+ SpecMissingDefaultGroupSpecError,
103
+ ComponentNodeGroupError,
104
+ RemoveBusyError,
105
+ SpecImportsServerError,
106
+ InvalidMiddlewareAttachmentError,
107
+ ImplMissingSpecImportError,
108
+ ImplMissingDefaultLayerError,
109
+ ImplNotFinalizedError,
110
+ ImplMissingFunctionsError,
111
+ ImplMissingMiddlewareError,
112
+ ParentChildNameCollisionError,
113
+ InvalidTableDefaultExportError,
114
+ InvalidTableFilenameError,
115
+ DuplicateTableNameError,
116
+ LegacySchemaFileError,
117
+ ConflictingDocNameError,
118
+ InvalidConvexConfigError,
119
+ InvalidDeclarationError,
120
+ HandWrittenConvexFileError,
121
+ DeclarationKindMismatchError,
122
+ CallbackPrefixError
123
+ ]);
124
+ const isCodegenError = (error) => {
125
+ if (isBuildError(error)) return true;
126
+ return Schema.is(CodegenError)(error);
127
+ };
128
+ const cross = red("✘");
129
+ const stemFromSpecPath = (specPath) => {
130
+ const lastSep = Math.max(specPath.lastIndexOf("/"), specPath.lastIndexOf("\\"));
131
+ const basename = lastSep < 0 ? specPath : specPath.slice(lastSep + 1);
132
+ return basename.endsWith(".spec.ts") ? basename.slice(0, -8) : basename;
133
+ };
134
+ const singleLine = (...parts) => `${cross} ${parts.join("")}`;
135
+ const renderMissingImplFileError = (error) => singleLine("Spec ", formatPath(error.specPath), " has no sibling impl; create ", formatPath(error.expectedImplPath), " and default-export a GroupImpl layer from it.");
136
+ const renderMissingSpecFileError = (error) => singleLine("Impl ", formatPath(error.implPath), " has no sibling spec; create ", formatPath(error.expectedSpecPath), " and default-export a GroupSpec from it, or remove the impl.");
137
+ const renderSpecMissingDefaultGroupSpecError = (error) => singleLine("Spec ", formatPath(error.specPath), " must default-export a GroupSpec; build it with GroupSpec.make() or GroupSpec.makeNode().");
138
+ const renderSpecImportsServerError = (error) => {
139
+ const importers = error.importerPaths.join(", ");
140
+ return singleLine("Spec ", formatPath(error.specPath), ` reaches a module that imports \`@confect/server\`: ${importers}. Spec modules are bundled into your client, so anything they import ships to the browser—move the server logic into a \`*.impl.ts\` module, or use \`import type\` if you only need the types.`);
141
+ };
142
+ const renderImplMissingSpecImportError = (error) => {
143
+ const stem = stemFromSpecPath(error.expectedSpecPath);
144
+ return singleLine("Impl ", formatPath(error.implPath), ` does not import its sibling spec; add \`import ${stem} from "./${stem}.spec"\` and pass it to FunctionImpl.make/GroupImpl.make.`);
145
+ };
146
+ const renderImplMissingDefaultLayerError = (error) => singleLine("Impl ", formatPath(error.implPath), " must default-export a GroupImpl layer; wrap your handlers with `GroupImpl.make(databaseSchema, groupSpec).pipe(Layer.provide(...))` and `export default` it.");
147
+ const renderImplNotFinalizedError = (error) => singleLine("Impl ", formatPath(error.implPath), " is not finalized; append `GroupImpl.finalize` to the end of the pipeline (e.g. `GroupImpl.make(databaseSchema, group).pipe(Layer.provide(...), GroupImpl.finalize)`).");
148
+ const renderImplMissingFunctionsError = (error) => {
149
+ const names = error.missingFunctionNames.join(", ");
150
+ return singleLine("Impl ", formatPath(error.implPath), ` does not implement every function declared by group \`${error.groupPath}\`; missing: ${names}. Add a \`FunctionImpl.make\` for each missing function and provide it to the group layer.`);
151
+ };
152
+ const renderImplMissingMiddlewareError = (error) => {
153
+ const keys = error.missingMiddlewareKeys.join(", ");
154
+ return singleLine("Impl ", formatPath(error.implPath), ` does not implement every middleware attached to group \`${error.groupPath}\`; missing: ${keys}. Provide a \`MiddlewareImpl.make\` (or \`makeByFunctionType\`/\`provides\`) layer for each missing middleware to the group layer.`);
155
+ };
156
+ const renderInvalidTableDefaultExportError = (error) => singleLine("Table ", formatPath(error.tablePath), " must default-export a Table (e.g. `export default Table.make({ ... })`); convert any named export to a default export.");
157
+ const renderInvalidTableFilenameError = (error) => singleLine("Table ", formatPath(error.tablePath), ` has an invalid filename: ${error.reason} Convex table names must start with a letter and contain only letters, numbers, and underscores; leading underscores are reserved for system tables.`);
158
+ const renderDuplicateTableNameError = (error) => {
159
+ const conflicts = error.collisions.map(({ tableName, tablePaths }) => `\`${tableName}\` (${tablePaths.join(", ")})`).join("; ");
160
+ return singleLine(`Multiple files under \`confect/tables/\` resolve to the same table name. Table names are derived from filenames, so each must be unique across the directory (including subdirectories); rename or remove all but one. Conflicts: ${conflicts}.`);
161
+ };
162
+ const renderConflictingDocNameError = (error) => {
163
+ const conflicts = pipe(error.collisions, Array.map(({ docName, tableNames }) => `\`${docName}\` (${Array.join(tableNames, ", ")})`), Array.join("; "));
164
+ return singleLine(`Multiple tables fold to the same generated document type name. Table names are converted to PascalCase (so \`user_profiles\` and \`userProfiles\` both become \`UserProfilesDoc\`); rename all but one of each colliding group. Conflicts: ${conflicts}.`);
165
+ };
166
+ const renderInvalidConvexConfigError = (error) => singleLine("Convex config ", formatPath(error.configPath), ` could not be evaluated: ${error.reason}`);
167
+ const renderLegacySchemaFileError = (error) => singleLine("Found a legacy ", formatPath(error.schemaPath), ". Delete it: tables in `confect/tables/*.ts` are now the single source of truth, and the runtime schema is generated as `confect/_generated/schema.ts`.");
168
+ const renderParentChildNameCollisionError = (error) => singleLine("Spec ", formatPath(error.parentSpecPath), ` declares a ${error.collisionKind} \`${error.collisionName}\` whose name collides with the sibling subdirectory spec `, formatPath(error.childSpecPath), `. Rename one of them so the assembled spec has a unique key at this path.`);
169
+ /**
170
+ * Render any {@link CodegenError} into a styled, ready-to-print string.
171
+ * Single-error variants render to a one-line `✘`-prefixed message;
172
+ * `BundleFailedError` (the only multi-error variant) renders to a header plus
173
+ * an esbuild diagnostic block.
174
+ */
175
+ const renderCodegenError = (error) => {
176
+ if (isBuildError(error)) return renderBuildError(error);
177
+ if (error._tag === "ComponentNodeGroupError") return singleLine(`Group "${error.groupPath}" in ${error.specPath} uses the Node runtime. Convex components do not support Node.js functions.`);
178
+ if (error._tag === "RemoveBusyError") return singleLine("Could not remove ", formatPath(error.path), ` after ${error.attempts} attempts because it is busy. Close other tools using it and try again.`);
179
+ if (error._tag === "InvalidDeclarationError") return singleLine("Declaration ", formatPath(error.declarationPath), ` is invalid: ${error.reason}`);
180
+ if (error._tag === "DeclarationKindMismatchError") return singleLine("Declaration ", formatPath(error.declarationPath), ` declares kind "${error.declaredKind}", but the target directory is kind "${error.targetKind}".`);
181
+ if (error._tag === "CallbackPrefixError") return singleLine("Callback contract ", `"${error.contractId}" in `, formatPath(error.declarationPath), ` must start with "${error.componentName}/" for component "${error.componentName}".`);
182
+ if (error._tag === "HandWrittenConvexFileError") return singleLine("Found a hand-written ", formatPath(error.convexPath), ". `confect codegen` writes it from ", formatPath(error.declarationPath), " now; move its contents there and delete the file.");
183
+ return Match.value(error).pipe(Match.tag("SnapshotError", ({ reason, relativePath, pathSegments }) => singleLine(`Invalid generation metadata (${reason})`, relativePath === "" ? "" : ` for ${relativePath}`, pathSegments.length === 0 ? "." : ` at ${pathSegments.join("/")}.`)), Match.tag("MissingImplFileError", renderMissingImplFileError), Match.tag("MissingSpecFileError", renderMissingSpecFileError), Match.tag("SpecMissingDefaultGroupSpecError", renderSpecMissingDefaultGroupSpecError), Match.tag("SpecImportsServerError", renderSpecImportsServerError), Match.tag("InvalidMiddlewareAttachmentError", (attachmentError) => singleLine("Spec ", formatPath(attachmentError.specPath), `: ${attachmentError.message}`)), Match.tag("ImplMissingSpecImportError", renderImplMissingSpecImportError), Match.tag("ImplMissingDefaultLayerError", renderImplMissingDefaultLayerError), Match.tag("ImplNotFinalizedError", renderImplNotFinalizedError), Match.tag("ImplMissingFunctionsError", renderImplMissingFunctionsError), Match.tag("ImplMissingMiddlewareError", renderImplMissingMiddlewareError), Match.tag("ParentChildNameCollisionError", renderParentChildNameCollisionError), Match.tag("InvalidTableDefaultExportError", renderInvalidTableDefaultExportError), Match.tag("InvalidTableFilenameError", renderInvalidTableFilenameError), Match.tag("DuplicateTableNameError", renderDuplicateTableNameError), Match.tag("LegacySchemaFileError", renderLegacySchemaFileError), Match.tag("ConflictingDocNameError", renderConflictingDocNameError), Match.tag("InvalidConvexConfigError", renderInvalidConvexConfigError), Match.exhaustive);
184
+ };
185
+ const logCodegenError = (error) => Console.error(renderCodegenError(error));
186
+ /**
187
+ * Log any {@link CodegenError} thrown by `effect` and propagate the failure
188
+ * unchanged so the caller's error channel is preserved.
189
+ */
190
+ const tapAndLog = (effect) => effect.pipe(Effect.tapError((error) => isCodegenError(error) ? logCodegenError(error) : Effect.void));
191
+ //#endregion
192
+ export { CallbackPrefixError, CodegenError, ComponentNodeGroupError, ConflictingDocNameError, DeclarationKindMismatchError, DuplicateTableNameError, HandWrittenConvexFileError, ImplMissingDefaultLayerError, ImplMissingFunctionsError, ImplMissingMiddlewareError, ImplMissingSpecImportError, ImplNotFinalizedError, InvalidConvexConfigError, InvalidDeclarationError, InvalidMiddlewareAttachmentError, InvalidTableDefaultExportError, InvalidTableFilenameError, LegacySchemaFileError, MissingImplFileError, MissingSpecFileError, ParentChildNameCollisionError, RemoveBusyError, SpecImportsServerError, SpecMissingDefaultGroupSpecError, isCodegenError, logCodegenError, renderCodegenError, tapAndLog };
193
+
194
+ //# sourceMappingURL=CodegenError.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodegenError.mjs","names":["Ansi.red"],"sources":["../src/CodegenError.ts"],"sourcesContent":["import * as Array from \"effect/Array\";\nimport * as Console from \"effect/Console\";\nimport { pipe } from \"effect/Function\";\nimport * as Effect from \"effect/Effect\";\nimport * as Match from \"effect/Match\";\nimport * as Option from \"effect/Option\";\nimport * as Schema from \"effect/Schema\";\nimport { BuildError, isBuildError } from \"./BuildError\";\nimport { SnapshotError } from \"./SnapshotError\";\nimport * as Ansi from \"./Ansi\";\nimport { formatPath, renderBuildError } from \"./log\";\n\n// --- Variants ---\n\nexport class MissingImplFileError extends Schema.TaggedError<MissingImplFileError>()(\n \"MissingImplFileError\",\n {\n specPath: Schema.String,\n expectedImplPath: Schema.String,\n },\n) {}\n\nexport class MissingSpecFileError extends Schema.TaggedError<MissingSpecFileError>()(\n \"MissingSpecFileError\",\n {\n implPath: Schema.String,\n expectedSpecPath: Schema.String,\n },\n) {}\n\nexport class SpecMissingDefaultGroupSpecError extends Schema.TaggedError<SpecMissingDefaultGroupSpecError>()(\n \"SpecMissingDefaultGroupSpecError\",\n {\n specPath: Schema.String,\n },\n) {}\n\nexport class RemoveBusyError extends Schema.TaggedError<RemoveBusyError>()(\n \"RemoveBusyError\",\n { path: Schema.String, attempts: Schema.Finite, cause: Schema.Unknown },\n) {}\n\nexport class ComponentNodeGroupError extends Schema.TaggedError<ComponentNodeGroupError>()(\n \"ComponentNodeGroupError\",\n {\n specPath: Schema.String,\n groupPath: Schema.String,\n },\n) {}\n\nexport class SpecImportsServerError extends Schema.TaggedError<SpecImportsServerError>()(\n \"SpecImportsServerError\",\n {\n specPath: Schema.String,\n importerPaths: Schema.Array(Schema.String),\n },\n) {}\n\nexport class InvalidMiddlewareAttachmentError extends Schema.TaggedError<InvalidMiddlewareAttachmentError>()(\n \"InvalidMiddlewareAttachmentError\",\n { specPath: Schema.String, message: Schema.String },\n) {}\n\nexport class ImplMissingSpecImportError extends Schema.TaggedError<ImplMissingSpecImportError>()(\n \"ImplMissingSpecImportError\",\n {\n implPath: Schema.String,\n expectedSpecPath: Schema.String,\n },\n) {}\n\nexport class ImplMissingDefaultLayerError extends Schema.TaggedError<ImplMissingDefaultLayerError>()(\n \"ImplMissingDefaultLayerError\",\n {\n implPath: Schema.String,\n },\n) {}\n\nexport class ImplNotFinalizedError extends Schema.TaggedError<ImplNotFinalizedError>()(\n \"ImplNotFinalizedError\",\n {\n implPath: Schema.String,\n },\n) {}\n\nexport class ImplMissingFunctionsError extends Schema.TaggedError<ImplMissingFunctionsError>()(\n \"ImplMissingFunctionsError\",\n {\n implPath: Schema.String,\n groupPath: Schema.String,\n missingFunctionNames: Schema.Array(Schema.String),\n },\n) {}\n\nexport class ImplMissingMiddlewareError extends Schema.TaggedError<ImplMissingMiddlewareError>()(\n \"ImplMissingMiddlewareError\",\n {\n implPath: Schema.String,\n groupPath: Schema.String,\n missingMiddlewareKeys: Schema.Array(Schema.String),\n },\n) {}\n\nexport class ParentChildNameCollisionError extends Schema.TaggedError<ParentChildNameCollisionError>()(\n \"ParentChildNameCollisionError\",\n {\n parentSpecPath: Schema.String,\n childSpecPath: Schema.String,\n collisionName: Schema.String,\n collisionKind: Schema.Literals([\"function\", \"group\"]),\n },\n) {}\n\nexport class InvalidTableDefaultExportError extends Schema.TaggedError<InvalidTableDefaultExportError>()(\n \"InvalidTableDefaultExportError\",\n {\n tablePath: Schema.String,\n },\n) {}\n\nexport class InvalidTableFilenameError extends Schema.TaggedError<InvalidTableFilenameError>()(\n \"InvalidTableFilenameError\",\n {\n tablePath: Schema.String,\n reason: Schema.String,\n },\n) {}\n\nexport class DuplicateTableNameError extends Schema.TaggedError<DuplicateTableNameError>()(\n \"DuplicateTableNameError\",\n {\n // Every table name that more than one file resolves to, each paired with\n // the colliding file paths. All collisions are captured in a single pass\n // so the user can fix them together rather than re-running codegen once\n // per conflict.\n collisions: Schema.Array(\n Schema.Struct({\n tableName: Schema.String,\n tablePaths: Schema.Array(Schema.String),\n }),\n ),\n },\n) {}\n\nexport class LegacySchemaFileError extends Schema.TaggedError<LegacySchemaFileError>()(\n \"LegacySchemaFileError\",\n {\n schemaPath: Schema.String,\n },\n) {}\n\nexport class ConflictingDocNameError extends Schema.TaggedError<ConflictingDocNameError>()(\n \"ConflictingDocNameError\",\n {\n collisions: Schema.Array(\n Schema.Struct({\n docName: Schema.String,\n tableNames: Schema.Array(Schema.String),\n }),\n ),\n },\n) {}\n\nexport class InvalidConvexConfigError extends Schema.TaggedError<InvalidConvexConfigError>()(\n \"InvalidConvexConfigError\",\n {\n configPath: Schema.String,\n reason: Schema.String,\n },\n) {}\n\nexport class InvalidDeclarationError extends Schema.TaggedError<InvalidDeclarationError>()(\n \"InvalidDeclarationError\",\n {\n declarationPath: Schema.String,\n reason: Schema.String,\n },\n) {}\n\nexport class HandWrittenConvexFileError extends Schema.TaggedError<HandWrittenConvexFileError>()(\n \"HandWrittenConvexFileError\",\n {\n convexPath: Schema.String,\n declarationPath: Schema.String,\n },\n) {}\n\nexport class DeclarationKindMismatchError extends Schema.TaggedError<DeclarationKindMismatchError>()(\n \"DeclarationKindMismatchError\",\n {\n declarationPath: Schema.String,\n declaredKind: Schema.Literals([\"app\", \"component\"]),\n targetKind: Schema.Literals([\"app\", \"component\"]),\n },\n) {}\n\nexport class CallbackPrefixError extends Schema.TaggedError<CallbackPrefixError>()(\n \"CallbackPrefixError\",\n {\n declarationPath: Schema.String,\n contractId: Schema.String,\n componentName: Schema.String,\n },\n) {}\n\nexport const CodegenError = Schema.Union([\n SnapshotError,\n BuildError,\n MissingImplFileError,\n MissingSpecFileError,\n SpecMissingDefaultGroupSpecError,\n ComponentNodeGroupError,\n RemoveBusyError,\n SpecImportsServerError,\n InvalidMiddlewareAttachmentError,\n ImplMissingSpecImportError,\n ImplMissingDefaultLayerError,\n ImplNotFinalizedError,\n ImplMissingFunctionsError,\n ImplMissingMiddlewareError,\n ParentChildNameCollisionError,\n InvalidTableDefaultExportError,\n InvalidTableFilenameError,\n DuplicateTableNameError,\n LegacySchemaFileError,\n ConflictingDocNameError,\n InvalidConvexConfigError,\n InvalidDeclarationError,\n HandWrittenConvexFileError,\n DeclarationKindMismatchError,\n CallbackPrefixError,\n]);\nexport type CodegenError = typeof CodegenError.Type;\n\nexport const isCodegenError = (error: unknown): error is CodegenError => {\n if (isBuildError(error)) return true;\n return Schema.is(CodegenError)(error);\n};\n\n// --- Per-variant rendering ---\n\nconst cross = Ansi.red(\"✘\");\n\nconst stemFromSpecPath = (specPath: string): string => {\n const lastSep = Math.max(\n specPath.lastIndexOf(\"/\"),\n specPath.lastIndexOf(\"\\\\\"),\n );\n const basename = lastSep < 0 ? specPath : specPath.slice(lastSep + 1);\n return basename.endsWith(\".spec.ts\")\n ? basename.slice(0, -\".spec.ts\".length)\n : basename;\n};\n\nconst singleLine = (...parts: ReadonlyArray<string>): string =>\n `${cross} ${parts.join(\"\")}`;\n\nconst renderMissingImplFileError = (error: MissingImplFileError): string =>\n singleLine(\n \"Spec \",\n formatPath(error.specPath),\n \" has no sibling impl; create \",\n formatPath(error.expectedImplPath),\n \" and default-export a GroupImpl layer from it.\",\n );\n\nconst renderMissingSpecFileError = (error: MissingSpecFileError): string =>\n singleLine(\n \"Impl \",\n formatPath(error.implPath),\n \" has no sibling spec; create \",\n formatPath(error.expectedSpecPath),\n \" and default-export a GroupSpec from it, or remove the impl.\",\n );\n\nconst renderSpecMissingDefaultGroupSpecError = (\n error: SpecMissingDefaultGroupSpecError,\n): string =>\n singleLine(\n \"Spec \",\n formatPath(error.specPath),\n \" must default-export a GroupSpec; build it with GroupSpec.make() or GroupSpec.makeNode().\",\n );\n\nconst renderSpecImportsServerError = (\n error: SpecImportsServerError,\n): string => {\n const importers = error.importerPaths.join(\", \");\n return singleLine(\n \"Spec \",\n formatPath(error.specPath),\n ` reaches a module that imports \\`@confect/server\\`: ${importers}. Spec modules are bundled into your client, so anything they import ships to the browser—move the server logic into a \\`*.impl.ts\\` module, or use \\`import type\\` if you only need the types.`,\n );\n};\n\nconst renderImplMissingSpecImportError = (\n error: ImplMissingSpecImportError,\n): string => {\n const stem = stemFromSpecPath(error.expectedSpecPath);\n return singleLine(\n \"Impl \",\n formatPath(error.implPath),\n ` does not import its sibling spec; add \\`import ${stem} from \"./${stem}.spec\"\\` and pass it to FunctionImpl.make/GroupImpl.make.`,\n );\n};\n\nconst renderImplMissingDefaultLayerError = (\n error: ImplMissingDefaultLayerError,\n): string =>\n singleLine(\n \"Impl \",\n formatPath(error.implPath),\n \" must default-export a GroupImpl layer; wrap your handlers with `GroupImpl.make(databaseSchema, groupSpec).pipe(Layer.provide(...))` and `export default` it.\",\n );\n\nconst renderImplNotFinalizedError = (error: ImplNotFinalizedError): string =>\n singleLine(\n \"Impl \",\n formatPath(error.implPath),\n \" is not finalized; append `GroupImpl.finalize` to the end of the pipeline (e.g. `GroupImpl.make(databaseSchema, group).pipe(Layer.provide(...), GroupImpl.finalize)`).\",\n );\n\nconst renderImplMissingFunctionsError = (\n error: ImplMissingFunctionsError,\n): string => {\n const names = error.missingFunctionNames.join(\", \");\n return singleLine(\n \"Impl \",\n formatPath(error.implPath),\n ` does not implement every function declared by group \\`${error.groupPath}\\`; missing: ${names}. Add a \\`FunctionImpl.make\\` for each missing function and provide it to the group layer.`,\n );\n};\n\nconst renderImplMissingMiddlewareError = (\n error: ImplMissingMiddlewareError,\n): string => {\n const keys = error.missingMiddlewareKeys.join(\", \");\n return singleLine(\n \"Impl \",\n formatPath(error.implPath),\n ` does not implement every middleware attached to group \\`${error.groupPath}\\`; missing: ${keys}. Provide a \\`MiddlewareImpl.make\\` (or \\`makeByFunctionType\\`/\\`provides\\`) layer for each missing middleware to the group layer.`,\n );\n};\n\nconst renderInvalidTableDefaultExportError = (\n error: InvalidTableDefaultExportError,\n): string =>\n singleLine(\n \"Table \",\n formatPath(error.tablePath),\n \" must default-export a Table (e.g. `export default Table.make({ ... })`); convert any named export to a default export.\",\n );\n\nconst renderInvalidTableFilenameError = (\n error: InvalidTableFilenameError,\n): string =>\n singleLine(\n \"Table \",\n formatPath(error.tablePath),\n ` has an invalid filename: ${error.reason} Convex table names must start with a letter and contain only letters, numbers, and underscores; leading underscores are reserved for system tables.`,\n );\n\nconst renderDuplicateTableNameError = (\n error: DuplicateTableNameError,\n): string => {\n const conflicts = error.collisions\n .map(\n ({ tableName, tablePaths }) =>\n `\\`${tableName}\\` (${tablePaths.join(\", \")})`,\n )\n .join(\"; \");\n return singleLine(\n `Multiple files under \\`confect/tables/\\` resolve to the same table name. Table names are derived from filenames, so each must be unique across the directory (including subdirectories); rename or remove all but one. Conflicts: ${conflicts}.`,\n );\n};\n\nconst renderConflictingDocNameError = (\n error: ConflictingDocNameError,\n): string => {\n const conflicts = pipe(\n error.collisions,\n Array.map(\n ({ docName, tableNames }) =>\n `\\`${docName}\\` (${Array.join(tableNames, \", \")})`,\n ),\n Array.join(\"; \"),\n );\n return singleLine(\n `Multiple tables fold to the same generated document type name. Table names are converted to PascalCase (so \\`user_profiles\\` and \\`userProfiles\\` both become \\`UserProfilesDoc\\`); rename all but one of each colliding group. Conflicts: ${conflicts}.`,\n );\n};\n\nconst renderInvalidConvexConfigError = (\n error: InvalidConvexConfigError,\n): string =>\n singleLine(\n \"Convex config \",\n formatPath(error.configPath),\n ` could not be evaluated: ${error.reason}`,\n );\n\nconst renderLegacySchemaFileError = (error: LegacySchemaFileError): string =>\n singleLine(\n \"Found a legacy \",\n formatPath(error.schemaPath),\n \". Delete it: tables in `confect/tables/*.ts` are now the single source of truth, and the runtime schema is generated as `confect/_generated/schema.ts`.\",\n );\n\nconst renderParentChildNameCollisionError = (\n error: ParentChildNameCollisionError,\n): string =>\n singleLine(\n \"Spec \",\n formatPath(error.parentSpecPath),\n ` declares a ${error.collisionKind} \\`${error.collisionName}\\` whose name collides with the sibling subdirectory spec `,\n formatPath(error.childSpecPath),\n `. Rename one of them so the assembled spec has a unique key at this path.`,\n );\n\n/**\n * Render any {@link CodegenError} into a styled, ready-to-print string.\n * Single-error variants render to a one-line `✘`-prefixed message;\n * `BundleFailedError` (the only multi-error variant) renders to a header plus\n * an esbuild diagnostic block.\n */\nexport const renderCodegenError = (error: CodegenError): string => {\n if (isBuildError(error)) return renderBuildError(error);\n // The renderer pipeline below is at Effect's pipe arity limit, so the\n // fork's errors render here.\n if (error._tag === \"ComponentNodeGroupError\") {\n return singleLine(\n `Group \"${error.groupPath}\" in ${error.specPath} uses the Node runtime. Convex components do not support Node.js functions.`,\n );\n }\n if (error._tag === \"RemoveBusyError\") {\n return singleLine(\n \"Could not remove \",\n formatPath(error.path),\n ` after ${error.attempts} attempts because it is busy. Close other tools using it and try again.`,\n );\n }\n if (error._tag === \"InvalidDeclarationError\") {\n return singleLine(\n \"Declaration \",\n formatPath(error.declarationPath),\n ` is invalid: ${error.reason}`,\n );\n }\n if (error._tag === \"DeclarationKindMismatchError\") {\n return singleLine(\n \"Declaration \",\n formatPath(error.declarationPath),\n ` declares kind \"${error.declaredKind}\", but the target directory is kind \"${error.targetKind}\".`,\n );\n }\n if (error._tag === \"CallbackPrefixError\") {\n return singleLine(\n \"Callback contract \",\n `\"${error.contractId}\" in `,\n formatPath(error.declarationPath),\n ` must start with \"${error.componentName}/\" for component \"${error.componentName}\".`,\n );\n }\n if (error._tag === \"HandWrittenConvexFileError\") {\n return singleLine(\n \"Found a hand-written \",\n formatPath(error.convexPath),\n \". `confect codegen` writes it from \",\n formatPath(error.declarationPath),\n \" now; move its contents there and delete the file.\",\n );\n }\n return Match.value(error).pipe(\n Match.tag(\"SnapshotError\", ({ reason, relativePath, pathSegments }) =>\n singleLine(\n `Invalid generation metadata (${reason})`,\n relativePath === \"\" ? \"\" : ` for ${relativePath}`,\n pathSegments.length === 0 ? \".\" : ` at ${pathSegments.join(\"/\")}.`,\n ),\n ),\n Match.tag(\"MissingImplFileError\", renderMissingImplFileError),\n Match.tag(\"MissingSpecFileError\", renderMissingSpecFileError),\n Match.tag(\n \"SpecMissingDefaultGroupSpecError\",\n renderSpecMissingDefaultGroupSpecError,\n ),\n Match.tag(\"SpecImportsServerError\", renderSpecImportsServerError),\n Match.tag(\"InvalidMiddlewareAttachmentError\", (attachmentError) =>\n singleLine(\n \"Spec \",\n formatPath(attachmentError.specPath),\n `: ${attachmentError.message}`,\n ),\n ),\n Match.tag(\"ImplMissingSpecImportError\", renderImplMissingSpecImportError),\n Match.tag(\n \"ImplMissingDefaultLayerError\",\n renderImplMissingDefaultLayerError,\n ),\n Match.tag(\"ImplNotFinalizedError\", renderImplNotFinalizedError),\n Match.tag(\"ImplMissingFunctionsError\", renderImplMissingFunctionsError),\n Match.tag(\"ImplMissingMiddlewareError\", renderImplMissingMiddlewareError),\n Match.tag(\n \"ParentChildNameCollisionError\",\n renderParentChildNameCollisionError,\n ),\n Match.tag(\n \"InvalidTableDefaultExportError\",\n renderInvalidTableDefaultExportError,\n ),\n Match.tag(\"InvalidTableFilenameError\", renderInvalidTableFilenameError),\n Match.tag(\"DuplicateTableNameError\", renderDuplicateTableNameError),\n Match.tag(\"LegacySchemaFileError\", renderLegacySchemaFileError),\n Match.tag(\"ConflictingDocNameError\", renderConflictingDocNameError),\n Match.tag(\"InvalidConvexConfigError\", renderInvalidConvexConfigError),\n Match.exhaustive,\n );\n};\n\nexport const logCodegenError = (error: CodegenError) =>\n Console.error(renderCodegenError(error));\n\n// --- Effect combinators ---\n\n/**\n * Log any {@link CodegenError} thrown by `effect` and propagate the failure\n * unchanged so the caller's error channel is preserved.\n */\nexport const tapAndLog = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, E, R> =>\n effect.pipe(\n Effect.tapError((error) =>\n isCodegenError(error) ? logCodegenError(error) : Effect.void,\n ),\n );\n\n/**\n * Catch any {@link CodegenError} thrown by `effect`, log it, and resolve to\n * `Option.none()`. Success resolves to `Option.some(value)`.\n */\n// oxlint-disable effecttsgo/unsafe-effect-type-assertion -- catchIf removes the error variant selected by this refinement.\nexport const catchAndLog = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<Option.Option<A>, Exclude<E, CodegenError>, R> =>\n Effect.catchIf(Effect.map(effect, Option.some<A>), isCodegenError, (error) =>\n logCodegenError(error).pipe(Effect.as(Option.none<A>())),\n ) as Effect.Effect<Option.Option<A>, Exclude<E, CodegenError>, R>;\n// oxlint-enable effecttsgo/unsafe-effect-type-assertion\n"],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { ConvexDirectory, layer as layer$1 } from "./ConvexDirectory.mjs";
2
+ import * as Effect from "effect/Effect";
3
+ import * as FileSystem from "effect/FileSystem";
4
+ import * as Path from "effect/Path";
5
+ import * as Context from "effect/Context";
6
+ import * as Ref from "effect/Ref";
7
+ import * as Schema from "effect/Schema";
8
+ import * as Layer from "effect/Layer";
9
+ //#region src/ConfectDirectory.ts
10
+ var ConfectDirectory = class ConfectDirectory extends Context.Service()("@confect/cli/ConfectDirectory") {
11
+ static get = ConfectDirectory.use((service) => service.get);
12
+ };
13
+ var ConfectDirectoryNotFoundError = class extends Schema.TaggedError()("ConfectDirectoryNotFoundError", {}) {
14
+ get message() {
15
+ return "Could not find Confect directory";
16
+ }
17
+ };
18
+ const findConfectDirectory = Effect.gen(function* () {
19
+ const fs = yield* FileSystem.FileSystem;
20
+ const path = yield* Path.Path;
21
+ const convexDirectory = yield* ConvexDirectory.get;
22
+ const confectDirectory = path.join(path.dirname(convexDirectory), "confect");
23
+ if (yield* fs.exists(confectDirectory)) return confectDirectory;
24
+ else return yield* new ConfectDirectoryNotFoundError();
25
+ });
26
+ const layerFromConvexDirectory = Layer.effect(ConfectDirectory, Effect.gen(function* () {
27
+ const confectDirectory = yield* findConfectDirectory;
28
+ const ref = yield* Ref.make(confectDirectory);
29
+ return { get: Ref.get(ref) };
30
+ }));
31
+ layerFromConvexDirectory.pipe(Layer.provide(layer$1));
32
+ //#endregion
33
+ export { ConfectDirectory, ConfectDirectoryNotFoundError, findConfectDirectory, layerFromConvexDirectory };
34
+
35
+ //# sourceMappingURL=ConfectDirectory.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfectDirectory.mjs","names":["ConvexDirectory.layer"],"sources":["../src/ConfectDirectory.ts"],"sourcesContent":["import * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as FileSystem from \"effect/FileSystem\";\nimport * as Layer from \"effect/Layer\";\nimport * as Path from \"effect/Path\";\nimport * as Ref from \"effect/Ref\";\nimport * as Schema from \"effect/Schema\";\nimport * as ConvexDirectory from \"./ConvexDirectory\";\n\nexport class ConfectDirectory extends Context.Service<\n ConfectDirectory,\n { readonly get: Effect.Effect<string> }\n>()(\"@confect/cli/ConfectDirectory\") {\n static readonly get = ConfectDirectory.use((service) => service.get);\n}\n\nexport class ConfectDirectoryNotFoundError extends Schema.TaggedError<ConfectDirectoryNotFoundError>()(\n \"ConfectDirectoryNotFoundError\",\n {},\n) {\n override get message(): string {\n return \"Could not find Confect directory\";\n }\n}\n\nexport const findConfectDirectory = Effect.gen(function* () {\n const fs = yield* FileSystem.FileSystem;\n const path = yield* Path.Path;\n\n const convexDirectory = yield* ConvexDirectory.ConvexDirectory.get;\n\n const confectDirectory = path.join(path.dirname(convexDirectory), \"confect\");\n\n if (yield* fs.exists(confectDirectory)) {\n return confectDirectory;\n } else {\n return yield* new ConfectDirectoryNotFoundError();\n }\n});\n\nexport const layerFromConvexDirectory = Layer.effect(\n ConfectDirectory,\n Effect.gen(function* () {\n const confectDirectory = yield* findConfectDirectory;\n\n const ref = yield* Ref.make<string>(confectDirectory);\n\n return { get: Ref.get(ref) } as const;\n }),\n);\n\nexport const layer = layerFromConvexDirectory.pipe(\n Layer.provide(ConvexDirectory.layer),\n);\n"],"mappings":";;;;;;;;;AASA,IAAa,mBAAb,MAAa,yBAAyB,QAAQ,QAG5C,CAAC,CAAC,+BAA+B,CAAC,CAAC;CACnC,OAAgB,MAAM,iBAAiB,KAAK,YAAY,QAAQ,GAAG;AACrE;AAEA,IAAa,gCAAb,cAAmD,OAAO,YAA2C,CAAC,CACpG,iCACA,CAAC,CACH,CAAC,CAAC;CACA,IAAa,UAAkB;EAC7B,OAAO;CACT;AACF;AAEA,MAAa,uBAAuB,OAAO,IAAI,aAAa;CAC1D,MAAM,KAAK,OAAO,WAAW;CAC7B,MAAM,OAAO,OAAO,KAAK;CAEzB,MAAM,kBAAkB,OAAA,gBAAuC;CAE/D,MAAM,mBAAmB,KAAK,KAAK,KAAK,QAAQ,eAAe,GAAG,SAAS;CAE3E,IAAI,OAAO,GAAG,OAAO,gBAAgB,GACnC,OAAO;MAEP,OAAO,OAAO,IAAI,8BAA8B;AAEpD,CAAC;AAED,MAAa,2BAA2B,MAAM,OAC5C,kBACA,OAAO,IAAI,aAAa;CACtB,MAAM,mBAAmB,OAAO;CAEhC,MAAM,MAAM,OAAO,IAAI,KAAa,gBAAgB;CAEpD,OAAO,EAAE,KAAK,IAAI,IAAI,GAAG,EAAE;AAC7B,CAAC,CACH;AAEqB,yBAAyB,KAC5C,MAAM,QAAQA,OAAqB,CACrC"}
@@ -0,0 +1,198 @@
1
+ import { fromBundlerError } from "./BuildError.mjs";
2
+ import { bundle, resolveModule } from "./Bundler.mjs";
3
+ import { InvalidConvexConfigError } from "./CodegenError.mjs";
4
+ import { toPosixPath } from "./utils.mjs";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Path from "effect/Path";
7
+ import * as Array from "effect/Array";
8
+ import { pipe } from "effect/Function";
9
+ import * as Match from "effect/Match";
10
+ import * as Option from "effect/Option";
11
+ import * as Record from "effect/Record";
12
+ import * as Schema from "effect/Schema";
13
+ import * as String from "effect/String";
14
+ import * as Predicate from "effect/Predicate";
15
+ import * as Order from "effect/Order";
16
+ //#region src/ConvexConfig.ts
17
+ const CONVEX_CONFIG_FILENAME = "convex.config.ts";
18
+ const COMPONENT_CONFIG_NAMESPACE = "confect-component-config";
19
+ /**
20
+ * Where the plugin records how a definition was imported: the specifier as
21
+ * written and the file it resolved to. Codegen reads it to write the import of
22
+ * each mounted component into the generated `convex.config.ts`.
23
+ */
24
+ const COMPONENT_IMPORT_KEY = "~confect/componentImport";
25
+ const componentImportOf = (definition) => {
26
+ if (!Predicate.hasProperty(definition, "~confect/componentImport")) return Option.none();
27
+ const recorded = definition[COMPONENT_IMPORT_KEY];
28
+ return Predicate.hasProperty(recorded, "specifier") && Predicate.isString(recorded.specifier) && Predicate.hasProperty(recorded, "path") && Predicate.isString(recorded.path) ? Option.some({
29
+ specifier: recorded.specifier,
30
+ path: recorded.path
31
+ }) : Option.none();
32
+ };
33
+ /**
34
+ * Matches the trailing `convex.config` segment of a component-definition import
35
+ * (with or without an extension), e.g. `@convex-dev/workpool/convex.config` or
36
+ * `./waitlist/convex.config.ts`.
37
+ */
38
+ const CONVEX_CONFIG_SUFFIX = /[/\\]convex\.config(\.[cm]?[jt]s)?$/;
39
+ /**
40
+ * Resolve the same config spellings that Convex accepts, for configs and test
41
+ * kits.
42
+ */
43
+ const resolveDefinition = (specifier, importer, path) => {
44
+ const extension = path.extname(specifier);
45
+ const candidates = [
46
+ specifier,
47
+ ...extension === ".js" ? [specifier.slice(0, -3) + ".ts"] : [],
48
+ ...extension !== ".js" && extension !== ".ts" ? [specifier + ".js", specifier + ".ts"] : []
49
+ ];
50
+ return Option.firstSomeOf(candidates.map((candidate) => resolveModule(candidate, importer)));
51
+ };
52
+ /**
53
+ * `convex/server`'s `app.use(definition)` rejects any definition object that
54
+ * lacks a string `componentDefinitionPath` ("This code only works in Convex
55
+ * runtime"): that property is normally stamped on by the Convex backend's
56
+ * module system when it evaluates a definition bundle. To evaluate
57
+ * `convex.config.ts` in plain Node, this plugin intercepts every non-entry
58
+ * import of a `convex.config` module (mirroring the Convex CLI's own
59
+ * `componentPlugin`) and swaps in a virtual wrapper that re-exports the real
60
+ * definition with `componentDefinitionPath` and `defaultName` filled in—the
61
+ * exact shape of Convex's `ImportedComponentDefinition`.
62
+ */
63
+ const componentConfigPlugin = (path) => ({
64
+ name: "confect:component-config",
65
+ setup(build) {
66
+ build.onResolve({ filter: /convex\.config/ }, (args) => {
67
+ if (args.kind === "entry-point") return void 0;
68
+ if (args.namespace === COMPONENT_CONFIG_NAMESPACE) return { path: args.path };
69
+ if (args.namespace !== "file" && args.namespace !== "") return void 0;
70
+ const importer = args.importer !== "" ? args.importer : path.join(args.resolveDir, "_");
71
+ return pipe(resolveDefinition(args.path, importer, path), Option.match({
72
+ onNone: () => void 0,
73
+ onSome: (resolved) => ({
74
+ path: resolved,
75
+ namespace: COMPONENT_CONFIG_NAMESPACE,
76
+ pluginData: { specifier: args.path }
77
+ })
78
+ }));
79
+ });
80
+ build.onLoad({
81
+ filter: /.*/,
82
+ namespace: COMPONENT_CONFIG_NAMESPACE
83
+ }, (args) => {
84
+ const specifier = args.pluginData.specifier;
85
+ const componentDefinitionPath = !String.startsWith(".")(specifier) && !path.isAbsolute(specifier) ? String.replace(CONVEX_CONFIG_SUFFIX, "")(specifier) : path.dirname(args.path);
86
+ return {
87
+ loader: "js",
88
+ resolveDir: path.dirname(args.path),
89
+ contents: Array.join([`import real from ${JSON.stringify(args.path)};`, `export default { ...real, componentDefinitionPath: ${JSON.stringify(componentDefinitionPath)}, defaultName: real._name, [${JSON.stringify(COMPONENT_IMPORT_KEY)}]: ${JSON.stringify({
90
+ specifier,
91
+ path: args.path
92
+ })} };`], "\n")
93
+ };
94
+ });
95
+ }
96
+ });
97
+ /**
98
+ * The subset of `app.export()` (Convex's `AppDefinitionAnalysis`) that the
99
+ * registry needs: each installed component's mount name and the
100
+ * `componentDefinitionPath` injected by {@link componentConfigPlugin}.
101
+ */
102
+ const AppDefinitionAnalysis = Schema.Struct({
103
+ httpMounts: Schema.optionalKey(Schema.Record(Schema.String, Schema.String)),
104
+ childComponents: Schema.Array(Schema.Struct({
105
+ name: Schema.String,
106
+ path: Schema.String
107
+ }))
108
+ });
109
+ const byName = Order.mapInput(Order.String, (component) => component.name);
110
+ /**
111
+ * Convex component names must be alphanumeric plus underscores (see
112
+ * `defineComponent`'s docs). Beyond rejecting genuinely invalid names, this is
113
+ * a drift tripwire: if a future convex version stopped resolving names the way
114
+ * we rely on (e.g. `defaultName` disappearing), the fallback name would be a
115
+ * path segment like `convex.config`—caught here as a clear error instead of
116
+ * silently emitting a broken registry.
117
+ */
118
+ const VALID_COMPONENT_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
119
+ /**
120
+ * Bundle and evaluate `convex/convex.config.ts` and list the components
121
+ * installed on the app, in mount-name order. `displayPath` is used in error
122
+ * messages (mirroring how impl/spec bundling reports relative paths).
123
+ */
124
+ const discoverInstalledComponents = Effect.fn("ConvexConfig.discoverInstalledComponents")(function* (convexConfigPath, displayPath, kind = "app") {
125
+ const path = yield* Path.Path;
126
+ const { module } = yield* bundle(convexConfigPath, { plugins: [componentConfigPlugin(path)] }).pipe(Effect.mapError((error) => fromBundlerError(displayPath, error)));
127
+ const app = module.default;
128
+ const definition = Match.value(kind).pipe(Match.when("app", () => ({
129
+ isRoot: true,
130
+ constructor: "defineApp"
131
+ })), Match.when("component", () => ({
132
+ isRoot: false,
133
+ constructor: "defineComponent"
134
+ })), Match.exhaustive);
135
+ if (app === null || typeof app !== "object" || app._isRoot !== definition.isRoot || typeof app.export !== "function") return yield* new InvalidConvexConfigError({
136
+ configPath: displayPath,
137
+ reason: `it must default-export the ${kind} definition created by \`${definition.constructor}()\`.`
138
+ });
139
+ const analysis = yield* Effect.try({
140
+ try: () => app.export(),
141
+ catch: (cause) => new InvalidConvexConfigError({
142
+ configPath: displayPath,
143
+ reason: `exporting the app definition threw: ${globalThis.String(cause)}.`
144
+ })
145
+ });
146
+ const decoded = yield* Schema.decodeUnknownEffect(AppDefinitionAnalysis)(analysis).pipe(Effect.mapError((cause) => new InvalidConvexConfigError({
147
+ configPath: displayPath,
148
+ reason: `the app definition's installed components could not be read: ${cause.message}.`
149
+ })));
150
+ const components = pipe(decoded.childComponents, Array.map(({ name, path: componentDefinitionPath }) => {
151
+ const httpPrefix = Object.entries(decoded.httpMounts ?? {}).find(([, reference]) => reference === `_reference/childComponent/${name}`)?.[0];
152
+ return {
153
+ name,
154
+ componentDefinitionPath,
155
+ ...httpPrefix === void 0 ? {} : { httpPrefix: httpPrefix.replace(/\/$/, "") }
156
+ };
157
+ }), Array.sort(byName));
158
+ const invalidNames = pipe(components, Array.map(({ name }) => name), Array.filter((name) => Option.isNone(String.match(VALID_COMPONENT_NAME)(name))));
159
+ if (Array.isArrayNonEmpty(invalidNames)) return yield* new InvalidConvexConfigError({
160
+ configPath: displayPath,
161
+ reason: `component names must be alphanumeric plus underscores, but got: ${pipe(invalidNames, Array.map((name) => `"${name}"`), Array.join(", "))}. Pass a valid \`name\` to \`app.use\`.`
162
+ });
163
+ const duplicateNames = pipe(components, Array.groupBy(({ name }) => name), Record.toEntries, Array.filter(([, group]) => group.length > 1), Array.map(([name]) => name));
164
+ if (Array.isArrayNonEmpty(duplicateNames)) return yield* new InvalidConvexConfigError({
165
+ configPath: displayPath,
166
+ reason: `multiple components are installed under the same name (${Array.join(duplicateNames, ", ")}); pass a unique \`name\` to \`app.use\` for each.`
167
+ });
168
+ return components;
169
+ });
170
+ /**
171
+ * The name passed to `defineComponent`, independent of the package's ID scope.
172
+ */
173
+ const componentName = Effect.fnUntraced(function* (configPath) {
174
+ const path = yield* Path.Path;
175
+ const { module } = yield* bundle(configPath, { plugins: [componentConfigPlugin(path)] }).pipe(Effect.mapError((error) => fromBundlerError("convex/convex.config.ts", error)));
176
+ const definition = module.default;
177
+ if (!Predicate.hasProperty(definition, "_name") || !Predicate.isString(definition._name)) return yield* new InvalidConvexConfigError({
178
+ configPath: "convex/convex.config.ts",
179
+ reason: "the component definition must have a string name."
180
+ });
181
+ return definition._name;
182
+ });
183
+ /**
184
+ * The module specifier the generated registry's `ComponentApi` type import
185
+ * should use for a component, following Convex's own codegen convention:
186
+ * `<definition directory>/_generated/component.js`. Bare (npm) definition
187
+ * directories are used verbatim; locally-defined components (recorded as
188
+ * absolute directories) become a relative path from `confect/_generated`.
189
+ */
190
+ const typeImportPath = (path, componentDefinitionPath, confectGeneratedDirectory) => {
191
+ if (!path.isAbsolute(componentDefinitionPath)) return componentDefinitionPath;
192
+ const relative = toPosixPath(path, path.relative(confectGeneratedDirectory, componentDefinitionPath));
193
+ return String.startsWith(".")(relative) ? relative : `./${relative}`;
194
+ };
195
+ //#endregion
196
+ export { COMPONENT_IMPORT_KEY, CONVEX_CONFIG_FILENAME, componentConfigPlugin, componentImportOf, componentName, discoverInstalledComponents, resolveDefinition, typeImportPath };
197
+
198
+ //# sourceMappingURL=ConvexConfig.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConvexConfig.mjs","names":["Bundler.resolveModule","Bundler.bundle"],"sources":["../src/ConvexConfig.ts"],"sourcesContent":["import { pipe } from \"effect/Function\";\nimport * as Array from \"effect/Array\";\nimport * as Effect from \"effect/Effect\";\nimport * as Match from \"effect/Match\";\nimport type * as FileSystem from \"effect/FileSystem\";\nimport * as Option from \"effect/Option\";\nimport * as Order from \"effect/Order\";\nimport * as Path from \"effect/Path\";\nimport * as Predicate from \"effect/Predicate\";\nimport * as Record from \"effect/Record\";\nimport * as Schema from \"effect/Schema\";\nimport * as String from \"effect/String\";\nimport type * as esbuild from \"esbuild\";\nimport { fromBundlerError, type BuildError } from \"./BuildError\";\nimport * as Bundler from \"./Bundler\";\nimport { InvalidConvexConfigError } from \"./CodegenError\";\nimport { toPosixPath } from \"./utils\";\n\nexport const CONVEX_CONFIG_FILENAME = \"convex.config.ts\";\n\n/**\n * A component installed on the app via `app.use(...)` in\n * `convex/convex.config.ts`.\n */\nexport interface InstalledComponent {\n /**\n * The mount name (`app.use`'s `name` option, falling back to the name the\n * component was defined with).\n */\n readonly name: string;\n readonly httpPrefix?: string;\n /**\n * The directory the component's definition lives in, mirroring the Convex\n * runtime's convention (a `componentDefinitionPath` identifies the\n * definition's directory): the import specifier minus its trailing\n * `convex.config` segment when it was bare (e.g. `@convex-dev/workpool`), or\n * the resolved absolute directory when it was relative (a locally-defined\n * component).\n */\n readonly componentDefinitionPath: string;\n}\n\nconst COMPONENT_CONFIG_NAMESPACE = \"confect-component-config\";\n\n/**\n * Where the plugin records how a definition was imported: the specifier as\n * written and the file it resolved to. Codegen reads it to write the import of\n * each mounted component into the generated `convex.config.ts`.\n */\nexport const COMPONENT_IMPORT_KEY = \"~confect/componentImport\";\n\nexport interface ComponentImport {\n readonly specifier: string;\n readonly path: string;\n}\n\nexport const componentImportOf = (\n definition: unknown,\n): Option.Option<ComponentImport> => {\n if (!Predicate.hasProperty(definition, COMPONENT_IMPORT_KEY)) {\n return Option.none();\n }\n const recorded = definition[COMPONENT_IMPORT_KEY];\n return Predicate.hasProperty(recorded, \"specifier\") &&\n Predicate.isString(recorded.specifier) &&\n Predicate.hasProperty(recorded, \"path\") &&\n Predicate.isString(recorded.path)\n ? Option.some({ specifier: recorded.specifier, path: recorded.path })\n : Option.none();\n};\n\n/**\n * Matches the trailing `convex.config` segment of a component-definition import\n * (with or without an extension), e.g. `@convex-dev/workpool/convex.config` or\n * `./waitlist/convex.config.ts`.\n */\nconst CONVEX_CONFIG_SUFFIX = /[/\\\\]convex\\.config(\\.[cm]?[jt]s)?$/;\n\n/**\n * Resolve the same config spellings that Convex accepts, for configs and test\n * kits.\n */\nexport const resolveDefinition = (\n specifier: string,\n importer: string,\n path: Path.Path,\n): Option.Option<string> => {\n const extension = path.extname(specifier);\n const candidates = [\n specifier,\n ...(extension === \".js\" ? [specifier.slice(0, -3) + \".ts\"] : []),\n ...(extension !== \".js\" && extension !== \".ts\"\n ? [specifier + \".js\", specifier + \".ts\"]\n : []),\n ];\n return Option.firstSomeOf(\n candidates.map((candidate) => Bundler.resolveModule(candidate, importer)),\n );\n};\n\n/**\n * `convex/server`'s `app.use(definition)` rejects any definition object that\n * lacks a string `componentDefinitionPath` (\"This code only works in Convex\n * runtime\"): that property is normally stamped on by the Convex backend's\n * module system when it evaluates a definition bundle. To evaluate\n * `convex.config.ts` in plain Node, this plugin intercepts every non-entry\n * import of a `convex.config` module (mirroring the Convex CLI's own\n * `componentPlugin`) and swaps in a virtual wrapper that re-exports the real\n * definition with `componentDefinitionPath` and `defaultName` filled in—the\n * exact shape of Convex's `ImportedComponentDefinition`.\n */\nexport const componentConfigPlugin = (path: Path.Path): esbuild.Plugin => ({\n name: \"confect:component-config\",\n setup(build) {\n build.onResolve({ filter: /convex\\.config/ }, (args) => {\n // The app's own `convex.config.ts` is the entry point; only imports of\n // *component* definitions get wrapped.\n if (args.kind === \"entry-point\") return undefined;\n\n // Claim a wrapper's import of the real definition into the file\n // namespace: bundled, the definition's own nested `convex.config`\n // imports re-enter this plugin and get stamped; externalized, an npm\n // definition would be evaluated natively by Node, where its top-level\n // `component.use(...)` of unstamped nested definitions throws.\n if (args.namespace === COMPONENT_CONFIG_NAMESPACE) {\n return { path: args.path };\n }\n if (args.namespace !== \"file\" && args.namespace !== \"\") return undefined;\n\n const importer =\n args.importer !== \"\" ? args.importer : path.join(args.resolveDir, \"_\");\n\n // Component definitions are conventionally imported extensionless\n // (`.../convex.config`), which npm `exports` maps resolve but plain\n // file resolution may not—probe the same candidates Convex does.\n return pipe(\n resolveDefinition(args.path, importer, path),\n Option.match({\n onNone: () => undefined,\n onSome: (resolved) => ({\n path: resolved,\n namespace: COMPONENT_CONFIG_NAMESPACE,\n pluginData: { specifier: args.path },\n }),\n }),\n );\n });\n\n build.onLoad(\n { filter: /.*/, namespace: COMPONENT_CONFIG_NAMESPACE },\n (args) => {\n const specifier = (args.pluginData as { specifier: string }).specifier;\n // The injected path is the definition's *directory*, matching the\n // Convex runtime's convention—so even if a future convex version\n // stops reading `defaultName`, `app.use`'s last-resort fallback\n // (`componentDefinitionPath.split(\"/\").pop()`) still yields the\n // conventional component name rather than `convex.config`. Convex's\n // codegen doesn't trust relative specifiers as identifiers (the\n // importer's location is lost after bundling), so those are recorded\n // as the resolved absolute directory; bare specifiers keep their\n // package prefix so the generated type import stays a package\n // specifier.\n const isBareSpecifier =\n !String.startsWith(\".\")(specifier) && !path.isAbsolute(specifier);\n const componentDefinitionPath = isBareSpecifier\n ? String.replace(CONVEX_CONFIG_SUFFIX, \"\")(specifier)\n : path.dirname(args.path);\n\n // The real module is imported (not inlined) so any nested\n // `convex.config` imports resolve from the definition's own file\n // rather than from this virtual wrapper. `defaultName` comes from\n // `defineComponent(name)`'s `_name`, keeping `app.use`'s name\n // resolution identical to the Convex runtime's.\n return {\n loader: \"js\",\n resolveDir: path.dirname(args.path),\n contents: Array.join(\n [\n `import real from ${JSON.stringify(args.path)};`,\n `export default { ...real, componentDefinitionPath: ${JSON.stringify(componentDefinitionPath)}, defaultName: real._name, [${JSON.stringify(COMPONENT_IMPORT_KEY)}]: ${JSON.stringify({ specifier, path: args.path })} };`,\n ],\n \"\\n\",\n ),\n };\n },\n );\n },\n});\n\n/**\n * The subset of `app.export()` (Convex's `AppDefinitionAnalysis`) that the\n * registry needs: each installed component's mount name and the\n * `componentDefinitionPath` injected by {@link componentConfigPlugin}.\n */\nconst AppDefinitionAnalysis = Schema.Struct({\n httpMounts: Schema.optionalKey(Schema.Record(Schema.String, Schema.String)),\n childComponents: Schema.Array(\n Schema.Struct({\n name: Schema.String,\n path: Schema.String,\n }),\n ),\n});\n\nconst byName = Order.mapInput(\n Order.String,\n (component: InstalledComponent) => component.name,\n);\n\n/**\n * Convex component names must be alphanumeric plus underscores (see\n * `defineComponent`'s docs). Beyond rejecting genuinely invalid names, this is\n * a drift tripwire: if a future convex version stopped resolving names the way\n * we rely on (e.g. `defaultName` disappearing), the fallback name would be a\n * path segment like `convex.config`—caught here as a clear error instead of\n * silently emitting a broken registry.\n */\nconst VALID_COMPONENT_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * Bundle and evaluate `convex/convex.config.ts` and list the components\n * installed on the app, in mount-name order. `displayPath` is used in error\n * messages (mirroring how impl/spec bundling reports relative paths).\n */\nexport const discoverInstalledComponents = Effect.fn(\n \"ConvexConfig.discoverInstalledComponents\",\n)(function* (\n convexConfigPath: string,\n displayPath: string,\n kind: \"app\" | \"component\" = \"app\",\n): Effect.fn.Return<\n ReadonlyArray<InstalledComponent>,\n BuildError | InvalidConvexConfigError,\n Path.Path | FileSystem.FileSystem\n> {\n const path = yield* Path.Path;\n\n const { module } = yield* Bundler.bundle(convexConfigPath, {\n plugins: [componentConfigPlugin(path)],\n }).pipe(Effect.mapError((error) => fromBundlerError(displayPath, error)));\n\n const app = module.default as\n | { _isRoot?: unknown; export?: unknown }\n | null\n | undefined;\n\n const definition = Match.value(kind).pipe(\n Match.when(\"app\", () => ({ isRoot: true, constructor: \"defineApp\" })),\n Match.when(\"component\", () => ({\n isRoot: false,\n constructor: \"defineComponent\",\n })),\n Match.exhaustive,\n );\n\n if (\n app === null ||\n typeof app !== \"object\" ||\n app._isRoot !== definition.isRoot ||\n typeof app.export !== \"function\"\n ) {\n return yield* new InvalidConvexConfigError({\n configPath: displayPath,\n reason: `it must default-export the ${kind} definition created by \\`${definition.constructor}()\\`.`,\n });\n }\n\n const analysis = yield* Effect.try({\n try: () => (app.export as () => unknown)(),\n catch: (cause) =>\n new InvalidConvexConfigError({\n configPath: displayPath,\n reason: `exporting the app definition threw: ${globalThis.String(cause)}.`,\n }),\n });\n\n const decoded = yield* Schema.decodeUnknownEffect(AppDefinitionAnalysis)(\n analysis,\n ).pipe(\n Effect.mapError(\n (cause) =>\n new InvalidConvexConfigError({\n configPath: displayPath,\n reason: `the app definition's installed components could not be read: ${cause.message}.`,\n }),\n ),\n );\n\n const components = pipe(\n decoded.childComponents,\n Array.map(({ name, path: componentDefinitionPath }): InstalledComponent => {\n const httpPrefix = Object.entries(decoded.httpMounts ?? {}).find(\n ([, reference]) => reference === `_reference/childComponent/${name}`,\n )?.[0];\n return {\n name,\n componentDefinitionPath,\n ...(httpPrefix === undefined\n ? {}\n : { httpPrefix: httpPrefix.replace(/\\/$/, \"\") }),\n };\n }),\n Array.sort(byName),\n );\n\n const invalidNames = pipe(\n components,\n Array.map(({ name }) => name),\n Array.filter((name) =>\n Option.isNone(String.match(VALID_COMPONENT_NAME)(name)),\n ),\n );\n if (Array.isArrayNonEmpty(invalidNames)) {\n return yield* new InvalidConvexConfigError({\n configPath: displayPath,\n reason: `component names must be alphanumeric plus underscores, but got: ${pipe(\n invalidNames,\n Array.map((name) => `\"${name}\"`),\n Array.join(\", \"),\n )}. Pass a valid \\`name\\` to \\`app.use\\`.`,\n });\n }\n\n const duplicateNames = pipe(\n components,\n Array.groupBy(({ name }) => name),\n Record.toEntries,\n Array.filter(([, group]) => group.length > 1),\n Array.map(([name]) => name),\n );\n if (Array.isArrayNonEmpty(duplicateNames)) {\n return yield* new InvalidConvexConfigError({\n configPath: displayPath,\n reason: `multiple components are installed under the same name (${Array.join(duplicateNames, \", \")}); pass a unique \\`name\\` to \\`app.use\\` for each.`,\n });\n }\n\n return components;\n});\n\n/**\n * The name passed to `defineComponent`, independent of the package's ID scope.\n */\nexport const componentName = Effect.fnUntraced(function* (configPath: string) {\n const path = yield* Path.Path;\n const { module } = yield* Bundler.bundle(configPath, {\n plugins: [componentConfigPlugin(path)],\n }).pipe(\n Effect.mapError((error) =>\n fromBundlerError(\"convex/convex.config.ts\", error),\n ),\n );\n const definition: unknown = module.default;\n if (\n !Predicate.hasProperty(definition, \"_name\") ||\n !Predicate.isString(definition._name)\n ) {\n return yield* new InvalidConvexConfigError({\n configPath: \"convex/convex.config.ts\",\n reason: \"the component definition must have a string name.\",\n });\n }\n return definition._name;\n});\n\n/**\n * The module specifier the generated registry's `ComponentApi` type import\n * should use for a component, following Convex's own codegen convention:\n * `<definition directory>/_generated/component.js`. Bare (npm) definition\n * directories are used verbatim; locally-defined components (recorded as\n * absolute directories) become a relative path from `confect/_generated`.\n */\nexport const typeImportPath = (\n path: Path.Path,\n componentDefinitionPath: string,\n confectGeneratedDirectory: string,\n): string => {\n if (!path.isAbsolute(componentDefinitionPath)) {\n return componentDefinitionPath;\n }\n const relative = toPosixPath(\n path,\n path.relative(confectGeneratedDirectory, componentDefinitionPath),\n );\n return String.startsWith(\".\")(relative) ? relative : `./${relative}`;\n};\n"],"mappings":"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"}