@quadrokit/client 0.3.10 → 0.3.12

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 CHANGED
@@ -51,8 +51,9 @@ Environment variables (often via `.env` in the project root): `VITE_4D_ORIGIN`,
51
51
 
52
52
  | File | Purpose |
53
53
  |------|---------|
54
- | **`types.gen.ts`** | Entity interfaces and `*Path` unions for typed `select`. |
55
- | **`client.gen.ts`** | `createClient(config)` dataclass APIs, optional `authentify`, `rpc`, `quadrokitCatalogMeta`. |
54
+ | **`types.gen.ts`** | Entity interfaces; **`*Path`** aliases use **`QuadroAttributePaths<T>`** (recursive dot paths, depth-limited for circular relations); **`QuadroClient`** typing. |
55
+ | **`catalog.gen.json`** | Catalog runtime spec (dataclass layouts, methods, relations) consumed by `@quadrokit/client/runtime` — keeps **`client.gen.ts`** tiny. |
56
+ | **`client.gen.ts`** | Thin `createClient(config)` that wires `QuadroHttp` + `buildQuadroClientFromCatalogSpec` + `catalog.gen.json`. |
56
57
  | **`meta.json`** | `__NAME`, `sessionCookieName` hint for 4D session cookies. |
57
58
 
58
59
  Point your app imports at the generated folder, for example:
@@ -1,4 +1,22 @@
1
1
  import type { CatalogJson } from '@quadrokit/shared';
2
+ /** Serializable spec consumed by {@link buildQuadroClientFromCatalogSpec} at runtime. */
3
+ export declare function buildCatalogRuntimeSpec(catalog: CatalogJson): {
4
+ classes: {
5
+ name: string;
6
+ relationMap: Record<string, string>;
7
+ keyNames: string[];
8
+ entityMethodNames: string[];
9
+ entityCollectionMethodNames: string[];
10
+ dataClassMethodNames: string[];
11
+ navigable: {
12
+ attr: string;
13
+ targetClass: string;
14
+ entityCollectionMethodNames: string[];
15
+ }[];
16
+ }[];
17
+ keyNamesByClass: Record<string, string[]>;
18
+ hasAuthentify: boolean;
19
+ };
2
20
  /** Warn when the catalog lists dataclasses but omits attributes (e.g. plain `GET /rest/$catalog` instead of `/rest/$catalog/$all`). */
3
21
  export declare function warnIfCatalogLacksAttributes(catalog: CatalogJson): void;
4
22
  export declare function writeGenerated(outDir: string, catalog: CatalogJson): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/generate/codegen.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAsC,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAmXxF,uIAAuI;AACvI,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAYvE;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBxF"}
1
+ {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/generate/codegen.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAsC,WAAW,EAAE,MAAM,mBAAmB,CAAA;AA4GxF,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,aAAa,EAAE,OAAO,CAAA;CACvB,CAuBA;AA0GD,uIAAuI;AACvI,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAYvE;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBxF"}
@@ -66,28 +66,7 @@ function keyNames(dc) {
66
66
  const k = dc.key?.map((x) => x.name) ?? ['ID'];
67
67
  return k.length ? k : ['ID'];
68
68
  }
69
- function collectPaths(dc, byName, maxDepth) {
70
- const paths = new Set();
71
- const visit = (current, prefix, depth) => {
72
- for (const a of current.attributes ?? []) {
73
- if (a.kind === 'storage' || a.kind === 'calculated' || a.kind === 'alias') {
74
- const p = prefix ? `${prefix}.${a.name}` : a.name;
75
- paths.add(p);
76
- }
77
- if (a.kind === 'relatedEntity' && a.type && depth < maxDepth) {
78
- const child = byName.get(a.type);
79
- const base = prefix ? `${prefix}.${a.name}` : a.name;
80
- paths.add(base);
81
- if (child) {
82
- visit(child, base, depth + 1);
83
- }
84
- }
85
- }
86
- };
87
- visit(dc, '', 0);
88
- return [...paths].sort();
89
- }
90
- function emitInterface(dc, _byName) {
69
+ function emitInterface(dc) {
91
70
  const lines = [];
92
71
  lines.push(`export interface ${dc.name} {`);
93
72
  for (const a of dc.attributes ?? []) {
@@ -115,42 +94,94 @@ function methodsForApply(dc, applyTo) {
115
94
  }
116
95
  return (dc.methods ?? []).filter((m) => m.applyTo === applyTo && m.exposed !== false);
117
96
  }
118
- function emitTypes(catalog) {
97
+ function catalogHasAuthentify(catalog) {
98
+ return Boolean(catalog.methods?.some((m) => m.name === 'authentify' && m.applyTo === 'dataStore'));
99
+ }
100
+ /** Serializable spec consumed by {@link buildQuadroClientFromCatalogSpec} at runtime. */
101
+ export function buildCatalogRuntimeSpec(catalog) {
119
102
  const classes = exposedDataClasses(catalog);
120
103
  const byName = new Map(classes.map((c) => [c.name, c]));
121
- const interfaces = classes.map((c) => emitInterface(c, byName));
104
+ return {
105
+ hasAuthentify: catalogHasAuthentify(catalog),
106
+ keyNamesByClass: Object.fromEntries(classes.map((x) => [x.name, [...keyNames(x)]])),
107
+ classes: classes.map((c) => ({
108
+ name: c.name,
109
+ relationMap: relationTargets(c),
110
+ keyNames: [...keyNames(c)],
111
+ entityMethodNames: methodsForApply(c, 'entity').map((m) => m.name),
112
+ entityCollectionMethodNames: methodsForApply(c, 'entityCollection').map((m) => m.name),
113
+ dataClassMethodNames: methodsForApply(c, 'dataClass').map((m) => m.name),
114
+ navigable: navigableRelations(c).map((n) => ({
115
+ attr: n.attr,
116
+ targetClass: n.targetClass,
117
+ entityCollectionMethodNames: methodsForApply(byName.get(n.targetClass), 'entityCollection').map((m) => m.name),
118
+ })),
119
+ })),
120
+ };
121
+ }
122
+ function emitQuadroClientTypeBlock(catalog, withEntities) {
123
+ const classes = exposedDataClasses(catalog);
124
+ const hasAuthentify = catalogHasAuthentify(catalog);
125
+ const authLine = hasAuthentify
126
+ ? ` authentify: { login: (body: { email: string; password: string }) => Promise<unknown> };\n`
127
+ : '';
128
+ const tail = ` rpc: (segments: string[], init?: { method?: 'GET' | 'POST'; body?: unknown }) => Promise<unknown>;
129
+ sessionCookieName: string;
130
+ _http: QuadroHttp;
131
+ };`;
132
+ if (!withEntities || classes.length === 0) {
133
+ return `export type QuadroClient = {
134
+ ${authLine}${tail}
135
+ `;
136
+ }
137
+ const dcFn = `type QuadroDataClassFn = <R = unknown>(args?: readonly unknown[], init?: ClassFunctionHttpOptions & { unwrapResult?: boolean }) => Promise<R>;
138
+
139
+ `;
140
+ const branches = classes
141
+ .map((c) => {
142
+ const keys = methodsForApply(c, 'dataClass')
143
+ .map((m) => `'${m.name}'`)
144
+ .join(' | ');
145
+ const rhs = keys
146
+ ? `BaseDataClassApi<${c.name}, ${c.name}Path> & { [K in ${keys}]: QuadroDataClassFn }`
147
+ : `BaseDataClassApi<${c.name}, ${c.name}Path>`;
148
+ return ` ${c.name}: ${rhs};`;
149
+ })
150
+ .join('\n');
151
+ return `${dcFn}export type QuadroClient = {
152
+ ${authLine}${branches}
153
+ ${tail}
154
+ `;
155
+ }
156
+ function emitTypes(catalog) {
157
+ const classes = exposedDataClasses(catalog);
158
+ const interfaces = classes.map((c) => emitInterface(c));
122
159
  const pathTypes = classes.map((c) => {
123
- const paths = collectPaths(c, byName, 2);
124
160
  const name = `${c.name}Path`;
125
- const body = paths.length ? paths.map((p) => `'${p}'`).join('\n | ') : 'never';
126
- return `export type ${name} =\n | ${body};`;
161
+ return `export type ${name} = QuadroAttributePaths<${c.name}>;`;
127
162
  });
128
163
  const header = `/* eslint-disable */\n/* Auto-generated by @quadrokit/client — do not edit */\n`;
164
+ const pathNote = classes.length > 0
165
+ ? `/**\n * *Path types use {@link QuadroAttributePaths} (recursive relation paths, depth-limited for circular graphs).\n * Override depth: \`type DeepEmployeePath = QuadroAttributePaths<Employee, 12>\`.\n */\n`
166
+ : '';
167
+ const runtimeImport = classes.length > 0
168
+ ? `import type { BaseDataClassApi, ClassFunctionHttpOptions, QuadroAttributePaths, QuadroHttp } from '@quadrokit/client/runtime';\n\n`
169
+ : `import type { QuadroHttp } from '@quadrokit/client/runtime';\n\n`;
129
170
  if (classes.length === 0) {
130
171
  const raw = catalog.dataClasses?.length ?? 0;
131
172
  const note = raw > 0
132
173
  ? `\n/**\n * No entity types: all ${raw} data class(es) in the catalog have exposed: false.\n * Enable REST exposure for tables in 4D, then run quadrokit-client generate again.\n */\n`
133
174
  : `\n/**\n * No entity types: the catalog has no dataClasses (or an empty list).\n */\n`;
134
- return `${header}${note}\n`;
175
+ return `${header}${runtimeImport}${note}\n${emitQuadroClientTypeBlock(catalog, false)}`;
135
176
  }
136
- return `${header}\n${interfaces.join('\n\n')}\n\n${pathTypes.join('\n\n')}\n`;
177
+ return `${header}${runtimeImport}${interfaces.join('\n\n')}\n\n${pathNote}${pathTypes.join('\n\n')}\n\n${emitQuadroClientTypeBlock(catalog, true)}`;
137
178
  }
138
179
  function emitClient(catalog) {
139
- const classes = exposedDataClasses(catalog);
140
- const byName = new Map(classes.map((c) => [c.name, c]));
141
180
  const dbName = catalog.__NAME ?? 'default';
142
- const hasAuthentify = catalog.methods?.some((m) => m.name === 'authentify' && m.applyTo === 'dataStore');
143
- const keyNamesRecord = Object.fromEntries(classes.map((x) => [x.name, keyNames(x)]));
144
- const imports = classes.length > 0
145
- ? `/* eslint-disable */\n/* Auto-generated by @quadrokit/client — do not edit */\n\nimport {\n QuadroHttp,\n makeDataClassApi,\n attachRelatedApis,\n attachEntityClassMethods,\n bindEntityCollectionMethods,\n callDataClassFunction,\n callDatastorePath,\n type ClassFunctionHttpOptions,\n type CollectionHandle,\n type CollectionOptions,\n type SelectedEntity,\n} from '@quadrokit/client/runtime';\n`
146
- : `/* eslint-disable */\n/* Auto-generated by @quadrokit/client — do not edit */\n\nimport { QuadroHttp, callDatastorePath } from '@quadrokit/client/runtime';\n`;
147
- const typeImports = classes.map((c) => c.name).join(', ');
148
- const pathImports = classes.map((c) => `${c.name}Path`).join(', ');
149
- const typeImportLine = typeImports || pathImports
150
- ? // Split so `rename-dist-js-to-mjs` does not rewrite this *emitted* import to `.mjs`.
151
- `\nimport type { ${[typeImports, pathImports].filter(Boolean).join(', ')} } from './types.gen';\n\n`
152
- : '\n';
153
- const header = `${imports}${typeImportLine}`;
181
+ const imports = `/* eslint-disable */\n/* Auto-generated by @quadrokit/client — do not edit */\n\nimport {\n QuadroHttp,\n buildQuadroClientFromCatalogSpec,\n type CatalogRuntimeSpec,\n} from '@quadrokit/client/runtime';\nimport catalogSpec from './catalog.gen.json' with { type: 'json' };\n`;
182
+ // Split so `rename-dist-js-to-mjs` does not rewrite this *emitted* import to `.mjs`.
183
+ const typeImport = `import type { QuadroClient } from './types.gen';\n\n`;
184
+ const header = `${imports}${typeImport}`;
154
185
  const metaExport = `
155
186
  export const quadrokitCatalogMeta = {
156
187
  __NAME: ${JSON.stringify(dbName)},
@@ -164,172 +195,19 @@ export interface QuadroClientConfig {
164
195
  defaultHeaders?: Record<string, string>;
165
196
  }
166
197
  `;
167
- const mapFunctions = classes
168
- .map((c) => {
169
- const nav = navigableRelations(c);
170
- const relMap = JSON.stringify(relationTargets(c));
171
- const kn = JSON.stringify(keyNames(c));
172
- const ecNav = nav.map((n) => ({
173
- attr: n.attr,
174
- targetClass: n.targetClass,
175
- entityCollectionMethodNames: methodsForApply(byName.get(n.targetClass), 'entityCollection').map((m) => m.name),
176
- }));
177
- const entityMethodNames = methodsForApply(c, 'entity').map((m) => m.name);
178
- return ` function map${c.name}Row(http: QuadroHttp, raw: unknown): ${c.name} {
179
- const row = raw as ${c.name};
180
- const pk = (row as { ID?: number }).ID ?? (row as { id?: number }).id;
181
- attachEntityClassMethods(
182
- raw,
183
- {
184
- http,
185
- className: '${c.name}',
186
- relationMap: ${relMap},
187
- keyNames: ${kn},
188
- },
189
- ${JSON.stringify(entityMethodNames)},
190
- );
191
- attachRelatedApis(
192
- raw,
193
- {
194
- http,
195
- parentClass: '${c.name}',
196
- parentId: pk as number,
197
- relationMap: ${relMap},
198
- keyNames: ${JSON.stringify(keyNamesRecord)},
199
- },
200
- ${JSON.stringify(ecNav)},
201
- );
202
- return row;
203
- }`;
204
- })
205
- .join('\n\n');
206
- const classBranches = classes
207
- .map((c) => {
208
- const relMap = JSON.stringify(relationTargets(c));
209
- const kn = JSON.stringify(keyNames(c));
210
- const pathsType = `${c.name}Path`;
211
- const ecNames = JSON.stringify(methodsForApply(c, 'entityCollection').map((m) => m.name));
212
- const dcBlock = methodsForApply(c, 'dataClass')
213
- .map((m) => ` ${m.name}: async <R = unknown>(args: readonly unknown[] = [], init?: ClassFunctionHttpOptions & { unwrapResult?: boolean }) =>
214
- callDataClassFunction<R>(http, '${c.name}', '${m.name}', args, init),`)
215
- .join('\n');
216
- const dcPrefix = dcBlock ? `${dcBlock}\n` : '';
217
- return ` ${c.name}: (() => {
218
- const cfg = {
219
- http,
220
- className: '${c.name}',
221
- relationMap: ${relMap},
222
- keyNames: ${kn},
223
- } as const;
224
- const api = makeDataClassApi<${c.name}>(cfg);
225
- return {
226
- ${dcPrefix} all<S extends readonly ${pathsType}[] = readonly []>(
227
- options?: CollectionOptions & { select?: S },
228
- ): CollectionHandle<S['length'] extends 0 ? ${c.name} : SelectedEntity<${c.name}, S>> {
229
- const inner = api.all(options as CollectionOptions);
230
- bindEntityCollectionMethods(inner, { http, className: '${c.name}', relationMap: ${relMap} }, ${ecNames});
231
- return {
232
- ...inner,
233
- delete: inner.delete.bind(inner),
234
- release: inner.release.bind(inner),
235
- get length() {
236
- return inner.length;
237
- },
238
- [Symbol.asyncIterator]() {
239
- const it = inner[Symbol.asyncIterator]();
240
- return {
241
- async next() {
242
- const n = await it.next();
243
- if (!n.done && n.value) {
244
- map${c.name}Row(http, n.value);
245
- }
246
- return n;
247
- },
248
- return(value) {
249
- return it.return?.(value) ?? Promise.resolve({ done: true, value });
250
- },
251
- throw(e) {
252
- return it.throw?.(e) ?? Promise.reject(e);
253
- },
254
- };
255
- },
256
- } as CollectionHandle<S['length'] extends 0 ? ${c.name} : SelectedEntity<${c.name}, S>>;
257
- },
258
- async get<S extends readonly ${pathsType}[] = readonly []>(
259
- id: string | number,
260
- options?: { select?: S },
261
- ): Promise<(S['length'] extends 0 ? ${c.name} : SelectedEntity<${c.name}, S>) | null> {
262
- const entity = await api.get(id, options);
263
- if (entity) {
264
- map${c.name}Row(http, entity);
265
- }
266
- return entity as (S['length'] extends 0 ? ${c.name} : SelectedEntity<${c.name}, S>) | null;
267
- },
268
- delete: (id: string | number) => api.delete(id),
269
- query<S extends readonly ${pathsType}[] = readonly []>(
270
- filter: string,
271
- options?: CollectionOptions & { params?: unknown[]; select?: S },
272
- ): CollectionHandle<S['length'] extends 0 ? ${c.name} : SelectedEntity<${c.name}, S>> {
273
- const inner = api.query(filter, options as CollectionOptions);
274
- bindEntityCollectionMethods(inner, { http, className: '${c.name}', relationMap: ${relMap} }, ${ecNames});
275
- return {
276
- ...inner,
277
- delete: inner.delete.bind(inner),
278
- release: inner.release.bind(inner),
279
- get length() {
280
- return inner.length;
281
- },
282
- [Symbol.asyncIterator]() {
283
- const it = inner[Symbol.asyncIterator]();
284
- return {
285
- async next() {
286
- const n = await it.next();
287
- if (!n.done && n.value) {
288
- map${c.name}Row(http, n.value);
289
- }
290
- return n;
291
- },
292
- return(value) {
293
- return it.return?.(value) ?? Promise.resolve({ done: true, value });
294
- },
295
- throw(e) {
296
- return it.throw?.(e) ?? Promise.reject(e);
297
- },
298
- };
299
- },
300
- } as CollectionHandle<S['length'] extends 0 ? ${c.name} : SelectedEntity<${c.name}, S>>;
301
- },
302
- };
303
- })(),`;
304
- })
305
- .join('\n');
306
- const authentifyBlock = hasAuthentify
307
- ? `
308
- authentify: {
309
- login: (body: { email: string; password: string }) =>
310
- callDatastorePath(http, ['authentify', 'login'], { body }),
311
- },`
312
- : '';
313
198
  const body = `
314
- export function createClient(config: QuadroClientConfig) {
199
+ export function createClient(config: QuadroClientConfig): QuadroClient {
315
200
  const http = new QuadroHttp({
316
201
  baseURL: config.baseURL,
317
202
  fetchImpl: config.fetchImpl,
318
203
  defaultHeaders: config.defaultHeaders,
319
204
  });
320
-
321
- ${mapFunctions}
322
-
323
- return {${authentifyBlock}
324
- ${classBranches}
325
- rpc: (segments: string[], init?: { method?: 'GET' | 'POST'; body?: unknown }) =>
326
- callDatastorePath(http, segments, init),
327
- sessionCookieName: quadrokitCatalogMeta.sessionCookieName,
328
- _http: http,
329
- };
205
+ return buildQuadroClientFromCatalogSpec(
206
+ http,
207
+ catalogSpec as unknown as CatalogRuntimeSpec,
208
+ quadrokitCatalogMeta,
209
+ ) as QuadroClient;
330
210
  }
331
-
332
- export type QuadroClient = ReturnType<typeof createClient>;
333
211
  `;
334
212
  return header + metaExport + configInterface + body;
335
213
  }
@@ -347,6 +225,7 @@ export function warnIfCatalogLacksAttributes(catalog) {
347
225
  }
348
226
  export async function writeGenerated(outDir, catalog) {
349
227
  await mkdir(outDir, { recursive: true });
228
+ await writeFile(path.join(outDir, 'catalog.gen.json'), `${JSON.stringify(buildCatalogRuntimeSpec(catalog), null, 2)}\n`, 'utf8');
350
229
  await writeFile(path.join(outDir, 'types.gen.ts'), emitTypes(catalog), 'utf8');
351
230
  await writeFile(path.join(outDir, 'client.gen.ts'), emitClient(catalog), 'utf8');
352
231
  await writeFile(path.join(outDir, 'meta.json'), JSON.stringify({
@@ -0,0 +1,25 @@
1
+ import { type RelatedNavigationSpec } from './data-class.js';
2
+ import type { QuadroHttp } from './http.js';
3
+ /** One dataclass entry in `catalog.gen.json` (codegen output). */
4
+ export interface CatalogClassRuntimeSpec {
5
+ name: string;
6
+ relationMap: Record<string, string>;
7
+ keyNames: readonly string[];
8
+ entityMethodNames: readonly string[];
9
+ entityCollectionMethodNames: readonly string[];
10
+ dataClassMethodNames: readonly string[];
11
+ navigable: readonly RelatedNavigationSpec[];
12
+ }
13
+ export interface CatalogRuntimeSpec {
14
+ classes: readonly CatalogClassRuntimeSpec[];
15
+ keyNamesByClass: Readonly<Record<string, readonly string[]>>;
16
+ hasAuthentify: boolean;
17
+ }
18
+ /**
19
+ * Builds the object returned by generated `createClient()` from `catalog.gen.json`.
20
+ * Keeps generated `client.gen.ts` small; all repetitive logic lives here.
21
+ */
22
+ export declare function buildQuadroClientFromCatalogSpec(http: QuadroHttp, spec: CatalogRuntimeSpec, meta: {
23
+ sessionCookieName: string;
24
+ }): Record<string, unknown>;
25
+ //# sourceMappingURL=catalog-builder.d.ts.map
@@ -0,0 +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,aAAa,EAAE,OAAO,CAAA;CACvB;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,CAoBzB"}
@@ -0,0 +1,99 @@
1
+ import { callDataClassFunction } from './class-function.mjs';
2
+ import { attachEntityClassMethods, attachRelatedApis, bindEntityCollectionMethods, makeDataClassApi, } from './data-class.mjs';
3
+ import { callDatastorePath } from './datastore.mjs';
4
+ function wrapCollectionWithRowMapper(inner, mapRow) {
5
+ return {
6
+ ...inner,
7
+ delete: inner.delete.bind(inner),
8
+ release: inner.release.bind(inner),
9
+ get length() {
10
+ return inner.length;
11
+ },
12
+ [Symbol.asyncIterator]() {
13
+ const it = inner[Symbol.asyncIterator]();
14
+ return {
15
+ async next() {
16
+ const n = await it.next();
17
+ if (!n.done && n.value) {
18
+ mapRow(n.value);
19
+ }
20
+ return n;
21
+ },
22
+ return(value) {
23
+ return it.return?.(value) ?? Promise.resolve({ done: true, value });
24
+ },
25
+ throw(e) {
26
+ return it.throw?.(e) ?? Promise.reject(e);
27
+ },
28
+ };
29
+ },
30
+ };
31
+ }
32
+ function mapRowFromSpec(http, raw, c, keyNamesRecord) {
33
+ const pk = raw.ID ?? raw.id;
34
+ attachEntityClassMethods(raw, {
35
+ http,
36
+ className: c.name,
37
+ relationMap: c.relationMap,
38
+ keyNames: c.keyNames,
39
+ }, c.entityMethodNames);
40
+ attachRelatedApis(raw, {
41
+ http,
42
+ parentClass: c.name,
43
+ parentId: pk,
44
+ relationMap: c.relationMap,
45
+ keyNames: keyNamesRecord,
46
+ }, c.navigable);
47
+ }
48
+ function makeDataClassNamespace(http, c, keyNamesRecord) {
49
+ const cfg = {
50
+ http,
51
+ className: c.name,
52
+ relationMap: c.relationMap,
53
+ keyNames: c.keyNames,
54
+ };
55
+ const api = makeDataClassApi(cfg);
56
+ const mapRow = (raw) => {
57
+ mapRowFromSpec(http, raw, c, keyNamesRecord);
58
+ return raw;
59
+ };
60
+ const bindEc = (inner) => {
61
+ bindEntityCollectionMethods(inner, { http, className: c.name, relationMap: c.relationMap }, c.entityCollectionMethodNames);
62
+ return wrapCollectionWithRowMapper(inner, mapRow);
63
+ };
64
+ const out = {};
65
+ for (const name of c.dataClassMethodNames) {
66
+ out[name] = async (args = [], init) => callDataClassFunction(http, c.name, name, args, init);
67
+ }
68
+ out.all = (options) => bindEc(api.all(options));
69
+ out.get = async (id, options) => {
70
+ const entity = await api.get(id, options);
71
+ if (entity) {
72
+ mapRow(entity);
73
+ }
74
+ return entity;
75
+ };
76
+ out.delete = (id) => api.delete(id);
77
+ out.query = (filter, options) => bindEc(api.query(filter, options ?? {}));
78
+ return out;
79
+ }
80
+ /**
81
+ * Builds the object returned by generated `createClient()` from `catalog.gen.json`.
82
+ * Keeps generated `client.gen.ts` small; all repetitive logic lives here.
83
+ */
84
+ export function buildQuadroClientFromCatalogSpec(http, spec, meta) {
85
+ const keyNamesRecord = spec.keyNamesByClass;
86
+ const out = {};
87
+ if (spec.hasAuthentify) {
88
+ out.authentify = {
89
+ login: (body) => callDatastorePath(http, ['authentify', 'login'], { body }),
90
+ };
91
+ }
92
+ for (const c of spec.classes) {
93
+ out[c.name] = makeDataClassNamespace(http, c, keyNamesRecord);
94
+ }
95
+ out.rpc = (segments, init) => callDatastorePath(http, segments, init);
96
+ out.sessionCookieName = meta.sessionCookieName;
97
+ out._http = http;
98
+ return out;
99
+ }
@@ -0,0 +1,17 @@
1
+ import type { CollectionHandle, CollectionOptions } from './collection.js';
2
+ import type { SelectedEntity } from './paths.js';
3
+ /** Shape of each dataclass namespace on `createClient()` (codegen composes with per-class datastore method keys). */
4
+ export type BaseDataClassApi<T, Path extends string> = {
5
+ all<S extends readonly Path[] = readonly []>(options?: CollectionOptions & {
6
+ select?: S;
7
+ }): CollectionHandle<S['length'] extends 0 ? T : SelectedEntity<T, S>>;
8
+ get<S extends readonly Path[] = readonly []>(id: string | number, options?: {
9
+ select?: S;
10
+ }): Promise<(S['length'] extends 0 ? T : SelectedEntity<T, S>) | null>;
11
+ delete(id: string | number): Promise<boolean>;
12
+ query<S extends readonly Path[] = readonly []>(filter: string, options?: CollectionOptions & {
13
+ params?: unknown[];
14
+ select?: S;
15
+ }): CollectionHandle<S['length'] extends 0 ? T : SelectedEntity<T, S>>;
16
+ };
17
+ //# sourceMappingURL=client-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-types.d.ts","sourceRoot":"","sources":["../../src/runtime/client-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,qHAAqH;AACrH,MAAM,MAAM,gBAAgB,CAAC,CAAC,EAAE,IAAI,SAAS,MAAM,IAAI;IACrD,GAAG,CAAC,CAAC,SAAS,SAAS,IAAI,EAAE,GAAG,SAAS,EAAE,EACzC,OAAO,CAAC,EAAE,iBAAiB,GAAG;QAAE,MAAM,CAAC,EAAE,CAAC,CAAA;KAAE,GAC3C,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACrE,GAAG,CAAC,CAAC,SAAS,SAAS,IAAI,EAAE,GAAG,SAAS,EAAE,EACzC,EAAE,EAAE,MAAM,GAAG,MAAM,EACnB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,CAAC,CAAA;KAAE,GACvB,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IACrE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC7C,KAAK,CAAC,CAAC,SAAS,SAAS,IAAI,EAAE,GAAG,SAAS,EAAE,EAC3C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,iBAAiB,GAAG;QAAE,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,CAAC,CAAA;KAAE,GAC/D,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;CACtE,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,10 +1,12 @@
1
+ export { buildQuadroClientFromCatalogSpec, type CatalogClassRuntimeSpec, type CatalogRuntimeSpec, } from './catalog-builder.js';
1
2
  export { type ClassFunctionHttpOptions, callDataClassFunction, callEntityCollectionFunction, callEntityFunction, type EntityCollectionMethodOptions, unwrapClassFunctionResult, } from './class-function.js';
3
+ export type { BaseDataClassApi } from './client-types.js';
2
4
  export { type CollectionContext, type CollectionHandle, type CollectionOptions, createCollection, } from './collection.js';
3
5
  export { attachEntityClassMethods, attachRelatedApis, bindEntityCollectionMethods, type DataClassRuntimeConfig, type EntityNavigationConfig, makeDataClassApi, makeRelatedCollectionApi, type RelatedNavigationSpec, } from './data-class.js';
4
6
  export { callDatastorePath, createDatastoreNamespace } from './datastore.js';
5
7
  export { QuadroHttpError } from './errors.js';
6
8
  export { mountPathFromBaseURL, normalizeBaseURL, type QuadroFetchOptions, QuadroHttp, } from './http.js';
7
- export type { Paths1, SelectedEntity } from './paths.js';
9
+ export type { Paths1, QuadroAttributePaths, SelectedEntity } from './paths.js';
8
10
  export { buildEntitySetCreationParams, buildEntitySetPageParams, buildListSearchParams, buildMethodSelectionQuery, type ListQueryParams, type MethodSelectionQuery, } from './query.js';
9
11
  export { unwrapEntity, unwrapEntityList } from './unwrap.js';
10
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAC7B,qBAAqB,EACrB,4BAA4B,EAC5B,kBAAkB,EAClB,KAAK,6BAA6B,EAClC,yBAAyB,GAC1B,MAAM,qBAAqB,CAAA;AAC5B,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,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,UAAU,GACX,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AACxD,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,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,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,3 +1,4 @@
1
+ export { buildQuadroClientFromCatalogSpec, } from './catalog-builder.mjs';
1
2
  export { callDataClassFunction, callEntityCollectionFunction, callEntityFunction, unwrapClassFunctionResult, } from './class-function.mjs';
2
3
  export { createCollection, } from './collection.mjs';
3
4
  export { attachEntityClassMethods, attachRelatedApis, bindEntityCollectionMethods, makeDataClassApi, makeRelatedCollectionApi, } from './data-class.mjs';
@@ -1,4 +1,17 @@
1
1
  /** Type-level helpers for `$attributes` dot paths (compile-time only). */
2
+ /** Decrements depth for {@link QuadroAttributePaths} (index = current max depth). */
3
+ type QuadroPathDepthPrev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
4
+ type QuadroPathNextDepth<D extends number> = D extends keyof QuadroPathDepthPrev ? QuadroPathDepthPrev[D] : 0;
5
+ /**
6
+ * Valid `$attributes` dot paths for entity `T` (e.g. `ceo.manager.manager.employer.name`),
7
+ * including arbitrary nesting along related-entity fields. Bounded by `MaxDepth` so circular
8
+ * graphs (e.g. `Employee.manager: Employee`) stay instantiable in TypeScript.
9
+ *
10
+ * Index-signature objects (`Record<string, unknown>`) are treated as leaves (single segment only).
11
+ */
12
+ export type QuadroAttributePaths<T, MaxDepth extends number = 8> = [MaxDepth] extends [0] ? never : T extends object ? T extends readonly unknown[] ? never : {
13
+ [K in keyof T & string]: NonNullable<T[K]> extends infer U ? U extends string | number | boolean | bigint | symbol ? K : U extends (...args: never) => unknown ? K : U extends readonly unknown[] ? K : [U] extends [never] ? K : U extends Date ? K : U extends object ? string extends keyof U ? K : K | `${K}.${QuadroAttributePaths<U, QuadroPathNextDepth<MaxDepth>>}` : K : K;
14
+ }[keyof T & string] : never;
2
15
  type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
3
16
  type PickOne<T, H extends string> = H extends keyof T & string ? Pick<T, H> : H extends `${infer K}.${infer R}` ? K extends keyof T & string ? NonNullable<T[K]> extends infer U ? U extends object ? {
4
17
  [P in K]: PickOne<U, R>;
@@ -8,7 +21,10 @@ declare const selectBrand: unique symbol;
8
21
  export type SelectedEntity<T, S extends readonly string[]> = UnionToIntersection<S[number] extends infer H ? (H extends string ? PickOne<T, H> : never) : never> extends infer O ? O extends object ? O & {
9
22
  readonly [selectBrand]: S;
10
23
  } : never : never;
11
- /** Flat union of first-level and nested dot paths (codegen emits concrete unions). */
24
+ /**
25
+ * Recursive dot paths (can hit "excessively deep" on circular entity types).
26
+ * Prefer {@link QuadroAttributePaths} for catalog-generated entities.
27
+ */
12
28
  export type Paths1<T> = T extends object ? {
13
29
  [K in keyof T & string]: NonNullable<T[K]> extends infer U ? U extends object ? K | `${K}.${Paths1<U>}` : K : K;
14
30
  }[keyof T & string] : never;
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/runtime/paths.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAE1E,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,GAAG,KAAK,CAAC,SAAS,CACjF,CAAC,EAAE,MAAM,CAAC,KACP,IAAI,GACL,CAAC,GACD,KAAK,CAAA;AAET,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,GAC1D,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GACV,CAAC,SAAS,GAAG,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,GAC/B,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,GACxB,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,GAC/B,CAAC,SAAS,MAAM,GACd;KAAG,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;CAAE,GAC3B,KAAK,GACP,KAAK,GACP,KAAK,GACP,KAAK,CAAA;AAEX,OAAO,CAAC,MAAM,WAAW,EAAE,OAAO,MAAM,CAAA;AAExC,2EAA2E;AAC3E,MAAM,MAAM,cAAc,CAAC,CAAC,EAAE,CAAC,SAAS,SAAS,MAAM,EAAE,IACvD,mBAAmB,CACjB,CAAC,CAAC,MAAM,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAC/E,SAAS,MAAM,CAAC,GACb,CAAC,SAAS,MAAM,GACd,CAAC,GAAG;IAAE,QAAQ,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;CAAE,GACjC,KAAK,GACP,KAAK,CAAA;AAEX,sFAAsF;AACtF,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,GACpC;KACG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,GACtD,CAAC,SAAS,MAAM,GACd,CAAC,GAAG,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,GACvB,CAAC,GACH,CAAC;CACN,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GACnB,KAAK,CAAA"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/runtime/paths.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quadrokit/client",
3
- "version": "0.3.10",
3
+ "version": "0.3.12",
4
4
  "description": "Typed 4D REST client and catalog code generator for QuadroKit",
5
5
  "type": "module",
6
6
  "main": "./dist/index.mjs",
@@ -29,7 +29,7 @@
29
29
  "generate:fixture": "bun run src/cli.ts generate --url file://../../assets/catalog.json --out ../../.quadrokit/generated-demo"
30
30
  },
31
31
  "dependencies": {
32
- "@quadrokit/shared": "^0.3.10",
32
+ "@quadrokit/shared": "^0.3.12",
33
33
  "undici": "^6.21.0"
34
34
  },
35
35
  "peerDependencies": {