@quadrokit/client 0.3.15 → 0.3.18
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 +68 -3
- package/dist/cli.mjs +1 -1
- package/dist/generate/codegen.d.ts +5 -3
- package/dist/generate/codegen.d.ts.map +1 -1
- package/dist/generate/codegen.mjs +27 -34
- package/dist/runtime/catalog-builder.d.ts +7 -4
- package/dist/runtime/catalog-builder.d.ts.map +1 -1
- package/dist/runtime/catalog-builder.mjs +2 -7
- package/dist/runtime/datastore.d.ts +1 -1
- package/dist/runtime/datastore.d.ts.map +1 -1
- package/dist/runtime/datastore.mjs +1 -1
- package/dist/runtime/events.d.ts +1 -1
- package/dist/runtime/events.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ Use a URL that returns the **full** catalog (dataclasses **with attributes**). P
|
|
|
45
45
|
| **`--login-url`** | Full login URL (default: `{catalog origin}/api/login`). |
|
|
46
46
|
| **`-v` / `--verbose`** | Step-by-step logs on stderr. |
|
|
47
47
|
| **`--insecure-tls`** | Skip TLS verification (dev / self-signed HTTPS only). |
|
|
48
|
-
| **`--no-split-type-files`** | Emit a single **`types.gen.ts
|
|
48
|
+
| **`--no-split-type-files`** | Emit a single **`types.gen.ts`**. **Default:** split typings — **`entities/<Class>.gen.ts`**, optional **`datastore.gen.ts`**, and **`types.gen.ts`** as the barrel. |
|
|
49
49
|
|
|
50
50
|
Environment variables (often via `.env` in the project root): `VITE_4D_ORIGIN`, `QUADROKIT_ACCESS_KEY`, `QUADROKIT_LOGIN_URL`, `QUADROKIT_CATALOG_TOKEN`, `QUADROKIT_GENERATE_VERBOSE`, `QUADROKIT_INSECURE_TLS`.
|
|
51
51
|
|
|
@@ -55,9 +55,11 @@ Environment variables (often via `.env` in the project root): `VITE_4D_ORIGIN`,
|
|
|
55
55
|
|------|---------|
|
|
56
56
|
| **`types.gen.ts`** | Barrel: **`QuadroClient`** typing; re-exports entity types and **`*Path`** aliases. |
|
|
57
57
|
| **`entities/<ClassName>.gen.ts`** | One file per exposed dataclass (default layout): **`export interface`** + **`export type`** **`<ClassName>Path`** (`QuadroAttributePaths<…>`). Omit with **`--no-split-type-files`** (single `types.gen.ts`). |
|
|
58
|
-
| **`datastore.gen.ts`** | When the catalog lists datastore REST methods
|
|
58
|
+
| **`datastore.gen.ts`** | When the catalog lists datastore REST methods: per-method **`Datastore_*`** aliases and **`QuadroDatastoreMethodFn`**. Omitted when there are no such exposed methods. Runtime **`catalog.gen.json`** stores **`path`** as **`["$catalog", "<methodName>"]`** → **`/rest/$catalog/<methodName>`** when **`baseURL`** is **`/rest`**. |
|
|
59
59
|
| **`catalog.gen.json`** | Catalog runtime spec (dataclass layouts, methods, relations) consumed by `@quadrokit/client/runtime` — keeps **`client.gen.ts`** tiny. |
|
|
60
60
|
| **`client.gen.ts`** | Thin `createClient(config)` that wires `QuadroHttp` + `buildQuadroClientFromCatalogSpec` + `catalog.gen.json`. Config supports optional **`events`** (see [Request lifecycle events](#request-lifecycle-events)). |
|
|
61
|
+
| **`_quadroFns.gen.ts`** | Shared helpers: **`ResolveOverride`**, **`QuadroDataClassFn`**, **`QuadroEntityFn`**, **`QuadroEntityCollectionFn`**, **`QuadroDatastoreFn`** (used by **`*.gen.ts`** and optional override files). |
|
|
62
|
+
| **`entities/<Class>.overrides.ts`**, **`datastore.overrides.ts`** | Optional stubs you edit to **narrow method signatures** (see [Narrowing function signatures](#narrowing-function-signatures-override-files)). Created if missing; preserved across regenerate when possible. |
|
|
61
63
|
| **`meta.json`** | `__NAME`, `sessionCookieName` hint for 4D session cookies. |
|
|
62
64
|
|
|
63
65
|
Point your app imports at the generated folder, for example:
|
|
@@ -139,7 +141,7 @@ You can also subscribe on the HTTP instance: **`quadro._http.subscribe(listener)
|
|
|
139
141
|
|
|
140
142
|
### Operations (`QuadroOperation`)
|
|
141
143
|
|
|
142
|
-
Examples include: **`http.json`**, **`http.void`**, **`http.request`**, **`collection.list`**, **`collection.release`**, **`dataclass.get`**, **`dataclass.delete`**, **`function.dataclass`**, **`function.entity`**, **`function.entityCollection`**, **`datastore
|
|
144
|
+
Examples include: **`http.json`**, **`http.void`**, **`http.request`**, **`collection.list`**, **`collection.release`**, **`dataclass.get`**, **`dataclass.delete`**, **`function.dataclass`**, **`function.entity`**, **`function.entityCollection`**, **`datastore`** (catalog datastore methods emit **`context.methodName`** set to the catalog method name).
|
|
143
145
|
|
|
144
146
|
### `QuadroHttp` helpers (advanced)
|
|
145
147
|
|
|
@@ -257,6 +259,69 @@ If the catalog does not list a method, it will not appear on the client — rege
|
|
|
257
259
|
|
|
258
260
|
---
|
|
259
261
|
|
|
262
|
+
## Narrowing function signatures (override files)
|
|
263
|
+
|
|
264
|
+
Generated ORDA **dataClass**, **entity**, and **entityCollection** methods, plus **datastore** methods, default to **loose** generics (`unknown` / `readonly unknown[]` for results and argument tuples). To type **return values** and **parameters** in TypeScript, add entries to the optional **override** modules beside the codegen output. The generator wires each method type as **`ResolveOverride<YourOverrides, "methodName", DefaultFn>`** in **`*.gen.ts`**: if your interface defines that **exact property name** (same spelling as the catalog / JS API), your signature wins; otherwise the default **`Quadro*Fn`** stands.
|
|
265
|
+
|
|
266
|
+
### Where the files live
|
|
267
|
+
|
|
268
|
+
**Split typings (default):** for each exposed dataclass, **`entities/<ClassName>.overrides.ts`** declares up to three interfaces:
|
|
269
|
+
|
|
270
|
+
| Interface | Catalog `applyTo` | Example call site |
|
|
271
|
+
|-----------|-------------------|-------------------|
|
|
272
|
+
| **`<ClassName>DataclassOverrides`** | dataClass | `quadro.Car.findACar(...)` |
|
|
273
|
+
| **`<ClassName>EntityOverrides`** | entity | `(await quadro.Car.get(id)).isAvailable(...)` |
|
|
274
|
+
| **`<ClassName>EntityCollectionOverrides`** | entityCollection | On **`all()`** / **`query()`** handles and related **`list`** APIs |
|
|
275
|
+
|
|
276
|
+
**`datastore.overrides.ts`** (next to **`types.gen.ts`**) maps **top-level** datastore methods on **`quadro`** by **catalog method name**.
|
|
277
|
+
|
|
278
|
+
**Single `types.gen.ts` (**`--no-split-type-files`**):** same idea, with **`./<ClassName>.overrides.ts`** and **`./datastore.overrides.ts`** next to **`types.gen.ts`**.
|
|
279
|
+
|
|
280
|
+
Stub files may **re-export** **`QuadroDataClassFn`**, **`QuadroEntityFn`**, **`QuadroEntityCollectionFn`**, **`QuadroDatastoreFn`** from **`_quadroFns.gen.ts`**; you can **`import type`** those helpers from **`_quadroFns.gen.js`** (or `.ts`) when you add properties.
|
|
281
|
+
|
|
282
|
+
### Fn type parameters (from `_quadroFns.gen.ts`)
|
|
283
|
+
|
|
284
|
+
- **`QuadroDataClassFn<R, A>`** — **`R`**: resolved **`Promise`** result type; **`A`**: **tuple** of positional arguments (sent as the JSON array body to 4D).
|
|
285
|
+
- **`QuadroEntityFn<R, A>`** — same shape for **per-entity** calls.
|
|
286
|
+
- **`QuadroEntityCollectionFn<R, A>`** — same **`R`** / **`A`**; real calls also accept **`init`** with **`EntityCollectionMethodOptions`** (`selection`, `entitySet`, …).
|
|
287
|
+
- **`QuadroDatastoreFn<B, R>`** — **`B`**: body type; **`R`**: result type for **`quadro.<datastoreMethod>(body?)`**.
|
|
288
|
+
|
|
289
|
+
### Examples
|
|
290
|
+
|
|
291
|
+
**Per-class overrides** (`entities/Car.overrides.ts` in the split layout):
|
|
292
|
+
|
|
293
|
+
```ts
|
|
294
|
+
import type { QuadroDataClassFn, QuadroEntityFn } from '../_quadroFns.gen.js'
|
|
295
|
+
import type { Car } from './Car.gen.js'
|
|
296
|
+
|
|
297
|
+
export interface CarDataclassOverrides {
|
|
298
|
+
/** Catalog method name must match exactly (e.g. findACar). */
|
|
299
|
+
findACar: QuadroDataClassFn<Car[], [string, string]>
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export interface CarEntityOverrides {
|
|
303
|
+
isAvailable: QuadroEntityFn<boolean, readonly []>
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export interface CarEntityCollectionOverrides {}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**Datastore overrides** (`datastore.overrides.ts`):
|
|
310
|
+
|
|
311
|
+
```ts
|
|
312
|
+
import type { QuadroDatastoreFn } from './_quadroFns.gen.js'
|
|
313
|
+
|
|
314
|
+
export interface DatastoreOverrides {
|
|
315
|
+
testFn: QuadroDatastoreFn<{ foo: string }, { ok: true }>
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Regenerate behavior
|
|
320
|
+
|
|
321
|
+
Run **`quadrokit-client generate`** after catalog changes. The tool **rewrites** **`*.gen.ts`** (and related generated files) but **keeps** your existing **`*.overrides.ts`** content when refreshing **`entities/`** (and only creates stub override files if missing). Do not rely on editing **`*.gen.ts`** — put signature narrowing in override modules only.
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
260
325
|
## Low-level runtime (advanced)
|
|
261
326
|
|
|
262
327
|
Import from **`@quadrokit/client/runtime`** when you need primitives without codegen:
|
package/dist/cli.mjs
CHANGED
|
@@ -142,7 +142,7 @@ Debug / TLS:
|
|
|
142
142
|
--insecure-tls Skip TLS certificate verification (dev/self-signed HTTPS only)
|
|
143
143
|
|
|
144
144
|
Output layout (default: split entity + datastore typings):
|
|
145
|
-
--no-split-type-files Emit a single types.gen.ts
|
|
145
|
+
--no-split-type-files Emit a single types.gen.ts; default is split files:
|
|
146
146
|
entities/<Class>.gen.ts, optional datastore.gen.ts, types.gen.ts barrel.
|
|
147
147
|
|
|
148
148
|
Env / .env: VITE_4D_ORIGIN, QUADROKIT_ACCESS_KEY, QUADROKIT_LOGIN_URL, QUADROKIT_CATALOG_TOKEN,
|
|
@@ -15,8 +15,10 @@ export declare function buildCatalogRuntimeSpec(catalog: CatalogJson): {
|
|
|
15
15
|
}[];
|
|
16
16
|
}[];
|
|
17
17
|
keyNamesByClass: Record<string, string[]>;
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
datastoreMethods: {
|
|
19
|
+
name: string;
|
|
20
|
+
path: string[];
|
|
21
|
+
}[];
|
|
20
22
|
};
|
|
21
23
|
/** Warn when the catalog lists dataclasses but omits attributes (e.g. plain `GET /rest/$catalog` instead of `/rest/$catalog/$all`). */
|
|
22
24
|
export declare function warnIfCatalogLacksAttributes(catalog: CatalogJson): void;
|
|
@@ -24,7 +26,7 @@ export interface WriteGeneratedOptions {
|
|
|
24
26
|
/**
|
|
25
27
|
* When `true` (default), emit each exposed dataclass as `entities/<Name>.gen.ts`, optional
|
|
26
28
|
* `datastore.gen.ts` (per-method `Datastore_*` aliases + `QuadroDatastoreMethodFn`), and a barrel `types.gen.ts`.
|
|
27
|
-
* When `false`, emit a single `types.gen.ts` (
|
|
29
|
+
* When `false`, emit a single `types.gen.ts` (all types in one file).
|
|
28
30
|
* `entities/<Name>.overrides.ts` and `datastore.overrides.ts` are created only if missing; existing
|
|
29
31
|
* entity override files are preserved when the `entities/` folder is regenerated.
|
|
30
32
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/generate/codegen.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,WAAW,EAEZ,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/generate/codegen.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,WAAW,EAEZ,MAAM,mBAAmB,CAAA;AAqc1B,yFAAyF;AACzF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,WAAW,GAAG;IAC7D,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACnC,QAAQ,EAAE,MAAM,EAAE,CAAA;QAClB,iBAAiB,EAAE,MAAM,EAAE,CAAA;QAC3B,2BAA2B,EAAE,MAAM,EAAE,CAAA;QACrC,oBAAoB,EAAE,MAAM,EAAE,CAAA;QAC9B,SAAS,EAAE;YACT,IAAI,EAAE,MAAM,CAAA;YACZ,WAAW,EAAE,MAAM,CAAA;YACnB,2BAA2B,EAAE,MAAM,EAAE,CAAA;SACtC,EAAE,CAAA;KACJ,EAAE,CAAA;IACH,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACzC,gBAAgB,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAA;CACrD,CA2BA;AAgOD,uIAAuI;AACvI,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAYvE;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAqCD,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW,EACpB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,IAAI,CAAC,CA6Ff"}
|
|
@@ -155,7 +155,7 @@ function emitOverridesStubFile(className, quadroFnRelativeToStub) {
|
|
|
155
155
|
return `/* eslint-disable */
|
|
156
156
|
/**
|
|
157
157
|
* Optional: narrow REST method typings for ${className}.
|
|
158
|
-
* Add entries under the interfaces (e.g. findACar: QuadroDataClassFn<[
|
|
158
|
+
* Add entries under the interfaces (e.g. findACar: QuadroDataClassFn<Car[], [string, string]> — R then A).
|
|
159
159
|
* Import fn types from \`'${quadroFnRelativeToStub}'\` when you add entries (or reference re-exports below).
|
|
160
160
|
*/
|
|
161
161
|
export type {
|
|
@@ -174,9 +174,9 @@ export interface ${className}EntityCollectionOverrides {}
|
|
|
174
174
|
function emitDatastoreOverridesStub(quadroFnsRelativeToStub) {
|
|
175
175
|
return `/* eslint-disable */
|
|
176
176
|
/**
|
|
177
|
-
* Optional: narrow
|
|
178
|
-
* Add one property per catalog method
|
|
179
|
-
*
|
|
177
|
+
* Optional: narrow datastore REST methods on \`QuadroClient\` (catalog \`applyTo: dataStore\` methods).
|
|
178
|
+
* Add one property per method name (must match catalog datastore method names). Use explicit
|
|
179
|
+
* \`(body?, init?) => Promise<R>\` shapes; \`QuadroDatastoreFn\` is not parameterized as \`QuadroDatastoreFn<B,R>\`.
|
|
180
180
|
*/
|
|
181
181
|
export type { QuadroDatastoreFn } from '${quadroFnsRelativeToStub}';
|
|
182
182
|
|
|
@@ -316,7 +316,7 @@ function emitEntityTypeFile(dc) {
|
|
|
316
316
|
return `${header}${body}\n`;
|
|
317
317
|
}
|
|
318
318
|
function buildDatastoreMethodAliasLines(catalog) {
|
|
319
|
-
const dsNames =
|
|
319
|
+
const dsNames = datastoreMethodNamesFromCatalog(catalog);
|
|
320
320
|
if (dsNames.length === 0) {
|
|
321
321
|
return '';
|
|
322
322
|
}
|
|
@@ -329,7 +329,7 @@ function buildDatastoreMethodAliasLines(catalog) {
|
|
|
329
329
|
.join('\n');
|
|
330
330
|
}
|
|
331
331
|
function emitDatastoreTypesFile(catalog) {
|
|
332
|
-
const dsNames =
|
|
332
|
+
const dsNames = datastoreMethodNamesFromCatalog(catalog);
|
|
333
333
|
const header = `/* eslint-disable */\n/* Auto-generated by @quadrokit/client — do not edit */\n\n`;
|
|
334
334
|
const imports = `import type {
|
|
335
335
|
ResolveOverride,
|
|
@@ -374,24 +374,16 @@ function sanitizeMethodId(name) {
|
|
|
374
374
|
function catalogMethodApplyToIsDatastore(applyTo) {
|
|
375
375
|
return applyTo?.trim().toLowerCase() === 'datastore';
|
|
376
376
|
}
|
|
377
|
-
/**
|
|
378
|
-
|
|
379
|
-
* Not emitted in types/runtime when absent or `exposed: false`.
|
|
380
|
-
*/
|
|
381
|
-
function catalogHasAuthentify(catalog) {
|
|
382
|
-
return Boolean(catalog.methods?.some((m) => m.name?.toLowerCase() === 'authentify' &&
|
|
383
|
-
catalogMethodApplyToIsDatastore(m.applyTo) &&
|
|
384
|
-
m.exposed !== false));
|
|
385
|
-
}
|
|
386
|
-
/** Top-level ORDA `methods` with datastore `applyTo`, excluding `authentify` (typed as `authentify.login` when present). */
|
|
387
|
-
function datastoreMethodsExcludingAuthentify(catalog) {
|
|
377
|
+
/** Top-level ORDA `methods` with datastore `applyTo`, in catalog order. */
|
|
378
|
+
function datastoreMethodNamesFromCatalog(catalog) {
|
|
388
379
|
return (catalog.methods ?? [])
|
|
389
|
-
.filter((m) => Boolean(m.name) &&
|
|
390
|
-
catalogMethodApplyToIsDatastore(m.applyTo) &&
|
|
391
|
-
m.exposed !== false &&
|
|
392
|
-
m.name.toLowerCase() !== 'authentify')
|
|
380
|
+
.filter((m) => Boolean(m.name) && catalogMethodApplyToIsDatastore(m.applyTo) && m.exposed !== false)
|
|
393
381
|
.map((m) => m.name);
|
|
394
382
|
}
|
|
383
|
+
/** URL segments after `baseURL` (e.g. `/rest`) — 4D datastore methods are `POST /rest/$catalog/<methodName>`. */
|
|
384
|
+
function datastoreHttpPathSegments(methodName) {
|
|
385
|
+
return ['$catalog', methodName];
|
|
386
|
+
}
|
|
395
387
|
function isValidJsIdentifier(name) {
|
|
396
388
|
return /^[A-Za-z_$][\w$]*$/.test(name);
|
|
397
389
|
}
|
|
@@ -402,9 +394,12 @@ function objectPropertyKey(name) {
|
|
|
402
394
|
export function buildCatalogRuntimeSpec(catalog) {
|
|
403
395
|
const classes = exposedDataClasses(catalog);
|
|
404
396
|
const byName = new Map(classes.map((c) => [c.name, c]));
|
|
397
|
+
const dsNames = datastoreMethodNamesFromCatalog(catalog);
|
|
405
398
|
return {
|
|
406
|
-
|
|
407
|
-
|
|
399
|
+
datastoreMethods: dsNames.map((name) => ({
|
|
400
|
+
name,
|
|
401
|
+
path: datastoreHttpPathSegments(name),
|
|
402
|
+
})),
|
|
408
403
|
keyNamesByClass: Object.fromEntries(classes.map((x) => [x.name, [...keyNames(x)]])),
|
|
409
404
|
classes: classes.map((c) => ({
|
|
410
405
|
name: c.name,
|
|
@@ -425,11 +420,7 @@ function emitQuadroClientTypeBlock(catalog, withEntities, datastoreFnStyle = 'in
|
|
|
425
420
|
/** When true, method types are referenced as `GenCar.Car_dataclass_*` from per-entity files. */
|
|
426
421
|
splitLayout = false) {
|
|
427
422
|
const classes = exposedDataClasses(catalog);
|
|
428
|
-
const
|
|
429
|
-
const dsNames = datastoreMethodsExcludingAuthentify(catalog);
|
|
430
|
-
const authLine = hasAuthentify
|
|
431
|
-
? ` authentify: { login: (body: { email: string; password: string }) => Promise<unknown> };\n`
|
|
432
|
-
: '';
|
|
423
|
+
const dsNames = datastoreMethodNamesFromCatalog(catalog);
|
|
433
424
|
const dsProps = dsNames.length > 0
|
|
434
425
|
? `${dsNames
|
|
435
426
|
.map((n) => {
|
|
@@ -445,7 +436,7 @@ splitLayout = false) {
|
|
|
445
436
|
};`;
|
|
446
437
|
if (!withEntities || classes.length === 0) {
|
|
447
438
|
return `export type QuadroClient = {
|
|
448
|
-
${
|
|
439
|
+
${dsProps}${tail}
|
|
449
440
|
`;
|
|
450
441
|
}
|
|
451
442
|
const branches = classes
|
|
@@ -468,13 +459,13 @@ ${props}
|
|
|
468
459
|
})
|
|
469
460
|
.join('\n');
|
|
470
461
|
return `export type QuadroClient = {
|
|
471
|
-
${
|
|
462
|
+
${dsProps}${branches}
|
|
472
463
|
${tail}
|
|
473
464
|
`;
|
|
474
465
|
}
|
|
475
466
|
function emitTypesMonolithic(catalog) {
|
|
476
467
|
const classes = exposedDataClasses(catalog);
|
|
477
|
-
const dsNames =
|
|
468
|
+
const dsNames = datastoreMethodNamesFromCatalog(catalog);
|
|
478
469
|
const quadroFnNames = quadroFnTypeNamesForCatalog(classes, dsNames);
|
|
479
470
|
const needsQuadroFns = quadroFnNames.length > 0;
|
|
480
471
|
const interfaces = classes.map((c) => emitInterface(c));
|
|
@@ -524,7 +515,7 @@ function emitTypesMonolithic(catalog) {
|
|
|
524
515
|
}
|
|
525
516
|
function emitTypesSplitMain(catalog) {
|
|
526
517
|
const classes = exposedDataClasses(catalog);
|
|
527
|
-
const dsNames =
|
|
518
|
+
const dsNames = datastoreMethodNamesFromCatalog(catalog);
|
|
528
519
|
const header = `/* eslint-disable */\n/* Auto-generated by @quadrokit/client — do not edit */\n`;
|
|
529
520
|
const pathNote = classes.length > 0
|
|
530
521
|
? `/**\n * *Path types use {@link QuadroAttributePaths} (recursive relation paths, depth-limited for circular graphs).\n * Override depth: \`type DeepEmployeePath = QuadroAttributePaths<Employee, 12>\`.\n * Entity interfaces and REST method aliases live under \`./entities/*.gen.ts\`; optional signature overrides in \`./entities/*.overrides.ts\`.\n * Datastore: \`./datastore.gen.ts\` and \`./datastore.overrides.ts\` when present.\n */\n`
|
|
@@ -656,7 +647,7 @@ export async function writeGenerated(outDir, catalog, options = {}) {
|
|
|
656
647
|
const datastorePath = path.join(outDir, 'datastore.gen.ts');
|
|
657
648
|
const quadroFnsPath = path.join(outDir, '_quadroFns.gen.ts');
|
|
658
649
|
const classes = exposedDataClasses(catalog);
|
|
659
|
-
const dsNames =
|
|
650
|
+
const dsNames = datastoreMethodNamesFromCatalog(catalog);
|
|
660
651
|
if (splitTypeFiles) {
|
|
661
652
|
const preservedEntityOverrides = await readExistingEntityOverrides(entitiesDir);
|
|
662
653
|
await rm(entitiesDir, { recursive: true, force: true });
|
|
@@ -684,11 +675,13 @@ export async function writeGenerated(outDir, catalog, options = {}) {
|
|
|
684
675
|
}
|
|
685
676
|
if (dsNames.length > 0) {
|
|
686
677
|
await writeFile(datastorePath, emitDatastoreTypesFile(catalog), 'utf8');
|
|
687
|
-
await writeStubIfMissing(path.join(outDir, 'datastore.overrides.ts'), emitDatastoreOverridesStub(`./_quadroFns.gen${EMITTED_TS_IMPORT_SUFFIX}`));
|
|
688
678
|
}
|
|
689
679
|
else {
|
|
690
680
|
await rm(datastorePath, { force: true }).catch(() => { });
|
|
691
681
|
}
|
|
682
|
+
if (dsNames.length > 0) {
|
|
683
|
+
await writeStubIfMissing(path.join(outDir, 'datastore.overrides.ts'), emitDatastoreOverridesStub(`./_quadroFns.gen${EMITTED_TS_IMPORT_SUFFIX}`));
|
|
684
|
+
}
|
|
692
685
|
await writeFile(path.join(outDir, 'types.gen.ts'), emitTypesSplitMain(catalog), 'utf8');
|
|
693
686
|
}
|
|
694
687
|
else {
|
|
@@ -10,13 +10,16 @@ export interface CatalogClassRuntimeSpec {
|
|
|
10
10
|
dataClassMethodNames: readonly string[];
|
|
11
11
|
navigable: readonly RelatedNavigationSpec[];
|
|
12
12
|
}
|
|
13
|
+
/** One datastore REST method: client key `name`, URL path segments (codegen: `['$catalog', name]`). */
|
|
14
|
+
export interface CatalogDatastoreMethodSpec {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
readonly path: readonly string[];
|
|
17
|
+
}
|
|
13
18
|
export interface CatalogRuntimeSpec {
|
|
14
19
|
classes: readonly CatalogClassRuntimeSpec[];
|
|
15
20
|
keyNamesByClass: Readonly<Record<string, readonly string[]>>;
|
|
16
|
-
/**
|
|
17
|
-
|
|
18
|
-
/** Top-level datastore REST methods from `catalog.methods` (`applyTo: dataStore`), excluding `authentify`. */
|
|
19
|
-
datastoreMethodNames: readonly string[];
|
|
21
|
+
/** Datastore REST methods from the catalog (`catalog.gen.json`). Empty when none are exposed. */
|
|
22
|
+
datastoreMethods: readonly CatalogDatastoreMethodSpec[];
|
|
20
23
|
}
|
|
21
24
|
/**
|
|
22
25
|
* Builds the object returned by generated `createClient()` from `catalog.gen.json`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-builder.d.ts","sourceRoot":"","sources":["../../src/runtime/catalog-builder.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,qBAAqB,EAC3B,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE3C,kEAAkE;AAClE,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,2BAA2B,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9C,oBAAoB,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,SAAS,EAAE,SAAS,qBAAqB,EAAE,CAAA;CAC5C;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,SAAS,uBAAuB,EAAE,CAAA;IAC3C,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAA;IAC5D,
|
|
1
|
+
{"version":3,"file":"catalog-builder.d.ts","sourceRoot":"","sources":["../../src/runtime/catalog-builder.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,qBAAqB,EAC3B,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE3C,kEAAkE;AAClE,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,2BAA2B,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9C,oBAAoB,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,SAAS,EAAE,SAAS,qBAAqB,EAAE,CAAA;CAC5C;AAED,uGAAuG;AACvG,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CACjC;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,SAAS,uBAAuB,EAAE,CAAA;IAC3C,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAA;IAC5D,iGAAiG;IACjG,gBAAgB,EAAE,SAAS,0BAA0B,EAAE,CAAA;CACxD;AAqHD;;;GAGG;AACH,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,kBAAkB,EACxB,IAAI,EAAE;IAAE,iBAAiB,EAAE,MAAM,CAAA;CAAE,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuBzB"}
|
|
@@ -84,13 +84,8 @@ function makeDataClassNamespace(http, c, keyNamesRecord) {
|
|
|
84
84
|
export function buildQuadroClientFromCatalogSpec(http, spec, meta) {
|
|
85
85
|
const keyNamesRecord = spec.keyNamesByClass;
|
|
86
86
|
const out = {};
|
|
87
|
-
|
|
88
|
-
out.
|
|
89
|
-
login: (body) => callDatastorePath(http, ['authentify', 'login'], { body }, { operation: 'auth.login' }),
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
for (const name of spec.datastoreMethodNames ?? []) {
|
|
93
|
-
out[name] = (body, init) => callDatastorePath(http, [name], { body, method: init?.method }, { operation: 'datastore', methodName: name });
|
|
87
|
+
for (const m of spec.datastoreMethods) {
|
|
88
|
+
out[m.name] = (body, init) => callDatastorePath(http, m.path, { body, method: init?.method }, { operation: 'datastore', methodName: m.name });
|
|
94
89
|
}
|
|
95
90
|
for (const c of spec.classes) {
|
|
96
91
|
out[c.name] = makeDataClassNamespace(http, c, keyNamesRecord);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { QuadroRequestContext } from './events.js';
|
|
2
2
|
import type { QuadroHttp } from './http.js';
|
|
3
|
-
/** Call
|
|
3
|
+
/** Call datastore REST paths built from `segments` (e.g. `['$catalog','myMethod']`; POST by default). */
|
|
4
4
|
export declare function callDatastorePath(http: QuadroHttp, segments: readonly string[], init?: {
|
|
5
5
|
method?: 'GET' | 'POST';
|
|
6
6
|
body?: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datastore.d.ts","sourceRoot":"","sources":["../../src/runtime/datastore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE3C,
|
|
1
|
+
{"version":3,"file":"datastore.d.ts","sourceRoot":"","sources":["../../src/runtime/datastore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE3C,yGAAyG;AACzG,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,EAClD,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,OAAO,CAAC,CAoBlB;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Call
|
|
1
|
+
/** Call datastore REST paths built from `segments` (e.g. `['$catalog','myMethod']`; POST by default). */
|
|
2
2
|
export async function callDatastorePath(http, segments, init, context) {
|
|
3
3
|
const path = `/${segments.join('/')}`;
|
|
4
4
|
const method = init?.method ?? 'POST';
|
package/dist/runtime/events.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Use {@link QuadroEventBus} with {@link QuadroHttp} options, or bridge to RxJS via `@quadrokit/client/rx`.
|
|
4
4
|
*/
|
|
5
5
|
/** What the client is doing (for filtering and UI). */
|
|
6
|
-
export type QuadroOperation = 'http.json' | 'http.void' | 'http.request' | 'collection.list' | 'collection.release' | 'dataclass.get' | 'dataclass.delete' | 'function.dataclass' | 'function.entity' | 'function.entityCollection' | 'datastore'
|
|
6
|
+
export type QuadroOperation = 'http.json' | 'http.void' | 'http.request' | 'collection.list' | 'collection.release' | 'dataclass.get' | 'dataclass.delete' | 'function.dataclass' | 'function.entity' | 'function.entityCollection' | 'datastore';
|
|
7
7
|
/** Optional metadata for an operation (class, method, entity key, arbitrary tags). */
|
|
8
8
|
export type QuadroRequestContext = {
|
|
9
9
|
operation: QuadroOperation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/runtime/events.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,uDAAuD;AACvD,MAAM,MAAM,eAAe,GACvB,WAAW,GACX,WAAW,GACX,cAAc,GACd,iBAAiB,GACjB,oBAAoB,GACpB,eAAe,GACf,kBAAkB,GAClB,oBAAoB,GACpB,iBAAiB,GACjB,2BAA2B,GAC3B,WAAW,
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/runtime/events.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,uDAAuD;AACvD,MAAM,MAAM,eAAe,GACvB,WAAW,GACX,WAAW,GACX,cAAc,GACd,iBAAiB,GACjB,oBAAoB,GACpB,eAAe,GACf,kBAAkB,GAClB,oBAAoB,GACpB,iBAAiB,GACjB,2BAA2B,GAC3B,WAAW,CAAA;AAEf,sFAAsF;AACtF,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,eAAe,CAAA;IAC1B,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC3B,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,SAAS,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,oBAAoB,CAAA;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,SAAS,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,oBAAoB,CAAA;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,oBAAoB,CAAA;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,OAAO,CAAA;IACd,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,GAAG,kBAAkB,GAAG,gBAAgB,CAAA;AAM1F;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4C;IAEtE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,GAAG,MAAM,IAAI;IAO/D,gBAAgB;IAChB,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAUpC;;;OAGG;IACH,aAAa,CAAC,CAAC,EACb,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC;CAmDd"}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { buildQuadroClientFromCatalogSpec, type CatalogClassRuntimeSpec, type CatalogRuntimeSpec, } from './catalog-builder.js';
|
|
1
|
+
export { buildQuadroClientFromCatalogSpec, type CatalogClassRuntimeSpec, type CatalogDatastoreMethodSpec, type CatalogRuntimeSpec, } from './catalog-builder.js';
|
|
2
2
|
export { type ClassFunctionHttpOptions, callDataClassFunction, callEntityCollectionFunction, callEntityFunction, type EntityCollectionMethodOptions, unwrapClassFunctionResult, } from './class-function.js';
|
|
3
3
|
export type { BaseDataClassApi } from './client-types.js';
|
|
4
4
|
export { type CollectionContext, type CollectionHandle, type CollectionOptions, createCollection, } from './collection.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gCAAgC,EAChC,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,GACxB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,KAAK,wBAAwB,EAC7B,qBAAqB,EACrB,4BAA4B,EAC5B,kBAAkB,EAClB,KAAK,6BAA6B,EAClC,yBAAyB,GAC1B,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,gBAAgB,GACjB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,2BAA2B,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,wBAAwB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,UAAU,GACX,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,MAAM,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC9E,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,eAAe,EACpB,KAAK,oBAAoB,GAC1B,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gCAAgC,EAChC,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,GACxB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,KAAK,wBAAwB,EAC7B,qBAAqB,EACrB,4BAA4B,EAC5B,kBAAkB,EAClB,KAAK,6BAA6B,EAClC,yBAAyB,GAC1B,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,gBAAgB,GACjB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,2BAA2B,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,wBAAwB,EACxB,KAAK,qBAAqB,GAC3B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,UAAU,GACX,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,MAAM,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC9E,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,eAAe,EACpB,KAAK,oBAAoB,GAC1B,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quadrokit/client",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.18",
|
|
4
4
|
"description": "Typed 4D REST client and catalog code generator for QuadroKit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.mjs",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"generate:fixture": "bun run src/cli.ts generate --url file://../../assets/catalog.json --out ../../.quadrokit/generated-demo"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@quadrokit/shared": "^0.3.
|
|
36
|
+
"@quadrokit/shared": "^0.3.18",
|
|
37
37
|
"undici": "^6.21.0"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|