@quadrokit/client 0.2.7 → 0.2.8

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
@@ -14,12 +14,12 @@ After install, the binary name is **`quadrokit-client`** (not the scoped package
14
14
 
15
15
  ```bash
16
16
  bunx quadrokit-client generate \
17
- --url 'http://localhost:7080/rest/$catalog' \
17
+ --url 'http://localhost:7080/rest/$catalog/$all' \
18
18
  --token YOUR_TOKEN \
19
19
  --out .quadrokit/generated
20
20
  ```
21
21
 
22
- - **`--url`**: HTTP(S) catalog URL or `file:///absolute/path/to/catalog.json`
22
+ - **`--url`**: HTTP(S) catalog URL or `file:///absolute/path/to/catalog.json`. Use **`/rest/$catalog/$all`** so the JSON includes dataclass **attributes**; plain `/rest/$catalog` only lists names (empty types). Defaults to `${VITE_4D_ORIGIN}/rest/$catalog/$all`.
23
23
  - **`--token`**: optional `Authorization: Bearer …` for protected catalog endpoints
24
24
  - **`--out`**: output directory (default `.quadrokit/generated`)
25
25
 
package/dist/cli.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import { readFile } from 'node:fs/promises';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { catalogFetchInit, defaultLoginUrlFromCatalogUrl, fetch4DAdminSessionCookie, vLog, wrapFetchError, } from './generate/catalog-session.mjs';
5
- import { writeGenerated } from './generate/codegen.mjs';
5
+ import { warnIfCatalogLacksAttributes, writeGenerated } from './generate/codegen.mjs';
6
6
  import { applyGenerateDotenv } from './generate/dotenv-cwd.mjs';
7
7
  function parseArgs(argv) {
8
8
  let command = '';
@@ -42,6 +42,14 @@ function parseArgs(argv) {
42
42
  }
43
43
  return { command, url, token, accessKey, loginUrl, out, verbose, insecureTls };
44
44
  }
45
+ /** 4D sometimes returns `dataClass` (summary) vs `dataClasses` (detail); align to `dataClasses`. */
46
+ function normalizeCatalogJson(raw) {
47
+ const o = raw;
48
+ if (o && typeof o === 'object' && !o.dataClasses && Array.isArray(o.dataClass)) {
49
+ return { ...o, dataClasses: o.dataClass };
50
+ }
51
+ return raw;
52
+ }
45
53
  function envFlag(name) {
46
54
  const v = process.env[name]?.trim().toLowerCase();
47
55
  return v === '1' || v === 'true' || v === 'yes';
@@ -60,7 +68,7 @@ async function loadCatalog(url, auth, debug) {
60
68
  vLog(debug, '📂', 'Local file', p);
61
69
  const text = await readFile(p, 'utf8');
62
70
  vLog(debug, '✅', 'Catalog JSON', `Read ${text.length} bytes from disk`);
63
- return JSON.parse(text);
71
+ return normalizeCatalogJson(JSON.parse(text));
64
72
  }
65
73
  const headers = {
66
74
  Accept: 'application/json',
@@ -109,7 +117,7 @@ async function main() {
109
117
  if (command !== 'generate') {
110
118
  console.error(`Usage: quadrokit-client generate [--url <catalog_url>] [auth] [options] [--out <dir>]
111
119
 
112
- --url defaults to \${VITE_4D_ORIGIN}/rest/\\$catalog (from env or .env in cwd), else http://127.0.0.1:7080/rest/\\$catalog
120
+ --url defaults to \${VITE_4D_ORIGIN}/rest/\\$catalog/\\$all (from env or .env in cwd), else http://127.0.0.1:7080/rest/\\$catalog/\\$all
113
121
 
114
122
  Auth (generator only; not used by the app runtime):
115
123
  --access-key <key> POST multipart accessKey to /api/login, then use 4DAdminSID for the catalog
@@ -125,8 +133,8 @@ Env / .env: VITE_4D_ORIGIN, QUADROKIT_ACCESS_KEY, QUADROKIT_LOGIN_URL, QUADROKIT
125
133
 
126
134
  Examples:
127
135
  quadrokit-client generate -v
128
- quadrokit-client generate --url https://localhost:7443/rest/\\$catalog --access-key MY_TOKEN --insecure-tls -v
129
- quadrokit-client generate --url http://localhost:7080/rest/\\$catalog --token secret
136
+ quadrokit-client generate --url https://localhost:7443/rest/\\$catalog/\\$all --access-key MY_TOKEN --insecure-tls -v
137
+ quadrokit-client generate --url http://localhost:7080/rest/\\$catalog/\\$all --token secret
130
138
  quadrokit-client generate --url file://./assets/catalog.json --out .quadrokit/generated
131
139
 
132
140
  bunx -p @quadrokit/client quadrokit-client generate
@@ -138,7 +146,7 @@ Examples:
138
146
  let url = parsed.url;
139
147
  if (!url) {
140
148
  const origin = (process.env.VITE_4D_ORIGIN || 'http://127.0.0.1:7080').replace(/\/$/, '');
141
- url = `${origin}/rest/$catalog`;
149
+ url = `${origin}/rest/$catalog/$all`;
142
150
  }
143
151
  const accessKey = accessKeyArg?.trim() || process.env.QUADROKIT_ACCESS_KEY?.trim() || undefined;
144
152
  const loginUrl = loginUrlArg?.trim() || process.env.QUADROKIT_LOGIN_URL?.trim() || undefined;
@@ -148,6 +156,7 @@ Examples:
148
156
  loginUrl,
149
157
  token: accessKey ? undefined : bearer,
150
158
  }, debug);
159
+ warnIfCatalogLacksAttributes(catalog);
151
160
  await writeGenerated(out, catalog);
152
161
  if (debug.verbose) {
153
162
  vLog(debug, '🎉', 'All set', `Generated client → ${out}`);
@@ -1,3 +1,5 @@
1
1
  import type { CatalogJson } from '@quadrokit/shared';
2
+ /** Warn when the catalog lists dataclasses but omits attributes (e.g. plain `GET /rest/$catalog` instead of `/rest/$catalog/$all`). */
3
+ export declare function warnIfCatalogLacksAttributes(catalog: CatalogJson): void;
2
4
  export declare function writeGenerated(outDir: string, catalog: CatalogJson): Promise<void>;
3
5
  //# sourceMappingURL=codegen.d.ts.map
@@ -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;AA8TxF,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;AA8TxF,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"}
@@ -287,6 +287,18 @@ export type QuadroClient = ReturnType<typeof createClient>;
287
287
  `;
288
288
  return header + metaExport + configInterface + body;
289
289
  }
290
+ /** Warn when the catalog lists dataclasses but omits attributes (e.g. plain `GET /rest/$catalog` instead of `/rest/$catalog/$all`). */
291
+ export function warnIfCatalogLacksAttributes(catalog) {
292
+ const classes = exposedDataClasses(catalog);
293
+ if (classes.length === 0) {
294
+ return;
295
+ }
296
+ const allLackAttrs = classes.every((c) => !(c.attributes && c.attributes.length > 0));
297
+ if (!allLackAttrs) {
298
+ return;
299
+ }
300
+ console.error('quadrokit: catalog has dataclass names but no attribute details. Fetch the full catalog: GET /rest/$catalog/$all (plain /rest/$catalog omits attributes). See 4D REST docs: $catalog/$all.');
301
+ }
290
302
  export async function writeGenerated(outDir, catalog) {
291
303
  await mkdir(outDir, { recursive: true });
292
304
  await writeFile(path.join(outDir, 'types.gen.ts'), emitTypes(catalog), 'utf8');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quadrokit/client",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
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.2.7",
32
+ "@quadrokit/shared": "^0.2.8",
33
33
  "undici": "^6.21.0"
34
34
  },
35
35
  "peerDependencies": {