cloesce 0.0.3-fix.1 → 0.0.3-fix.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.
@@ -6,77 +6,178 @@ import { fileURLToPath } from "node:url";
6
6
  import { command, run, subcommands, flag, option, optional, string, } from "cmd-ts";
7
7
  import { Project } from "ts-morph";
8
8
  import { CidlExtractor } from "./extract.js";
9
- import { ExtractorError, ExtractorErrorCode, getErrorInfo } from "./common.js";
9
+ import { ExtractorError, ExtractorErrorCode, getErrorInfo } from "../common.js";
10
10
  const __filename = fileURLToPath(import.meta.url);
11
11
  const __dirname = path.dirname(__filename);
12
- const WASM_PATH = path.join(__dirname, "cli.wasm");
13
- function loadCloesceConfig(root, debug = false) {
14
- const configPath = path.join(root, "cloesce-config.json");
15
- if (fs.existsSync(configPath)) {
16
- try {
17
- const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
18
- if (debug)
19
- console.log(`Loaded config from ${configPath}`);
20
- return config;
21
- }
22
- catch (err) {
23
- console.warn(`Failed to parse cloesce-config.json: ${err}`);
24
- }
25
- }
26
- return {};
27
- }
28
- function readPackageJsonProjectName(cwd) {
29
- const pkgPath = path.join(cwd, "package.json");
30
- let projectName = path.basename(cwd);
31
- if (fs.existsSync(pkgPath)) {
32
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
33
- projectName = pkg.name ?? projectName;
34
- }
35
- return projectName;
36
- }
37
- function findCloesceProject(root, searchPaths, project) {
38
- for (const searchPath of searchPaths) {
39
- let fullPath;
40
- if (path.isAbsolute(searchPath) || searchPath.startsWith(root)) {
41
- fullPath = path.normalize(searchPath);
42
- }
43
- else {
44
- fullPath = path.resolve(root, searchPath);
45
- }
46
- if (!fs.existsSync(fullPath)) {
47
- console.warn(`Warning: Path "${searchPath}" does not exist`);
48
- continue;
49
- }
50
- const stats = fs.statSync(fullPath);
51
- if (stats.isFile() && /\.cloesce\.ts$/i.test(fullPath)) {
52
- project.addSourceFileAtPath(fullPath);
53
- }
54
- else if (stats.isDirectory()) {
55
- walkDirectory(fullPath, project);
56
- }
57
- }
58
- function walkDirectory(dir, project) {
59
- for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
60
- const fullPath = path.join(dir, entry.name);
61
- if (entry.isDirectory() && !entry.name.startsWith(".")) {
62
- walkDirectory(fullPath, project);
63
- }
64
- else if (entry.isFile() && /\.cloesce\.ts$/i.test(entry.name)) {
65
- project.addSourceFileAtPath(fullPath);
66
- }
67
- }
68
- }
69
- }
70
- function formatErr(e) {
71
- const { description, suggestion } = getErrorInfo(e.code);
72
- const contextLine = e.context ? `Context: ${e.context}\n` : "";
73
- const snippetLine = e.snippet ? `${e.snippet}\n\n` : "";
74
- return `==== CLOESCE ERROR ====
75
- Error [${ExtractorErrorCode[e.code]}]: ${description}
76
- Phase: TypeScript IDL Extraction
77
- ${contextLine}${snippetLine}Suggested fix: ${suggestion}`;
78
- }
79
- async function runExtractor(opts) {
12
+ const GENERATOR_WASM_PATH = path.join(__dirname, "cli.wasm");
13
+ const cmds = subcommands({
14
+ name: "cloesce",
15
+ cmds: {
16
+ compile: command({
17
+ name: "compile",
18
+ description: "Run through the full compilation process.",
19
+ args: {
20
+ debug: flag({
21
+ long: "debug",
22
+ short: "d",
23
+ description: "Show debug output",
24
+ }),
25
+ },
26
+ handler: async (args) => {
27
+ const config = loadCloesceConfig(process.cwd(), args.debug);
28
+ if (!config.workersUrl || !config.clientUrl) {
29
+ console.error("Error: `workersUrl` and `clientUrl` must be defined in cloesce.config.json");
30
+ process.exit(1);
31
+ }
32
+ // Creates a `cidl.json` file. Exits the process on failure.
33
+ await extract({ debug: args.debug });
34
+ const root = process.cwd();
35
+ const outputDir = config.outputDir ?? ".generated";
36
+ const allConfig = {
37
+ name: "all",
38
+ wasmFile: "generator.wasm",
39
+ args: [
40
+ "generate",
41
+ "all",
42
+ path.join(outputDir, "cidl.json"),
43
+ path.join(root, "wrangler.toml"),
44
+ path.join(outputDir, "migrations.sql"),
45
+ path.join(outputDir, "workers.ts"),
46
+ path.join(outputDir, "client.ts"),
47
+ config.clientUrl,
48
+ config.workersUrl,
49
+ ],
50
+ };
51
+ // Runs a generator command. Exits the process on failure.
52
+ await generate(allConfig);
53
+ },
54
+ }),
55
+ wrangler: command({
56
+ name: "wrangler",
57
+ description: "Generate wrangler.toml configuration",
58
+ args: {},
59
+ handler: async () => {
60
+ const root = process.cwd();
61
+ await generate({
62
+ name: "wrangler",
63
+ wasmFile: "generator.wasm",
64
+ args: ["generate", "wrangler", path.join(root, "wrangler.toml")],
65
+ });
66
+ },
67
+ }),
68
+ d1: command({
69
+ name: "d1",
70
+ description: "Generate database schema",
71
+ args: {},
72
+ handler: async () => {
73
+ const config = loadCloesceConfig(process.cwd());
74
+ const outputDir = config.outputDir ?? ".generated";
75
+ await generate({
76
+ name: "d1",
77
+ wasmFile: "generator.wasm",
78
+ args: [
79
+ "generate",
80
+ "d1",
81
+ path.join(outputDir, "cidl.json"),
82
+ path.join(outputDir, "migrations.sql"),
83
+ ],
84
+ });
85
+ },
86
+ }),
87
+ workers: command({
88
+ name: "workers",
89
+ description: "Generate workers TypeScript",
90
+ args: {},
91
+ handler: async () => {
92
+ const config = loadCloesceConfig(process.cwd());
93
+ const root = process.cwd();
94
+ const outputDir = config.outputDir ?? ".generated";
95
+ if (!config.workersUrl) {
96
+ console.error("Error: workersUrl must be defined in cloesce-config.json");
97
+ process.exit(1);
98
+ }
99
+ await generate({
100
+ name: "workers",
101
+ wasmFile: "generator.wasm",
102
+ args: [
103
+ "generate",
104
+ "workers",
105
+ path.join(outputDir, "cidl.json"),
106
+ path.join(outputDir, "workers.ts"),
107
+ path.join(root, "wrangler.toml"),
108
+ config.workersUrl,
109
+ ],
110
+ });
111
+ },
112
+ }),
113
+ client: command({
114
+ name: "client",
115
+ description: "Generate client TypeScript",
116
+ args: {},
117
+ handler: async () => {
118
+ const config = loadCloesceConfig(process.cwd());
119
+ const outputDir = config.outputDir ?? ".generated";
120
+ if (!config.clientUrl) {
121
+ console.error("Error: clientUrl must be defined in cloesce-config.json");
122
+ process.exit(1);
123
+ }
124
+ await generate({
125
+ name: "client",
126
+ wasmFile: "generator.wasm",
127
+ args: [
128
+ "generate",
129
+ "client",
130
+ path.join(outputDir, "cidl.json"),
131
+ path.join(outputDir, "client.ts"),
132
+ config.clientUrl,
133
+ ],
134
+ });
135
+ },
136
+ }),
137
+ extract: command({
138
+ name: "extract",
139
+ description: "Extract models and write cidl.json only",
140
+ args: {
141
+ projectName: option({
142
+ long: "project-name",
143
+ type: optional(string),
144
+ description: "Project name",
145
+ }),
146
+ out: option({
147
+ long: "out",
148
+ short: "o",
149
+ type: optional(string),
150
+ description: "Output path (default: .generated/cidl.json)",
151
+ }),
152
+ inp: option({
153
+ long: "in",
154
+ short: "i",
155
+ type: optional(string),
156
+ description: "Input file or directory",
157
+ }),
158
+ location: option({
159
+ long: "location",
160
+ short: "l",
161
+ type: optional(string),
162
+ description: "Project directory (default: cwd)",
163
+ }),
164
+ truncateSourcePaths: flag({
165
+ long: "truncateSourcePaths",
166
+ description: "Sets all source paths to just their file name",
167
+ }),
168
+ debug: flag({
169
+ long: "debug",
170
+ short: "d",
171
+ description: "Show debug output",
172
+ }),
173
+ },
174
+ handler: async (args) => {
175
+ await extract({ ...args });
176
+ },
177
+ }),
178
+ },
179
+ });
180
+ async function extract(opts) {
80
181
  const root = process.cwd();
81
182
  const projectRoot = process.cwd();
82
183
  const config = loadCloesceConfig(projectRoot, opts.debug);
@@ -132,7 +233,7 @@ async function runExtractor(opts) {
132
233
  process.exit(1);
133
234
  }
134
235
  }
135
- async function runWasmCommand(config) {
236
+ async function generate(config) {
136
237
  const root = process.cwd();
137
238
  // Look for wrangler.toml in the root directory
138
239
  const wranglerPath = path.join(root, "wrangler.toml");
@@ -158,11 +259,11 @@ async function runWasmCommand(config) {
158
259
  });
159
260
  const wasi = new WASI({
160
261
  version: "preview1",
161
- args: [path.basename(WASM_PATH), ...wasiArgs],
262
+ args: [path.basename(GENERATOR_WASM_PATH), ...wasiArgs],
162
263
  env: { ...process.env, ...config.env },
163
264
  preopens: { "/": root },
164
265
  });
165
- const bytes = fs.readFileSync(WASM_PATH);
266
+ const bytes = fs.readFileSync(GENERATOR_WASM_PATH);
166
267
  const mod = await WebAssembly.compile(bytes);
167
268
  const instance = await WebAssembly.instantiate(mod, {
168
269
  wasi_snapshot_preview1: wasi.wasiImport,
@@ -174,179 +275,73 @@ async function runWasmCommand(config) {
174
275
  console.error(`WASM execution failed for ${config.name}:`, err);
175
276
  }
176
277
  }
177
- const runCmd = command({
178
- name: "run",
179
- description: "Extract CIDL and run all code generators",
180
- args: {
181
- debug: flag({
182
- long: "debug",
183
- short: "d",
184
- description: "Show debug output",
185
- }),
186
- },
187
- handler: async (args) => {
188
- const config = loadCloesceConfig(process.cwd(), args.debug);
189
- if (!config.workersUrl || !config.clientUrl) {
190
- console.error("Error: workersUrl and clientUrl must be defined in cloesce-config.json");
191
- process.exit(1);
278
+ function loadCloesceConfig(root, debug = false) {
279
+ const configPath = path.join(root, "cloesce.config.json");
280
+ if (fs.existsSync(configPath)) {
281
+ try {
282
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
283
+ if (debug)
284
+ console.log(`Loaded config from ${configPath}`);
285
+ return config;
192
286
  }
193
- await runExtractor({ debug: args.debug });
194
- const root = process.cwd();
195
- const outputDir = config.outputDir ?? ".generated";
196
- const allConfig = {
197
- name: "all",
198
- wasmFile: "cli.wasm",
199
- args: [
200
- "generate",
201
- "all",
202
- path.join(outputDir, "cidl.json"),
203
- path.join(root, "wrangler.toml"),
204
- path.join(outputDir, "migrations.sql"),
205
- path.join(outputDir, "workers.ts"),
206
- path.join(outputDir, "client.ts"),
207
- config.clientUrl,
208
- config.workersUrl,
209
- ],
210
- };
211
- await runWasmCommand(allConfig);
212
- },
213
- });
214
- // In case the user wants to run individual steps we should probably allow them
215
- const wranglerCmd = command({
216
- name: "wrangler",
217
- description: "Generate wrangler.toml configuration",
218
- args: {},
219
- handler: async () => {
220
- const root = process.cwd();
221
- await runWasmCommand({
222
- name: "wrangler",
223
- wasmFile: "cli.wasm",
224
- args: ["generate", "wrangler", path.join(root, "wrangler.toml")],
225
- });
226
- },
227
- });
228
- const d1Cmd = command({
229
- name: "d1",
230
- description: "Generate database schema",
231
- args: {},
232
- handler: async () => {
233
- const config = loadCloesceConfig(process.cwd());
234
- const outputDir = config.outputDir ?? ".generated";
235
- await runWasmCommand({
236
- name: "d1",
237
- wasmFile: "cli.wasm",
238
- args: [
239
- "generate",
240
- "d1",
241
- path.join(outputDir, "cidl.json"),
242
- path.join(outputDir, "migrations.sql"),
243
- ],
244
- });
245
- },
246
- });
247
- const workersCmd = command({
248
- name: "workers",
249
- description: "Generate workers TypeScript",
250
- args: {},
251
- handler: async () => {
252
- const config = loadCloesceConfig(process.cwd());
253
- const root = process.cwd();
254
- const outputDir = config.outputDir ?? ".generated";
255
- if (!config.workersUrl) {
256
- console.error("Error: workersUrl must be defined in cloesce-config.json");
257
- process.exit(1);
287
+ catch (err) {
288
+ console.warn(`Failed to parse cloesce.config.json: ${err}`);
258
289
  }
259
- await runWasmCommand({
260
- name: "workers",
261
- wasmFile: "cli.wasm",
262
- args: [
263
- "generate",
264
- "workers",
265
- path.join(outputDir, "cidl.json"),
266
- path.join(outputDir, "workers.ts"),
267
- path.join(root, "wrangler.toml"),
268
- config.workersUrl,
269
- ],
270
- });
271
- },
272
- });
273
- const clientCmd = command({
274
- name: "client",
275
- description: "Generate client TypeScript",
276
- args: {},
277
- handler: async () => {
278
- const config = loadCloesceConfig(process.cwd());
279
- const outputDir = config.outputDir ?? ".generated";
280
- if (!config.clientUrl) {
281
- console.error("Error: clientUrl must be defined in cloesce-config.json");
282
- process.exit(1);
290
+ }
291
+ return {};
292
+ }
293
+ function readPackageJsonProjectName(cwd) {
294
+ const pkgPath = path.join(cwd, "package.json");
295
+ let projectName = path.basename(cwd);
296
+ if (fs.existsSync(pkgPath)) {
297
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
298
+ projectName = pkg.name ?? projectName;
299
+ }
300
+ return projectName;
301
+ }
302
+ function findCloesceProject(root, searchPaths, project) {
303
+ for (const searchPath of searchPaths) {
304
+ let fullPath;
305
+ if (path.isAbsolute(searchPath) || searchPath.startsWith(root)) {
306
+ fullPath = path.normalize(searchPath);
283
307
  }
284
- await runWasmCommand({
285
- name: "client",
286
- wasmFile: "cli.wasm",
287
- args: [
288
- "generate",
289
- "client",
290
- path.join(outputDir, "cidl.json"),
291
- path.join(outputDir, "client.ts"),
292
- config.clientUrl,
293
- ],
294
- });
295
- },
296
- });
297
- const extractCmd = command({
298
- name: "extract",
299
- description: "Extract models and write cidl.json only",
300
- args: {
301
- projectName: option({
302
- long: "project-name",
303
- type: optional(string),
304
- description: "Project name",
305
- }),
306
- out: option({
307
- long: "out",
308
- short: "o",
309
- type: optional(string),
310
- description: "Output path (default: .generated/cidl.json)",
311
- }),
312
- inp: option({
313
- long: "in",
314
- short: "i",
315
- type: optional(string),
316
- description: "Input file or directory",
317
- }),
318
- location: option({
319
- long: "location",
320
- short: "l",
321
- type: optional(string),
322
- description: "Project directory (default: cwd)",
323
- }),
324
- truncateSourcePaths: flag({
325
- long: "truncateSourcePaths",
326
- description: "Sets all source paths to just their file name",
327
- }),
328
- debug: flag({
329
- long: "debug",
330
- short: "d",
331
- description: "Show debug output",
332
- }),
333
- },
334
- handler: async (args) => {
335
- await runExtractor({ ...args });
336
- },
337
- });
338
- const router = subcommands({
339
- name: "cloesce",
340
- cmds: {
341
- run: runCmd,
342
- extract: extractCmd,
343
- wrangler: wranglerCmd,
344
- d1: d1Cmd,
345
- workers: workersCmd,
346
- client: clientCmd,
347
- },
348
- });
349
- run(router, process.argv.slice(2)).catch((err) => {
308
+ else {
309
+ fullPath = path.resolve(root, searchPath);
310
+ }
311
+ if (!fs.existsSync(fullPath)) {
312
+ console.warn(`Warning: Path "${searchPath}" does not exist`);
313
+ continue;
314
+ }
315
+ const stats = fs.statSync(fullPath);
316
+ if (stats.isFile() && /\.cloesce\.ts$/i.test(fullPath)) {
317
+ project.addSourceFileAtPath(fullPath);
318
+ }
319
+ else if (stats.isDirectory()) {
320
+ walkDirectory(fullPath, project);
321
+ }
322
+ }
323
+ function walkDirectory(dir, project) {
324
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
325
+ const fullPath = path.join(dir, entry.name);
326
+ if (entry.isDirectory() && !entry.name.startsWith(".")) {
327
+ walkDirectory(fullPath, project);
328
+ }
329
+ else if (entry.isFile() && /\.cloesce\.ts$/i.test(entry.name)) {
330
+ project.addSourceFileAtPath(fullPath);
331
+ }
332
+ }
333
+ }
334
+ }
335
+ function formatErr(e) {
336
+ const { description, suggestion } = getErrorInfo(e.code);
337
+ const contextLine = e.context ? `Context: ${e.context}\n` : "";
338
+ const snippetLine = e.snippet ? `${e.snippet}\n\n` : "";
339
+ return `==== CLOESCE ERROR ====
340
+ Error [${ExtractorErrorCode[e.code]}]: ${description}
341
+ Phase: TypeScript IDL Extraction
342
+ ${contextLine}${snippetLine}Suggested fix: ${suggestion}`;
343
+ }
344
+ run(cmds, process.argv.slice(2)).catch((err) => {
350
345
  console.error(err);
351
346
  process.exit(1);
352
347
  });
@@ -1,5 +1,5 @@
1
1
  import { SyntaxKind, } from "ts-morph";
2
- import { HttpVerb, left, right, ExtractorError, ExtractorErrorCode, } from "./common.js";
2
+ import { HttpVerb, left, right, ExtractorError, ExtractorErrorCode, } from "../common.js";
3
3
  import { TypeFormatFlags } from "typescript";
4
4
  var AttributeDecoratorKind;
5
5
  (function (AttributeDecoratorKind) {
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { cloesce, modelsFromSql } from "./cloesce.js";
1
+ export { cloesce, modelsFromSql } from "./runtime/runtime.js";
2
2
  // Compiler hints
3
3
  export const D1 = () => { };
4
4
  export const PlainOldObject = () => { };