@confect/cli 1.0.0-next.0

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 (92) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +7 -0
  3. package/dist/FunctionPath.mjs +19 -0
  4. package/dist/FunctionPath.mjs.map +1 -0
  5. package/dist/FunctionPaths.mjs +41 -0
  6. package/dist/FunctionPaths.mjs.map +1 -0
  7. package/dist/GroupPath.mjs +52 -0
  8. package/dist/GroupPath.mjs.map +1 -0
  9. package/dist/GroupPaths.mjs +9 -0
  10. package/dist/GroupPaths.mjs.map +1 -0
  11. package/dist/_virtual/rolldown_runtime.mjs +28 -0
  12. package/dist/cliApp.mjs +13 -0
  13. package/dist/cliApp.mjs.map +1 -0
  14. package/dist/confect/codegen.mjs +111 -0
  15. package/dist/confect/codegen.mjs.map +1 -0
  16. package/dist/confect/dev.mjs +253 -0
  17. package/dist/confect/dev.mjs.map +1 -0
  18. package/dist/confect.mjs +14 -0
  19. package/dist/confect.mjs.map +1 -0
  20. package/dist/index.d.mts +1 -0
  21. package/dist/index.mjs +19 -0
  22. package/dist/index.mjs.map +1 -0
  23. package/dist/log.mjs +25 -0
  24. package/dist/log.mjs.map +1 -0
  25. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/NodeCommandExecutor.mjs +12 -0
  26. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/NodeCommandExecutor.mjs.map +1 -0
  27. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/NodeFileSystem.mjs +15 -0
  28. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/NodeFileSystem.mjs.map +1 -0
  29. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/NodePath.mjs +25 -0
  30. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/NodePath.mjs.map +1 -0
  31. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/NodeRuntime.mjs +12 -0
  32. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/NodeRuntime.mjs.map +1 -0
  33. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/NodeTerminal.mjs +17 -0
  34. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/NodeTerminal.mjs.map +1 -0
  35. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/commandExecutor.mjs +129 -0
  36. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/commandExecutor.mjs.map +1 -0
  37. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/error.mjs +43 -0
  38. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/error.mjs.map +1 -0
  39. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/fileSystem.mjs +329 -0
  40. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/fileSystem.mjs.map +1 -0
  41. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/path.mjs +51 -0
  42. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/path.mjs.map +1 -0
  43. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/runtime.mjs +31 -0
  44. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/runtime.mjs.map +1 -0
  45. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/sink.mjs +24 -0
  46. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/sink.mjs.map +1 -0
  47. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/stream.mjs +91 -0
  48. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/stream.mjs.map +1 -0
  49. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/terminal.mjs +75 -0
  50. package/dist/node_modules/.pnpm/@effect_platform-node-shared@0.53.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effe_e0eeb3aae5ffec3060feb87d17ffb17c/node_modules/@effect/platform-node-shared/dist/esm/internal/terminal.mjs.map +1 -0
  51. package/dist/node_modules/.pnpm/@effect_platform-node@0.100.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effect@3.1_a15ca1802d939cd85cc564105ef862ac/node_modules/@effect/platform-node/dist/esm/NodeContext.mjs +21 -0
  52. package/dist/node_modules/.pnpm/@effect_platform-node@0.100.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effect@3.1_a15ca1802d939cd85cc564105ef862ac/node_modules/@effect/platform-node/dist/esm/NodeContext.mjs.map +1 -0
  53. package/dist/node_modules/.pnpm/@effect_platform-node@0.100.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effect@3.1_a15ca1802d939cd85cc564105ef862ac/node_modules/@effect/platform-node/dist/esm/NodeFileSystem.mjs +15 -0
  54. package/dist/node_modules/.pnpm/@effect_platform-node@0.100.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effect@3.1_a15ca1802d939cd85cc564105ef862ac/node_modules/@effect/platform-node/dist/esm/NodeFileSystem.mjs.map +1 -0
  55. package/dist/node_modules/.pnpm/@effect_platform-node@0.100.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effect@3.1_a15ca1802d939cd85cc564105ef862ac/node_modules/@effect/platform-node/dist/esm/NodeRuntime.mjs +15 -0
  56. package/dist/node_modules/.pnpm/@effect_platform-node@0.100.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effect@3.1_a15ca1802d939cd85cc564105ef862ac/node_modules/@effect/platform-node/dist/esm/NodeRuntime.mjs.map +1 -0
  57. package/dist/node_modules/.pnpm/@effect_platform-node@0.100.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effect@3.1_a15ca1802d939cd85cc564105ef862ac/node_modules/@effect/platform-node/dist/esm/NodeWorker.mjs +27 -0
  58. package/dist/node_modules/.pnpm/@effect_platform-node@0.100.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effect@3.1_a15ca1802d939cd85cc564105ef862ac/node_modules/@effect/platform-node/dist/esm/NodeWorker.mjs.map +1 -0
  59. package/dist/node_modules/.pnpm/@effect_platform-node@0.100.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effect@3.1_a15ca1802d939cd85cc564105ef862ac/node_modules/@effect/platform-node/dist/esm/internal/worker.mjs +71 -0
  60. package/dist/node_modules/.pnpm/@effect_platform-node@0.100.0_@effect_cluster@0.52.9_@effect_platform@0.93.2_effect@3.1_a15ca1802d939cd85cc564105ef862ac/node_modules/@effect/platform-node/dist/esm/internal/worker.mjs.map +1 -0
  61. package/dist/packages/cli/package.mjs +6 -0
  62. package/dist/packages/cli/package.mjs.map +1 -0
  63. package/dist/packages/core/dist/Spec.mjs +23 -0
  64. package/dist/packages/core/dist/Spec.mjs.map +1 -0
  65. package/dist/packages/core/dist/_virtual/rolldown_runtime.mjs +14 -0
  66. package/dist/packages/core/dist/_virtual/rolldown_runtime.mjs.map +1 -0
  67. package/dist/services/ConfectDirectory.mjs +31 -0
  68. package/dist/services/ConfectDirectory.mjs.map +1 -0
  69. package/dist/services/ConvexDirectory.mjs +41 -0
  70. package/dist/services/ConvexDirectory.mjs.map +1 -0
  71. package/dist/services/ProjectRoot.mjs +35 -0
  72. package/dist/services/ProjectRoot.mjs.map +1 -0
  73. package/dist/templates.mjs +204 -0
  74. package/dist/templates.mjs.map +1 -0
  75. package/dist/utils.mjs +162 -0
  76. package/dist/utils.mjs.map +1 -0
  77. package/package.json +86 -0
  78. package/src/FunctionPath.ts +28 -0
  79. package/src/FunctionPaths.ts +103 -0
  80. package/src/GroupPath.ts +117 -0
  81. package/src/GroupPaths.ts +7 -0
  82. package/src/cliApp.ts +8 -0
  83. package/src/confect/codegen.ts +228 -0
  84. package/src/confect/dev.ts +611 -0
  85. package/src/confect.ts +19 -0
  86. package/src/index.ts +22 -0
  87. package/src/log.ts +106 -0
  88. package/src/services/ConfectDirectory.ts +41 -0
  89. package/src/services/ConvexDirectory.ts +67 -0
  90. package/src/services/ProjectRoot.ts +49 -0
  91. package/src/templates.ts +380 -0
  92. package/src/utils.ts +332 -0
package/src/utils.ts ADDED
@@ -0,0 +1,332 @@
1
+ import type { FunctionSpec, Spec } from "@confect/core";
2
+ import { FileSystem, Path } from "@effect/platform";
3
+ import type { PlatformError } from "@effect/platform/Error";
4
+ import {
5
+ Array,
6
+ Effect,
7
+ HashSet,
8
+ Option,
9
+ Order,
10
+ pipe,
11
+ Record,
12
+ String,
13
+ } from "effect";
14
+ import * as FunctionPaths from "./FunctionPaths";
15
+ import * as GroupPath from "./GroupPath";
16
+ import * as GroupPaths from "./GroupPaths";
17
+ import { logFileAdded, logFileModified, logFileRemoved } from "./log";
18
+ import { ConfectDirectory } from "./services/ConfectDirectory";
19
+ import { ConvexDirectory } from "./services/ConvexDirectory";
20
+ import * as templates from "./templates";
21
+
22
+ export const removePathExtension = (pathStr: string) =>
23
+ Effect.gen(function* () {
24
+ const path = yield* Path.Path;
25
+
26
+ return String.slice(0, -path.extname(pathStr).length)(pathStr);
27
+ });
28
+
29
+ export const writeFileStringAndLog = (filePath: string, contents: string) =>
30
+ Effect.gen(function* () {
31
+ const fs = yield* FileSystem.FileSystem;
32
+ if (!(yield* fs.exists(filePath))) {
33
+ yield* fs.writeFileString(filePath, contents);
34
+ yield* logFileAdded(filePath);
35
+ return;
36
+ }
37
+ const existing = yield* fs.readFileString(filePath);
38
+ if (existing !== contents) {
39
+ yield* fs.writeFileString(filePath, contents);
40
+ yield* logFileModified(filePath);
41
+ }
42
+ });
43
+
44
+ export const findProjectRoot = Effect.gen(function* () {
45
+ const fs = yield* FileSystem.FileSystem;
46
+ const path = yield* Path.Path;
47
+
48
+ const startDir = path.resolve(".");
49
+ const root = path.parse(startDir).root;
50
+
51
+ const directories = Array.unfold(startDir, (dir) =>
52
+ dir === root
53
+ ? Option.none()
54
+ : Option.some([dir, path.dirname(dir)] as const),
55
+ );
56
+
57
+ const projectRoot = yield* Effect.findFirst(directories, (dir) =>
58
+ fs.exists(path.join(dir, "package.json")),
59
+ );
60
+
61
+ return Option.getOrElse(projectRoot, () => startDir);
62
+ });
63
+
64
+ export type WriteChange = "Added" | "Modified" | "Unchanged";
65
+
66
+ export const writeFileString = (
67
+ filePath: string,
68
+ contents: string,
69
+ ): Effect.Effect<WriteChange, PlatformError, FileSystem.FileSystem> =>
70
+ Effect.gen(function* () {
71
+ const fs = yield* FileSystem.FileSystem;
72
+
73
+ if (!(yield* fs.exists(filePath))) {
74
+ yield* fs.writeFileString(filePath, contents);
75
+ return "Added";
76
+ }
77
+ const existing = yield* fs.readFileString(filePath);
78
+ if (existing !== contents) {
79
+ yield* fs.writeFileString(filePath, contents);
80
+ return "Modified";
81
+ }
82
+ return "Unchanged";
83
+ });
84
+
85
+ export const generateGroupModule = ({
86
+ groupPath,
87
+ functionNames,
88
+ }: {
89
+ groupPath: GroupPath.GroupPath;
90
+ functionNames: string[];
91
+ }) =>
92
+ Effect.gen(function* () {
93
+ const fs = yield* FileSystem.FileSystem;
94
+ const path = yield* Path.Path;
95
+ const convexDirectory = yield* ConvexDirectory.get;
96
+ const confectDirectory = yield* ConfectDirectory.get;
97
+
98
+ const relativeModulePath = yield* GroupPath.modulePath(groupPath);
99
+ const modulePath = path.join(convexDirectory, relativeModulePath);
100
+
101
+ const directoryPath = path.dirname(modulePath);
102
+ if (!(yield* fs.exists(directoryPath))) {
103
+ yield* fs.makeDirectory(directoryPath, { recursive: true });
104
+ }
105
+
106
+ const registeredFunctionsPath = path.join(
107
+ confectDirectory,
108
+ "_generated",
109
+ "registeredFunctions.ts",
110
+ );
111
+ const registeredFunctionsImportPath = yield* removePathExtension(
112
+ path.relative(path.dirname(modulePath), registeredFunctionsPath),
113
+ );
114
+
115
+ const functionsContentsString = yield* templates.functions({
116
+ groupPath,
117
+ functionNames,
118
+ registeredFunctionsImportPath,
119
+ });
120
+
121
+ if (!(yield* fs.exists(modulePath))) {
122
+ yield* fs.writeFileString(modulePath, functionsContentsString);
123
+ return "Added" as const;
124
+ }
125
+ const existing = yield* fs.readFileString(modulePath);
126
+ if (existing !== functionsContentsString) {
127
+ yield* fs.writeFileString(modulePath, functionsContentsString);
128
+ return "Modified" as const;
129
+ }
130
+ return "Unchanged" as const;
131
+ });
132
+
133
+ const logGroupPaths = <R>(
134
+ groupPaths: GroupPaths.GroupPaths,
135
+ logFn: (fullPath: string) => Effect.Effect<void, never, R>,
136
+ ) =>
137
+ Effect.gen(function* () {
138
+ const path = yield* Path.Path;
139
+ const convexDirectory = yield* ConvexDirectory.get;
140
+
141
+ yield* Effect.forEach(groupPaths, (gp) =>
142
+ Effect.gen(function* () {
143
+ const relativeModulePath = yield* GroupPath.modulePath(gp);
144
+ yield* logFn(path.join(convexDirectory, relativeModulePath));
145
+ }),
146
+ );
147
+ });
148
+
149
+ export const generateFunctions = (spec: Spec.AnyWithProps) =>
150
+ Effect.gen(function* () {
151
+ const path = yield* Path.Path;
152
+ const convexDirectory = yield* ConvexDirectory.get;
153
+
154
+ const groupPathsFromFs = yield* getGroupPathsFromFs;
155
+ const functionPaths = FunctionPaths.make(spec);
156
+ const groupPathsFromSpec = FunctionPaths.groupPaths(functionPaths);
157
+
158
+ const overlappingGroupPaths = GroupPaths.GroupPaths.make(
159
+ HashSet.intersection(groupPathsFromFs, groupPathsFromSpec),
160
+ );
161
+ yield* Effect.forEach(overlappingGroupPaths, (groupPath) =>
162
+ Effect.gen(function* () {
163
+ const group = yield* GroupPath.getGroupSpec(spec, groupPath);
164
+ const functionNames = pipe(
165
+ group.functions,
166
+ Record.values,
167
+ Array.sortBy(
168
+ Order.mapInput(
169
+ Order.string,
170
+ (fn: FunctionSpec.AnyWithProps) => fn.name,
171
+ ),
172
+ ),
173
+ Array.map((fn) => fn.name),
174
+ );
175
+ const result = yield* generateGroupModule({ groupPath, functionNames });
176
+ if (result === "Modified") {
177
+ const relativeModulePath = yield* GroupPath.modulePath(groupPath);
178
+ yield* logFileModified(
179
+ path.join(convexDirectory, relativeModulePath),
180
+ );
181
+ }
182
+ }),
183
+ );
184
+
185
+ const extinctGroupPaths = GroupPaths.GroupPaths.make(
186
+ HashSet.difference(groupPathsFromFs, groupPathsFromSpec),
187
+ );
188
+ yield* removeGroups(extinctGroupPaths);
189
+ yield* logGroupPaths(extinctGroupPaths, logFileRemoved);
190
+
191
+ const newGroupPaths = GroupPaths.GroupPaths.make(
192
+ HashSet.difference(groupPathsFromSpec, groupPathsFromFs),
193
+ );
194
+ yield* writeGroups(spec, newGroupPaths);
195
+ yield* logGroupPaths(newGroupPaths, logFileAdded);
196
+
197
+ return functionPaths;
198
+ });
199
+
200
+ const getGroupPathsFromFs = Effect.gen(function* () {
201
+ const fs = yield* FileSystem.FileSystem;
202
+ const path = yield* Path.Path;
203
+ const convexDirectory = yield* ConvexDirectory.get;
204
+
205
+ const RESERVED_CONVEX_TS_FILE_NAMES = new Set([
206
+ "schema.ts",
207
+ "http.ts",
208
+ "crons.ts",
209
+ "auth.config.ts",
210
+ "convex.config.ts",
211
+ ]);
212
+
213
+ const allConvexPaths = yield* fs.readDirectory(convexDirectory, {
214
+ recursive: true,
215
+ });
216
+ const groupPathArray = yield* pipe(
217
+ allConvexPaths,
218
+ Array.filter(
219
+ (convexPath) =>
220
+ path.extname(convexPath) === ".ts" &&
221
+ !RESERVED_CONVEX_TS_FILE_NAMES.has(path.basename(convexPath)) &&
222
+ path.basename(path.dirname(convexPath)) !== "_generated",
223
+ ),
224
+ Effect.forEach((groupModulePath) =>
225
+ GroupPath.fromGroupModulePath(groupModulePath),
226
+ ),
227
+ );
228
+ return pipe(groupPathArray, HashSet.fromIterable, GroupPaths.GroupPaths.make);
229
+ });
230
+
231
+ export const removeGroups = (groupPaths: GroupPaths.GroupPaths) =>
232
+ Effect.gen(function* () {
233
+ const fs = yield* FileSystem.FileSystem;
234
+ const path = yield* Path.Path;
235
+ const convexDirectory = yield* ConvexDirectory.get;
236
+
237
+ yield* Effect.all(
238
+ HashSet.map(groupPaths, (groupPath) =>
239
+ Effect.gen(function* () {
240
+ const relativeModulePath = yield* GroupPath.modulePath(groupPath);
241
+ const modulePath = path.join(convexDirectory, relativeModulePath);
242
+
243
+ yield* Effect.logDebug(`Removing group '${relativeModulePath}'...`);
244
+
245
+ yield* fs.remove(modulePath);
246
+ yield* Effect.logDebug(`Group '${relativeModulePath}' removed`);
247
+ }),
248
+ ),
249
+ { concurrency: "unbounded" },
250
+ );
251
+ });
252
+
253
+ export const writeGroups = (
254
+ spec: Spec.AnyWithProps,
255
+ groupPaths: GroupPaths.GroupPaths,
256
+ ) =>
257
+ Effect.forEach(groupPaths, (groupPath) =>
258
+ Effect.gen(function* () {
259
+ const group = yield* GroupPath.getGroupSpec(spec, groupPath);
260
+
261
+ const functionNames = pipe(
262
+ group.functions,
263
+ Record.values,
264
+ Array.sortBy(
265
+ Order.mapInput(
266
+ Order.string,
267
+ (fn: FunctionSpec.AnyWithProps) => fn.name,
268
+ ),
269
+ ),
270
+ Array.map((fn) => fn.name),
271
+ );
272
+
273
+ yield* Effect.logDebug(`Generating group ${groupPath}...`);
274
+ yield* generateGroupModule({
275
+ groupPath,
276
+ functionNames,
277
+ });
278
+ yield* Effect.logDebug(`Group ${groupPath} generated`);
279
+ }),
280
+ );
281
+
282
+ const generateOptionalFile = (
283
+ confectFile: string,
284
+ convexFile: string,
285
+ generateContents: (importPath: string) => Effect.Effect<string>,
286
+ ) =>
287
+ Effect.gen(function* () {
288
+ const fs = yield* FileSystem.FileSystem;
289
+ const path = yield* Path.Path;
290
+ const confectDirectory = yield* ConfectDirectory.get;
291
+ const convexDirectory = yield* ConvexDirectory.get;
292
+
293
+ const confectFilePath = path.join(confectDirectory, confectFile);
294
+
295
+ if (!(yield* fs.exists(confectFilePath))) {
296
+ return Option.none();
297
+ }
298
+
299
+ const convexFilePath = path.join(convexDirectory, convexFile);
300
+ const relativeImportPath = path.relative(
301
+ path.dirname(convexFilePath),
302
+ confectFilePath,
303
+ );
304
+ const importPathWithoutExt = yield* removePathExtension(relativeImportPath);
305
+ const contents = yield* generateContents(importPathWithoutExt);
306
+ const change = yield* writeFileString(convexFilePath, contents);
307
+ return Option.some({ change, convexFilePath });
308
+ });
309
+
310
+ export const generateHttp = generateOptionalFile(
311
+ "http.ts",
312
+ "http.ts",
313
+ (importPath) => templates.http({ httpImportPath: importPath }),
314
+ );
315
+
316
+ export const generateConvexConfig = generateOptionalFile(
317
+ "app.ts",
318
+ "convex.config.ts",
319
+ (importPath) => templates.convexConfig({ appImportPath: importPath }),
320
+ );
321
+
322
+ export const generateCrons = generateOptionalFile(
323
+ "crons.ts",
324
+ "crons.ts",
325
+ (importPath) => templates.crons({ cronsImportPath: importPath }),
326
+ );
327
+
328
+ export const generateAuthConfig = generateOptionalFile(
329
+ "auth.ts",
330
+ "auth.config.ts",
331
+ (importPath) => templates.authConfig({ authImportPath: importPath }),
332
+ );