@chelone/core 0.6.0 → 0.7.0

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.
Files changed (242) hide show
  1. package/dist/assistant/assistant-session.d.ts +6 -0
  2. package/dist/assistant/assistant-session.js +204 -181
  3. package/dist/assistant/echo-transport.js +26 -29
  4. package/dist/assistant/http-transport.d.ts +10 -0
  5. package/dist/assistant/http-transport.js +98 -0
  6. package/dist/assistant/types.d.ts +1 -7
  7. package/dist/auth/access-control.d.ts +13 -5
  8. package/dist/auth/access-control.js +25 -21
  9. package/dist/auth/auth-options.d.ts +21 -17
  10. package/dist/auth/auth-options.js +80 -48
  11. package/dist/auth/permission-matrix.d.ts +12 -0
  12. package/dist/auth/permission-matrix.js +67 -0
  13. package/dist/auth/types.d.ts +14 -4
  14. package/dist/block-editor/block-document.d.ts +60 -0
  15. package/dist/block-editor/block-document.js +143 -0
  16. package/dist/block-editor/data-blocks.d.ts +63 -0
  17. package/dist/block-editor/data-blocks.js +117 -0
  18. package/dist/chart/chart-data.js +46 -44
  19. package/dist/command-menu/hotkey.js +58 -47
  20. package/dist/command-menu/recents.js +8 -11
  21. package/dist/command-menu/registry.d.ts +9 -5
  22. package/dist/command-menu/registry.js +36 -46
  23. package/dist/controller/calendar-dates.js +82 -113
  24. package/dist/controller/calendar-events.js +93 -88
  25. package/dist/controller/client-list-controller.d.ts +2 -2
  26. package/dist/controller/client-list-controller.js +251 -254
  27. package/dist/controller/data-table-columns.d.ts +2 -0
  28. package/dist/controller/data-table-columns.js +50 -56
  29. package/dist/controller/deep-equal.d.ts +1 -0
  30. package/dist/controller/deep-equal.js +14 -0
  31. package/dist/controller/filter-toggle.js +36 -44
  32. package/dist/controller/in-place-editor.d.ts +42 -0
  33. package/dist/controller/in-place-editor.js +42 -0
  34. package/dist/controller/infinite-list-controller.js +219 -189
  35. package/dist/controller/inspector.d.ts +49 -0
  36. package/dist/controller/inspector.js +64 -0
  37. package/dist/controller/job-monitor.d.ts +3 -4
  38. package/dist/controller/job-monitor.js +37 -47
  39. package/dist/controller/kanban-board.d.ts +2 -3
  40. package/dist/controller/kanban-board.js +43 -24
  41. package/dist/controller/list-controller.d.ts +5 -5
  42. package/dist/controller/list-controller.js +444 -400
  43. package/dist/controller/list-params.js +96 -87
  44. package/dist/controller/pivot-grid.js +89 -95
  45. package/dist/controller/prev-next.d.ts +2 -2
  46. package/dist/controller/prev-next.js +74 -54
  47. package/dist/controller/record-controllers.d.ts +14 -6
  48. package/dist/controller/record-controllers.js +288 -257
  49. package/dist/controller/record-diff.d.ts +21 -0
  50. package/dist/controller/record-diff.js +50 -0
  51. package/dist/controller/record-timeline.js +42 -30
  52. package/dist/controller/record-tree.js +57 -47
  53. package/dist/controller/record-workflow.d.ts +38 -16
  54. package/dist/controller/record-workflow.js +85 -64
  55. package/dist/controller/reference-many-controller.js +198 -192
  56. package/dist/controller/reference-one-controller.d.ts +1 -1
  57. package/dist/controller/reference-one-controller.js +63 -56
  58. package/dist/controller/saved-queries.js +104 -91
  59. package/dist/controller/translate-fallback.js +10 -6
  60. package/dist/csv/export.d.ts +2 -1
  61. package/dist/csv/export.js +43 -40
  62. package/dist/csv/import-controller.js +185 -169
  63. package/dist/csv/match-headers.js +29 -22
  64. package/dist/csv/parse-with.js +60 -54
  65. package/dist/csv/run-import.js +69 -72
  66. package/dist/csv/validate-rows.d.ts +1 -1
  67. package/dist/csv/validate-rows.js +65 -52
  68. package/dist/data/cache-ops.d.ts +5 -4
  69. package/dist/data/cache-ops.js +208 -188
  70. package/dist/data/combine-data-providers.js +25 -23
  71. package/dist/data/data-provider-log.d.ts +45 -0
  72. package/dist/data/data-provider-log.js +93 -0
  73. package/dist/data/errors.js +14 -10
  74. package/dist/data/fake-provider.d.ts +6 -3
  75. package/dist/data/fake-provider.js +129 -114
  76. package/dist/data/fetch-utils.js +61 -44
  77. package/dist/data/filter-branch.d.ts +5 -0
  78. package/dist/data/filter-branch.js +10 -0
  79. package/dist/data/get-many-aggregate.js +84 -76
  80. package/dist/data/http-error.js +17 -12
  81. package/dist/data/keys.js +50 -36
  82. package/dist/data/mutation-options.d.ts +14 -9
  83. package/dist/data/mutation-options.js +93 -109
  84. package/dist/data/query-options.js +73 -68
  85. package/dist/data/remove-empty.d.ts +3 -0
  86. package/dist/data/remove-empty.js +11 -0
  87. package/dist/data/undoable.d.ts +2 -2
  88. package/dist/data/undoable.js +190 -174
  89. package/dist/data/with-lifecycle-callbacks.d.ts +45 -17
  90. package/dist/data/with-lifecycle-callbacks.js +66 -52
  91. package/dist/environment/application-update-store.js +58 -55
  92. package/dist/environment/offline-store.js +21 -21
  93. package/dist/form/array-binding.d.ts +30 -11
  94. package/dist/form/array-binding.js +184 -166
  95. package/dist/form/choice-ids.d.ts +7 -0
  96. package/dist/form/choice-ids.js +11 -0
  97. package/dist/form/choices-controller.d.ts +3 -2
  98. package/dist/form/choices-controller.js +302 -275
  99. package/dist/form/date-format.d.ts +38 -0
  100. package/dist/form/date-format.js +89 -0
  101. package/dist/form/dirty-values.d.ts +2 -2
  102. package/dist/form/dirty-values.js +22 -11
  103. package/dist/form/duration.d.ts +22 -0
  104. package/dist/form/duration.js +49 -0
  105. package/dist/form/edit-create-form.d.ts +12 -5
  106. package/dist/form/edit-create-form.js +243 -188
  107. package/dist/form/event-value.d.ts +6 -0
  108. package/dist/form/event-value.js +17 -0
  109. package/dist/form/field-error.d.ts +14 -0
  110. package/dist/form/field-error.js +28 -0
  111. package/dist/form/field-name.d.ts +20 -0
  112. package/dist/form/field-name.js +6 -0
  113. package/dist/form/filter-form-values.js +63 -49
  114. package/dist/form/form-controller.d.ts +9 -1
  115. package/dist/form/form-controller.js +165 -160
  116. package/dist/form/form-groups.d.ts +4 -3
  117. package/dist/form/form-groups.js +79 -79
  118. package/dist/form/form-handle.d.ts +175 -0
  119. package/dist/form/form-handle.js +68 -0
  120. package/dist/form/input-binding.d.ts +56 -31
  121. package/dist/form/input-binding.js +169 -118
  122. package/dist/form/input-values.d.ts +130 -0
  123. package/dist/form/input-values.js +177 -0
  124. package/dist/form/json-text.js +51 -37
  125. package/dist/form/save-pipeline.d.ts +6 -8
  126. package/dist/form/save-pipeline.js +91 -82
  127. package/dist/form/set-form-values.d.ts +6 -0
  128. package/dist/form/set-form-values.js +10 -0
  129. package/dist/form/source.js +97 -65
  130. package/dist/form/text-of.d.ts +2 -0
  131. package/dist/form/text-of.js +7 -0
  132. package/dist/form/validators.d.ts +58 -19
  133. package/dist/form/validators.js +97 -71
  134. package/dist/geo/bbox.d.ts +5 -4
  135. package/dist/geo/bbox.js +69 -48
  136. package/dist/geo/bounds.d.ts +14 -3
  137. package/dist/geo/bounds.js +98 -68
  138. package/dist/geo/constraints.js +88 -93
  139. package/dist/geo/coordinates.js +31 -23
  140. package/dist/geo/editor.d.ts +13 -13
  141. package/dist/geo/editor.js +176 -153
  142. package/dist/geo/geocoding.d.ts +4 -4
  143. package/dist/geo/geocoding.js +38 -41
  144. package/dist/geo/geojson.d.ts +12 -74
  145. package/dist/geo/geojson.js +52 -40
  146. package/dist/geo/geometry-math.d.ts +4 -4
  147. package/dist/geo/geometry-math.js +100 -93
  148. package/dist/geo/index.d.ts +7 -6
  149. package/dist/geo/map-layers.d.ts +42 -7
  150. package/dist/geo/map-layers.js +88 -62
  151. package/dist/geo/map-style.js +31 -32
  152. package/dist/geo/messages.js +48 -45
  153. package/dist/geo/nominatim.js +88 -80
  154. package/dist/geo/osm-presets.d.ts +4 -3
  155. package/dist/geo/osm-presets.js +108 -86
  156. package/dist/geo/osm-tags.js +14 -12
  157. package/dist/geo/overpass.d.ts +14 -2
  158. package/dist/geo/overpass.js +83 -90
  159. package/dist/geo/shape-value.d.ts +9 -5
  160. package/dist/geo/shape-value.js +169 -146
  161. package/dist/geo/snap-to-roads.d.ts +3 -3
  162. package/dist/geo/snap-to-roads.js +55 -50
  163. package/dist/geo/throttle.js +36 -39
  164. package/dist/guards.d.ts +37 -0
  165. package/dist/guards.js +62 -0
  166. package/dist/i18n/default-messages.js +34 -29
  167. package/dist/i18n/english-messages.js +187 -189
  168. package/dist/i18n/i18n.d.ts +2 -2
  169. package/dist/i18n/i18n.js +47 -60
  170. package/dist/i18n/inflection.d.ts +34 -0
  171. package/dist/i18n/inflection.js +82 -0
  172. package/dist/i18n/messages.d.ts +10 -2
  173. package/dist/i18n/messages.js +17 -4
  174. package/dist/i18n/missing-keys.js +66 -62
  175. package/dist/i18n/translatable.d.ts +16 -1
  176. package/dist/i18n/translatable.js +40 -47
  177. package/dist/index.d.ts +71 -24
  178. package/dist/index.js +40 -288
  179. package/dist/json/deep-equal.d.ts +8 -0
  180. package/dist/json/deep-equal.js +24 -0
  181. package/dist/json/strip-json-comments.js +38 -42
  182. package/dist/noop.d.ts +2 -0
  183. package/dist/noop.js +4 -0
  184. package/dist/notification/error-message.d.ts +2 -0
  185. package/dist/notification/error-message.js +10 -0
  186. package/dist/notification/notification-store.d.ts +3 -2
  187. package/dist/notification/notification-store.js +41 -45
  188. package/dist/onboarding-tour/placement.js +63 -78
  189. package/dist/onboarding-tour/tour-controller.js +46 -54
  190. package/dist/realtime/add-events-for-mutations.js +75 -81
  191. package/dist/realtime/announce-lock.js +16 -13
  192. package/dist/realtime/broadcast-channel-transport.js +65 -59
  193. package/dist/realtime/copy-members.js +22 -14
  194. package/dist/realtime/in-memory-lock-provider.js +40 -48
  195. package/dist/realtime/live.js +95 -101
  196. package/dist/realtime/lock-options.js +16 -16
  197. package/dist/realtime/lock-session.js +91 -78
  198. package/dist/realtime/memory-transport.js +25 -25
  199. package/dist/realtime/presence.js +120 -122
  200. package/dist/realtime/realtime-data-provider.d.ts +10 -0
  201. package/dist/realtime/realtime-data-provider.js +45 -42
  202. package/dist/realtime/reconnect-backoff.js +17 -0
  203. package/dist/realtime/sse-transport.d.ts +31 -0
  204. package/dist/realtime/sse-transport.js +235 -0
  205. package/dist/realtime/status-store.js +23 -28
  206. package/dist/realtime/topic-hub.js +62 -71
  207. package/dist/realtime/topics.js +10 -12
  208. package/dist/realtime/types.js +10 -12
  209. package/dist/realtime/unread-count.js +21 -21
  210. package/dist/realtime/websocket-transport.d.ts +32 -0
  211. package/dist/realtime/websocket-transport.js +306 -0
  212. package/dist/resource/describe-resource.d.ts +2 -0
  213. package/dist/resource/describe-resource.js +232 -219
  214. package/dist/resource/get-at-path.js +29 -14
  215. package/dist/resource/identifier.d.ts +18 -0
  216. package/dist/resource/identifier.js +27 -0
  217. package/dist/resource/record.d.ts +4 -0
  218. package/dist/resource/record.js +10 -0
  219. package/dist/resource/register.d.ts +7 -0
  220. package/dist/resource/registry-store.d.ts +45 -15
  221. package/dist/resource/registry-store.js +67 -60
  222. package/dist/resource/registry.d.ts +10 -0
  223. package/dist/resource/registry.js +8 -4
  224. package/dist/resource/source-path.d.ts +16 -1
  225. package/dist/rich-text/rich-text-extras.d.ts +132 -0
  226. package/dist/rich-text/rich-text-extras.js +179 -0
  227. package/dist/rich-text/rich-text-image.d.ts +124 -0
  228. package/dist/rich-text/rich-text-image.js +163 -0
  229. package/dist/rich-text/rich-text.d.ts +6 -0
  230. package/dist/rich-text/rich-text.js +125 -88
  231. package/dist/router/location.d.ts +22 -4
  232. package/dist/router/location.js +41 -18
  233. package/dist/router/match.js +47 -39
  234. package/dist/router/paths.js +40 -34
  235. package/dist/router/record-from-location.d.ts +1 -1
  236. package/dist/router/record-from-location.js +25 -17
  237. package/dist/store/adapters.js +51 -55
  238. package/dist/store/micro-store.js +57 -59
  239. package/dist/store/shallow-equal.d.ts +12 -0
  240. package/dist/store/shallow-equal.js +20 -0
  241. package/dist/store/store.js +54 -57
  242. package/package.json +13 -11
@@ -1,246 +1,259 @@
1
- const bagOf = (value) => typeof value === "object" && value !== null ? value : void 0;
2
- const stripZod = (typeName) => typeName.replace(/^Zod/, "").toLowerCase();
3
- const formatsOf = (checks, format) => {
4
- const formats = /* @__PURE__ */ new Set();
5
- if (typeof format === "string") formats.add(format);
6
- if (Array.isArray(checks)) {
7
- for (const check of checks) {
8
- const legacy = bagOf(check)?.kind;
9
- const modern = bagOf(bagOf(bagOf(check)?._zod)?.def)?.format;
10
- for (const found of [legacy, modern]) {
11
- if (typeof found === "string") formats.add(found);
12
- }
13
- }
14
- }
15
- return formats;
1
+ // src/resource/describe-resource.ts
2
+ var bagOf = (value) => typeof value === "object" && value !== null ? value : void 0;
3
+ var stripZod = (typeName) => typeName.replace(/^Zod/, "").toLowerCase();
4
+ var formatsOf = (checks, format) => {
5
+ const formats = /* @__PURE__ */ new Set();
6
+ if (typeof format === "string") formats.add(format);
7
+ if (Array.isArray(checks)) for (const check of checks) {
8
+ const legacy = bagOf(check)?.kind;
9
+ const modern = bagOf(bagOf(bagOf(check)?._zod)?.def)?.format;
10
+ for (const found of [legacy, modern]) if (typeof found === "string") formats.add(found);
11
+ }
12
+ return formats;
16
13
  };
17
14
  function readZod3(def) {
18
- const typeName = typeof def.typeName === "string" ? def.typeName : "";
19
- const node = {
20
- type: stripZod(typeName),
21
- formats: formatsOf(def.checks, void 0)
22
- };
23
- switch (typeName) {
24
- case "ZodOptional":
25
- case "ZodNullable":
26
- case "ZodDefault":
27
- case "ZodCatch":
28
- case "ZodReadonly":
29
- node.inner = def.innerType;
30
- break;
31
- case "ZodBranded":
32
- node.inner = def.type;
33
- break;
34
- case "ZodEffects":
35
- node.inner = def.schema;
36
- break;
37
- case "ZodPipeline":
38
- node.inner = def.in;
39
- break;
40
- case "ZodEnum":
41
- node.entries = Object.fromEntries(
42
- def.values.map((value) => [value, value])
43
- );
44
- break;
45
- case "ZodNativeEnum":
46
- node.type = "enum";
47
- node.entries = def.values;
48
- break;
49
- case "ZodUnion":
50
- node.options = def.options;
51
- break;
52
- case "ZodLiteral":
53
- node.value = def.value;
54
- break;
55
- case "ZodArray":
56
- node.element = def.type;
57
- break;
58
- case "ZodObject":
59
- if (typeof def.shape === "function") {
60
- node.shape = def.shape();
61
- }
62
- break;
63
- }
64
- return node;
15
+ const typeName = typeof def.typeName === "string" ? def.typeName : "";
16
+ const node = {
17
+ type: stripZod(typeName),
18
+ formats: formatsOf(def.checks, void 0)
19
+ };
20
+ switch (typeName) {
21
+ case "ZodOptional":
22
+ case "ZodNullable":
23
+ case "ZodDefault":
24
+ case "ZodCatch":
25
+ case "ZodReadonly":
26
+ node.inner = def.innerType;
27
+ break;
28
+ case "ZodBranded":
29
+ node.inner = def.type;
30
+ break;
31
+ case "ZodEffects":
32
+ node.inner = def.schema;
33
+ break;
34
+ case "ZodPipeline":
35
+ node.inner = def.in;
36
+ break;
37
+ case "ZodEnum":
38
+ node.entries = Object.fromEntries(def.values.map((value) => [value, value]));
39
+ break;
40
+ case "ZodNativeEnum":
41
+ node.type = "enum";
42
+ node.entries = def.values;
43
+ break;
44
+ case "ZodUnion":
45
+ node.options = def.options;
46
+ break;
47
+ case "ZodLiteral":
48
+ node.value = def.value;
49
+ break;
50
+ case "ZodArray":
51
+ node.element = def.type;
52
+ break;
53
+ case "ZodObject": if (typeof def.shape === "function") node.shape = def.shape();
54
+ }
55
+ return node;
65
56
  }
66
57
  function readZod4(def) {
67
- const type = typeof def.type === "string" ? def.type : "";
68
- const node = {
69
- type,
70
- formats: formatsOf(def.checks, def.format)
71
- };
72
- switch (type) {
73
- case "optional":
74
- case "nullable":
75
- case "nonoptional":
76
- case "default":
77
- case "prefault":
78
- case "catch":
79
- case "readonly":
80
- node.inner = def.innerType;
81
- break;
82
- case "pipe": {
83
- const into = bagOf(bagOf(bagOf(def.in)?._zod)?.def)?.type;
84
- node.inner = into === "transform" ? def.out : def.in;
85
- break;
86
- }
87
- case "enum":
88
- node.entries = def.entries;
89
- break;
90
- case "union":
91
- node.options = def.options;
92
- break;
93
- case "literal":
94
- node.value = def.values?.[0];
95
- if (def.values?.length !== 1) {
96
- node.type = "literals";
97
- }
98
- break;
99
- case "array":
100
- node.element = def.element;
101
- break;
102
- case "object":
103
- node.shape = def.shape;
104
- break;
105
- }
106
- return node;
58
+ const type = typeof def.type === "string" ? def.type : "";
59
+ const node = {
60
+ type,
61
+ formats: formatsOf(def.checks, def.format)
62
+ };
63
+ switch (type) {
64
+ case "optional":
65
+ case "nullable":
66
+ case "nonoptional":
67
+ case "default":
68
+ case "prefault":
69
+ case "catch":
70
+ case "readonly":
71
+ node.inner = def.innerType;
72
+ break;
73
+ case "pipe":
74
+ node.inner = bagOf(bagOf(bagOf(def.in)?._zod)?.def)?.type === "transform" ? def.out : def.in;
75
+ break;
76
+ case "enum":
77
+ node.entries = def.entries;
78
+ break;
79
+ case "union":
80
+ node.options = def.options;
81
+ break;
82
+ case "literal":
83
+ node.value = def.values?.[0];
84
+ if (def.values?.length !== 1) node.type = "literals";
85
+ break;
86
+ case "array":
87
+ node.element = def.element;
88
+ break;
89
+ case "object": node.shape = def.shape;
90
+ }
91
+ return node;
107
92
  }
108
93
  function read(schema) {
109
- const zod4 = bagOf(bagOf(bagOf(schema)?._zod)?.def);
110
- if (zod4) return readZod4(zod4);
111
- const zod3 = bagOf(bagOf(schema)?._def);
112
- if (zod3) return readZod3(zod3);
113
- return { type: "unknown", formats: /* @__PURE__ */ new Set() };
94
+ const zod4 = bagOf(bagOf(bagOf(schema)?._zod)?.def);
95
+ if (zod4) return readZod4(zod4);
96
+ const zod3 = bagOf(bagOf(schema)?._def);
97
+ if (zod3) return readZod3(zod3);
98
+ return {
99
+ type: "unknown",
100
+ formats: /* @__PURE__ */ new Set()
101
+ };
114
102
  }
115
- const descriptionOf = (schema) => {
116
- const description = bagOf(schema)?.description;
117
- return typeof description === "string" ? description : void 0;
103
+ var descriptionOf = (schema) => {
104
+ const description = bagOf(schema)?.description;
105
+ return typeof description === "string" ? description : void 0;
118
106
  };
119
107
  function unwrap(schema) {
120
- let current = schema;
121
- let label;
122
- for (let depth = 0; depth < 64; depth++) {
123
- const node = read(current);
124
- label ??= descriptionOf(current);
125
- if (node.inner === void 0) return { node, label };
126
- current = node.inner;
127
- }
128
- return { node: read(current), label };
108
+ let current = schema;
109
+ let label;
110
+ for (let depth = 0; depth < 64; depth++) {
111
+ const node = read(current);
112
+ label ??= descriptionOf(current);
113
+ if (node.inner === void 0) return {
114
+ node,
115
+ label
116
+ };
117
+ current = node.inner;
118
+ }
119
+ return {
120
+ node: read(current),
121
+ label
122
+ };
129
123
  }
130
- const unsupported = (reason) => ({
131
- kind: "unsupported",
132
- reason
124
+ var unsupported = (reason) => ({
125
+ kind: "unsupported",
126
+ reason
133
127
  });
134
128
  function describeString({ formats }) {
135
- if (formats.has("datetime")) {
136
- return {
137
- kind: "dateTime",
138
- field: "DateField",
139
- input: "DateTimeInput",
140
- fieldProps: { showTime: true }
141
- };
142
- }
143
- if (formats.has("date")) {
144
- return { kind: "date", field: "DateField", input: "DateInput" };
145
- }
146
- if (formats.has("email")) {
147
- return { kind: "email", field: "EmailField", input: "TextInput" };
148
- }
149
- if (formats.has("url")) {
150
- return { kind: "url", field: "UrlField", input: "TextInput" };
151
- }
152
- return { kind: "text", field: "TextField", input: "TextInput" };
129
+ if (formats.has("datetime")) return {
130
+ kind: "dateTime",
131
+ field: "DateField",
132
+ input: "DateTimeInput",
133
+ fieldProps: { showTime: true }
134
+ };
135
+ if (formats.has("date")) return {
136
+ kind: "date",
137
+ field: "DateField",
138
+ input: "DateInput"
139
+ };
140
+ if (formats.has("email")) return {
141
+ kind: "email",
142
+ field: "EmailField",
143
+ input: "TextInput"
144
+ };
145
+ if (formats.has("url")) return {
146
+ kind: "url",
147
+ field: "UrlField",
148
+ input: "TextInput"
149
+ };
150
+ return {
151
+ kind: "text",
152
+ field: "TextField",
153
+ input: "TextInput"
154
+ };
153
155
  }
154
156
  function select(choices) {
155
- return {
156
- kind: "select",
157
- field: "SelectField",
158
- input: "SelectInput",
159
- choices
160
- };
157
+ return {
158
+ kind: "select",
159
+ field: "SelectField",
160
+ input: "SelectInput",
161
+ choices
162
+ };
161
163
  }
162
- const toChoices = (ids) => ids.map((id) => ({ id, name: String(id) }));
164
+ var toChoices = (ids) => ids.map((id) => ({
165
+ id,
166
+ name: String(id)
167
+ }));
163
168
  function describeEnum({ entries = {} }) {
164
- const ids = Object.keys(entries).filter((key) => typeof entries[entries[key]] !== "number").map((key) => entries[key]);
165
- return select(toChoices(ids));
169
+ const ids = [];
170
+ for (const key of Object.keys(entries)) {
171
+ const value = entries[key];
172
+ if (value === void 0 || typeof entries[value] === "number") continue;
173
+ ids.push(value);
174
+ }
175
+ return select(toChoices(ids));
166
176
  }
167
177
  function describeUnion({ options = [] }) {
168
- const ids = [];
169
- for (const option of options) {
170
- const { node: member } = unwrap(option);
171
- const value = member.value;
172
- if (member.type !== "literal" || typeof value !== "string" && typeof value !== "number") {
173
- return unsupported("union schema");
174
- }
175
- ids.push(value);
176
- }
177
- return select(toChoices(ids));
178
+ const ids = [];
179
+ for (const option of options) {
180
+ const { node: member } = unwrap(option);
181
+ const value = member.value;
182
+ if (member.type !== "literal" || typeof value !== "string" && typeof value !== "number") return unsupported("union schema");
183
+ ids.push(value);
184
+ }
185
+ return select(toChoices(ids));
178
186
  }
179
187
  function describeArray({ element }) {
180
- const member = element === void 0 ? void 0 : unwrap(element).node;
181
- if (member?.type === "string") {
182
- return {
183
- kind: "textArray",
184
- field: "TextArrayField",
185
- input: "TextArrayInput"
186
- };
187
- }
188
- if (member?.type === "object") return unsupported("array of objects");
189
- return unsupported(`array of ${member?.type ?? "unknown"}s`);
188
+ const member = element === void 0 ? void 0 : unwrap(element).node;
189
+ if (member?.type === "string") return {
190
+ kind: "textArray",
191
+ field: "TextArrayField",
192
+ input: "TextArrayInput"
193
+ };
194
+ if (member?.type === "object") return unsupported("array of objects");
195
+ return unsupported(`array of ${member?.type ?? "unknown"}s`);
190
196
  }
191
197
  function describeKind(node) {
192
- switch (node.type) {
193
- case "string":
194
- return describeString(node);
195
- case "number":
196
- return { kind: "number", field: "NumberField", input: "NumberInput" };
197
- case "boolean":
198
- return { kind: "boolean", field: "BooleanField", input: "BooleanInput" };
199
- case "date":
200
- return { kind: "date", field: "DateField", input: "DateInput" };
201
- case "enum":
202
- return describeEnum(node);
203
- case "union":
204
- return describeUnion(node);
205
- case "array":
206
- return describeArray(node);
207
- default:
208
- return unsupported(`${node.type || "unknown"} schema`);
209
- }
198
+ switch (node.type) {
199
+ case "string": return describeString(node);
200
+ case "number": return {
201
+ kind: "number",
202
+ field: "NumberField",
203
+ input: "NumberInput"
204
+ };
205
+ case "boolean": return {
206
+ kind: "boolean",
207
+ field: "BooleanField",
208
+ input: "BooleanInput"
209
+ };
210
+ case "date": return {
211
+ kind: "date",
212
+ field: "DateField",
213
+ input: "DateInput"
214
+ };
215
+ case "enum": return describeEnum(node);
216
+ case "union": return describeUnion(node);
217
+ case "array": return describeArray(node);
218
+ default: return unsupported(`${node.type || "unknown"} schema`);
219
+ }
210
220
  }
221
+ /** For core's block editor helpers; not exported from the package index. */
211
222
  function describeField(source, schema, references) {
212
- const { node, label } = unwrap(schema);
213
- const target = references && Object.hasOwn(references, source) ? references[source] : void 0;
214
- const described = target === void 0 ? describeKind(node) : node.type === "array" ? {
215
- kind: "referenceArray",
216
- field: "ReferenceArrayField",
217
- input: "ReferenceArrayInput",
218
- reference: target
219
- } : {
220
- kind: "reference",
221
- field: "ReferenceField",
222
- input: "ReferenceInput",
223
- reference: target
224
- };
225
- return {
226
- source,
227
- primary: source === "id",
228
- ...label === void 0 ? {} : { label },
229
- ...described
230
- };
223
+ const { node, label } = unwrap(schema);
224
+ const target = references && Object.hasOwn(references, source) ? references[source] : void 0;
225
+ const described = target === void 0 ? describeKind(node) : node.type === "array" ? {
226
+ kind: "referenceArray",
227
+ field: "ReferenceArrayField",
228
+ input: "ReferenceArrayInput",
229
+ reference: target
230
+ } : {
231
+ kind: "reference",
232
+ field: "ReferenceField",
233
+ input: "ReferenceInput",
234
+ reference: target
235
+ };
236
+ return {
237
+ source,
238
+ primary: source === "id",
239
+ ...label === void 0 ? {} : { label },
240
+ ...described
241
+ };
231
242
  }
243
+ /**
244
+ * Turns a resource's registered Zod schema (Zod 3 or Zod 4) into one descriptor per field, in
245
+ * schema key order. Returns `undefined` when there is no schema to read or it
246
+ * is not an object. Both adapters' guessers build their views from this, never
247
+ * from fetched values.
248
+ */
232
249
  function describeResource(resource, config) {
233
- if (!config?.schema) return void 0;
234
- const { node } = unwrap(config.schema);
235
- if (node.type !== "object" || !node.shape) return void 0;
236
- const { shape } = node;
237
- return {
238
- resource,
239
- fields: Object.keys(shape).map(
240
- (source) => describeField(source, shape[source], config.references)
241
- )
242
- };
250
+ if (!config?.schema) return void 0;
251
+ const { node } = unwrap(config.schema);
252
+ if (node.type !== "object" || !node.shape) return void 0;
253
+ const { shape } = node;
254
+ return {
255
+ resource,
256
+ fields: Object.keys(shape).map((source) => describeField(source, shape[source], config.references))
257
+ };
243
258
  }
244
- export {
245
- describeResource
246
- };
259
+ export { describeField, describeResource };
@@ -1,16 +1,31 @@
1
- const PATH_SEGMENT = /\[([^\]]*)\]|[^.[\]]+/g;
1
+ // src/resource/get-at-path.ts
2
+ /**
3
+ * The one path grammar chelone reads a record with. Dot members (`a.b`),
4
+ * bracket indices (`a[0].b`) and numeric-dot indices (`a.0.b`) all resolve to
5
+ * the same value, matching `lodash/get`'s relevant semantics.
6
+ *
7
+ * The core tree, calendar and client-list readers read through this, and so do
8
+ * both adapters' `useFieldValue` and `useGetRecordRepresentation`: a `source`
9
+ * written one way reads the same record everywhere, and one walker is left.
10
+ */
11
+ /** Matches a `[index]` bracket group or a run of non-`.` / non-`[` characters. */
12
+ var PATH_SEGMENT = /\[([^\]]*)\]|[^.[\]]+/g;
13
+ /**
14
+ * Read the value at `source` off `record`. An empty `source` returns the record
15
+ * itself; a step that is null, undefined or a primitive returns `undefined`.
16
+ *
17
+ * An own key equal to the whole `source` wins before any split, as in
18
+ * `lodash/get`: a record that literally holds a `"nested.level"` key — a
19
+ * flattened filter payload, for instance — still reads.
20
+ */
2
21
  function getAtPath(record, source) {
3
- if (source === "") return record;
4
- if (record !== null && typeof record === "object" && Object.hasOwn(record, source)) {
5
- return record[source];
6
- }
7
- let current = record;
8
- for (const match of source.matchAll(PATH_SEGMENT)) {
9
- if (current === null || typeof current !== "object") return void 0;
10
- current = current[match[1] !== void 0 ? match[1] : match[0]];
11
- }
12
- return current;
22
+ if (source === "") return record;
23
+ if (record !== null && typeof record === "object" && Object.hasOwn(record, source)) return record[source];
24
+ let current = record;
25
+ for (const match of source.matchAll(PATH_SEGMENT)) {
26
+ if (current === null || typeof current !== "object") return void 0;
27
+ current = current[match[1] !== void 0 ? match[1] : match[0]];
28
+ }
29
+ return current;
13
30
  }
14
- export {
15
- getAtPath
16
- };
31
+ export { getAtPath };
@@ -1 +1,19 @@
1
1
  export type Identifier = string | number;
2
+ /**
3
+ * True for the value a record id or foreign key holds: a `string` or a `number`.
4
+ * The check for a value read out of a record at a `source`, where the record's
5
+ * own type does not pin the field.
6
+ */
7
+ export declare function isIdentifier(value: unknown): value is Identifier;
8
+ /**
9
+ * True for an array whose every member is an {@link Identifier}: the shape a
10
+ * to-many foreign key holds on a record.
11
+ */
12
+ export declare function isIdentifierArray(value: unknown): value is Identifier[];
13
+ /**
14
+ * The ids a to-many foreign key holds. An array that is all ids is returned as
15
+ * it is; one with a member that is not an id keeps its id members, because a
16
+ * nullable `int[]` reads as nulls between real ids and dropping the whole array
17
+ * would hide records the record has. Anything that is not an array is no ids.
18
+ */
19
+ export declare function identifiersOf(value: unknown): Identifier[];
@@ -0,0 +1,27 @@
1
+ // src/resource/identifier.ts
2
+ /**
3
+ * True for the value a record id or foreign key holds: a `string` or a `number`.
4
+ * The check for a value read out of a record at a `source`, where the record's
5
+ * own type does not pin the field.
6
+ */
7
+ function isIdentifier(value) {
8
+ return typeof value === "string" || typeof value === "number";
9
+ }
10
+ /**
11
+ * True for an array whose every member is an {@link Identifier}: the shape a
12
+ * to-many foreign key holds on a record.
13
+ */
14
+ function isIdentifierArray(value) {
15
+ return Array.isArray(value) && value.every(isIdentifier);
16
+ }
17
+ /**
18
+ * The ids a to-many foreign key holds. An array that is all ids is returned as
19
+ * it is; one with a member that is not an id keeps its id members, because a
20
+ * nullable `int[]` reads as nulls between real ids and dropping the whole array
21
+ * would hide records the record has. Anything that is not an array is no ids.
22
+ */
23
+ function identifiersOf(value) {
24
+ if (isIdentifierArray(value)) return value;
25
+ return Array.isArray(value) ? value.filter(isIdentifier) : [];
26
+ }
27
+ export { identifiersOf, isIdentifier, isIdentifierArray };
@@ -7,3 +7,7 @@ export interface ResourceRecord<TId extends Identifier = Identifier> {
7
7
  export type LooseRecord = ResourceRecord & {
8
8
  [key: string]: unknown;
9
9
  };
10
+ /** True for a value shaped like a record: a non-null, non-array object with an `id`. The check for a value that reaches a hook typed `unknown`. */
11
+ export declare function isResourceRecord(value: unknown): value is ResourceRecord;
12
+ /** True for a non-null, non-array object: the shape a record has once it reaches a data provider. */
13
+ export declare function isLooseRecord<T extends ResourceRecord>(value: T): value is T & LooseRecord;
@@ -0,0 +1,10 @@
1
+ // src/resource/record.ts
2
+ /** True for a value shaped like a record: a non-null, non-array object with an `id`. The check for a value that reaches a hook typed `unknown`. */
3
+ function isResourceRecord(value) {
4
+ return typeof value === "object" && value !== null && !Array.isArray(value) && "id" in value;
5
+ }
6
+ /** True for a non-null, non-array object: the shape a record has once it reaches a data provider. */
7
+ function isLooseRecord(value) {
8
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9
+ }
10
+ export { isLooseRecord, isResourceRecord };
@@ -20,6 +20,13 @@ export interface Register {
20
20
  export type RegisteredResources = Register extends {
21
21
  resources: infer TResources extends ResourceMap;
22
22
  } ? TResources : ResourceMap;
23
+ /**
24
+ * The registered permissions type, or `unknown` when nothing is registered.
25
+ * An app registers it with `interface Register { permissions: string[] }`.
26
+ */
27
+ export type RegisteredPermissions = Register extends {
28
+ permissions: infer TPermissions;
29
+ } ? TPermissions : unknown;
23
30
  /** The registered resource names, or `string` when nothing is registered. */
24
31
  export type RegisteredResourceName = keyof RegisteredResources & string;
25
32
  /** The record type of a registered resource, or {@link LooseRecord} when it has no schema. */