cloesce 0.0.5-unstable.1 → 0.0.5-unstable.11

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 (41) hide show
  1. package/dist/ast.d.ts +96 -106
  2. package/dist/ast.d.ts.map +1 -1
  3. package/dist/ast.js +12 -12
  4. package/dist/cli.d.ts +1 -1
  5. package/dist/cli.js +330 -368
  6. package/dist/common.d.ts +23 -0
  7. package/dist/common.d.ts.map +1 -0
  8. package/dist/common.js +78 -0
  9. package/dist/extractor/err.d.ts +25 -26
  10. package/dist/extractor/err.d.ts.map +1 -1
  11. package/dist/extractor/err.js +95 -129
  12. package/dist/extractor/extract.d.ts +24 -61
  13. package/dist/extractor/extract.d.ts.map +1 -1
  14. package/dist/extractor/extract.js +1006 -836
  15. package/dist/generator.wasm +0 -0
  16. package/dist/orm.wasm +0 -0
  17. package/dist/router/crud.d.ts +2 -3
  18. package/dist/router/crud.d.ts.map +1 -1
  19. package/dist/router/crud.js +58 -48
  20. package/dist/router/orm.d.ts +66 -0
  21. package/dist/router/orm.d.ts.map +1 -0
  22. package/dist/router/orm.js +447 -0
  23. package/dist/router/router.d.ts +93 -139
  24. package/dist/router/router.d.ts.map +1 -1
  25. package/dist/router/router.js +389 -432
  26. package/dist/router/validator.d.ts +7 -12
  27. package/dist/router/validator.d.ts.map +1 -1
  28. package/dist/router/validator.js +190 -159
  29. package/dist/router/wasm.d.ts +26 -67
  30. package/dist/router/wasm.d.ts.map +1 -1
  31. package/dist/router/wasm.js +52 -103
  32. package/dist/ui/backend.d.ts +103 -382
  33. package/dist/ui/backend.d.ts.map +1 -1
  34. package/dist/ui/backend.js +143 -430
  35. package/package.json +4 -10
  36. package/dist/ui/client.d.ts +0 -7
  37. package/dist/ui/client.d.ts.map +0 -1
  38. package/dist/ui/client.js +0 -2
  39. package/dist/ui/common.d.ts +0 -126
  40. package/dist/ui/common.d.ts.map +0 -1
  41. package/dist/ui/common.js +0 -203
package/dist/cli.js CHANGED
@@ -3,406 +3,368 @@ import { WASI } from "node:wasi";
3
3
  import fs from "node:fs";
4
4
  import { readFile } from "fs/promises";
5
5
  import path from "node:path";
6
- import {
7
- command,
8
- run,
9
- subcommands,
10
- flag,
11
- string,
12
- positional,
13
- option,
14
- optional,
15
- } from "cmd-ts";
6
+ import { command, run, subcommands, flag, string, positional, option, optional, } from "cmd-ts";
16
7
  import { Project } from "ts-morph";
17
8
  import { CidlExtractor } from "./extractor/extract.js";
18
- import {
19
- ExtractorError,
20
- ExtractorErrorCode,
21
- getErrorInfo,
22
- } from "./extractor/err.js";
9
+ import { ExtractorError, ExtractorErrorCode, getErrorInfo, } from "./extractor/err.js";
23
10
  let debugPhase = "npm cloesce";
24
11
  function debug(...args) {
25
- console.log(`[${debugPhase}]: `, ...args);
12
+ console.log(`[${debugPhase}]: `, ...args);
26
13
  }
27
14
  const cmds = subcommands({
28
- name: "cloesce",
29
- cmds: {
30
- compile: command({
31
- name: "compile",
32
- description: "Run through the full compilation process.",
33
- args: {},
34
- handler: async () => {
35
- const config = loadCloesceConfig(process.cwd());
36
- if (!config) {
37
- process.exit(1);
38
- }
39
- await extract(config);
40
- debugPhase = "npm cloesce";
41
- const outputDir = config.outPath ?? ".generated";
42
- const generateConfig = {
43
- name: "generate",
44
- wasmFile: "generator.wasm",
45
- args: [
46
- "generate",
47
- path.join(outputDir, "cidl.pre.json"),
48
- path.join(outputDir, "cidl.json"),
49
- "wrangler.toml",
50
- path.join(outputDir, "workers.ts"),
51
- path.join(outputDir, "client.ts"),
52
- config.workersUrl,
53
- ],
54
- };
55
- await generate(generateConfig);
56
- },
57
- }),
58
- extract: command({
59
- name: "extract",
60
- description: "Extract models and write cidl.pre.json",
61
- args: {
62
- projectName: option({
63
- long: "project-name",
64
- type: optional(string),
65
- description: "Project name",
66
- }),
67
- out: option({
68
- long: "out",
69
- short: "o",
70
- type: optional(string),
71
- }),
72
- inp: option({
73
- long: "in",
74
- short: "i",
75
- type: optional(string),
76
- description: "Input file or directory",
15
+ name: "cloesce",
16
+ cmds: {
17
+ compile: command({
18
+ name: "compile",
19
+ description: "Run through the full compilation process.",
20
+ args: {},
21
+ handler: async () => {
22
+ const config = loadCloesceConfig(process.cwd());
23
+ if (!config) {
24
+ process.exit(1);
25
+ }
26
+ await extract(config);
27
+ debugPhase = "npm cloesce";
28
+ const outputDir = config.outPath ?? ".generated";
29
+ const generateConfig = {
30
+ name: "generate",
31
+ wasmFile: "generator.wasm",
32
+ args: [
33
+ "generate",
34
+ path.join(outputDir, "cidl.pre.json"),
35
+ path.join(outputDir, "cidl.json"),
36
+ "wrangler.toml",
37
+ path.join(outputDir, "workers.ts"),
38
+ path.join(outputDir, "client.ts"),
39
+ config.workersUrl,
40
+ ],
41
+ };
42
+ await generate(generateConfig);
43
+ },
77
44
  }),
78
- truncateSourcePaths: flag({
79
- long: "truncateSourcePaths",
80
- description: "Sets all source paths to just their file name",
45
+ extract: command({
46
+ name: "extract",
47
+ description: "Extract models and write cidl.pre.json",
48
+ args: {
49
+ projectName: option({
50
+ long: "project-name",
51
+ type: optional(string),
52
+ description: "Project name",
53
+ }),
54
+ out: option({
55
+ long: "out",
56
+ short: "o",
57
+ type: optional(string),
58
+ }),
59
+ inp: option({
60
+ long: "in",
61
+ short: "i",
62
+ type: optional(string),
63
+ description: "Input file or directory",
64
+ }),
65
+ truncateSourcePaths: flag({
66
+ long: "truncateSourcePaths",
67
+ description: "Sets all source paths to just their file name",
68
+ }),
69
+ skipTsCheck: flag({
70
+ long: "skipTsCheck",
71
+ description: "Skip TypeScript compilation checks",
72
+ }),
73
+ },
74
+ handler: async (args) => {
75
+ const config = {
76
+ projectName: args.projectName,
77
+ outPath: args.out,
78
+ paths: [args.inp],
79
+ truncateSourcePaths: false,
80
+ workersUrl: "",
81
+ migrationsPath: "",
82
+ };
83
+ await extract(config, {
84
+ truncateSourcePaths: args.truncateSourcePaths,
85
+ skipTsCheck: args.skipTsCheck,
86
+ });
87
+ },
81
88
  }),
82
- skipTsCheck: flag({
83
- long: "skipTsCheck",
84
- description: "Skip TypeScript compilation checks",
89
+ migrate: command({
90
+ name: "migrate",
91
+ description: "Creates a database migration.",
92
+ args: {
93
+ name: positional({ type: string, displayName: "name" }),
94
+ debug: flag({
95
+ long: "debug",
96
+ short: "d",
97
+ description: "Show debug output",
98
+ }),
99
+ },
100
+ handler: async (args) => {
101
+ const config = loadCloesceConfig(process.cwd());
102
+ if (!config) {
103
+ process.exit(1);
104
+ }
105
+ const cidlPath = path.join(config.outPath, "cidl.json");
106
+ if (!fs.existsSync(cidlPath)) {
107
+ console.error("Err: No cloesce file found, have you ran `cloesce compile`?");
108
+ process.exit(1);
109
+ }
110
+ if (!fs.existsSync(config.migrationsPath)) {
111
+ fs.mkdirSync(config.migrationsPath);
112
+ }
113
+ const migrationPrefix = path.join(config.migrationsPath, `${timestamp()}_${args.name}`);
114
+ let wasmArgs = [
115
+ "migrations",
116
+ cidlPath,
117
+ `${migrationPrefix}.json`,
118
+ `${migrationPrefix}.sql`,
119
+ ];
120
+ // Add last migration if exists
121
+ {
122
+ const files = fs.readdirSync(config.migrationsPath);
123
+ const jsonFiles = files.filter((f) => f.endsWith(".json"));
124
+ // Sort descending by filename
125
+ jsonFiles.sort((a, b) => b.localeCompare(a, undefined, { numeric: true }));
126
+ if (jsonFiles.length > 0) {
127
+ wasmArgs.push(path.join(config.migrationsPath, jsonFiles[0]));
128
+ }
129
+ }
130
+ const migrateConfig = {
131
+ name: "migrations",
132
+ wasmFile: "generator.wasm",
133
+ args: wasmArgs,
134
+ };
135
+ // Runs a generator command. Exits the process on failure.
136
+ await generate(migrateConfig);
137
+ },
85
138
  }),
86
- },
87
- handler: async (args) => {
88
- const config = {
89
- projectName: args.projectName,
90
- outPath: args.out,
91
- paths: [args.inp],
92
- truncateSourcePaths: false,
93
- workersUrl: "",
94
- migrationsPath: "",
95
- };
96
- await extract(config, {
97
- truncateSourcePaths: args.truncateSourcePaths,
98
- skipTsCheck: args.skipTsCheck,
99
- });
100
- },
101
- }),
102
- migrate: command({
103
- name: "migrate",
104
- description: "Creates a database migration.",
105
- args: {
106
- name: positional({ type: string, displayName: "name" }),
107
- debug: flag({
108
- long: "debug",
109
- short: "d",
110
- description: "Show debug output",
111
- }),
112
- },
113
- handler: async (args) => {
114
- const config = loadCloesceConfig(process.cwd());
115
- if (!config) {
116
- process.exit(1);
117
- }
118
- const cidlPath = path.join(config.outPath, "cidl.json");
119
- if (!fs.existsSync(cidlPath)) {
120
- console.error(
121
- "Err: No cloesce file found, have you ran `cloesce compile`?",
122
- );
123
- process.exit(1);
124
- }
125
- if (!fs.existsSync(config.migrationsPath)) {
126
- fs.mkdirSync(config.migrationsPath);
127
- }
128
- const migrationPrefix = path.join(
129
- config.migrationsPath,
130
- `${timestamp()}_${args.name}`,
131
- );
132
- let wasmArgs = [
133
- "migrations",
134
- cidlPath,
135
- `${migrationPrefix}.json`,
136
- `${migrationPrefix}.sql`,
137
- ];
138
- // Add last migration if exists
139
- {
140
- const files = fs.readdirSync(config.migrationsPath);
141
- const jsonFiles = files.filter((f) => f.endsWith(".json"));
142
- // Sort descending by filename
143
- jsonFiles.sort((a, b) =>
144
- b.localeCompare(a, undefined, { numeric: true }),
145
- );
146
- if (jsonFiles.length > 0) {
147
- wasmArgs.push(path.join(config.migrationsPath, jsonFiles[0]));
148
- }
149
- }
150
- const migrateConfig = {
151
- name: "migrations",
152
- wasmFile: "generator.wasm",
153
- args: wasmArgs,
154
- };
155
- // Runs a generator command. Exits the process on failure.
156
- await generate(migrateConfig);
157
- },
158
- }),
159
- },
139
+ },
160
140
  });
161
141
  async function extract(config, args = {}) {
162
- const startTime = Date.now();
163
- debugPhase = "extractor";
164
- debug("Preparing extraction...");
165
- const root = process.cwd();
166
- const projectRoot = process.cwd();
167
- const searchPaths = config.paths ?? [root];
168
- const outPath = (() => {
169
- // If the out path is a directory, join it with "cidl.pre.json"
170
- if (
171
- fs.existsSync(config.outPath) &&
172
- fs.statSync(config.outPath).isDirectory()
173
- ) {
174
- return path.join(config.outPath, "cidl.pre.json");
142
+ const startTime = Date.now();
143
+ debugPhase = "extractor";
144
+ debug("Preparing extraction...");
145
+ const root = process.cwd();
146
+ const projectRoot = process.cwd();
147
+ const searchPaths = config.paths ?? [root];
148
+ const outPath = (() => {
149
+ // If the out path is a directory, join it with "cidl.pre.json"
150
+ if (fs.existsSync(config.outPath) &&
151
+ fs.statSync(config.outPath).isDirectory()) {
152
+ return path.join(config.outPath, "cidl.pre.json");
153
+ }
154
+ // If the out path is a file, use it directly
155
+ if (config.outPath && config.outPath.endsWith(".json")) {
156
+ return config.outPath;
157
+ }
158
+ // Default to .generated/cidl.pre.json
159
+ return path.join(config.outPath ?? ".generated", "cidl.pre.json");
160
+ })();
161
+ const truncate = args.truncateSourcePaths ?? config.truncateSourcePaths ?? false;
162
+ const cloesceProjectName = config.projectName ?? readPackageJsonProjectName(projectRoot);
163
+ const project = new Project({
164
+ skipAddingFilesFromTsConfig: true,
165
+ compilerOptions: {
166
+ skipLibCheck: true,
167
+ strictNullChecks: true,
168
+ experimentalDecorators: true,
169
+ emitDecoratorMetadata: true,
170
+ },
171
+ });
172
+ findCloesceProject(root, searchPaths, project);
173
+ const fileCount = project.getSourceFiles().length;
174
+ if (fileCount === 0) {
175
+ new ExtractorError(ExtractorErrorCode.MissingFile);
175
176
  }
176
- // If the out path is a file, use it directly
177
- if (config.outPath && config.outPath.endsWith(".json")) {
178
- return config.outPath;
177
+ debug(`Found ${fileCount} .cloesce.ts files`);
178
+ // Run typescript compiler checks to before extraction
179
+ if (!args.skipTsCheck) {
180
+ const tscStart = Date.now();
181
+ debug("Running TypeScript compiler checks...");
182
+ const diagnostics = project.getPreEmitDiagnostics();
183
+ if (diagnostics.length > 0) {
184
+ console.error("TypeScript errors detected in provided files:");
185
+ console.error(project.formatDiagnosticsWithColorAndContext(diagnostics));
186
+ process.exit(1);
187
+ }
188
+ debug(`TypeScript checks completed in ${Date.now() - tscStart}ms`);
179
189
  }
180
- // Default to .generated/cidl.pre.json
181
- return path.join(config.outPath ?? ".generated", "cidl.pre.json");
182
- })();
183
- const truncate =
184
- args.truncateSourcePaths ?? config.truncateSourcePaths ?? false;
185
- const cloesceProjectName =
186
- config.projectName ?? readPackageJsonProjectName(projectRoot);
187
- const project = new Project({
188
- skipAddingFilesFromTsConfig: true,
189
- compilerOptions: {
190
- skipLibCheck: true,
191
- strictNullChecks: true,
192
- experimentalDecorators: true,
193
- emitDecoratorMetadata: true,
194
- },
195
- });
196
- findCloesceProject(root, searchPaths, project);
197
- const fileCount = project.getSourceFiles().length;
198
- if (fileCount === 0) {
199
- new ExtractorError(ExtractorErrorCode.MissingFile);
200
- }
201
- debug(`Found ${fileCount} .cloesce.ts files`);
202
- // Run typescript compiler checks to before extraction
203
- if (!args.skipTsCheck) {
204
- const tscStart = Date.now();
205
- debug("Running TypeScript compiler checks...");
206
- const diagnostics = project.getPreEmitDiagnostics();
207
- if (diagnostics.length > 0) {
208
- console.error("TypeScript errors detected in provided files:");
209
- console.error(project.formatDiagnosticsWithColorAndContext(diagnostics));
210
- process.exit(1);
190
+ try {
191
+ const extractorStart = Date.now();
192
+ debug("Extracting CIDL...");
193
+ const result = CidlExtractor.extract(cloesceProjectName, project);
194
+ if (result.isLeft()) {
195
+ console.error(formatErr(result.value));
196
+ process.exit(1);
197
+ }
198
+ const ast = result.unwrap();
199
+ if (truncate) {
200
+ if (ast.wrangler_env) {
201
+ ast.wrangler_env.source_path =
202
+ "./" + path.basename(ast.wrangler_env.source_path);
203
+ }
204
+ if (ast.main_source) {
205
+ ast.main_source = "./" + path.basename(ast.main_source);
206
+ }
207
+ for (const model of Object.values(ast.models)) {
208
+ model.source_path = "./" + path.basename(model.source_path);
209
+ }
210
+ for (const poo of Object.values(ast.poos)) {
211
+ poo.source_path = "./" + path.basename(poo.source_path);
212
+ }
213
+ for (const service of Object.values(ast.services)) {
214
+ service.source_path = "./" + path.basename(service.source_path);
215
+ }
216
+ }
217
+ const json = JSON.stringify(ast, null, 4);
218
+ fs.mkdirSync(path.dirname(outPath), { recursive: true });
219
+ fs.writeFileSync(outPath, json);
220
+ debug(`Successfully extracted cidl.pre.json ${outPath} in ${Date.now() - extractorStart}ms`);
221
+ return { outPath, projectName: cloesceProjectName };
211
222
  }
212
- debug(`TypeScript checks completed in ${Date.now() - tscStart}ms`);
213
- }
214
- try {
215
- const extractorStart = Date.now();
216
- debug("Extracting CIDL...");
217
- const extractor = new CidlExtractor(cloesceProjectName, "v0.0.4");
218
- const result = extractor.extract(project);
219
- if (result.isLeft()) {
220
- console.error(formatErr(result.value));
221
- process.exit(1);
223
+ catch (err) {
224
+ console.error("Critical uncaught error in extractor. \nSubmit a ticket to https://github.com/bens-schreiber/cloesce\n\n", err?.message ?? "No error message.", "\n", err?.stack ?? "No error stack.");
225
+ process.exit(1);
222
226
  }
223
- let ast = result.unwrap();
224
- if (truncate) {
225
- if (ast.wrangler_env) {
226
- ast.wrangler_env.source_path =
227
- "./" + path.basename(ast.wrangler_env.source_path);
228
- }
229
- if (ast.app_source) {
230
- ast.app_source = "./" + path.basename(ast.app_source);
231
- }
232
- for (const model of Object.values(ast.models)) {
233
- model.source_path = "./" + path.basename(model.source_path);
234
- }
235
- for (const poo of Object.values(ast.poos)) {
236
- poo.source_path = "./" + path.basename(poo.source_path);
237
- }
238
- for (const service of Object.values(ast.services)) {
239
- service.source_path = "./" + path.basename(service.source_path);
240
- }
227
+ finally {
228
+ debug(`Extraction process completed in ${Date.now() - startTime}ms`);
241
229
  }
242
- const json = JSON.stringify(ast, null, 4);
243
- fs.mkdirSync(path.dirname(outPath), { recursive: true });
244
- fs.writeFileSync(outPath, json);
245
- debug(
246
- `Successfully extracted cidl.pre.json ${outPath} in ${Date.now() - extractorStart}ms`,
247
- );
248
- return { outPath, projectName: cloesceProjectName };
249
- } catch (err) {
250
- console.error(
251
- "Critical uncaught error in extractor. \nSubmit a ticket to https://github.com/bens-schreiber/cloesce\n\n",
252
- err?.message ?? "No error message.",
253
- "\n",
254
- err?.stack ?? "No error stack.",
255
- );
256
- process.exit(1);
257
- } finally {
258
- debug(`Extraction process completed in ${Date.now() - startTime}ms`);
259
- }
260
230
  }
261
231
  async function generate(config) {
262
- const debugStart = Date.now();
263
- debug(`Starting generator`);
264
- const root = process.cwd();
265
- // Look for wrangler.toml in the root directory
266
- const wranglerPath = path.join(root, "wrangler.toml");
267
- if (!fs.existsSync(wranglerPath)) {
268
- debug("No wrangler.toml found, creating empty file.");
269
- fs.writeFileSync(wranglerPath, "");
270
- }
271
- debug(`Using wrangler.toml at ${wranglerPath}`);
272
- const wasi = new WASI({
273
- version: "preview1",
274
- args: ["generate", ...config.args],
275
- env: { ...process.env, ...config.env },
276
- preopens: { ".": root },
277
- });
278
- const readWasmStart = Date.now();
279
- debug(`Reading generator binary...`);
280
- const wasm = await readFile(new URL("./generator.wasm", import.meta.url));
281
- const mod = await WebAssembly.compile(new Uint8Array(wasm));
282
- let instance = await WebAssembly.instantiate(mod, {
283
- wasi_snapshot_preview1: wasi.wasiImport,
284
- });
285
- debug(
286
- `Read and compiled generator wasm binary in ${Date.now() - readWasmStart}ms`,
287
- );
288
- try {
289
- wasi.start(instance);
290
- } catch (err) {
291
- console.error(`WASM execution failed for ${config.name}:`, err);
292
- throw err;
293
- } finally {
294
- debug(`Generator ${config.name} completed in ${Date.now() - debugStart}ms`);
295
- }
296
- }
297
- function loadCloesceConfig(root) {
298
- const configPath = path.join(root, "cloesce.config.json");
299
- if (!fs.existsSync(configPath)) {
300
- debug("No cloesce.config.json found");
301
- return undefined;
302
- }
303
- try {
304
- const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
305
- debug(`Loaded config from ${configPath}`);
306
- if (!config.paths || !Array.isArray(config.paths)) {
307
- debug("No paths specified in cloesce.config.json, defaulting to root");
308
- config.paths = [root];
232
+ const debugStart = Date.now();
233
+ debug(`Starting generator`);
234
+ const root = process.cwd();
235
+ // Look for wrangler.toml in the root directory
236
+ const wranglerPath = path.join(root, "wrangler.toml");
237
+ if (!fs.existsSync(wranglerPath)) {
238
+ debug("No wrangler.toml found, creating empty file.");
239
+ fs.writeFileSync(wranglerPath, "");
309
240
  }
310
- if (!config.projectName) {
311
- debug(
312
- "No projectName specified in cloesce.config.json, reading from package.json",
313
- );
314
- config.projectName = readPackageJsonProjectName(root);
241
+ debug(`Using wrangler.toml at ${wranglerPath}`);
242
+ const wasi = new WASI({
243
+ version: "preview1",
244
+ args: ["generate", ...config.args],
245
+ env: { ...process.env, ...config.env },
246
+ preopens: { ".": root },
247
+ });
248
+ const readWasmStart = Date.now();
249
+ debug(`Reading generator binary...`);
250
+ const wasm = await readFile(new URL("./generator.wasm", import.meta.url));
251
+ const mod = await WebAssembly.compile(new Uint8Array(wasm));
252
+ let instance = await WebAssembly.instantiate(mod, {
253
+ wasi_snapshot_preview1: wasi.wasiImport,
254
+ });
255
+ debug(`Read and compiled generator wasm binary in ${Date.now() - readWasmStart}ms`);
256
+ try {
257
+ wasi.start(instance);
315
258
  }
316
- if (!config.outPath) {
317
- debug(
318
- "No outPath specified in cloesce.config.json, defaulting to .generated",
319
- );
320
- config.outPath = ".generated";
259
+ catch (err) {
260
+ console.error(`WASM execution failed for ${config.name}:`, err);
261
+ throw err;
321
262
  }
322
- if (!config.workersUrl) {
323
- debug(
324
- "No workersUrl specified in cloesce.config.json, localhost:8787 will be used",
325
- );
326
- config.workersUrl = "http://localhost:8787";
263
+ finally {
264
+ debug(`Generator ${config.name} completed in ${Date.now() - debugStart}ms`);
327
265
  }
328
- if (!config.migrationsPath) {
329
- debug(
330
- "No migrationsPath specified in cloesce.config.json, defaulting to ./migrations",
331
- );
332
- config.migrationsPath = "./migrations";
266
+ }
267
+ function loadCloesceConfig(root) {
268
+ const configPath = path.join(root, "cloesce.config.json");
269
+ if (!fs.existsSync(configPath)) {
270
+ debug("No cloesce.config.json found");
271
+ return undefined;
333
272
  }
334
- if (typeof config.truncateSourcePaths !== "boolean") {
335
- config.truncateSourcePaths = false;
273
+ try {
274
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
275
+ debug(`Loaded config from ${configPath}`);
276
+ if (!config.paths || !Array.isArray(config.paths)) {
277
+ debug("No paths specified in cloesce.config.json, defaulting to root");
278
+ config.paths = [root];
279
+ }
280
+ if (!config.projectName) {
281
+ debug("No projectName specified in cloesce.config.json, reading from package.json");
282
+ config.projectName = readPackageJsonProjectName(root);
283
+ }
284
+ if (!config.outPath) {
285
+ debug("No outPath specified in cloesce.config.json, defaulting to .generated");
286
+ config.outPath = ".generated";
287
+ }
288
+ if (!config.workersUrl) {
289
+ debug("No workersUrl specified in cloesce.config.json, localhost:8787 will be used");
290
+ config.workersUrl = "http://localhost:8787";
291
+ }
292
+ if (!config.migrationsPath) {
293
+ debug("No migrationsPath specified in cloesce.config.json, defaulting to ./migrations");
294
+ config.migrationsPath = "./migrations";
295
+ }
296
+ if (typeof config.truncateSourcePaths !== "boolean") {
297
+ config.truncateSourcePaths = false;
298
+ }
299
+ debug(`Cloesce Config: ${JSON.stringify({ ...config, truncateSourcePaths: undefined }, null, 4)}`);
300
+ return config;
301
+ }
302
+ catch (err) {
303
+ console.warn(`Failed to parse cloesce.config.json: ${err}`);
304
+ throw err;
336
305
  }
337
- debug(
338
- `Cloesce Config: ${JSON.stringify({ ...config, truncateSourcePaths: undefined }, null, 4)}`,
339
- );
340
- return config;
341
- } catch (err) {
342
- console.warn(`Failed to parse cloesce.config.json: ${err}`);
343
- throw err;
344
- }
345
306
  }
346
307
  function timestamp() {
347
- const d = new Date();
348
- return (
349
- d.getFullYear().toString() +
350
- String(d.getMonth() + 1).padStart(2, "0") +
351
- String(d.getDate()).padStart(2, "0") +
352
- "T" +
353
- String(d.getHours()).padStart(2, "0") +
354
- String(d.getMinutes()).padStart(2, "0") +
355
- String(d.getSeconds()).padStart(2, "0")
356
- );
308
+ const d = new Date();
309
+ return (d.getFullYear().toString() +
310
+ String(d.getMonth() + 1).padStart(2, "0") +
311
+ String(d.getDate()).padStart(2, "0") +
312
+ "T" +
313
+ String(d.getHours()).padStart(2, "0") +
314
+ String(d.getMinutes()).padStart(2, "0") +
315
+ String(d.getSeconds()).padStart(2, "0"));
357
316
  }
358
317
  function readPackageJsonProjectName(cwd) {
359
- const pkgPath = path.join(cwd, "package.json");
360
- let projectName = path.basename(cwd);
361
- if (fs.existsSync(pkgPath)) {
362
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
363
- projectName = pkg.name ?? projectName;
364
- }
365
- return projectName;
318
+ const pkgPath = path.join(cwd, "package.json");
319
+ let projectName = path.basename(cwd);
320
+ if (fs.existsSync(pkgPath)) {
321
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
322
+ projectName = pkg.name ?? projectName;
323
+ }
324
+ return projectName;
366
325
  }
367
326
  function findCloesceProject(root, searchPaths, project) {
368
- for (const searchPath of searchPaths) {
369
- let fullPath;
370
- if (path.isAbsolute(searchPath) || searchPath.startsWith(root)) {
371
- fullPath = path.normalize(searchPath);
372
- } else {
373
- fullPath = path.resolve(root, searchPath);
374
- }
375
- if (!fs.existsSync(fullPath)) {
376
- console.warn(`Warning: Path "${searchPath}" does not exist`);
377
- continue;
378
- }
379
- const stats = fs.statSync(fullPath);
380
- if (stats.isFile() && /\.cloesce\.ts$/i.test(fullPath)) {
381
- debug(`Found file: ${fullPath}`);
382
- project.addSourceFileAtPath(fullPath);
383
- } else if (stats.isDirectory()) {
384
- debug(`Searching directory: ${fullPath}`);
385
- walkDirectory(fullPath);
327
+ for (const searchPath of searchPaths) {
328
+ let fullPath;
329
+ if (path.isAbsolute(searchPath) || searchPath.startsWith(root)) {
330
+ fullPath = path.normalize(searchPath);
331
+ }
332
+ else {
333
+ fullPath = path.resolve(root, searchPath);
334
+ }
335
+ if (!fs.existsSync(fullPath)) {
336
+ console.warn(`Warning: Path "${searchPath}" does not exist`);
337
+ continue;
338
+ }
339
+ const stats = fs.statSync(fullPath);
340
+ if (stats.isFile() && /\.cloesce\.ts$/i.test(fullPath)) {
341
+ debug(`Found file: ${fullPath}`);
342
+ project.addSourceFileAtPath(fullPath);
343
+ }
344
+ else if (stats.isDirectory()) {
345
+ debug(`Searching directory: ${fullPath}`);
346
+ walkDirectory(fullPath);
347
+ }
386
348
  }
387
- }
388
- function walkDirectory(dir) {
389
- for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
390
- const fullPath = path.join(dir, entry.name);
391
- if (entry.isDirectory() && !entry.name.startsWith(".")) {
392
- debug(`Entering directory: ${fullPath}`);
393
- walkDirectory(fullPath);
394
- } else if (entry.isFile() && /\.cloesce\.ts$/i.test(entry.name)) {
395
- debug(`Found file: ${fullPath}`);
396
- project.addSourceFileAtPath(fullPath);
397
- }
349
+ function walkDirectory(dir) {
350
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
351
+ const fullPath = path.join(dir, entry.name);
352
+ if (entry.isDirectory() && !entry.name.startsWith(".")) {
353
+ debug(`Entering directory: ${fullPath}`);
354
+ walkDirectory(fullPath);
355
+ }
356
+ else if (entry.isFile() && /\.cloesce\.ts$/i.test(entry.name)) {
357
+ debug(`Found file: ${fullPath}`);
358
+ project.addSourceFileAtPath(fullPath);
359
+ }
360
+ }
398
361
  }
399
- }
400
362
  }
401
363
  function formatErr(e) {
402
- const { description, suggestion } = getErrorInfo(e.code);
403
- const contextLine = e.context ? `Context: ${e.context}\n` : "";
404
- const snippetLine = e.snippet ? `${e.snippet}\n\n` : "";
405
- return `
364
+ const { description, suggestion } = getErrorInfo(e.code);
365
+ const contextLine = e.context ? `Context: ${e.context}\n` : "";
366
+ const snippetLine = e.snippet ? `${e.snippet}\n\n` : "";
367
+ return `
406
368
  ==== CLOESCE ERROR ====
407
369
  Error [${ExtractorErrorCode[e.code]}]: ${description}
408
370
  Phase: TypeScript IDL Extraction
@@ -411,6 +373,6 @@ ${contextLine}${snippetLine}Suggested fix: ${suggestion}
411
373
  `;
412
374
  }
413
375
  run(cmds, process.argv.slice(2)).catch((err) => {
414
- console.error(err);
415
- process.exit(1);
376
+ console.error(err);
377
+ process.exit(1);
416
378
  });