cloesce 0.0.4-unstable.4 → 0.0.4-unstable.6
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.
- package/README.md +122 -152
- package/dist/cli.js +26 -14
- package/dist/common.d.ts +14 -50
- package/dist/common.d.ts.map +1 -1
- package/dist/common.js +42 -22
- package/dist/extractor/extract.d.ts.map +1 -1
- package/dist/extractor/extract.js +44 -47
- package/dist/generator.wasm +0 -0
- package/dist/orm.wasm +0 -0
- package/dist/router/crud.d.ts.map +1 -1
- package/dist/router/crud.js +16 -11
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/router.js +25 -24
- package/dist/router/wasm.d.ts +9 -2
- package/dist/router/wasm.d.ts.map +1 -1
- package/dist/router/wasm.js +11 -5
- package/dist/ui/backend.d.ts +142 -84
- package/dist/ui/backend.d.ts.map +1 -1
- package/dist/ui/backend.js +176 -130
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,23 +6,23 @@ Cloesce is working towards a stable alpha MVP (v0.1.0), with the general milesto
|
|
|
6
6
|
|
|
7
7
|
Internal documentation going over design decisions and general thoughts for each milestone can be found [here](https://cloesce.pages.dev/).
|
|
8
8
|
|
|
9
|
-
# Documentation
|
|
9
|
+
# Documentation
|
|
10
10
|
|
|
11
11
|
## Getting Started
|
|
12
12
|
|
|
13
13
|
`v0.0.4` supports only Typescript-to-Typescript projects. An example project is shown [here](https://github.com/bens-schreiber/cloesce/tree/main/examples).
|
|
14
14
|
|
|
15
|
-
1
|
|
15
|
+
### 1) NPM
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Create an NPM project and install cloesce
|
|
18
18
|
|
|
19
19
|
```sh
|
|
20
|
-
npm i cloesce@0.0.4-unstable.
|
|
20
|
+
npm i cloesce@0.0.4-unstable.6
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
2
|
|
23
|
+
### 2) TypeScript
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Create a `tsconfig.json` with the following values:
|
|
26
26
|
|
|
27
27
|
```json
|
|
28
28
|
{
|
|
@@ -38,9 +38,9 @@ npm i cloesce@0.0.4-unstable.3
|
|
|
38
38
|
}
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
3
|
|
41
|
+
### 3) Cloesce Config
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Create a `cloesce.config.json` with your desired configuration:
|
|
44
44
|
|
|
45
45
|
```json
|
|
46
46
|
{
|
|
@@ -50,7 +50,7 @@ npm i cloesce@0.0.4-unstable.3
|
|
|
50
50
|
}
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
4
|
|
53
|
+
### 4) Vite
|
|
54
54
|
|
|
55
55
|
To prevent CORS issues, a Vite proxy can be used for the frontend:
|
|
56
56
|
|
|
@@ -70,9 +70,9 @@ export default defineConfig({
|
|
|
70
70
|
});
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
5
|
|
73
|
+
### 5) Wrangler Config
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
Cloesce will generate any missing `wrangler.toml` values (or the file if missing). A minimal `wrangler.toml` looks like this:
|
|
76
76
|
|
|
77
77
|
```toml
|
|
78
78
|
compatibility_date = "2025-10-02"
|
|
@@ -85,12 +85,11 @@ database_id = "..."
|
|
|
85
85
|
database_name = "example"
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
##
|
|
88
|
+
## Cloesce Models
|
|
89
89
|
|
|
90
90
|
A model is a type which represents:
|
|
91
91
|
|
|
92
92
|
- a database table,
|
|
93
|
-
- database views
|
|
94
93
|
- REST API
|
|
95
94
|
- Client API
|
|
96
95
|
- Cloudflare infrastructure (D1 + Workers)
|
|
@@ -120,13 +119,18 @@ export class Horse {
|
|
|
120
119
|
- `@POST` reveals the method as an API endpoint with the `POST` HTTP Verb.
|
|
121
120
|
- All Cloesce models need to be under a `.cloesce.ts` file.
|
|
122
121
|
|
|
123
|
-
To compile this model into a working full stack application, Cloesce must undergo both **compilation** and **migrations**.
|
|
122
|
+
To compile this model into a working full stack application, Cloesce must undergo both **compilation** and **migrations**.
|
|
124
123
|
|
|
125
|
-
|
|
124
|
+
Compilation is the process of extracting the metadata language that powers Cloesce, ensuring it is a valid program, and then producing code to orchestrate the program across different domains (database, backend, frontend, cloud).
|
|
126
125
|
|
|
127
|
-
|
|
126
|
+
Migrations utilize the history of validated metadata to create SQL code, translating the evolution of your models.
|
|
128
127
|
|
|
129
|
-
|
|
128
|
+
### Compiling
|
|
129
|
+
|
|
130
|
+
- `npx cloesce compile`
|
|
131
|
+
- `npx cloesce migrate <name>`.
|
|
132
|
+
|
|
133
|
+
After running the above commands, you will have a full project capable of being ran with Wrangler:
|
|
130
134
|
|
|
131
135
|
```sh
|
|
132
136
|
# Apply the generated migrations
|
|
@@ -136,13 +140,19 @@ npx wrangler d1 migrations apply <db-name>
|
|
|
136
140
|
npx wrangler dev
|
|
137
141
|
```
|
|
138
142
|
|
|
139
|
-
|
|
143
|
+
### Compiled Artifacts
|
|
144
|
+
|
|
145
|
+
#### `.generated/`
|
|
146
|
+
|
|
147
|
+
These values should not be committed to git, as they depend on the file system of the machine running it.
|
|
140
148
|
|
|
141
149
|
- `client.ts` is an importable API with all of your backend types and endpoints
|
|
142
150
|
- `workers.ts` is the workers entrypoint.
|
|
143
151
|
- `cidl.json` is the working metadata for the project
|
|
144
152
|
|
|
145
|
-
|
|
153
|
+
#### `migrations`
|
|
154
|
+
|
|
155
|
+
After running `npx cloesce migrate <name>`, a new migration will be created in the `migrations/` folder. For example, after creating a migration called `Initial`, you will see:
|
|
146
156
|
|
|
147
157
|
- `<date>_Initial.json` contains all model information necessary from SQL
|
|
148
158
|
- `<date>_Initial.sql` contains the acual SQL migrations. In this early version of Cloesce, it's important to check migrations every time.
|
|
@@ -170,7 +180,7 @@ In order to interact with your database, you will need to define a WranglerEnv
|
|
|
170
180
|
import { WranglerEnv } from "cloesce/backend";
|
|
171
181
|
|
|
172
182
|
@WranglerEnv
|
|
173
|
-
export class
|
|
183
|
+
export class MyEnv {
|
|
174
184
|
db: D1Database; // only one DB is supported for now-- make sure it matches the name in `wrangler.toml`
|
|
175
185
|
|
|
176
186
|
// you can also define values in the toml under [[vars]]
|
|
@@ -178,7 +188,7 @@ export class Env {
|
|
|
178
188
|
}
|
|
179
189
|
```
|
|
180
190
|
|
|
181
|
-
|
|
191
|
+
Your WranglerEnv can then be injected into any model method using the `@Inject` decorator:
|
|
182
192
|
|
|
183
193
|
```ts
|
|
184
194
|
@D1
|
|
@@ -187,7 +197,7 @@ export class Horse {
|
|
|
187
197
|
id: number;
|
|
188
198
|
|
|
189
199
|
@POST
|
|
190
|
-
async neigh(@Inject env:
|
|
200
|
+
async neigh(@Inject env: MyEnv): Promise<string> {
|
|
191
201
|
await env.db.prepare(...);
|
|
192
202
|
|
|
193
203
|
return `i am ${this.name}, this is my horse noise`;
|
|
@@ -195,10 +205,9 @@ export class Horse {
|
|
|
195
205
|
}
|
|
196
206
|
```
|
|
197
207
|
|
|
198
|
-
### Foreign
|
|
208
|
+
### Foreign Key Column
|
|
199
209
|
|
|
200
|
-
|
|
201
|
-
Foreign keys are scalar attributes which must reference some other model's primary key:
|
|
210
|
+
Reference another model via a foreign key using the `@ForeignKey` decorator:
|
|
202
211
|
|
|
203
212
|
```ts
|
|
204
213
|
@D1
|
|
@@ -217,7 +226,9 @@ export class Person {
|
|
|
217
226
|
}
|
|
218
227
|
```
|
|
219
228
|
|
|
220
|
-
|
|
229
|
+
### One to One
|
|
230
|
+
|
|
231
|
+
Cloesce allows you to relate models via `1:1` relationships using the `@OneToOne` decorator. It requires that a foreign key already exists on the model.
|
|
221
232
|
|
|
222
233
|
```ts
|
|
223
234
|
@D1
|
|
@@ -239,7 +250,7 @@ export class Person {
|
|
|
239
250
|
}
|
|
240
251
|
```
|
|
241
252
|
|
|
242
|
-
In `v0.0.4`, there are no defaults, only very explicit decisons. Because of that, navigation properties won't exist at runtime unless you tell them to. Cloesce does this via a `
|
|
253
|
+
In `v0.0.4`, there are no defaults, only very explicit decisons. Because of that, navigation properties won't exist at runtime unless you tell them to. Cloesce does this via a `Data Source`, which describes the foreign key dependencies you wish to include. All scalar properties are included by default and cannot be excluded.
|
|
243
254
|
|
|
244
255
|
```ts
|
|
245
256
|
@D1
|
|
@@ -266,129 +277,9 @@ export class Person {
|
|
|
266
277
|
}
|
|
267
278
|
```
|
|
268
279
|
|
|
269
|
-
Data sources
|
|
270
|
-
|
|
271
|
-
```ts
|
|
272
|
-
@D1
|
|
273
|
-
export class Person {
|
|
274
|
-
@PrimaryKey
|
|
275
|
-
id: number;
|
|
276
|
-
|
|
277
|
-
@ForeignKey(Dog)
|
|
278
|
-
dogId: number;
|
|
279
|
-
|
|
280
|
-
@OneToOne("dogId")
|
|
281
|
-
dog: Dog | undefined;
|
|
282
|
-
|
|
283
|
-
@DataSource
|
|
284
|
-
static readonly default: IncludeTree<Person> = {
|
|
285
|
-
dog: {},
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
@GET
|
|
289
|
-
static async get(id: number, @Inject env: WranglerEnv): Promise<Person> {
|
|
290
|
-
let records = await env.db
|
|
291
|
-
.prepare("SELECT * FROM [Person.default] WHERE [id] = ?") // Person.default is the SQL view generated from the IncludeTree
|
|
292
|
-
.bind(id)
|
|
293
|
-
.run();
|
|
294
|
-
|
|
295
|
-
let persons = Orm.mapSql(Person, records.results, Person.default);
|
|
296
|
-
return persons.value[0];
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
Note that the `get` code can be simplified using CRUD methods or the ORM primitive `get`.
|
|
302
|
-
|
|
303
|
-
#### View Aliasing
|
|
304
|
-
|
|
305
|
-
The generated views will always be aliased so that they can be accessed in an object like notation. For example, given some `Horse` that has a relationship with `Like`:
|
|
306
|
-
|
|
307
|
-
```ts
|
|
308
|
-
@D1
|
|
309
|
-
export class Horse {
|
|
310
|
-
@PrimaryKey
|
|
311
|
-
id: Integer;
|
|
312
|
-
|
|
313
|
-
name: string;
|
|
314
|
-
bio: string | null;
|
|
315
|
-
|
|
316
|
-
@OneToMany("horseId1")
|
|
317
|
-
likes: Like[];
|
|
318
|
-
|
|
319
|
-
@DataSource
|
|
320
|
-
static readonly default: IncludeTree<Horse> = {
|
|
321
|
-
likes: { horse2: {} },
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
@D1
|
|
326
|
-
export class Like {
|
|
327
|
-
@PrimaryKey
|
|
328
|
-
id: Integer;
|
|
329
|
-
|
|
330
|
-
@ForeignKey(Horse)
|
|
331
|
-
horseId1: Integer;
|
|
332
|
-
|
|
333
|
-
@ForeignKey(Horse)
|
|
334
|
-
horseId2: Integer;
|
|
335
|
-
|
|
336
|
-
@OneToOne("horseId2")
|
|
337
|
-
horse2: Horse | undefined;
|
|
338
|
-
}
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
If you wanted to find all horses that like one another, a valid SQL query using the `default` data source would look like:
|
|
342
|
-
|
|
343
|
-
```sql
|
|
344
|
-
SELECT * FROM [Horse.default] as H1
|
|
345
|
-
WHERE
|
|
346
|
-
H1.[id] = ?
|
|
347
|
-
AND EXISTS (
|
|
348
|
-
SELECT 1
|
|
349
|
-
FROM [Horse.default] AS H2
|
|
350
|
-
WHERE H2.[id] = H1.[likes.horse2.id]
|
|
351
|
-
AND H2.[likes.horse2.id] = H1.[id]
|
|
352
|
-
);
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
The actual generated view for `default` looks like:
|
|
356
|
-
|
|
357
|
-
```sql
|
|
358
|
-
CREATE VIEW IF NOT EXISTS "Horse.default" AS
|
|
359
|
-
SELECT
|
|
360
|
-
"Horse"."id" AS "id",
|
|
361
|
-
"Horse"."name" AS "name",
|
|
362
|
-
"Horse"."bio" AS "bio",
|
|
363
|
-
"Like"."id" AS "likes.id",
|
|
364
|
-
"Like"."horseId1" AS "likes.horseId1",
|
|
365
|
-
"Like"."horseId2" AS "likes.horseId2",
|
|
366
|
-
"Horse1"."id" AS "likes.horse2.id",
|
|
367
|
-
"Horse1"."name" AS "likes.horse2.name",
|
|
368
|
-
"Horse1"."bio" AS "likes.horse2.bio"
|
|
369
|
-
FROM
|
|
370
|
-
"Horse"
|
|
371
|
-
LEFT JOIN
|
|
372
|
-
"Like" ON "Horse"."id" = "Like"."horseId1"
|
|
373
|
-
LEFT JOIN
|
|
374
|
-
"Horse" AS "Horse1" ON "Like"."horseId2" = "Horse1"."id";
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
#### DataSourceOf<T>
|
|
378
|
-
|
|
379
|
-
If it is important to determine what data source the frontend called the instantiated method with, the type `DataSourceOf<T>` allows explicit data source parameters:
|
|
380
|
-
|
|
381
|
-
```ts
|
|
382
|
-
@D1
|
|
383
|
-
class Foo {
|
|
384
|
-
...
|
|
280
|
+
Data sources describe how foreign keys should be joined on model hydration (i.e. when invoking any instantiated method). They are composed of an `IncludeTree<T>`, a recursive type composed of the relationships you wish to include. All scalar properties are always included.
|
|
385
281
|
|
|
386
|
-
|
|
387
|
-
bar(ds: DataSourceOf<Foo>) {
|
|
388
|
-
// ds = "DataSource1" | "DataSource2" | ... | "none"
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
```
|
|
282
|
+
Note that `DataSourceOf` is added implicitly to all instantiated methods if no data source parameter is defined.
|
|
392
283
|
|
|
393
284
|
### One to Many
|
|
394
285
|
|
|
@@ -452,6 +343,24 @@ export class Course {
|
|
|
452
343
|
}
|
|
453
344
|
```
|
|
454
345
|
|
|
346
|
+
### DataSourceOf<T>
|
|
347
|
+
|
|
348
|
+
If it is important to determine what data source the frontend called the instantiated method with, the type `DataSourceOf<T>` allows explicit data source parameters:
|
|
349
|
+
|
|
350
|
+
```ts
|
|
351
|
+
@D1
|
|
352
|
+
class Foo {
|
|
353
|
+
...
|
|
354
|
+
|
|
355
|
+
@POST
|
|
356
|
+
bar(ds: DataSourceOf<Foo>) {
|
|
357
|
+
// ds = "DataSource1" | "DataSource2" | ... | "none"
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Data sources are implicitly added to all instantiated methods if no data source parameter is defined.
|
|
363
|
+
|
|
455
364
|
### ORM Methods
|
|
456
365
|
|
|
457
366
|
Cloesce provides a suite of ORM methods for getting, listing, updating and inserting models.
|
|
@@ -474,6 +383,44 @@ class Horse {
|
|
|
474
383
|
|
|
475
384
|
#### List, Get
|
|
476
385
|
|
|
386
|
+
Both methods take an optional `IncludeTree<T>` parameter to specify what relationships in the generated CTE.
|
|
387
|
+
|
|
388
|
+
```ts
|
|
389
|
+
@D1
|
|
390
|
+
export class Person {
|
|
391
|
+
@PrimaryKey
|
|
392
|
+
id: number;
|
|
393
|
+
|
|
394
|
+
@ForeignKey(Dog)
|
|
395
|
+
dogId: number;
|
|
396
|
+
|
|
397
|
+
@OneToOne("dogId")
|
|
398
|
+
dog: Dog | undefined;
|
|
399
|
+
|
|
400
|
+
@DataSource
|
|
401
|
+
static readonly default: IncludeTree<Person> = {
|
|
402
|
+
dog: {},
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
Running `Orm.listQuery` with the data source `Person.default` would produce the CTE:
|
|
408
|
+
|
|
409
|
+
```sql
|
|
410
|
+
WITH "Person_view" AS (
|
|
411
|
+
SELECT
|
|
412
|
+
"Person"."id" AS "id",
|
|
413
|
+
"Person"."dogId" AS "dogId",
|
|
414
|
+
"Dog"."id" AS "dog.id"
|
|
415
|
+
FROM
|
|
416
|
+
"Person"
|
|
417
|
+
LEFT JOIN
|
|
418
|
+
"Dog" ON "Person"."dogId" = "Dog"."id"
|
|
419
|
+
) SELECT * FROM "Person_view"
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
Example usages:
|
|
423
|
+
|
|
477
424
|
```ts
|
|
478
425
|
@D1
|
|
479
426
|
class Horse {
|
|
@@ -481,17 +428,39 @@ class Horse {
|
|
|
481
428
|
@GET
|
|
482
429
|
static async get(@Inject { db }: Env, id: number): Promise<Horse> {
|
|
483
430
|
const orm = Orm.fromD1(db);
|
|
484
|
-
return (await orm.get(Horse, id,
|
|
431
|
+
return (await orm.get(Horse, id, Horse.default)).value;
|
|
485
432
|
}
|
|
486
433
|
|
|
487
434
|
@GET
|
|
488
435
|
static async list(@Inject { db }: Env): Promise<Horse[]> {
|
|
489
436
|
const orm = Orm.fromD1(db);
|
|
490
|
-
return (await orm.list(Horse,
|
|
437
|
+
return (await orm.list(Horse, {})).value;
|
|
491
438
|
}
|
|
492
439
|
}
|
|
493
440
|
```
|
|
494
441
|
|
|
442
|
+
`list` takes an optional `from` parameter to modify the source of the list query. This is useful in filtering / limiting results.
|
|
443
|
+
|
|
444
|
+
```ts
|
|
445
|
+
await orm.list(
|
|
446
|
+
Horse,
|
|
447
|
+
Horse.default,
|
|
448
|
+
"SELECT * FROM Horse ORDER BY name LIMIT 10"
|
|
449
|
+
);
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
produces SQL
|
|
453
|
+
|
|
454
|
+
```sql
|
|
455
|
+
WITH "Horse_view" AS (
|
|
456
|
+
SELECT
|
|
457
|
+
"Horse"."id" AS "id",
|
|
458
|
+
"Horse"."name" AS "name"
|
|
459
|
+
FROM
|
|
460
|
+
(SELECT * FROM Horse ORDER BY name LIMIT 10) as "Horse"
|
|
461
|
+
) SELECT * FROM "Horse_view"
|
|
462
|
+
```
|
|
463
|
+
|
|
495
464
|
### CRUD Methods
|
|
496
465
|
|
|
497
466
|
Generic `GET, POST, PATCH` (and in a future version, DEL) boilerplate methods do not need to be copied around. Cloesce supports CRUD generation, a syntactic sugar that adds the methods to the compiler output.
|
|
@@ -628,10 +597,11 @@ class Foo {
|
|
|
628
597
|
## Integration Tests
|
|
629
598
|
|
|
630
599
|
- Regression tests: `cargo run --bin test regression`
|
|
631
|
-
- Pass fail extractor tests: `cargo run --bin test run-fail`
|
|
632
600
|
|
|
633
601
|
Optionally, pass `--check` if new snapshots should not be created.
|
|
634
602
|
|
|
603
|
+
To target a specific fixture, pass `--fixture folder_name`
|
|
604
|
+
|
|
635
605
|
To update integration snapshots, run:
|
|
636
606
|
|
|
637
607
|
- `cargo run --bin update`
|
package/dist/cli.js
CHANGED
|
@@ -29,12 +29,11 @@ const cmds = subcommands({
|
|
|
29
29
|
// Creates a `cidl.json` file. Exits the process on failure.
|
|
30
30
|
await extract({ debug: args.debug });
|
|
31
31
|
const outputDir = config.outputDir ?? ".generated";
|
|
32
|
-
const
|
|
33
|
-
name: "
|
|
32
|
+
const generateConfig = {
|
|
33
|
+
name: "generate",
|
|
34
34
|
wasmFile: "generator.wasm",
|
|
35
35
|
args: [
|
|
36
36
|
"generate",
|
|
37
|
-
"all",
|
|
38
37
|
path.join(outputDir, "cidl.pre.json"),
|
|
39
38
|
path.join(outputDir, "cidl.json"),
|
|
40
39
|
"wrangler.toml",
|
|
@@ -45,7 +44,7 @@ const cmds = subcommands({
|
|
|
45
44
|
],
|
|
46
45
|
};
|
|
47
46
|
// Runs a generator command. Exits the process on failure.
|
|
48
|
-
await generate(
|
|
47
|
+
await generate(generateConfig);
|
|
49
48
|
},
|
|
50
49
|
}),
|
|
51
50
|
extract: command({
|
|
@@ -83,6 +82,10 @@ const cmds = subcommands({
|
|
|
83
82
|
short: "d",
|
|
84
83
|
description: "Show debug output",
|
|
85
84
|
}),
|
|
85
|
+
skipTsCheck: flag({
|
|
86
|
+
long: "skipTsCheck",
|
|
87
|
+
description: "Skip TypeScript compilation checks",
|
|
88
|
+
}),
|
|
86
89
|
},
|
|
87
90
|
handler: async (args) => {
|
|
88
91
|
await extract({ ...args });
|
|
@@ -138,15 +141,15 @@ const cmds = subcommands({
|
|
|
138
141
|
}),
|
|
139
142
|
},
|
|
140
143
|
});
|
|
141
|
-
async function extract(
|
|
144
|
+
async function extract(args) {
|
|
142
145
|
const root = process.cwd();
|
|
143
146
|
const projectRoot = process.cwd();
|
|
144
|
-
const config = loadCloesceConfig(projectRoot,
|
|
145
|
-
const searchPaths =
|
|
147
|
+
const config = loadCloesceConfig(projectRoot, args.debug);
|
|
148
|
+
const searchPaths = args.inp ? [args.inp] : (config.paths ?? [root]);
|
|
146
149
|
const outputDir = config.outputDir ?? ".generated";
|
|
147
|
-
const outPath =
|
|
148
|
-
const truncate =
|
|
149
|
-
const cloesceProjectName =
|
|
150
|
+
const outPath = args.out ?? path.join(outputDir, "cidl.pre.json");
|
|
151
|
+
const truncate = args.truncateSourcePaths ?? config.truncateSourcePaths ?? false;
|
|
152
|
+
const cloesceProjectName = args.projectName ??
|
|
150
153
|
config.projectName ??
|
|
151
154
|
readPackageJsonProjectName(projectRoot);
|
|
152
155
|
const project = new Project({
|
|
@@ -159,16 +162,25 @@ async function extract(opts) {
|
|
|
159
162
|
if (fileCount === 0) {
|
|
160
163
|
new ExtractorError(ExtractorErrorCode.MissingFile);
|
|
161
164
|
}
|
|
162
|
-
if (
|
|
165
|
+
if (args.debug)
|
|
163
166
|
console.log(`Found ${fileCount} .cloesce.ts files`);
|
|
167
|
+
// Run typescript compiler checks to before extraction
|
|
168
|
+
if (!args.skipTsCheck) {
|
|
169
|
+
const diagnostics = project.getPreEmitDiagnostics();
|
|
170
|
+
if (diagnostics.length > 0) {
|
|
171
|
+
console.error("TypeScript errors detected in provided files:");
|
|
172
|
+
console.error(project.formatDiagnosticsWithColorAndContext(diagnostics));
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
164
176
|
try {
|
|
165
|
-
const extractor = new CidlExtractor(cloesceProjectName, "v0.0.
|
|
177
|
+
const extractor = new CidlExtractor(cloesceProjectName, "v0.0.4");
|
|
166
178
|
const result = extractor.extract(project);
|
|
167
|
-
if (
|
|
179
|
+
if (result.isLeft()) {
|
|
168
180
|
console.error(formatErr(result.value));
|
|
169
181
|
process.exit(1);
|
|
170
182
|
}
|
|
171
|
-
let ast = result.
|
|
183
|
+
let ast = result.unwrap();
|
|
172
184
|
if (truncate) {
|
|
173
185
|
ast.wrangler_env.source_path =
|
|
174
186
|
"./" + path.basename(ast.wrangler_env.source_path);
|
package/dist/common.d.ts
CHANGED
|
@@ -78,55 +78,19 @@ type DeepPartialInner<T> = T extends (infer U)[] ? DeepPartialInner<U>[] : T ext
|
|
|
78
78
|
export type DeepPartial<T> = DeepPartialInner<T> & {
|
|
79
79
|
__brand?: "Partial";
|
|
80
80
|
};
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
* ```ts
|
|
95
|
-
* const result: Either<string, number> = compute();
|
|
96
|
-
*
|
|
97
|
-
* if (!result.ok) {
|
|
98
|
-
* console.error("Failed:", result.value);
|
|
99
|
-
* } else {
|
|
100
|
-
* console.log("Success:", result.value);
|
|
101
|
-
* }
|
|
102
|
-
* ```
|
|
103
|
-
*/
|
|
104
|
-
export type Either<L, R> = {
|
|
105
|
-
ok: false;
|
|
106
|
-
value: L;
|
|
107
|
-
} | {
|
|
108
|
-
ok: true;
|
|
109
|
-
value: R;
|
|
110
|
-
};
|
|
111
|
-
/**
|
|
112
|
-
* Creates a failed `Either` result.
|
|
113
|
-
*
|
|
114
|
-
* Typically used to represent an error condition or unsuccessful operation.
|
|
115
|
-
*
|
|
116
|
-
* @param value The error or failure value to wrap.
|
|
117
|
-
* @returns An `Either` with `ok: false` and the given value.
|
|
118
|
-
*/
|
|
119
|
-
export declare function left<L>(value: L): Either<L, never>;
|
|
120
|
-
/**
|
|
121
|
-
* Creates a successful `Either` result.
|
|
122
|
-
*
|
|
123
|
-
* Typically used to represent a successful operation while maintaining
|
|
124
|
-
* a consistent `Either`-based return type.
|
|
125
|
-
*
|
|
126
|
-
* @param value The success value to wrap.
|
|
127
|
-
* @returns An `Either` with `ok: true` and the given value.
|
|
128
|
-
*/
|
|
129
|
-
export declare function right<R>(value: R): Either<never, R>;
|
|
81
|
+
export declare class Either<L, R> {
|
|
82
|
+
private readonly inner;
|
|
83
|
+
private constructor();
|
|
84
|
+
get value(): L | R;
|
|
85
|
+
static left<L, R = never>(value: L): Either<L, R>;
|
|
86
|
+
static right<R, L = never>(value: R): Either<L, R>;
|
|
87
|
+
isLeft(): this is Either<L, never>;
|
|
88
|
+
isRight(): this is Either<never, R>;
|
|
89
|
+
unwrap(): R;
|
|
90
|
+
unwrapLeft(): L;
|
|
91
|
+
map<B>(fn: (val: R) => B): Either<L, B>;
|
|
92
|
+
mapLeft<B>(fn: (val: L) => B): Either<B, R>;
|
|
93
|
+
}
|
|
130
94
|
/**
|
|
131
95
|
* Represents the result of an HTTP operation in a monadic style.
|
|
132
96
|
*
|
|
@@ -356,7 +320,7 @@ export interface WranglerEnv {
|
|
|
356
320
|
export interface CloesceAst {
|
|
357
321
|
version: string;
|
|
358
322
|
project_name: string;
|
|
359
|
-
language:
|
|
323
|
+
language: string;
|
|
360
324
|
wrangler_env: WranglerEnv;
|
|
361
325
|
models: Record<string, Model>;
|
|
362
326
|
poos: Record<string, PlainOldObject>;
|
package/dist/common.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,oBAAY,kBAAkB;IAC5B,aAAa,IAAA;IACb,uBAAuB,IAAA;IACvB,WAAW,IAAA;IACX,mBAAmB,IAAA;IACnB,2BAA2B,IAAA;IAC3B,kBAAkB,IAAA;IAClB,kBAAkB,IAAA;IAClB,wBAAwB,IAAA;IACxB,wBAAwB,IAAA;IACxB,kCAAkC,IAAA;IAClC,kCAAkC,KAAA;IAClC,kCAAkC,KAAA;IAClC,yBAAyB,KAAA;IACzB,iBAAiB,KAAA;IACjB,sBAAsB,KAAA;IACtB,kBAAkB,KAAA;IAClB,mBAAmB,KAAA;IACnB,WAAW,KAAA;CACZ;AAyFD,wBAAgB,YAAY,CAAC,IAAI,EAAE,kBAAkB;iBArFpC,MAAM;gBAAc,MAAM;EAuF1C;AAED,qBAAa,cAAc;IAIN,IAAI,EAAE,kBAAkB;IAH3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;gBAEE,IAAI,EAAE,kBAAkB;IAE3C,UAAU,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,GAAG,SAAS;CAG/D;AAED,KAAK,gBAAgB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAC5C,gBAAgB,CAAC,CAAC,CAAC,EAAE,GACrB,CAAC,SAAS,MAAM,GACd;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAC3C,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC;AAE3E
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"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"}
|