@metaobjectsdev/runtime-web 1.0.5-rc.1 → 1.0.5-rc.10

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.
@@ -1,8 +1,14 @@
1
1
  /**
2
2
  * Build a bracketed qs URL fragment from a filter object.
3
3
  *
4
- * Output shape (qs's default bracketed style):
5
- * ?filter[email][like]=%25@x.com&filter[subscribed]=true&sort=createdAt:desc&limit=25&withCount=1&search=term
4
+ * Output shape (qs's bracketed style), shown DECODED:
5
+ * ?filter[email][like]=%@x.com&filter[subscribed]=true&sort=createdAt:desc&limit=25&withCount=1&search=term
6
+ *
7
+ * On the wire the brackets are percent-encoded (`filter%5Bemail%5D%5Blike%5D=…`). RFC 3986
8
+ * admits no raw `[`/`]` in a query, and Tomcat — every Spring Boot app's default server —
9
+ * answers a raw one with its own HTML 400, so the generated Java and Kotlin controllers could
10
+ * not serve a single filtered request while this sent them raw. Every server-side parser
11
+ * decodes before it reads the brackets, so the encoded form means the same thing everywhere.
6
12
  *
7
13
  * Top-level `limit`, `offset`, `sort`, `withCount`, and `search` are emitted
8
14
  * at the top level (not under `filter`). All other keys go inside `filter`.
@@ -1 +1 @@
1
- {"version":3,"file":"filter-qs.d.ts","sourceRoot":"","sources":["../src/filter-qs.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAYrE"}
1
+ {"version":3,"file":"filter-qs.d.ts","sourceRoot":"","sources":["../src/filter-qs.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAYrE"}
package/dist/filter-qs.js CHANGED
@@ -2,8 +2,14 @@ import qs from "qs";
2
2
  /**
3
3
  * Build a bracketed qs URL fragment from a filter object.
4
4
  *
5
- * Output shape (qs's default bracketed style):
6
- * ?filter[email][like]=%25@x.com&filter[subscribed]=true&sort=createdAt:desc&limit=25&withCount=1&search=term
5
+ * Output shape (qs's bracketed style), shown DECODED:
6
+ * ?filter[email][like]=%@x.com&filter[subscribed]=true&sort=createdAt:desc&limit=25&withCount=1&search=term
7
+ *
8
+ * On the wire the brackets are percent-encoded (`filter%5Bemail%5D%5Blike%5D=…`). RFC 3986
9
+ * admits no raw `[`/`]` in a query, and Tomcat — every Spring Boot app's default server —
10
+ * answers a raw one with its own HTML 400, so the generated Java and Kotlin controllers could
11
+ * not serve a single filtered request while this sent them raw. Every server-side parser
12
+ * decodes before it reads the brackets, so the encoded form means the same thing everywhere.
7
13
  *
8
14
  * Top-level `limit`, `offset`, `sort`, `withCount`, and `search` are emitted
9
15
  * at the top level (not under `filter`). All other keys go inside `filter`.
@@ -34,6 +40,6 @@ export function buildFilterQs(filter) {
34
40
  filterObj.or = or;
35
41
  if (and !== undefined)
36
42
  filterObj.and = and;
37
- return qs.stringify({ ...top, filter: filterObj }, { encodeValuesOnly: true });
43
+ return qs.stringify({ ...top, filter: filterObj });
38
44
  }
39
45
  //# sourceMappingURL=filter-qs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter-qs.js","sourceRoot":"","sources":["../src/filter-qs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,aAAa,CAAC,MAA+B;IAC3D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,MAAa,CAAC;IACrF,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,IAAI,KAAK,KAAS,SAAS;QAAE,GAAG,CAAC,KAAK,GAAO,KAAK,CAAC;IACnD,IAAI,MAAM,KAAQ,SAAS;QAAE,GAAG,CAAC,MAAM,GAAM,MAAM,CAAC;IACpD,IAAI,IAAI,KAAU,SAAS;QAAE,GAAG,CAAC,IAAI,GAAQ,IAAI,CAAC;IAClD,IAAI,SAAS,KAAK,SAAS;QAAE,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;IACvD,IAAI,MAAM,KAAQ,SAAS;QAAE,GAAG,CAAC,MAAM,GAAM,MAAM,CAAC;IACpD,MAAM,SAAS,GAA4B,EAAE,GAAG,MAAM,EAAE,CAAC;IACzD,IAAI,EAAE,KAAM,SAAS;QAAE,SAAS,CAAC,EAAE,GAAI,EAAE,CAAC;IAC1C,IAAI,GAAG,KAAK,SAAS;QAAE,SAAS,CAAC,GAAG,GAAG,GAAG,CAAC;IAC3C,OAAO,EAAE,CAAC,SAAS,CAAC,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;AACjF,CAAC"}
1
+ {"version":3,"file":"filter-qs.js","sourceRoot":"","sources":["../src/filter-qs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,aAAa,CAAC,MAA+B;IAC3D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,MAAa,CAAC;IACrF,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,IAAI,KAAK,KAAS,SAAS;QAAE,GAAG,CAAC,KAAK,GAAO,KAAK,CAAC;IACnD,IAAI,MAAM,KAAQ,SAAS;QAAE,GAAG,CAAC,MAAM,GAAM,MAAM,CAAC;IACpD,IAAI,IAAI,KAAU,SAAS;QAAE,GAAG,CAAC,IAAI,GAAQ,IAAI,CAAC;IAClD,IAAI,SAAS,KAAK,SAAS;QAAE,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;IACvD,IAAI,MAAM,KAAQ,SAAS;QAAE,GAAG,CAAC,MAAM,GAAM,MAAM,CAAC;IACpD,MAAM,SAAS,GAA4B,EAAE,GAAG,MAAM,EAAE,CAAC;IACzD,IAAI,EAAE,KAAM,SAAS;QAAE,SAAS,CAAC,EAAE,GAAI,EAAE,CAAC;IAC1C,IAAI,GAAG,KAAK,SAAS;QAAE,SAAS,CAAC,GAAG,GAAG,GAAG,CAAC;IAC3C,OAAO,EAAE,CAAC,SAAS,CAAC,EAAE,GAAG,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;AACrD,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { MetaObject } from "@metaobjectsdev/metadata";
1
+ import type { MetaRead } from "./meta-read.js";
2
2
  import type { GridConfig } from "./fetcher.js";
3
3
  /** A neutral, framework-agnostic column descriptor derived from metadata. */
4
4
  export interface MetaColumn {
@@ -21,5 +21,5 @@ export interface MetaGrid {
21
21
  * Otherwise every field becomes a column with sensible defaults — so it works
22
22
  * for ANY object, with or without a declared grid.
23
23
  */
24
- export declare function buildGrid(meta: MetaObject, gridName?: string): MetaGrid;
24
+ export declare function buildGrid(meta: MetaRead, gridName?: string): MetaGrid;
25
25
  //# sourceMappingURL=grid-from-metadata.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"grid-from-metadata.d.ts","sourceRoot":"","sources":["../src/grid-from-metadata.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAuB,MAAM,0BAA0B,CAAC;AAgBhF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM/C,6EAA6E;AAC7E,MAAM,WAAW,UAAU;IACzB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAwDD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAmCvE"}
1
+ {"version":3,"file":"grid-from-metadata.d.ts","sourceRoot":"","sources":["../src/grid-from-metadata.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,QAAQ,EAA+B,MAAM,gBAAgB,CAAC;AAgB5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM/C,6EAA6E;AAC7E,MAAM,WAAW,UAAU;IACzB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAwDD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAmCrE"}
@@ -1 +1 @@
1
- {"version":3,"file":"grid-from-metadata.js","sourceRoot":"","sources":["../src/grid-from-metadata.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"grid-from-metadata.js","sourceRoot":"","sources":["../src/grid-from-metadata.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,8 @@ export type { EntityFetcher, GridConfig } from "./fetcher.js";
4
4
  export { joinBaseUrl } from "./join-base-url.js";
5
5
  export { buildGrid } from "./grid-from-metadata.js";
6
6
  export type { MetaColumn, MetaGrid } from "./grid-from-metadata.js";
7
+ export type { MetaRead, MetaFieldRead, MetaViewRead, MetaLayoutRead, MetaModelRead, AttrReader, } from "./meta-read.js";
8
+ export { loadMetaModel } from "./load-meta-model.js";
7
9
  export { canvasToJpegBlob } from "./canvas-to-jpeg-blob.js";
8
10
  export { reencodeJpeg } from "./reencode-jpeg.js";
9
11
  export type { ImageUploadAdapter, ImageMeta } from "./image-adapter.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACpE,YAAY,EACV,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,UAAU,GACjF,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ export { formatCurrency, parseCurrency, minorUnitsFor } from "./currency.js";
3
3
  export { buildFilterQs } from "./filter-qs.js";
4
4
  export { joinBaseUrl } from "./join-base-url.js";
5
5
  export { buildGrid } from "./grid-from-metadata.js";
6
+ export { loadMetaModel } from "./load-meta-model.js";
6
7
  export { canvasToJpegBlob } from "./canvas-to-jpeg-blob.js";
7
8
  export { reencodeJpeg } from "./reencode-jpeg.js";
8
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAKpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { MetaModelRead } from "./meta-read.js";
2
+ /**
3
+ * Read a `GET /_meta` document (effective canonical JSON) into a browser model.
4
+ *
5
+ * Accepts the raw response text or an already-parsed value. The document is
6
+ * assumed valid: the server loaded and validated it, and serving the EFFECTIVE
7
+ * form means every inherited member is already materialized here — so `extends`
8
+ * is deliberately never followed (see attrReaderFor).
9
+ */
10
+ export declare function loadMetaModel(json: string | unknown): MetaModelRead;
11
+ //# sourceMappingURL=load-meta-model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-meta-model.d.ts","sourceRoot":"","sources":["../src/load-meta-model.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACiC,aAAa,EACzD,MAAM,gBAAgB,CAAC;AA4GxB;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa,CAWnE"}
@@ -0,0 +1,128 @@
1
+ // UI-2 — read the `GET /_meta` document into a model buildGrid can walk.
2
+ //
3
+ // Deliberately NOT the metadata loader: that package's root barrel exports
4
+ // MetaDataLoader, which transitively imports `node:url`, so it cannot be bundled
5
+ // for a browser (#287). This is a reader over an already-validated, already-
6
+ // resolved document — no validation, no registry, no super-resolution.
7
+ //
8
+ // #287: metamodel VALUES come from the browser-safe constants subpath, never the
9
+ // package root — see grid-from-metadata.ts for the full story. The type imports
10
+ // below are fine on the root: `import type` is erased at build time.
11
+ import { TYPE_FIELD, TYPE_LAYOUT, TYPE_VIEW, TYPE_OBJECT, ATTR_PREFIX, RESERVED_KEY_NAME, RESERVED_KEY_PACKAGE, RESERVED_KEY_CHILDREN, TYPE_SUBTYPE_SEPARATOR, } from "@metaobjectsdev/metadata/constants";
12
+ function isRecord(v) {
13
+ return typeof v === "object" && v !== null && !Array.isArray(v);
14
+ }
15
+ /** A canonical node is a single-key object: { "field.string": { ... } }. */
16
+ function readNode(value) {
17
+ if (!isRecord(value))
18
+ return undefined;
19
+ const keys = Object.keys(value);
20
+ if (keys.length !== 1)
21
+ return undefined;
22
+ const fused = keys[0];
23
+ const body = value[fused];
24
+ if (!isRecord(body))
25
+ return undefined;
26
+ const sep = fused.indexOf(TYPE_SUBTYPE_SEPARATOR);
27
+ if (sep < 0)
28
+ return undefined;
29
+ return { type: fused.slice(0, sep), subType: fused.slice(sep + TYPE_SUBTYPE_SEPARATOR.length), body };
30
+ }
31
+ function childrenOf(node) {
32
+ const raw = node.body[RESERVED_KEY_CHILDREN];
33
+ if (!Array.isArray(raw))
34
+ return [];
35
+ const out = [];
36
+ for (const entry of raw) {
37
+ const child = readNode(entry);
38
+ if (child !== undefined)
39
+ out.push(child);
40
+ }
41
+ return out;
42
+ }
43
+ /**
44
+ * Attributes are the `@`-prefixed body keys, read without the prefix.
45
+ *
46
+ * Every OTHER body key — `name`, `package`, `children`, and — the trap — `extends`
47
+ * — is structural and is excluded here by construction (it never starts with
48
+ * `ATTR_PREFIX`), not by naming and skipping it. The effective document still
49
+ * carries `extends`, with the members it once referenced already inlined
50
+ * elsewhere in the body; this reader never follows it, so nothing is resolved
51
+ * and nothing is double-counted.
52
+ */
53
+ function attrReaderFor(node) {
54
+ const attrs = new Map();
55
+ for (const [key, value] of Object.entries(node.body)) {
56
+ if (key.startsWith(ATTR_PREFIX))
57
+ attrs.set(key.slice(ATTR_PREFIX.length), value);
58
+ }
59
+ return (name) => attrs.get(name);
60
+ }
61
+ function nameOf(node) {
62
+ const raw = node.body[RESERVED_KEY_NAME];
63
+ return typeof raw === "string" ? raw : "";
64
+ }
65
+ /**
66
+ * A node's OWN `package` body key, when present. Objects never inherit a file's
67
+ * default package (only certain root-level fields/validators do — see
68
+ * parser-core.ts), so this is undefined unless the node declared one itself,
69
+ * matching what `MetaData.package` reads server-side.
70
+ */
71
+ function packageOf(node) {
72
+ const raw = node.body[RESERVED_KEY_PACKAGE];
73
+ return typeof raw === "string" ? raw : undefined;
74
+ }
75
+ function toView(node) {
76
+ return { subType: node.subType, attr: attrReaderFor(node) };
77
+ }
78
+ function toField(node) {
79
+ const views = childrenOf(node).filter((c) => c.type === TYPE_VIEW).map(toView);
80
+ return {
81
+ name: nameOf(node),
82
+ subType: node.subType,
83
+ attr: attrReaderFor(node),
84
+ views: () => views,
85
+ };
86
+ }
87
+ function toLayout(node) {
88
+ return { name: nameOf(node), subType: node.subType, attr: attrReaderFor(node) };
89
+ }
90
+ function toObject(node) {
91
+ const kids = childrenOf(node);
92
+ const fields = kids.filter((c) => c.type === TYPE_FIELD).map(toField);
93
+ const layouts = kids.filter((c) => c.type === TYPE_LAYOUT).map(toLayout);
94
+ const pkg = packageOf(node);
95
+ return {
96
+ name: nameOf(node),
97
+ // Conditional spread, not `package: pkg`: exactOptionalPropertyTypes
98
+ // distinguishes "absent" from "present and undefined", and MetaRead.package
99
+ // is meant to read as absent (not `undefined`-valued) for a node with no
100
+ // own package.
101
+ ...(pkg !== undefined ? { package: pkg } : {}),
102
+ subType: node.subType,
103
+ attr: attrReaderFor(node),
104
+ fields: () => fields,
105
+ layouts: () => layouts,
106
+ };
107
+ }
108
+ /**
109
+ * Read a `GET /_meta` document (effective canonical JSON) into a browser model.
110
+ *
111
+ * Accepts the raw response text or an already-parsed value. The document is
112
+ * assumed valid: the server loaded and validated it, and serving the EFFECTIVE
113
+ * form means every inherited member is already materialized here — so `extends`
114
+ * is deliberately never followed (see attrReaderFor).
115
+ */
116
+ export function loadMetaModel(json) {
117
+ const parsed = typeof json === "string" ? JSON.parse(json) : json;
118
+ const root = readNode(parsed);
119
+ const objects = root === undefined
120
+ ? []
121
+ : childrenOf(root).filter((c) => c.type === TYPE_OBJECT).map(toObject);
122
+ const byName = new Map(objects.map((o) => [o.name, o]));
123
+ return {
124
+ objects: () => objects,
125
+ object: (name) => byName.get(name),
126
+ };
127
+ }
128
+ //# sourceMappingURL=load-meta-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-meta-model.js","sourceRoot":"","sources":["../src/load-meta-model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /** A metadata attribute reader. Returns `undefined` for an unset OR unregistered name. */
2
+ export type AttrReader = (name: string) => unknown;
3
+ export interface MetaViewRead {
4
+ readonly subType: string;
5
+ attr: AttrReader;
6
+ }
7
+ export interface MetaFieldRead {
8
+ readonly name: string;
9
+ readonly subType: string;
10
+ attr: AttrReader;
11
+ views(): MetaViewRead[];
12
+ }
13
+ export interface MetaLayoutRead {
14
+ readonly name: string;
15
+ readonly subType: string;
16
+ attr: AttrReader;
17
+ }
18
+ /** One object (entity / value / projection) as a runtime UI reads it. */
19
+ export interface MetaRead {
20
+ readonly name: string;
21
+ /**
22
+ * The node's OWN package, when declared. Undefined for a node that inherits its
23
+ * package from the declaring file's default rather than declaring one itself —
24
+ * the same "own, not resolved" reading `MetaData.package` carries server-side
25
+ * (objects never auto-inherit a file's default package; see parser-core.ts).
26
+ *
27
+ * `object(name)` and the model's `byName` lookup key on the SHORT name only, so
28
+ * two same-named objects in different packages (a shape this repo models
29
+ * deliberately — see `fixtures/conformance/xpkg-collision-*`) are NOT
30
+ * disambiguated by `object()`. A caller that might see a cross-package
31
+ * collision should walk `objects()` and filter on `package` itself.
32
+ */
33
+ readonly package?: string;
34
+ readonly subType: string;
35
+ attr: AttrReader;
36
+ fields(): MetaFieldRead[];
37
+ layouts(): MetaLayoutRead[];
38
+ }
39
+ /** The whole model, as returned by `loadMetaModel`. */
40
+ export interface MetaModelRead {
41
+ objects(): MetaRead[];
42
+ object(name: string): MetaRead | undefined;
43
+ }
44
+ //# sourceMappingURL=meta-read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta-read.d.ts","sourceRoot":"","sources":["../src/meta-read.ts"],"names":[],"mappings":"AAWA,0FAA0F;AAC1F,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;AAEnD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,IAAI,YAAY,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,yEAAyE;AACzE,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,IAAI,aAAa,EAAE,CAAC;IAC1B,OAAO,IAAI,cAAc,EAAE,CAAC;CAC7B;AAED,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,OAAO,IAAI,QAAQ,EAAE,CAAC;IACtB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;CAC5C"}
@@ -0,0 +1,12 @@
1
+ // The narrow, read-only metadata surface a runtime UI consumer needs.
2
+ //
3
+ // Declared here rather than imported from @metaobjectsdev/metadata because this
4
+ // package must satisfy it with a browser-built model too: the metadata package's
5
+ // root barrel exports MetaDataLoader, which transitively imports `node:url`, so
6
+ // it cannot be bundled for a browser (#287). A real MetaObject satisfies these
7
+ // interfaces structurally, so server-side callers are unaffected.
8
+ //
9
+ // ADR-0039: every accessor here is the RESOLVING one. `attr()` must answer with
10
+ // inherited values, and `views()`/`fields()` must include inherited members.
11
+ export {};
12
+ //# sourceMappingURL=meta-read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta-read.js","sourceRoot":"","sources":["../src/meta-read.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,gFAAgF;AAChF,iFAAiF;AACjF,gFAAgF;AAChF,+EAA+E;AAC/E,kEAAkE;AAClE,EAAE;AACF,gFAAgF;AAChF,6EAA6E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaobjectsdev/runtime-web",
3
- "version": "1.0.5-rc.1",
3
+ "version": "1.0.5-rc.10",
4
4
  "description": "Pure framework-agnostic browser core for metaobjects: currency, filter URL serialization, fetcher contract types.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -45,7 +45,7 @@
45
45
  "access": "public"
46
46
  },
47
47
  "dependencies": {
48
- "@metaobjectsdev/metadata": "1.0.5-rc.1",
48
+ "@metaobjectsdev/metadata": "1.0.5-rc.10",
49
49
  "qs": "^6.13.0"
50
50
  },
51
51
  "devDependencies": {
package/src/filter-qs.ts CHANGED
@@ -3,8 +3,14 @@ import qs from "qs";
3
3
  /**
4
4
  * Build a bracketed qs URL fragment from a filter object.
5
5
  *
6
- * Output shape (qs's default bracketed style):
7
- * ?filter[email][like]=%25@x.com&filter[subscribed]=true&sort=createdAt:desc&limit=25&withCount=1&search=term
6
+ * Output shape (qs's bracketed style), shown DECODED:
7
+ * ?filter[email][like]=%@x.com&filter[subscribed]=true&sort=createdAt:desc&limit=25&withCount=1&search=term
8
+ *
9
+ * On the wire the brackets are percent-encoded (`filter%5Bemail%5D%5Blike%5D=…`). RFC 3986
10
+ * admits no raw `[`/`]` in a query, and Tomcat — every Spring Boot app's default server —
11
+ * answers a raw one with its own HTML 400, so the generated Java and Kotlin controllers could
12
+ * not serve a single filtered request while this sent them raw. Every server-side parser
13
+ * decodes before it reads the brackets, so the encoded form means the same thing everywhere.
8
14
  *
9
15
  * Top-level `limit`, `offset`, `sort`, `withCount`, and `search` are emitted
10
16
  * at the top level (not under `filter`). All other keys go inside `filter`.
@@ -28,5 +34,5 @@ export function buildFilterQs(filter: Record<string, unknown>): string {
28
34
  const filterObj: Record<string, unknown> = { ...fields };
29
35
  if (or !== undefined) filterObj.or = or;
30
36
  if (and !== undefined) filterObj.and = and;
31
- return qs.stringify({ ...top, filter: filterObj }, { encodeValuesOnly: true });
37
+ return qs.stringify({ ...top, filter: filterObj });
32
38
  }
@@ -8,8 +8,12 @@
8
8
  // Mirrors the derivation in codegen-ts-tanstack's columns-file (humanized
9
9
  // headers, the field's view subtype as the cell-renderer hint, @columns / grid
10
10
  // attrs from the dataGrid layout) so a runtime-built grid matches a generated
11
- // one. Browser-safe: depends only on @metaobjectsdev/metadata.
12
- import type { MetaObject, MetaField, MetaView } from "@metaobjectsdev/metadata";
11
+ // one. Browser-safe: types come from the local MetaRead surface (./meta-read.js)
12
+ // below, never from @metaobjectsdev/metadata's classes, and the only values
13
+ // imported from that package come from its browser-safe /constants subpath
14
+ // (#287 — the metadata root barrel cannot be bundled). A real MetaObject
15
+ // satisfies MetaRead structurally, so server callers are unaffected.
16
+ import type { MetaRead, MetaFieldRead, MetaViewRead } from "./meta-read.js";
13
17
  // #287: metamodel VALUES come from the browser-safe constants subpath, never the package
14
18
  // root. The root exports MetaDataLoader -> library-sources.ts -> `node:url`, so a single
15
19
  // constant import from it made every browser bundle fail ("Browser polyfill for module
@@ -51,14 +55,14 @@ function humanize(s: string): string {
51
55
  return s.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/^./, (c) => c.toUpperCase());
52
56
  }
53
57
 
54
- function firstView(field: MetaField): MetaView | undefined {
58
+ function firstView(field: MetaFieldRead): MetaViewRead | undefined {
55
59
  // views(), not ownViews(): ADR-0039 — a field that `extends` an abstract parent
56
60
  // inherits the parent's view, and an own-only read drops it, so the column would
57
61
  // silently lose both its header and its renderer hint.
58
62
  return field.views()[0];
59
63
  }
60
64
 
61
- function header(field: MetaField): string {
65
+ function header(field: MetaFieldRead): string {
62
66
  // DOC_ATTR_TITLE, not the literal "label". `@label` is registered by NO provider in
63
67
  // any port — `@title` is the documentation commonAttr chartered as the display label
64
68
  // — so this read was `undefined` for every field that ever set one, and every grid
@@ -70,7 +74,7 @@ function header(field: MetaField): string {
70
74
  return typeof label === "string" ? label : humanize(field.name);
71
75
  }
72
76
 
73
- function viewKind(field: MetaField): string {
77
+ function viewKind(field: MetaFieldRead): string {
74
78
  return firstView(field)?.subType ?? field.subType;
75
79
  }
76
80
 
@@ -93,7 +97,7 @@ function viewKind(field: MetaField): string {
93
97
  */
94
98
  function gridDefaultSortOrder(
95
99
  declaredOrder: unknown,
96
- field: MetaField | undefined,
100
+ field: MetaFieldRead | undefined,
97
101
  ): "asc" | "desc" {
98
102
  if (declaredOrder === "asc" || declaredOrder === "desc") return declaredOrder;
99
103
  const fromField = field?.attr(FIELD_ATTR_SORTABLE_DEFAULT_ORDER);
@@ -108,7 +112,7 @@ function gridDefaultSortOrder(
108
112
  * Otherwise every field becomes a column with sensible defaults — so it works
109
113
  * for ANY object, with or without a declared grid.
110
114
  */
111
- export function buildGrid(meta: MetaObject, gridName?: string): MetaGrid {
115
+ export function buildGrid(meta: MetaRead, gridName?: string): MetaGrid {
112
116
  const layouts = meta.layouts().filter((l) => l.subType === LAYOUT_SUBTYPE_DATA_GRID);
113
117
  const layout = gridName ? layouts.find((l) => l.name === gridName) : layouts[0];
114
118
 
@@ -126,7 +130,7 @@ export function buildGrid(meta: MetaObject, gridName?: string): MetaGrid {
126
130
 
127
131
  const columns: MetaColumn[] = names
128
132
  .map((n) => fieldsByName.get(n))
129
- .filter((f): f is MetaField => f !== undefined)
133
+ .filter((f): f is MetaFieldRead => f !== undefined)
130
134
  .map((f) => ({ field: f.name, header: header(f), viewKind: viewKind(f) }));
131
135
 
132
136
  const pageSizeAttr = layout?.attr(LAYOUT_DATA_GRID_ATTR_PAGE_SIZE);
package/src/index.ts CHANGED
@@ -5,6 +5,10 @@ export type { EntityFetcher, GridConfig } from "./fetcher.js";
5
5
  export { joinBaseUrl } from "./join-base-url.js";
6
6
  export { buildGrid } from "./grid-from-metadata.js";
7
7
  export type { MetaColumn, MetaGrid } from "./grid-from-metadata.js";
8
+ export type {
9
+ MetaRead, MetaFieldRead, MetaViewRead, MetaLayoutRead, MetaModelRead, AttrReader,
10
+ } from "./meta-read.js";
11
+ export { loadMetaModel } from "./load-meta-model.js";
8
12
  export { canvasToJpegBlob } from "./canvas-to-jpeg-blob.js";
9
13
  export { reencodeJpeg } from "./reencode-jpeg.js";
10
14
  export type { ImageUploadAdapter, ImageMeta } from "./image-adapter.js";
@@ -0,0 +1,144 @@
1
+ // UI-2 — read the `GET /_meta` document into a model buildGrid can walk.
2
+ //
3
+ // Deliberately NOT the metadata loader: that package's root barrel exports
4
+ // MetaDataLoader, which transitively imports `node:url`, so it cannot be bundled
5
+ // for a browser (#287). This is a reader over an already-validated, already-
6
+ // resolved document — no validation, no registry, no super-resolution.
7
+ //
8
+ // #287: metamodel VALUES come from the browser-safe constants subpath, never the
9
+ // package root — see grid-from-metadata.ts for the full story. The type imports
10
+ // below are fine on the root: `import type` is erased at build time.
11
+ import {
12
+ TYPE_FIELD, TYPE_LAYOUT, TYPE_VIEW, TYPE_OBJECT,
13
+ ATTR_PREFIX, RESERVED_KEY_NAME, RESERVED_KEY_PACKAGE, RESERVED_KEY_CHILDREN, TYPE_SUBTYPE_SEPARATOR,
14
+ } from "@metaobjectsdev/metadata/constants";
15
+ import type {
16
+ AttrReader, MetaFieldRead, MetaLayoutRead, MetaModelRead, MetaRead, MetaViewRead,
17
+ } from "./meta-read.js";
18
+
19
+ /** One parsed node: its fused "type.subType" key and its body. */
20
+ interface RawNode {
21
+ type: string;
22
+ subType: string;
23
+ body: Record<string, unknown>;
24
+ }
25
+
26
+ function isRecord(v: unknown): v is Record<string, unknown> {
27
+ return typeof v === "object" && v !== null && !Array.isArray(v);
28
+ }
29
+
30
+ /** A canonical node is a single-key object: { "field.string": { ... } }. */
31
+ function readNode(value: unknown): RawNode | undefined {
32
+ if (!isRecord(value)) return undefined;
33
+ const keys = Object.keys(value);
34
+ if (keys.length !== 1) return undefined;
35
+ const fused = keys[0]!;
36
+ const body = value[fused];
37
+ if (!isRecord(body)) return undefined;
38
+ const sep = fused.indexOf(TYPE_SUBTYPE_SEPARATOR);
39
+ if (sep < 0) return undefined;
40
+ return { type: fused.slice(0, sep), subType: fused.slice(sep + TYPE_SUBTYPE_SEPARATOR.length), body };
41
+ }
42
+
43
+ function childrenOf(node: RawNode): RawNode[] {
44
+ const raw = node.body[RESERVED_KEY_CHILDREN];
45
+ if (!Array.isArray(raw)) return [];
46
+ const out: RawNode[] = [];
47
+ for (const entry of raw) {
48
+ const child = readNode(entry);
49
+ if (child !== undefined) out.push(child);
50
+ }
51
+ return out;
52
+ }
53
+
54
+ /**
55
+ * Attributes are the `@`-prefixed body keys, read without the prefix.
56
+ *
57
+ * Every OTHER body key — `name`, `package`, `children`, and — the trap — `extends`
58
+ * — is structural and is excluded here by construction (it never starts with
59
+ * `ATTR_PREFIX`), not by naming and skipping it. The effective document still
60
+ * carries `extends`, with the members it once referenced already inlined
61
+ * elsewhere in the body; this reader never follows it, so nothing is resolved
62
+ * and nothing is double-counted.
63
+ */
64
+ function attrReaderFor(node: RawNode): AttrReader {
65
+ const attrs = new Map<string, unknown>();
66
+ for (const [key, value] of Object.entries(node.body)) {
67
+ if (key.startsWith(ATTR_PREFIX)) attrs.set(key.slice(ATTR_PREFIX.length), value);
68
+ }
69
+ return (name: string) => attrs.get(name);
70
+ }
71
+
72
+ function nameOf(node: RawNode): string {
73
+ const raw = node.body[RESERVED_KEY_NAME];
74
+ return typeof raw === "string" ? raw : "";
75
+ }
76
+
77
+ /**
78
+ * A node's OWN `package` body key, when present. Objects never inherit a file's
79
+ * default package (only certain root-level fields/validators do — see
80
+ * parser-core.ts), so this is undefined unless the node declared one itself,
81
+ * matching what `MetaData.package` reads server-side.
82
+ */
83
+ function packageOf(node: RawNode): string | undefined {
84
+ const raw = node.body[RESERVED_KEY_PACKAGE];
85
+ return typeof raw === "string" ? raw : undefined;
86
+ }
87
+
88
+ function toView(node: RawNode): MetaViewRead {
89
+ return { subType: node.subType, attr: attrReaderFor(node) };
90
+ }
91
+
92
+ function toField(node: RawNode): MetaFieldRead {
93
+ const views = childrenOf(node).filter((c) => c.type === TYPE_VIEW).map(toView);
94
+ return {
95
+ name: nameOf(node),
96
+ subType: node.subType,
97
+ attr: attrReaderFor(node),
98
+ views: () => views,
99
+ };
100
+ }
101
+
102
+ function toLayout(node: RawNode): MetaLayoutRead {
103
+ return { name: nameOf(node), subType: node.subType, attr: attrReaderFor(node) };
104
+ }
105
+
106
+ function toObject(node: RawNode): MetaRead {
107
+ const kids = childrenOf(node);
108
+ const fields = kids.filter((c) => c.type === TYPE_FIELD).map(toField);
109
+ const layouts = kids.filter((c) => c.type === TYPE_LAYOUT).map(toLayout);
110
+ const pkg = packageOf(node);
111
+ return {
112
+ name: nameOf(node),
113
+ // Conditional spread, not `package: pkg`: exactOptionalPropertyTypes
114
+ // distinguishes "absent" from "present and undefined", and MetaRead.package
115
+ // is meant to read as absent (not `undefined`-valued) for a node with no
116
+ // own package.
117
+ ...(pkg !== undefined ? { package: pkg } : {}),
118
+ subType: node.subType,
119
+ attr: attrReaderFor(node),
120
+ fields: () => fields,
121
+ layouts: () => layouts,
122
+ };
123
+ }
124
+
125
+ /**
126
+ * Read a `GET /_meta` document (effective canonical JSON) into a browser model.
127
+ *
128
+ * Accepts the raw response text or an already-parsed value. The document is
129
+ * assumed valid: the server loaded and validated it, and serving the EFFECTIVE
130
+ * form means every inherited member is already materialized here — so `extends`
131
+ * is deliberately never followed (see attrReaderFor).
132
+ */
133
+ export function loadMetaModel(json: string | unknown): MetaModelRead {
134
+ const parsed: unknown = typeof json === "string" ? JSON.parse(json) : json;
135
+ const root = readNode(parsed);
136
+ const objects = root === undefined
137
+ ? []
138
+ : childrenOf(root).filter((c) => c.type === TYPE_OBJECT).map(toObject);
139
+ const byName = new Map(objects.map((o) => [o.name, o] as const));
140
+ return {
141
+ objects: () => objects,
142
+ object: (name: string) => byName.get(name),
143
+ };
144
+ }
@@ -0,0 +1,59 @@
1
+ // The narrow, read-only metadata surface a runtime UI consumer needs.
2
+ //
3
+ // Declared here rather than imported from @metaobjectsdev/metadata because this
4
+ // package must satisfy it with a browser-built model too: the metadata package's
5
+ // root barrel exports MetaDataLoader, which transitively imports `node:url`, so
6
+ // it cannot be bundled for a browser (#287). A real MetaObject satisfies these
7
+ // interfaces structurally, so server-side callers are unaffected.
8
+ //
9
+ // ADR-0039: every accessor here is the RESOLVING one. `attr()` must answer with
10
+ // inherited values, and `views()`/`fields()` must include inherited members.
11
+
12
+ /** A metadata attribute reader. Returns `undefined` for an unset OR unregistered name. */
13
+ export type AttrReader = (name: string) => unknown;
14
+
15
+ export interface MetaViewRead {
16
+ readonly subType: string;
17
+ attr: AttrReader;
18
+ }
19
+
20
+ export interface MetaFieldRead {
21
+ readonly name: string;
22
+ readonly subType: string;
23
+ attr: AttrReader;
24
+ views(): MetaViewRead[];
25
+ }
26
+
27
+ export interface MetaLayoutRead {
28
+ readonly name: string;
29
+ readonly subType: string;
30
+ attr: AttrReader;
31
+ }
32
+
33
+ /** One object (entity / value / projection) as a runtime UI reads it. */
34
+ export interface MetaRead {
35
+ readonly name: string;
36
+ /**
37
+ * The node's OWN package, when declared. Undefined for a node that inherits its
38
+ * package from the declaring file's default rather than declaring one itself —
39
+ * the same "own, not resolved" reading `MetaData.package` carries server-side
40
+ * (objects never auto-inherit a file's default package; see parser-core.ts).
41
+ *
42
+ * `object(name)` and the model's `byName` lookup key on the SHORT name only, so
43
+ * two same-named objects in different packages (a shape this repo models
44
+ * deliberately — see `fixtures/conformance/xpkg-collision-*`) are NOT
45
+ * disambiguated by `object()`. A caller that might see a cross-package
46
+ * collision should walk `objects()` and filter on `package` itself.
47
+ */
48
+ readonly package?: string;
49
+ readonly subType: string;
50
+ attr: AttrReader;
51
+ fields(): MetaFieldRead[];
52
+ layouts(): MetaLayoutRead[];
53
+ }
54
+
55
+ /** The whole model, as returned by `loadMetaModel`. */
56
+ export interface MetaModelRead {
57
+ objects(): MetaRead[];
58
+ object(name: string): MetaRead | undefined;
59
+ }