@stonecrop/schema 0.17.0 → 0.19.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.
- package/dist/cli.js +1 -1
- package/dist/index.js +43 -39
- package/dist/schema.d.ts +56 -0
- package/dist/src/doctype.d.ts +11 -0
- package/dist/src/doctype.d.ts.map +1 -1
- package/dist/src/doctype.js +34 -1
- package/dist/src/field.d.ts +41 -0
- package/dist/src/field.d.ts.map +1 -1
- package/dist/src/field.js +56 -0
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/{validation-C25HJXWs.js → validation-1DGAGmuU.js} +205 -173
- package/dist/validation-1DGAGmuU.js.map +1 -0
- package/package.json +1 -1
- package/dist/validation-C25HJXWs.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import { readFileSync as c, existsSync as v, mkdirSync as O, writeFileSync as k
|
|
|
3
3
|
import { resolve as d, join as C } from "node:path";
|
|
4
4
|
import { parseArgs as P } from "node:util";
|
|
5
5
|
import { getIntrospectionQuery as j } from "graphql";
|
|
6
|
-
import { c as E, m as J, f as L, v as R } from "./validation-
|
|
6
|
+
import { c as E, m as J, f as L, v as R } from "./validation-1DGAGmuU.js";
|
|
7
7
|
async function q(e, f) {
|
|
8
8
|
const o = await fetch(e, {
|
|
9
9
|
method: "POST",
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as c, D as A, F as p, G as y, I as u, a as S, L as T, T as m, b as F, d as I, V as D, W as L, e as N, g as C, h as f, i as O, j as k, k as E, c as b, l as x, n as _, o as g, f as P, p as R, q as h, r as M, s as v, t as w, u as K, m as W, w as G, x as j, y as Q, z as V, B as Y, C as q, E as z, H as X, v as B, J as H } from "./validation-1DGAGmuU.js";
|
|
2
2
|
const a = {
|
|
3
3
|
ATextInput: "text",
|
|
4
4
|
ATextboxInput: "text",
|
|
@@ -17,7 +17,7 @@ const a = {
|
|
|
17
17
|
AQuantityInput: "quantity",
|
|
18
18
|
ACurrencyInput: "currency"
|
|
19
19
|
};
|
|
20
|
-
function
|
|
20
|
+
function s(e) {
|
|
21
21
|
return e ? a[e] : void 0;
|
|
22
22
|
}
|
|
23
23
|
const t = {
|
|
@@ -28,54 +28,58 @@ const t = {
|
|
|
28
28
|
function i(e) {
|
|
29
29
|
return e ? t[e] : void 0;
|
|
30
30
|
}
|
|
31
|
-
function
|
|
31
|
+
function o(e, n) {
|
|
32
32
|
return i(e.component ?? n) === "inline" ? "inline" : e.cardinality === "noneOrMany" || e.cardinality === "atLeastOne" ? "table" : "record";
|
|
33
33
|
}
|
|
34
|
-
const
|
|
34
|
+
const l = [
|
|
35
35
|
.../* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(t)])
|
|
36
36
|
].toSorted();
|
|
37
37
|
export {
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
c as ActionDefinition,
|
|
39
|
+
l as CANONICAL_COMPONENTS,
|
|
40
40
|
a as COMPONENT_CATEGORY,
|
|
41
41
|
t as COMPONENT_LINK_EXPANSION,
|
|
42
42
|
A as DoctypeFieldSchema,
|
|
43
43
|
p as FieldsetFieldSchema,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
y as GQL_SCALAR_MAP,
|
|
45
|
+
u as INTERNAL_SCALARS,
|
|
46
|
+
S as INTROSPECTED_IDENTITY_PROPS,
|
|
47
|
+
T as LINK_DISPLAY_SUFFIX,
|
|
47
48
|
m as TableFieldSchema,
|
|
48
|
-
|
|
49
|
+
F as TableViewConfig,
|
|
49
50
|
I as TriggerDefinition,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
D as ValueFieldSchema,
|
|
52
|
+
L as WELL_KNOWN_SCALARS,
|
|
53
|
+
N as WorkflowLayout,
|
|
54
|
+
C as WorkflowMeta,
|
|
55
|
+
f as buildScalarMap,
|
|
56
|
+
O as camelToLabel,
|
|
57
|
+
k as camelToSnake,
|
|
58
|
+
E as classifyFieldType,
|
|
59
|
+
s as componentCategory,
|
|
59
60
|
i as componentLinkExpansion,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
g as
|
|
64
|
-
P as
|
|
65
|
-
R as
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
W as
|
|
72
|
-
G as
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
q as
|
|
79
|
-
z as
|
|
61
|
+
b as convertGraphQLSchema,
|
|
62
|
+
x as defaultIsEntityField,
|
|
63
|
+
_ as defaultIsEntityType,
|
|
64
|
+
g as flattenFields,
|
|
65
|
+
P as formatDoctypeDrift,
|
|
66
|
+
R as getDisplayField,
|
|
67
|
+
h as getPrimaryKeyField,
|
|
68
|
+
M as getRecordIdField,
|
|
69
|
+
v as getRecordIdentity,
|
|
70
|
+
w as isActionAllowedInState,
|
|
71
|
+
K as linkDisplayFieldname,
|
|
72
|
+
W as mergeIntrospectedDoctype,
|
|
73
|
+
G as normalizeFieldKind,
|
|
74
|
+
j as parseDoctype,
|
|
75
|
+
Q as parseField,
|
|
76
|
+
V as pascalToSnake,
|
|
77
|
+
o as resolveLinkRenderMode,
|
|
78
|
+
Y as snakeToCamel,
|
|
79
|
+
q as snakeToLabel,
|
|
80
|
+
z as toPascalCase,
|
|
81
|
+
X as toSlug,
|
|
82
|
+
B as validateDoctype,
|
|
83
|
+
H as validateField
|
|
80
84
|
};
|
|
81
85
|
//# sourceMappingURL=index.js.map
|
package/dist/schema.d.ts
CHANGED
|
@@ -524,6 +524,7 @@ export declare const DoctypeFieldSchema: z.ZodType<DoctypeField, unknown, z.core
|
|
|
524
524
|
export declare const DoctypeMeta: z.ZodObject<{
|
|
525
525
|
name: z.ZodString;
|
|
526
526
|
slug: z.ZodOptional<z.ZodString>;
|
|
527
|
+
displayField: z.ZodOptional<z.ZodString>;
|
|
527
528
|
fields: z.ZodArray<z.ZodType<DoctypeField, unknown, z.core.$ZodTypeInternals<DoctypeField, unknown>>>;
|
|
528
529
|
links: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
529
530
|
target: z.ZodString;
|
|
@@ -715,6 +716,28 @@ export declare const FieldValidation: z.ZodObject<{
|
|
|
715
716
|
*/
|
|
716
717
|
export declare type FieldValidation = z.infer<typeof FieldValidation>;
|
|
717
718
|
|
|
719
|
+
/**
|
|
720
|
+
* Recursively flatten Fieldset containers into a flat array of non-container fields.
|
|
721
|
+
* Fieldset entries are replaced by their children; all other fields pass through.
|
|
722
|
+
*
|
|
723
|
+
* A fieldset is a layout grouping, not a scope: every field inside one is a field of the doctype,
|
|
724
|
+
* with a column of its own and a name a link can bind to. Anything asking "what does this doctype
|
|
725
|
+
* declare" must therefore descend, and the two ways to get that wrong point opposite ways — the
|
|
726
|
+
* SELECT builder would omit real columns, while a validator would report a working declaration as
|
|
727
|
+
* broken.
|
|
728
|
+
*
|
|
729
|
+
* Lives here rather than in the adapter because both sides need it: the middleware builds SQL from
|
|
730
|
+
* it, and `DoctypeMeta`'s own validation asks the same question at the load gate. It sat in the
|
|
731
|
+
* adapter while the validator hand-rolled a top-level-only scan, and that is exactly the second
|
|
732
|
+
* failure this comment names — a `displayField` inside a fieldset was rejected at authoring time
|
|
733
|
+
* and would have worked at runtime.
|
|
734
|
+
*
|
|
735
|
+
* @param fields - the doctype's top-level fields
|
|
736
|
+
* @returns every non-container field, fieldset children included
|
|
737
|
+
* @public
|
|
738
|
+
*/
|
|
739
|
+
export declare function flattenFields(fields: readonly DoctypeField[]): (ValueField | TableField)[];
|
|
740
|
+
|
|
718
741
|
/**
|
|
719
742
|
* Render a drift report as human-readable lines. Empty when generation agrees with the doctype.
|
|
720
743
|
*
|
|
@@ -725,6 +748,27 @@ export declare type FieldValidation = z.infer<typeof FieldValidation>;
|
|
|
725
748
|
*/
|
|
726
749
|
export declare function formatDoctypeDrift(drift: DoctypeDrift): string[];
|
|
727
750
|
|
|
751
|
+
/**
|
|
752
|
+
* Resolve the field a doctype nominates as its display text, or `undefined` when the nomination
|
|
753
|
+
* does not name a readable column.
|
|
754
|
+
*
|
|
755
|
+
* This is the single definition of "is this a usable `displayField`". Both sides depend on it:
|
|
756
|
+
* `DoctypeMeta` refuses a bad nomination at the load gate, and the adapter builds a SELECT from
|
|
757
|
+
* the field it returns. Call this; never re-derive the rule, or the gate and the query will
|
|
758
|
+
* disagree about which nominations are legal — which they did, in both directions at once.
|
|
759
|
+
*
|
|
760
|
+
* Two things disqualify a nomination, and both are the doctype saying so itself:
|
|
761
|
+
* - it names no field at all, fieldset children included
|
|
762
|
+
* - it names a `computed` field, which is declared precisely to state it has no column, so a
|
|
763
|
+
* SELECT built from it would reference a column the database does not have
|
|
764
|
+
*
|
|
765
|
+
* @param fields - the doctype's top-level fields
|
|
766
|
+
* @param displayField - the nominated fieldname
|
|
767
|
+
* @returns the nominated field, or `undefined` when it is not a readable column
|
|
768
|
+
* @public
|
|
769
|
+
*/
|
|
770
|
+
export declare function getDisplayField(fields: readonly DoctypeField[], displayField: string | undefined): ValueField | undefined;
|
|
771
|
+
|
|
728
772
|
/**
|
|
729
773
|
* Find the field a doctype marks as its primary key, or `undefined` when none is marked.
|
|
730
774
|
*
|
|
@@ -1059,6 +1103,12 @@ export declare const LazyFetch: z.ZodObject<{
|
|
|
1059
1103
|
*/
|
|
1060
1104
|
export declare type LazyFetch = z.infer<typeof LazyFetch>;
|
|
1061
1105
|
|
|
1106
|
+
/**
|
|
1107
|
+
* Suffix appended to a link fieldname for its pre-resolved display text in record payloads.
|
|
1108
|
+
* @public
|
|
1109
|
+
*/
|
|
1110
|
+
export declare const LINK_DISPLAY_SUFFIX = "__display";
|
|
1111
|
+
|
|
1062
1112
|
/**
|
|
1063
1113
|
* Link declaration - describes a relationship from one doctype to another.
|
|
1064
1114
|
* @public
|
|
@@ -1092,6 +1142,12 @@ export declare const LinkDeclaration: z.ZodObject<{
|
|
|
1092
1142
|
*/
|
|
1093
1143
|
export declare type LinkDeclaration = z.infer<typeof LinkDeclaration>;
|
|
1094
1144
|
|
|
1145
|
+
/**
|
|
1146
|
+
* Build the payload key for a link field's display text (e.g. `customerId__display`).
|
|
1147
|
+
* @public
|
|
1148
|
+
*/
|
|
1149
|
+
export declare function linkDisplayFieldname(fieldname: string): string;
|
|
1150
|
+
|
|
1095
1151
|
/**
|
|
1096
1152
|
* Whether a link component expands its target doctype, or renders the link inline.
|
|
1097
1153
|
*
|
package/dist/src/doctype.d.ts
CHANGED
|
@@ -248,6 +248,7 @@ export type WorkflowMeta = z.infer<typeof WorkflowMeta>;
|
|
|
248
248
|
export declare const DoctypeMeta: z.ZodObject<{
|
|
249
249
|
name: z.ZodString;
|
|
250
250
|
slug: z.ZodOptional<z.ZodString>;
|
|
251
|
+
displayField: z.ZodOptional<z.ZodString>;
|
|
251
252
|
fields: z.ZodArray<z.ZodType<import("./field").DoctypeField, unknown, z.core.$ZodTypeInternals<import("./field").DoctypeField, unknown>>>;
|
|
252
253
|
links: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
253
254
|
target: z.ZodString;
|
|
@@ -313,6 +314,16 @@ export declare const DoctypeMeta: z.ZodObject<{
|
|
|
313
314
|
* @public
|
|
314
315
|
*/
|
|
315
316
|
export type DoctypeMeta = z.infer<typeof DoctypeMeta>;
|
|
317
|
+
/**
|
|
318
|
+
* Suffix appended to a link fieldname for its pre-resolved display text in record payloads.
|
|
319
|
+
* @public
|
|
320
|
+
*/
|
|
321
|
+
export declare const LINK_DISPLAY_SUFFIX = "__display";
|
|
322
|
+
/**
|
|
323
|
+
* Build the payload key for a link field's display text (e.g. `customerId__display`).
|
|
324
|
+
* @public
|
|
325
|
+
*/
|
|
326
|
+
export declare function linkDisplayFieldname(fieldname: string): string;
|
|
316
327
|
/**
|
|
317
328
|
* Context for identifying what doctype/record we're working with.
|
|
318
329
|
* Used by graphql-middleware and graphql-client to resolve schema metadata.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctype.d.ts","sourceRoot":"","sources":["../../src/doctype.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB;;;GAGG;AACH,eAAO,MAAM,WAAW;;;;;EAGtB,CAAA;AAEF;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAErD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAA;AAEvC;;;GAGG;AACH,eAAO,MAAM,SAAS;;;iBAUnB,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AAEjD;;;GAGG;AACH,eAAO,MAAM,SAAS;;iBAQnB,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AAEjD;;;GAGG;AACH,eAAO,MAAM,WAAW;;;iBAUrB,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa;;;;;;;;6BAGxB,CAAA;AAEF;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAEzD;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;iBA0BzB,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAE7D;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;iBAgC1B,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAE/D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB;;;;iBAc3B,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAEjE;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAAE,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAIjH;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;kBAO1B,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqBtB,CAAA;AAEH;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEvD;;;GAGG;AACH,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"doctype.d.ts","sourceRoot":"","sources":["../../src/doctype.ts"],"names":[],"mappings":"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"}
|
package/dist/src/doctype.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { DoctypeFieldSchema } from './field';
|
|
2
|
+
import { DoctypeFieldSchema, flattenFields, getDisplayField } from './field';
|
|
3
3
|
/**
|
|
4
4
|
* Cardinality for relationship links.
|
|
5
5
|
* @public
|
|
@@ -208,6 +208,12 @@ export const DoctypeMeta = z
|
|
|
208
208
|
name: z.string().min(1),
|
|
209
209
|
/** URL-friendly slug (kebab-case) */
|
|
210
210
|
slug: z.string().min(1).optional(),
|
|
211
|
+
/**
|
|
212
|
+
* Field on this doctype used when displaying a reference to one of its records.
|
|
213
|
+
* When a record elsewhere holds a foreign key to this doctype, the middleware may
|
|
214
|
+
* include `fieldname__display` alongside the raw id, resolved from this field.
|
|
215
|
+
*/
|
|
216
|
+
displayField: z.string().min(1).optional(),
|
|
211
217
|
/** Field definitions (a link field is one carrying `doctype`) */
|
|
212
218
|
fields: z.array(DoctypeFieldSchema),
|
|
213
219
|
/** Relationship links to other doctypes */
|
|
@@ -245,4 +251,31 @@ export const DoctypeMeta = z
|
|
|
245
251
|
.join(', ')}); a record is identified by exactly one field. A composite database key is mapped to a single identity by the adapter, so a doctype never declares its parts`,
|
|
246
252
|
});
|
|
247
253
|
}
|
|
254
|
+
// Through `getDisplayField` rather than a scan written here, because the adapter builds its
|
|
255
|
+
// SELECT from that same call. The two hand-rolled versions disagreed in both directions at
|
|
256
|
+
// once: this gate scanned top-level only, so it rejected a fieldset-nested field that would
|
|
257
|
+
// have worked, while neither side excluded `computed` fields, so a nomination naming one
|
|
258
|
+
// passed the gate and then failed as a missing column at query time.
|
|
259
|
+
if (doctype.displayField && !getDisplayField(doctype.fields, doctype.displayField)) {
|
|
260
|
+
const named = flattenFields(doctype.fields).find(f => f.fieldname === doctype.displayField);
|
|
261
|
+
ctx.addIssue({
|
|
262
|
+
code: 'custom',
|
|
263
|
+
path: ['displayField'],
|
|
264
|
+
message: named
|
|
265
|
+
? `displayField "${doctype.displayField}" names a computed field, which has no column to read a display value from`
|
|
266
|
+
: `displayField "${doctype.displayField}" is not declared on this doctype`,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
248
269
|
});
|
|
270
|
+
/**
|
|
271
|
+
* Suffix appended to a link fieldname for its pre-resolved display text in record payloads.
|
|
272
|
+
* @public
|
|
273
|
+
*/
|
|
274
|
+
export const LINK_DISPLAY_SUFFIX = '__display';
|
|
275
|
+
/**
|
|
276
|
+
* Build the payload key for a link field's display text (e.g. `customerId__display`).
|
|
277
|
+
* @public
|
|
278
|
+
*/
|
|
279
|
+
export function linkDisplayFieldname(fieldname) {
|
|
280
|
+
return `${fieldname}${LINK_DISPLAY_SUFFIX}`;
|
|
281
|
+
}
|
package/dist/src/field.d.ts
CHANGED
|
@@ -205,6 +205,47 @@ export declare const INTROSPECTED_IDENTITY_PROPS: readonly ["fieldname", "primar
|
|
|
205
205
|
* @public
|
|
206
206
|
*/
|
|
207
207
|
export declare function getPrimaryKeyField(fields: readonly DoctypeField[]): ValueField | undefined;
|
|
208
|
+
/**
|
|
209
|
+
* Recursively flatten Fieldset containers into a flat array of non-container fields.
|
|
210
|
+
* Fieldset entries are replaced by their children; all other fields pass through.
|
|
211
|
+
*
|
|
212
|
+
* A fieldset is a layout grouping, not a scope: every field inside one is a field of the doctype,
|
|
213
|
+
* with a column of its own and a name a link can bind to. Anything asking "what does this doctype
|
|
214
|
+
* declare" must therefore descend, and the two ways to get that wrong point opposite ways — the
|
|
215
|
+
* SELECT builder would omit real columns, while a validator would report a working declaration as
|
|
216
|
+
* broken.
|
|
217
|
+
*
|
|
218
|
+
* Lives here rather than in the adapter because both sides need it: the middleware builds SQL from
|
|
219
|
+
* it, and `DoctypeMeta`'s own validation asks the same question at the load gate. It sat in the
|
|
220
|
+
* adapter while the validator hand-rolled a top-level-only scan, and that is exactly the second
|
|
221
|
+
* failure this comment names — a `displayField` inside a fieldset was rejected at authoring time
|
|
222
|
+
* and would have worked at runtime.
|
|
223
|
+
*
|
|
224
|
+
* @param fields - the doctype's top-level fields
|
|
225
|
+
* @returns every non-container field, fieldset children included
|
|
226
|
+
* @public
|
|
227
|
+
*/
|
|
228
|
+
export declare function flattenFields(fields: readonly DoctypeField[]): (ValueField | TableField)[];
|
|
229
|
+
/**
|
|
230
|
+
* Resolve the field a doctype nominates as its display text, or `undefined` when the nomination
|
|
231
|
+
* does not name a readable column.
|
|
232
|
+
*
|
|
233
|
+
* This is the single definition of "is this a usable `displayField`". Both sides depend on it:
|
|
234
|
+
* `DoctypeMeta` refuses a bad nomination at the load gate, and the adapter builds a SELECT from
|
|
235
|
+
* the field it returns. Call this; never re-derive the rule, or the gate and the query will
|
|
236
|
+
* disagree about which nominations are legal — which they did, in both directions at once.
|
|
237
|
+
*
|
|
238
|
+
* Two things disqualify a nomination, and both are the doctype saying so itself:
|
|
239
|
+
* - it names no field at all, fieldset children included
|
|
240
|
+
* - it names a `computed` field, which is declared precisely to state it has no column, so a
|
|
241
|
+
* SELECT built from it would reference a column the database does not have
|
|
242
|
+
*
|
|
243
|
+
* @param fields - the doctype's top-level fields
|
|
244
|
+
* @param displayField - the nominated fieldname
|
|
245
|
+
* @returns the nominated field, or `undefined` when it is not a readable column
|
|
246
|
+
* @public
|
|
247
|
+
*/
|
|
248
|
+
export declare function getDisplayField(fields: readonly DoctypeField[], displayField: string | undefined): ValueField | undefined;
|
|
208
249
|
/**
|
|
209
250
|
* The name of the field a record is identified by: the declared `primaryKey`, or `id` when the
|
|
210
251
|
* doctype declares none.
|
package/dist/src/field.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/field.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/field.ts"],"names":[],"mappings":"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"}
|
package/dist/src/field.js
CHANGED
|
@@ -139,6 +139,62 @@ export const INTROSPECTED_IDENTITY_PROPS = [
|
|
|
139
139
|
export function getPrimaryKeyField(fields) {
|
|
140
140
|
return fields.find((f) => f.kind === 'field' && Boolean(f.primaryKey));
|
|
141
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Recursively flatten Fieldset containers into a flat array of non-container fields.
|
|
144
|
+
* Fieldset entries are replaced by their children; all other fields pass through.
|
|
145
|
+
*
|
|
146
|
+
* A fieldset is a layout grouping, not a scope: every field inside one is a field of the doctype,
|
|
147
|
+
* with a column of its own and a name a link can bind to. Anything asking "what does this doctype
|
|
148
|
+
* declare" must therefore descend, and the two ways to get that wrong point opposite ways — the
|
|
149
|
+
* SELECT builder would omit real columns, while a validator would report a working declaration as
|
|
150
|
+
* broken.
|
|
151
|
+
*
|
|
152
|
+
* Lives here rather than in the adapter because both sides need it: the middleware builds SQL from
|
|
153
|
+
* it, and `DoctypeMeta`'s own validation asks the same question at the load gate. It sat in the
|
|
154
|
+
* adapter while the validator hand-rolled a top-level-only scan, and that is exactly the second
|
|
155
|
+
* failure this comment names — a `displayField` inside a fieldset was rejected at authoring time
|
|
156
|
+
* and would have worked at runtime.
|
|
157
|
+
*
|
|
158
|
+
* @param fields - the doctype's top-level fields
|
|
159
|
+
* @returns every non-container field, fieldset children included
|
|
160
|
+
* @public
|
|
161
|
+
*/
|
|
162
|
+
export function flattenFields(fields) {
|
|
163
|
+
const result = [];
|
|
164
|
+
for (const f of fields) {
|
|
165
|
+
if (f.kind === 'fieldset') {
|
|
166
|
+
result.push(...flattenFields(f.schema));
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
result.push(f);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Resolve the field a doctype nominates as its display text, or `undefined` when the nomination
|
|
176
|
+
* does not name a readable column.
|
|
177
|
+
*
|
|
178
|
+
* This is the single definition of "is this a usable `displayField`". Both sides depend on it:
|
|
179
|
+
* `DoctypeMeta` refuses a bad nomination at the load gate, and the adapter builds a SELECT from
|
|
180
|
+
* the field it returns. Call this; never re-derive the rule, or the gate and the query will
|
|
181
|
+
* disagree about which nominations are legal — which they did, in both directions at once.
|
|
182
|
+
*
|
|
183
|
+
* Two things disqualify a nomination, and both are the doctype saying so itself:
|
|
184
|
+
* - it names no field at all, fieldset children included
|
|
185
|
+
* - it names a `computed` field, which is declared precisely to state it has no column, so a
|
|
186
|
+
* SELECT built from it would reference a column the database does not have
|
|
187
|
+
*
|
|
188
|
+
* @param fields - the doctype's top-level fields
|
|
189
|
+
* @param displayField - the nominated fieldname
|
|
190
|
+
* @returns the nominated field, or `undefined` when it is not a readable column
|
|
191
|
+
* @public
|
|
192
|
+
*/
|
|
193
|
+
export function getDisplayField(fields, displayField) {
|
|
194
|
+
if (!displayField)
|
|
195
|
+
return undefined;
|
|
196
|
+
return flattenFields(fields).find((f) => f.kind === 'field' && !f.computed && f.fieldname === displayField);
|
|
197
|
+
}
|
|
142
198
|
/**
|
|
143
199
|
* The name of the field a record is identified by: the declared `primaryKey`, or `id` when the
|
|
144
200
|
* doctype declares none.
|
package/dist/src/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ export type { InteractionMode } from './mode';
|
|
|
2
2
|
export { TableViewConfig } from './table';
|
|
3
3
|
export { CANONICAL_COMPONENTS, COMPONENT_CATEGORY, COMPONENT_LINK_EXPANSION, componentCategory, componentLinkExpansion, resolveLinkRenderMode, type ComponentCategory, type LinkExpansion, type LinkRenderMode, } from './component-meta';
|
|
4
4
|
export type { DoctypeField, FieldOptions, FieldValidation, FieldsetField, TableField, ValueField } from './field';
|
|
5
|
-
export { DoctypeFieldSchema, FieldsetFieldSchema, getPrimaryKeyField, getRecordIdentity, getRecordIdField, INTROSPECTED_IDENTITY_PROPS, normalizeFieldKind, TableFieldSchema, ValueFieldSchema, } from './field';
|
|
6
|
-
export { ActionDefinition, TriggerDefinition, WorkflowLayout, WorkflowMeta, isActionAllowedInState } from './doctype';
|
|
5
|
+
export { DoctypeFieldSchema, FieldsetFieldSchema, flattenFields, getDisplayField, getPrimaryKeyField, getRecordIdentity, getRecordIdField, INTROSPECTED_IDENTITY_PROPS, normalizeFieldKind, TableFieldSchema, ValueFieldSchema, } from './field';
|
|
6
|
+
export { ActionDefinition, TriggerDefinition, WorkflowLayout, WorkflowMeta, isActionAllowedInState, LINK_DISPLAY_SUFFIX, linkDisplayFieldname, } from './doctype';
|
|
7
7
|
export type { Cardinality, CustomFetch, DataClient, DoctypeContext, DoctypeMeta, DoctypeRef, FetchStrategy, GetRecordOptions, GetRecordResult, GetRecordsOptions, GetRecordsResult, LazyFetch, LinkDeclaration, SerializedFunction, SyncFetch, } from './doctype';
|
|
8
8
|
export { parseDoctype, parseField, validateDoctype, validateField, type ValidationError, type ValidationResult, } from './validation';
|
|
9
9
|
export { buildScalarMap, classifyFieldType, convertGraphQLSchema, defaultIsEntityField, defaultIsEntityType, formatDoctypeDrift, GQL_SCALAR_MAP, INTERNAL_SCALARS, mergeIntrospectedDoctype, WELL_KNOWN_SCALARS, type AuthoredDoctype, type ConvertedGraphQLDoctype, type DoctypeDrift, type GraphQLConversionFieldMeta, type GraphQLConversionOptions, type IntrospectionSource, type MergeResult, } from './converter';
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAGzC,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,cAAc,GACnB,MAAM,kBAAkB,CAAA;AAGzB,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACjH,OAAO,EACN,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,2BAA2B,EAC3B,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,GAChB,MAAM,SAAS,CAAA;AAKhB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAGzC,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,cAAc,GACnB,MAAM,kBAAkB,CAAA;AAGzB,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACjH,OAAO,EACN,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,2BAA2B,EAC3B,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,GAChB,MAAM,SAAS,CAAA;AAKhB,OAAO,EACN,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,GACpB,MAAM,WAAW,CAAA;AAClB,YAAY,EACX,WAAW,EACX,WAAW,EACX,UAAU,EACV,cAAc,EACd,WAAW,EACX,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,SAAS,GACT,MAAM,WAAW,CAAA;AAGlB,OAAO,EACN,YAAY,EACZ,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACrB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACN,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,wBAAwB,EACxB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,YAAY,EACjB,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EACxB,KAAK,WAAW,GAChB,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAGtH,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA"}
|
package/dist/src/index.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
export { TableViewConfig } from './table';
|
|
3
3
|
// Component → semantic category — the single source of "what kind of value does this component render"
|
|
4
4
|
export { CANONICAL_COMPONENTS, COMPONENT_CATEGORY, COMPONENT_LINK_EXPANSION, componentCategory, componentLinkExpansion, resolveLinkRenderMode, } from './component-meta';
|
|
5
|
-
export { DoctypeFieldSchema, FieldsetFieldSchema, getPrimaryKeyField, getRecordIdentity, getRecordIdField, INTROSPECTED_IDENTITY_PROPS, normalizeFieldKind, TableFieldSchema, ValueFieldSchema, } from './field';
|
|
5
|
+
export { DoctypeFieldSchema, FieldsetFieldSchema, flattenFields, getDisplayField, getPrimaryKeyField, getRecordIdentity, getRecordIdField, INTROSPECTED_IDENTITY_PROPS, normalizeFieldKind, TableFieldSchema, ValueFieldSchema, } from './field';
|
|
6
6
|
// Doctype schema
|
|
7
7
|
// ActionDefinition and WorkflowMeta are exported as values (Zod schemas) so consumers can use
|
|
8
8
|
// .safeParse(), .shape, etc. at runtime. TypeScript types are inferred from the same exports.
|
|
9
|
-
export { ActionDefinition, TriggerDefinition, WorkflowLayout, WorkflowMeta, isActionAllowedInState } from './doctype';
|
|
9
|
+
export { ActionDefinition, TriggerDefinition, WorkflowLayout, WorkflowMeta, isActionAllowedInState, LINK_DISPLAY_SUFFIX, linkDisplayFieldname, } from './doctype';
|
|
10
10
|
// Validation helpers
|
|
11
11
|
export { parseDoctype, parseField, validateDoctype, validateField, } from './validation';
|
|
12
12
|
// GraphQL to Doctype conversion
|