@coffer-org/plugin-transit 7.0.1 → 7.1.1
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/bus_route/index.js +12 -7
- package/dist/index.js +2 -0
- package/dist/schema.js +479 -922
- package/package.json +4 -4
package/dist/schema.js
CHANGED
|
@@ -29,6 +29,8 @@ function defineLibrary(v) {
|
|
|
29
29
|
//#region ../sdk/src/plugin.ts
|
|
30
30
|
function definePlugin(p) {
|
|
31
31
|
if (!p.id) throw new Error("[plugin] missing id");
|
|
32
|
+
if (!p.label) throw new Error(`[plugin] ${p.id}: missing label`);
|
|
33
|
+
if (!p.description) throw new Error(`[plugin] ${p.id}: missing description`);
|
|
32
34
|
if (!p.version) console.warn(`[plugin] ${p.id}: missing version`);
|
|
33
35
|
return p;
|
|
34
36
|
}
|
|
@@ -169,7 +171,7 @@ function slugify(input) {
|
|
|
169
171
|
return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
170
172
|
}
|
|
171
173
|
var captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {};
|
|
172
|
-
function isObject
|
|
174
|
+
function isObject(data) {
|
|
173
175
|
return typeof data === "object" && data !== null && !Array.isArray(data);
|
|
174
176
|
}
|
|
175
177
|
var allowsEval = /* @__PURE__*/ cached(() => {
|
|
@@ -183,12 +185,12 @@ var allowsEval = /* @__PURE__*/ cached(() => {
|
|
|
183
185
|
}
|
|
184
186
|
});
|
|
185
187
|
function isPlainObject(o) {
|
|
186
|
-
if (isObject
|
|
188
|
+
if (isObject(o) === false) return false;
|
|
187
189
|
const ctor = o.constructor;
|
|
188
190
|
if (ctor === void 0) return true;
|
|
189
191
|
if (typeof ctor !== "function") return true;
|
|
190
192
|
const prot = ctor.prototype;
|
|
191
|
-
if (isObject
|
|
193
|
+
if (isObject(prot) === false) return false;
|
|
192
194
|
if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) return false;
|
|
193
195
|
return true;
|
|
194
196
|
}
|
|
@@ -1590,13 +1592,13 @@ var $ZodObject = /*@__PURE__*/ $constructor("$ZodObject", (inst, def) => {
|
|
|
1590
1592
|
}
|
|
1591
1593
|
return propValues;
|
|
1592
1594
|
});
|
|
1593
|
-
const isObject = isObject
|
|
1595
|
+
const isObject$2 = isObject;
|
|
1594
1596
|
const catchall = def.catchall;
|
|
1595
1597
|
let value;
|
|
1596
1598
|
inst._zod.parse = (payload, ctx) => {
|
|
1597
1599
|
value ?? (value = _normalized.value);
|
|
1598
1600
|
const input = payload.value;
|
|
1599
|
-
if (!isObject(input)) {
|
|
1601
|
+
if (!isObject$2(input)) {
|
|
1600
1602
|
payload.issues.push({
|
|
1601
1603
|
expected: "object",
|
|
1602
1604
|
code: "invalid_type",
|
|
@@ -1719,7 +1721,7 @@ var $ZodObjectJIT = /*@__PURE__*/ $constructor("$ZodObjectJIT", (inst, def) => {
|
|
|
1719
1721
|
return (payload, ctx) => fn(shape, payload, ctx);
|
|
1720
1722
|
};
|
|
1721
1723
|
let fastpass;
|
|
1722
|
-
const isObject = isObject
|
|
1724
|
+
const isObject$1 = isObject;
|
|
1723
1725
|
const jit = !globalConfig.jitless;
|
|
1724
1726
|
const fastEnabled = jit && allowsEval.value;
|
|
1725
1727
|
const catchall = def.catchall;
|
|
@@ -1727,7 +1729,7 @@ var $ZodObjectJIT = /*@__PURE__*/ $constructor("$ZodObjectJIT", (inst, def) => {
|
|
|
1727
1729
|
inst._zod.parse = (payload, ctx) => {
|
|
1728
1730
|
value ?? (value = _normalized.value);
|
|
1729
1731
|
const input = payload.value;
|
|
1730
|
-
if (!isObject(input)) {
|
|
1732
|
+
if (!isObject$1(input)) {
|
|
1731
1733
|
payload.issues.push({
|
|
1732
1734
|
expected: "object",
|
|
1733
1735
|
code: "invalid_type",
|
|
@@ -2729,7 +2731,7 @@ function initializeContext(params) {
|
|
|
2729
2731
|
external: params?.external ?? void 0
|
|
2730
2732
|
};
|
|
2731
2733
|
}
|
|
2732
|
-
function process
|
|
2734
|
+
function process(schema, ctx, _params = {
|
|
2733
2735
|
path: [],
|
|
2734
2736
|
schemaPath: []
|
|
2735
2737
|
}) {
|
|
@@ -2766,7 +2768,7 @@ function process$1(schema, ctx, _params = {
|
|
|
2766
2768
|
const parent = schema._zod.parent;
|
|
2767
2769
|
if (parent) {
|
|
2768
2770
|
if (!result.ref) result.ref = parent;
|
|
2769
|
-
process
|
|
2771
|
+
process(parent, ctx, params);
|
|
2770
2772
|
ctx.seen.get(parent).isParent = true;
|
|
2771
2773
|
}
|
|
2772
2774
|
}
|
|
@@ -2986,7 +2988,7 @@ var createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
|
|
|
2986
2988
|
...params,
|
|
2987
2989
|
processors
|
|
2988
2990
|
});
|
|
2989
|
-
process
|
|
2991
|
+
process(schema, ctx);
|
|
2990
2992
|
extractDefs(ctx, schema);
|
|
2991
2993
|
return finalize(ctx, schema);
|
|
2992
2994
|
};
|
|
@@ -2998,7 +3000,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
|
|
|
2998
3000
|
io,
|
|
2999
3001
|
processors
|
|
3000
3002
|
});
|
|
3001
|
-
process
|
|
3003
|
+
process(schema, ctx);
|
|
3002
3004
|
extractDefs(ctx, schema);
|
|
3003
3005
|
return finalize(ctx, schema);
|
|
3004
3006
|
};
|
|
@@ -3078,7 +3080,7 @@ var arrayProcessor = (schema, ctx, _json, params) => {
|
|
|
3078
3080
|
if (typeof minimum === "number") json.minItems = minimum;
|
|
3079
3081
|
if (typeof maximum === "number") json.maxItems = maximum;
|
|
3080
3082
|
json.type = "array";
|
|
3081
|
-
json.items = process
|
|
3083
|
+
json.items = process(def.element, ctx, {
|
|
3082
3084
|
...params,
|
|
3083
3085
|
path: [...params.path, "items"]
|
|
3084
3086
|
});
|
|
@@ -3089,7 +3091,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
3089
3091
|
json.type = "object";
|
|
3090
3092
|
json.properties = {};
|
|
3091
3093
|
const shape = def.shape;
|
|
3092
|
-
for (const key in shape) json.properties[key] = process
|
|
3094
|
+
for (const key in shape) json.properties[key] = process(shape[key], ctx, {
|
|
3093
3095
|
...params,
|
|
3094
3096
|
path: [
|
|
3095
3097
|
...params.path,
|
|
@@ -3107,7 +3109,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
3107
3109
|
if (def.catchall?._zod.def.type === "never") json.additionalProperties = false;
|
|
3108
3110
|
else if (!def.catchall) {
|
|
3109
3111
|
if (ctx.io === "output") json.additionalProperties = false;
|
|
3110
|
-
} else if (def.catchall) json.additionalProperties = process
|
|
3112
|
+
} else if (def.catchall) json.additionalProperties = process(def.catchall, ctx, {
|
|
3111
3113
|
...params,
|
|
3112
3114
|
path: [...params.path, "additionalProperties"]
|
|
3113
3115
|
});
|
|
@@ -3115,7 +3117,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
3115
3117
|
var unionProcessor = (schema, ctx, json, params) => {
|
|
3116
3118
|
const def = schema._zod.def;
|
|
3117
3119
|
const isExclusive = def.inclusive === false;
|
|
3118
|
-
const options = def.options.map((x, i) => process
|
|
3120
|
+
const options = def.options.map((x, i) => process(x, ctx, {
|
|
3119
3121
|
...params,
|
|
3120
3122
|
path: [
|
|
3121
3123
|
...params.path,
|
|
@@ -3128,7 +3130,7 @@ var unionProcessor = (schema, ctx, json, params) => {
|
|
|
3128
3130
|
};
|
|
3129
3131
|
var intersectionProcessor = (schema, ctx, json, params) => {
|
|
3130
3132
|
const def = schema._zod.def;
|
|
3131
|
-
const a = process
|
|
3133
|
+
const a = process(def.left, ctx, {
|
|
3132
3134
|
...params,
|
|
3133
3135
|
path: [
|
|
3134
3136
|
...params.path,
|
|
@@ -3136,7 +3138,7 @@ var intersectionProcessor = (schema, ctx, json, params) => {
|
|
|
3136
3138
|
0
|
|
3137
3139
|
]
|
|
3138
3140
|
});
|
|
3139
|
-
const b = process
|
|
3141
|
+
const b = process(def.right, ctx, {
|
|
3140
3142
|
...params,
|
|
3141
3143
|
path: [
|
|
3142
3144
|
...params.path,
|
|
@@ -3149,7 +3151,7 @@ var intersectionProcessor = (schema, ctx, json, params) => {
|
|
|
3149
3151
|
};
|
|
3150
3152
|
var nullableProcessor = (schema, ctx, json, params) => {
|
|
3151
3153
|
const def = schema._zod.def;
|
|
3152
|
-
const inner = process
|
|
3154
|
+
const inner = process(def.innerType, ctx, params);
|
|
3153
3155
|
const seen = ctx.seen.get(schema);
|
|
3154
3156
|
if (ctx.target === "openapi-3.0") {
|
|
3155
3157
|
seen.ref = def.innerType;
|
|
@@ -3158,27 +3160,27 @@ var nullableProcessor = (schema, ctx, json, params) => {
|
|
|
3158
3160
|
};
|
|
3159
3161
|
var nonoptionalProcessor = (schema, ctx, _json, params) => {
|
|
3160
3162
|
const def = schema._zod.def;
|
|
3161
|
-
process
|
|
3163
|
+
process(def.innerType, ctx, params);
|
|
3162
3164
|
const seen = ctx.seen.get(schema);
|
|
3163
3165
|
seen.ref = def.innerType;
|
|
3164
3166
|
};
|
|
3165
3167
|
var defaultProcessor = (schema, ctx, json, params) => {
|
|
3166
3168
|
const def = schema._zod.def;
|
|
3167
|
-
process
|
|
3169
|
+
process(def.innerType, ctx, params);
|
|
3168
3170
|
const seen = ctx.seen.get(schema);
|
|
3169
3171
|
seen.ref = def.innerType;
|
|
3170
3172
|
json.default = JSON.parse(JSON.stringify(def.defaultValue));
|
|
3171
3173
|
};
|
|
3172
3174
|
var prefaultProcessor = (schema, ctx, json, params) => {
|
|
3173
3175
|
const def = schema._zod.def;
|
|
3174
|
-
process
|
|
3176
|
+
process(def.innerType, ctx, params);
|
|
3175
3177
|
const seen = ctx.seen.get(schema);
|
|
3176
3178
|
seen.ref = def.innerType;
|
|
3177
3179
|
if (ctx.io === "input") json._prefault = JSON.parse(JSON.stringify(def.defaultValue));
|
|
3178
3180
|
};
|
|
3179
3181
|
var catchProcessor = (schema, ctx, json, params) => {
|
|
3180
3182
|
const def = schema._zod.def;
|
|
3181
|
-
process
|
|
3183
|
+
process(def.innerType, ctx, params);
|
|
3182
3184
|
const seen = ctx.seen.get(schema);
|
|
3183
3185
|
seen.ref = def.innerType;
|
|
3184
3186
|
let catchValue;
|
|
@@ -3193,20 +3195,20 @@ var pipeProcessor = (schema, ctx, _json, params) => {
|
|
|
3193
3195
|
const def = schema._zod.def;
|
|
3194
3196
|
const inIsTransform = def.in._zod.traits.has("$ZodTransform");
|
|
3195
3197
|
const innerType = ctx.io === "input" ? inIsTransform ? def.out : def.in : def.out;
|
|
3196
|
-
process
|
|
3198
|
+
process(innerType, ctx, params);
|
|
3197
3199
|
const seen = ctx.seen.get(schema);
|
|
3198
3200
|
seen.ref = innerType;
|
|
3199
3201
|
};
|
|
3200
3202
|
var readonlyProcessor = (schema, ctx, json, params) => {
|
|
3201
3203
|
const def = schema._zod.def;
|
|
3202
|
-
process
|
|
3204
|
+
process(def.innerType, ctx, params);
|
|
3203
3205
|
const seen = ctx.seen.get(schema);
|
|
3204
3206
|
seen.ref = def.innerType;
|
|
3205
3207
|
json.readOnly = true;
|
|
3206
3208
|
};
|
|
3207
3209
|
var optionalProcessor = (schema, ctx, _json, params) => {
|
|
3208
3210
|
const def = schema._zod.def;
|
|
3209
|
-
process
|
|
3211
|
+
process(def.innerType, ctx, params);
|
|
3210
3212
|
const seen = ctx.seen.get(schema);
|
|
3211
3213
|
seen.ref = def.innerType;
|
|
3212
3214
|
};
|
|
@@ -4467,16 +4469,18 @@ function jsonRefined(inner, code) {
|
|
|
4467
4469
|
});
|
|
4468
4470
|
});
|
|
4469
4471
|
}
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4472
|
+
/**
|
|
4473
|
+
* An empty value is no value: `''` and `null` become `undefined`, and the field's own schema
|
|
4474
|
+
* never sees them. Every field is optional, so this is the ONLY shape — a field cannot demand
|
|
4475
|
+
* a value, and the rules it carries judge what was entered rather than whether anything was.
|
|
4476
|
+
*
|
|
4477
|
+
* This used to have a second branch, for `required` fields, which turned the same emptiness
|
|
4478
|
+
* into a `required` issue through a `z.unknown()` guard piped into the schema. That branch is
|
|
4479
|
+
* why a `.min(1)` on a required string was unreachable: the empty string had already been
|
|
4480
|
+
* converted to the issue before the string schema ran.
|
|
4481
|
+
*/
|
|
4482
|
+
function optionalize(schema) {
|
|
4483
|
+
return preprocess((v) => v === "" || v === null ? void 0 : v, schema.optional());
|
|
4480
4484
|
}
|
|
4481
4485
|
//#endregion
|
|
4482
4486
|
//#region ../sdk/src/fields/meta.ts
|
|
@@ -4558,7 +4562,7 @@ function applyMultiple(base, multiple) {
|
|
|
4558
4562
|
multiple: true
|
|
4559
4563
|
},
|
|
4560
4564
|
json: true,
|
|
4561
|
-
zod: optionalize(s
|
|
4565
|
+
zod: optionalize(s)
|
|
4562
4566
|
};
|
|
4563
4567
|
}
|
|
4564
4568
|
/** Inline option entry → OptionItem (plain string = value and label at once). */
|
|
@@ -4673,13 +4677,6 @@ function wrapKey(key, opts, meta) {
|
|
|
4673
4677
|
noLabel: true
|
|
4674
4678
|
}
|
|
4675
4679
|
};
|
|
4676
|
-
if (opts.role) m = {
|
|
4677
|
-
...m,
|
|
4678
|
-
hints: {
|
|
4679
|
-
...m.hints,
|
|
4680
|
-
role: opts.role
|
|
4681
|
-
}
|
|
4682
|
-
};
|
|
4683
4680
|
if (opts.editor) m = {
|
|
4684
4681
|
...m,
|
|
4685
4682
|
hints: {
|
|
@@ -4701,6 +4698,13 @@ function wrapKey(key, opts, meta) {
|
|
|
4701
4698
|
span: opts.span
|
|
4702
4699
|
}
|
|
4703
4700
|
};
|
|
4701
|
+
if (opts.faces !== void 0) m = {
|
|
4702
|
+
...m,
|
|
4703
|
+
hints: {
|
|
4704
|
+
...m.hints,
|
|
4705
|
+
faces: opts.faces
|
|
4706
|
+
}
|
|
4707
|
+
};
|
|
4704
4708
|
if (opts.default !== void 0) m = {
|
|
4705
4709
|
...m,
|
|
4706
4710
|
default: opts.default
|
|
@@ -4800,9 +4804,9 @@ function normalizeOpts(rawIn) {
|
|
|
4800
4804
|
...v.valueLabel !== void 0 ? { valueLabel: v.valueLabel } : {},
|
|
4801
4805
|
compareWith: v.compareWith,
|
|
4802
4806
|
span: v.span,
|
|
4807
|
+
faces: v.faces,
|
|
4803
4808
|
emphasis: v.emphasis,
|
|
4804
4809
|
noLabel: v.noLabel,
|
|
4805
|
-
role: v.role,
|
|
4806
4810
|
editor: v.editor,
|
|
4807
4811
|
activate: v.activate
|
|
4808
4812
|
};
|
|
@@ -4943,7 +4947,7 @@ function registerPreset(factory, base, presetOpts, over = {}) {
|
|
|
4943
4947
|
* dimensions, check(single)) and differed only in the validation code and the per-role
|
|
4944
4948
|
* default zod.
|
|
4945
4949
|
*
|
|
4946
|
-
* raw → jsonValue →
|
|
4950
|
+
* raw → jsonValue → carries nothing? (passthrough, when `acceptsEmptyRow`)
|
|
4947
4951
|
* → carries nothing at all? (pass through, there is nothing to judge)
|
|
4948
4952
|
* → rowSchema (partsRowShape) → stripServerOwnedParts → optional per-type refine
|
|
4949
4953
|
*
|
|
@@ -4953,28 +4957,16 @@ function registerPreset(factory, base, presetOpts, over = {}) {
|
|
|
4953
4957
|
* exactly once.
|
|
4954
4958
|
*/
|
|
4955
4959
|
function buildComposite(def, opts, parts) {
|
|
4956
|
-
const
|
|
4957
|
-
const roleZod = def.roleZod(opts, parts);
|
|
4958
|
-
const rowSchema = object(partsRowShape(roleZod, parts, required === true ? "strict" : "null"));
|
|
4959
|
-
const absentRowSchema = required === true ? object(partsRowShape(roleZod, parts, "null-or-missing")) : rowSchema;
|
|
4960
|
+
const rowSchema = object(partsRowShape(def.roleZod(opts, parts), parts));
|
|
4960
4961
|
const roleKeys = (which) => parts.filter((p) => p.mode === "stored" && (which?.(p) ?? true)).map(partValueKey);
|
|
4961
|
-
const
|
|
4962
|
-
const clientKeys = def.absenceRoles ? roleKeys() : void 0;
|
|
4962
|
+
const clientKeys = def.acceptsEmptyRow ? roleKeys() : void 0;
|
|
4963
4963
|
const zod = unknown().transform((raw, ctx) => {
|
|
4964
4964
|
const parsed = jsonValue(raw);
|
|
4965
4965
|
const p = parsed;
|
|
4966
4966
|
const isRow = p == null || typeof p === "object" && !Array.isArray(p);
|
|
4967
4967
|
/** Every one of `keys` empty in this value — `null`/absent alike. */
|
|
4968
4968
|
const allEmpty = (keys) => isRow && (p == null || keys.length > 0 && keys.every((k) => p[k] == null));
|
|
4969
|
-
|
|
4970
|
-
if (absenceKeys && clientKeys) {
|
|
4971
|
-
absent = allEmpty(absenceKeys);
|
|
4972
|
-
if (absent && required) ctx.addIssue({
|
|
4973
|
-
code: ZodIssueCode.custom,
|
|
4974
|
-
message: vmsg("required")
|
|
4975
|
-
});
|
|
4976
|
-
if (allEmpty(clientKeys)) return raw;
|
|
4977
|
-
}
|
|
4969
|
+
if (clientKeys && allEmpty(clientKeys)) return raw;
|
|
4978
4970
|
if (typeof parsed === "string") {
|
|
4979
4971
|
ctx.addIssue({
|
|
4980
4972
|
code: ZodIssueCode.custom,
|
|
@@ -4982,7 +4974,7 @@ function buildComposite(def, opts, parts) {
|
|
|
4982
4974
|
});
|
|
4983
4975
|
return NEVER;
|
|
4984
4976
|
}
|
|
4985
|
-
const r =
|
|
4977
|
+
const r = rowSchema.safeParse(parsed);
|
|
4986
4978
|
if (!r.success) {
|
|
4987
4979
|
const message = typeof def.structureCode === "function" ? def.structureCode(r.error) : vmsg(def.structureCode);
|
|
4988
4980
|
ctx.addIssue({
|
|
@@ -5035,12 +5027,10 @@ function materialize(decl, name) {
|
|
|
5035
5027
|
if (isComposite(type) && (opts.multiple ?? false) && parts.length > 0 && !type.selfManages?.has("multiple")) return collectionGroup(name, opts, parts, type.collectionView);
|
|
5036
5028
|
const built = isComposite(type) ? buildComposite(type, opts, parts) : type.build(opts, parts, name);
|
|
5037
5029
|
const selfOptional = type.selfManages?.has("optional") ?? false;
|
|
5038
|
-
const required = selfOptional ? false : opts.required ?? false;
|
|
5039
5030
|
const base = {
|
|
5040
5031
|
kind: type.kind,
|
|
5041
5032
|
label: opts.label ?? "",
|
|
5042
5033
|
...opts.agent !== void 0 && { agent: opts.agent },
|
|
5043
|
-
required,
|
|
5044
5034
|
prim: type.prim,
|
|
5045
5035
|
column: built.column,
|
|
5046
5036
|
hints: built.hints ?? {},
|
|
@@ -5051,7 +5041,7 @@ function materialize(decl, name) {
|
|
|
5051
5041
|
columns: built.columns,
|
|
5052
5042
|
parts
|
|
5053
5043
|
},
|
|
5054
|
-
zod: selfOptional ? built.zod : optionalize(built.zod
|
|
5044
|
+
zod: selfOptional ? built.zod : optionalize(built.zod)
|
|
5055
5045
|
};
|
|
5056
5046
|
return wrapKey(name, opts, type.selfManages?.has("multiple") ? base : applyMultiple(base, opts.multiple ?? false));
|
|
5057
5047
|
}
|
|
@@ -5081,7 +5071,6 @@ function collectionGroup(key, opts, parts, collectionView) {
|
|
|
5081
5071
|
key,
|
|
5082
5072
|
scope: "nest",
|
|
5083
5073
|
multiple: true,
|
|
5084
|
-
required: opts.required ?? false,
|
|
5085
5074
|
label: opts.label ?? key,
|
|
5086
5075
|
...opts.agent !== void 0 && { agent: opts.agent },
|
|
5087
5076
|
display: "wrap",
|
|
@@ -5252,7 +5241,7 @@ function accepts(def, d) {
|
|
|
5252
5241
|
}
|
|
5253
5242
|
/**
|
|
5254
5243
|
* The correction every role gets for free: keep what the author said ABOUT the field
|
|
5255
|
-
* (`label`, `
|
|
5244
|
+
* (`label`, `ui`, `value` — a constant or a ComputeFn), replace the type, and
|
|
5256
5245
|
* drop what belonged to the OLD type (`rules` — a number's min/max mean nothing to a
|
|
5257
5246
|
* picture — and `multiple`, because a composite role owns exactly one column). A role whose
|
|
5258
5247
|
* own default needs more than a bare factory (`measured`'s unit, `period`'s endpoints)
|
|
@@ -5260,10 +5249,9 @@ function accepts(def, d) {
|
|
|
5260
5249
|
*/
|
|
5261
5250
|
function retypeTo(factory) {
|
|
5262
5251
|
return (d) => {
|
|
5263
|
-
const { label,
|
|
5252
|
+
const { label, value } = d?.opts ?? {};
|
|
5264
5253
|
return declare(factory, {
|
|
5265
5254
|
label,
|
|
5266
|
-
required,
|
|
5267
5255
|
value,
|
|
5268
5256
|
noSearch: d?.opts.noSearch,
|
|
5269
5257
|
ui: uiOf(d?.opts)
|
|
@@ -5449,72 +5437,73 @@ function partColumns(parts) {
|
|
|
5449
5437
|
}
|
|
5450
5438
|
return cols;
|
|
5451
5439
|
}
|
|
5452
|
-
|
|
5440
|
+
/**
|
|
5441
|
+
* A composite's write-time row shape, DERIVED from its resolved parts. `shape` carries
|
|
5442
|
+
* the composite's DEFAULT schema per role — the literal the factory writes by hand
|
|
5443
|
+
* (`{ value: numSchema, unit: z.string().refine(…) }`) — and each part decides which
|
|
5444
|
+
* schema guards its (role-named) key:
|
|
5445
|
+
*
|
|
5446
|
+
* - a plain STORED part is keyed by its role name, matching the value object and the
|
|
5447
|
+
* column `<field>__<role>` that `flattenEmbeddedAt`/`nestEmbeddedAt` read. A role left
|
|
5448
|
+
* to its default filling keeps the default schema — byte-identical to the hand-written
|
|
5449
|
+
* literal, so every existing structure/unit/range code and message is preserved.
|
|
5450
|
+
* - an OVERRIDDEN stored part is validated by its OWN zod (`meta.zod`) instead of the
|
|
5451
|
+
* default schema for that role. This is what makes a RETYPED filling real: an
|
|
5452
|
+
* `f.int({})` magnitude rejects 5.5 (its own `int` check) and gets an integer column,
|
|
5453
|
+
* and an `f.relation({…})` currency accepts a record id instead of being measured
|
|
5454
|
+
* against an ISO-4217 string rule it was never meant to satisfy. The filling also
|
|
5455
|
+
* brings its own optionality and its own min/max — an author replacing a filling
|
|
5456
|
+
* takes over that role's constraints, so `f.real({ rules: { min: 0 } })` is how a
|
|
5457
|
+
* replaced magnitude keeps a bound.
|
|
5458
|
+
* - a COMPUTED-AND-STORED part ('computedStored') is keyed by its role name like any
|
|
5459
|
+
* other part, but its schema is `z.unknown().optional()`: the SERVER owns the value, so
|
|
5460
|
+
* whatever the client sends there is ignored — `stripServerOwnedParts` deletes it a
|
|
5461
|
+
* moment later and the write path recomputes the column. It is stripped rather than
|
|
5462
|
+
* `z.never()`-rejected because a read hands the client that key (it is a real column,
|
|
5463
|
+
* present in every response), so rejecting it would break a read → PATCH-the-whole-object
|
|
5464
|
+
* round trip.
|
|
5465
|
+
* - a CLIENT-OWNED stored part of a composite also accepts
|
|
5466
|
+
* an explicit `null` (`tolerateNull`), which is what closes the read → write round trip
|
|
5467
|
+
* for a PARTIALLY FILLED composite. A SELECT returns every sub-column, so a record whose
|
|
5468
|
+
* magnitude column is set and whose unit column is empty reads back as
|
|
5469
|
+
* `{value: 900, unit: null}` (`nestEmbeddedAt` drops the key only when EVERY column is
|
|
5470
|
+
* empty — `0` is a value), and feeding that exact object back used to fail with
|
|
5471
|
+
* `measured_structure`: the write path refused the shape its own read produced. The null
|
|
5472
|
+
* slot now parses through and is written back as NULL, so the round trip is closed and
|
|
5473
|
+
* clearing ONE role of a filled composite works instead of erroring.
|
|
5474
|
+
* NULL, not absence: a read emits every stored role (empty ones as `null`), so `null` is
|
|
5475
|
+
* how "this record has no value there" arrives, while an ABSENT key is a writer that
|
|
5476
|
+
* never mentioned a role it owns — which stays the structure error it has always been
|
|
5477
|
+
* (`{unit: 'kg'}` with no magnitude, `{lat: 50}` with no longitude). That is the
|
|
5478
|
+
* all-or-nothing rule for a DECLARATION, and it is untouched.
|
|
5479
|
+
* A composite used to be able to override this: `required: true` kept every client-owned
|
|
5480
|
+
* slot MANDATORY, null included, so that "tolerate null" could not turn a demanded field
|
|
5481
|
+
* optional. Nothing demands a value now, so there is no override and the rule above is the
|
|
5482
|
+
* only one.
|
|
5483
|
+
*/
|
|
5484
|
+
/**
|
|
5485
|
+
* How much a CLIENT-OWNED slot forgives in the row shape: exactly one thing, an explicit
|
|
5486
|
+
* `null`. `.nullable()`, never `.nullish()` — a part that is MISSING entirely is still a
|
|
5487
|
+
* malformed row (`{lat: 5.5}` is half a coordinate), which is the one rule about composites
|
|
5488
|
+
* that judges CORRECTNESS rather than presence.
|
|
5489
|
+
*
|
|
5490
|
+
* There used to be a `RowTolerance` of three levels, and the field's `required` is what chose
|
|
5491
|
+
* between them: 'strict' when the field demanded a value, 'null-or-missing' when the value was
|
|
5492
|
+
* ABSENT under that demand — the third existing only so an absent required composite did not
|
|
5493
|
+
* report the same absence twice, once as `required` and once as a structure code. With nothing
|
|
5494
|
+
* able to demand a value there is no first issue to restate, so both levels and the type
|
|
5495
|
+
* itself are gone.
|
|
5496
|
+
*/
|
|
5497
|
+
function partsRowShape(shape, parts) {
|
|
5453
5498
|
const out = { ...shape };
|
|
5454
5499
|
for (const p of parts) if (p.mode === "computedStored") out[p.key] = unknown().optional();
|
|
5455
5500
|
else {
|
|
5456
5501
|
const own = p.overridden ? p.meta.zod : shape[p.role] ?? unknown().optional();
|
|
5457
|
-
|
|
5458
|
-
out[p.key] = relaxed ? tolerance === "null-or-missing" ? own.nullish() : own.nullable() : own;
|
|
5502
|
+
out[p.key] = own.nullable();
|
|
5459
5503
|
}
|
|
5460
5504
|
return out;
|
|
5461
5505
|
}
|
|
5462
5506
|
/**
|
|
5463
|
-
* MIXED OWNERSHIP of the STORED parts: the composite has a computed-and-stored part (the
|
|
5464
|
-
* server owns that column) AND a plain stored part (the client owns that one). Returns the
|
|
5465
|
-
* two role lists, or null when the composite is uniformly owned.
|
|
5466
|
-
*
|
|
5467
|
-
* Such a composite IS materialized by the write path (`applyStoredParts`): the server's part
|
|
5468
|
-
* is computed on every write, whether or not the write carries the field, and the client's
|
|
5469
|
-
* columns keep whatever the record already holds. A computed sum exists whether or not a
|
|
5470
|
-
* user has picked a unit, and a NULL column is invisible to SQL. See THE ABSENT-COMPOSITE
|
|
5471
|
-
* RULE in `@coffer-org/server/part-injection` and `docs/decisions.md` (2026-08-12).
|
|
5472
|
-
*
|
|
5473
|
-
* The one shape this is still wrong for is a composite that MANDATES one of those client-owned
|
|
5474
|
-
* roles — see `mandatedClientParts` below.
|
|
5475
|
-
*/
|
|
5476
|
-
function mixedOwnedStoredParts(parts) {
|
|
5477
|
-
const server = parts.filter((p) => p.mode === "computedStored").map((p) => p.role);
|
|
5478
|
-
const client = parts.filter((p) => p.mode === "stored").map((p) => p.role);
|
|
5479
|
-
return server.length > 0 && client.length > 0 ? {
|
|
5480
|
-
server,
|
|
5481
|
-
client
|
|
5482
|
-
} : null;
|
|
5483
|
-
}
|
|
5484
|
-
/**
|
|
5485
|
-
* The CLIENT-OWNED stored roles this composite demands a value for — the roles a
|
|
5486
|
-
* server-materialized half-value would leave empty in breach of the field's own contract.
|
|
5487
|
-
* Empty list → nothing is mandated and the composite is safe to materialize.
|
|
5488
|
-
*
|
|
5489
|
-
* THE MANDATE HAS TWO SOURCES, and reading only the first is a bug this had:
|
|
5490
|
-
*
|
|
5491
|
-
* - the FIELD's own `required`, which `partsRowShape` turns into `tolerateNull = false` for
|
|
5492
|
-
* every client-owned slot;
|
|
5493
|
-
* - the FILLING's `required`, per part: `partsRowShape` keeps an OVERRIDDEN part's own
|
|
5494
|
-
* mandate ("a filling the author declared `required` keeps its mandate"), so
|
|
5495
|
-
* `fields: { unit: f.string({ required: true, … }) }` makes THAT slot non-nullable even
|
|
5496
|
-
* when the field around it is optional.
|
|
5497
|
-
*
|
|
5498
|
-
* Either way the materialized value — the server's column filled, the client's empty — reads
|
|
5499
|
-
* back as `{value: 5, unit: null}` and is rejected by the composite's own zod with
|
|
5500
|
-
* `{"code":"required"}` the moment a record form or an MCP agent feeds it straight back. So
|
|
5501
|
-
* both sources must count, and the write path refuses to materialize when either speaks.
|
|
5502
|
-
*
|
|
5503
|
-
* A CONDITION counts too, though its harm is different and milder. `partsRowShape` compares
|
|
5504
|
-
* `=== true`, so a conditional mandate does not make the slot non-nullable and the round trip
|
|
5505
|
-
* still parses; what it does instead is let a materialized object satisfy
|
|
5506
|
-
* `updateRecord`'s conditional-required check (which only asks whether the value is non-null),
|
|
5507
|
-
* excusing the user from a field the schema says is mandatory. Nothing static can evaluate a
|
|
5508
|
-
* Condition here, so any mandate that is not literally `false`/absent is treated as speaking —
|
|
5509
|
-
* conservative in the safe direction, since refusing to materialize is exactly the older
|
|
5510
|
-
* behaviour and loses nothing.
|
|
5511
|
-
*/
|
|
5512
|
-
function mandatedClientParts(required, parts) {
|
|
5513
|
-
const speaks = (flag) => flag !== void 0 && flag !== false;
|
|
5514
|
-
const field = speaks(required);
|
|
5515
|
-
return parts.filter((p) => p.mode === "stored" && (field || p.overridden && speaks(p.meta.required))).map((p) => p.role);
|
|
5516
|
-
}
|
|
5517
|
-
/**
|
|
5518
5507
|
* Drops SERVER-OWNED part slots from a successfully parsed composite row: a computed-and-stored
|
|
5519
5508
|
* role, keyed by its role name. Its value belongs to the schema, not to the writer — it is
|
|
5520
5509
|
* recomputed and written by the server on the same write (`applyStoredParts`) — so a client
|
|
@@ -5561,13 +5550,10 @@ function email(o) {
|
|
|
5561
5550
|
registerPreset("email", "string", {}, {
|
|
5562
5551
|
kind: "email",
|
|
5563
5552
|
widget: "email",
|
|
5564
|
-
build(
|
|
5565
|
-
const required = o.required ?? false;
|
|
5566
|
-
let s = string$1().email({ message: vmsg("email") });
|
|
5567
|
-
if (required) s = s.min(1, { message: vmsg("min_length", { min: 1 }) });
|
|
5553
|
+
build() {
|
|
5568
5554
|
return {
|
|
5569
5555
|
column: "text",
|
|
5570
|
-
zod:
|
|
5556
|
+
zod: string$1().email({ message: vmsg("email") }),
|
|
5571
5557
|
hints: {
|
|
5572
5558
|
format: "email",
|
|
5573
5559
|
inputType: "email"
|
|
@@ -5590,12 +5576,10 @@ function tel(o) {
|
|
|
5590
5576
|
registerPreset("tel", "string", {}, {
|
|
5591
5577
|
kind: "tel",
|
|
5592
5578
|
widget: "tel",
|
|
5593
|
-
build(
|
|
5594
|
-
const required = o.required ?? false;
|
|
5595
|
-
const base_z = string$1().regex(TEL_RE, { message: vmsg("pattern", { messageKey: "core.presets.tel" }) });
|
|
5579
|
+
build() {
|
|
5596
5580
|
return {
|
|
5597
5581
|
column: "text",
|
|
5598
|
-
zod:
|
|
5582
|
+
zod: string$1().regex(TEL_RE, { message: vmsg("pattern", { messageKey: "core.presets.tel" }) }),
|
|
5599
5583
|
hints: {
|
|
5600
5584
|
format: "tel",
|
|
5601
5585
|
inputType: "tel"
|
|
@@ -5619,10 +5603,10 @@ registerPreset("password", "string", {}, {
|
|
|
5619
5603
|
kind: "password",
|
|
5620
5604
|
widget: "password",
|
|
5621
5605
|
selfManages: /* @__PURE__ */ new Set(["multiple"]),
|
|
5622
|
-
build(
|
|
5606
|
+
build() {
|
|
5623
5607
|
return {
|
|
5624
5608
|
column: "text",
|
|
5625
|
-
zod:
|
|
5609
|
+
zod: string$1(),
|
|
5626
5610
|
hints: {
|
|
5627
5611
|
format: "password",
|
|
5628
5612
|
inputType: "password"
|
|
@@ -5684,6 +5668,31 @@ function internalOauthGrants(o) {
|
|
|
5684
5668
|
}
|
|
5685
5669
|
});
|
|
5686
5670
|
}
|
|
5671
|
+
/**
|
|
5672
|
+
* The account page's linked-accounts section. Same trick as `internalApiToken`: a container
|
|
5673
|
+
* with a custom `ui.kind`, drawn by its own renderer, which reads `/api/auth/links` itself.
|
|
5674
|
+
* The declared children are what one ROW holds — the renderer reads them through the slot
|
|
5675
|
+
* contract, so this is a declaration, not a layout.
|
|
5676
|
+
*
|
|
5677
|
+
* @layer preset
|
|
5678
|
+
* @base group
|
|
5679
|
+
* @prim —
|
|
5680
|
+
* @widget internalIdentityLinks
|
|
5681
|
+
* @example f.internalIdentityLinks({ label: 'auth.linksTitle' })
|
|
5682
|
+
*/
|
|
5683
|
+
function internalIdentityLinks(o) {
|
|
5684
|
+
return group({
|
|
5685
|
+
scope: "nest",
|
|
5686
|
+
label: o.label,
|
|
5687
|
+
multiple: true,
|
|
5688
|
+
ui: { kind: "internalIdentityLinks" },
|
|
5689
|
+
fields: {
|
|
5690
|
+
provider: string({}),
|
|
5691
|
+
externalId: string({}),
|
|
5692
|
+
linkedAt: string({})
|
|
5693
|
+
}
|
|
5694
|
+
});
|
|
5695
|
+
}
|
|
5687
5696
|
var SLUG_RE = /^[a-z0-9-]+$/;
|
|
5688
5697
|
/**
|
|
5689
5698
|
* Slug — kind 'slug', `^[a-z0-9-]+$`.
|
|
@@ -5708,6 +5717,63 @@ registerPreset("slug", "string", {}, {
|
|
|
5708
5717
|
};
|
|
5709
5718
|
}
|
|
5710
5719
|
});
|
|
5720
|
+
/**
|
|
5721
|
+
* Identifier — a code printed for a machine and read back by one: a serial number, an order
|
|
5722
|
+
* number, a policy number, an IMEI. What a person actually DOES with one is copy it, which is
|
|
5723
|
+
* why this is a type of its own and not `f.string({ ui: { voice: 'data' } })`: the machine face
|
|
5724
|
+
* is one word on any string now, but the click that copies belongs to the kind.
|
|
5725
|
+
*
|
|
5726
|
+
* Deliberately unvalidated beyond a length: an identifier's format belongs to whoever issued
|
|
5727
|
+
* it, and a pattern here would reject the next manufacturer's.
|
|
5728
|
+
*
|
|
5729
|
+
* @layer preset
|
|
5730
|
+
* @base string
|
|
5731
|
+
* @prim text
|
|
5732
|
+
* @widget identifier
|
|
5733
|
+
* @example f.identifier({ label: 'mod.fields.serialNumber' })
|
|
5734
|
+
*/
|
|
5735
|
+
function identifier(o) {
|
|
5736
|
+
return declare("identifier", o);
|
|
5737
|
+
}
|
|
5738
|
+
registerPreset("identifier", "string", {}, {
|
|
5739
|
+
kind: "identifier",
|
|
5740
|
+
widget: "identifier",
|
|
5741
|
+
build() {
|
|
5742
|
+
return {
|
|
5743
|
+
column: "text",
|
|
5744
|
+
zod: string$1(),
|
|
5745
|
+
hints: {}
|
|
5746
|
+
};
|
|
5747
|
+
}
|
|
5748
|
+
});
|
|
5749
|
+
/**
|
|
5750
|
+
* The machine-readable zone of a travel document — the identifier taken to its limit: printed
|
|
5751
|
+
* for a scanner, not for a person. Fixed pitch, chevrons kept as the filler they are, and the
|
|
5752
|
+
* line breaks preserved, because an MRZ's line structure is part of what it encodes.
|
|
5753
|
+
*
|
|
5754
|
+
* Unvalidated on purpose, like `identifier`: the ICAO line formats differ by document type, and
|
|
5755
|
+
* a strip transcribed from a real document is worth storing even when it does not check out.
|
|
5756
|
+
*
|
|
5757
|
+
* @layer preset
|
|
5758
|
+
* @base string
|
|
5759
|
+
* @prim text
|
|
5760
|
+
* @widget mrz
|
|
5761
|
+
* @example f.mrz({ label: 'documents.personal_document.fields.mrz' })
|
|
5762
|
+
*/
|
|
5763
|
+
function mrz(o) {
|
|
5764
|
+
return declare("mrz", o);
|
|
5765
|
+
}
|
|
5766
|
+
registerPreset("mrz", "string", {}, {
|
|
5767
|
+
kind: "mrz",
|
|
5768
|
+
widget: "mrz",
|
|
5769
|
+
build() {
|
|
5770
|
+
return {
|
|
5771
|
+
column: "text",
|
|
5772
|
+
zod: string$1(),
|
|
5773
|
+
hints: {}
|
|
5774
|
+
};
|
|
5775
|
+
}
|
|
5776
|
+
});
|
|
5711
5777
|
var COLOR_RE = /^#[0-9a-fA-F]{6}$/;
|
|
5712
5778
|
/**
|
|
5713
5779
|
* Hex color — kind 'color', `#rrggbb` + swatch widget.
|
|
@@ -5747,10 +5813,10 @@ function colorname(o) {
|
|
|
5747
5813
|
registerPreset("colorname", "string", {}, {
|
|
5748
5814
|
kind: "colorname",
|
|
5749
5815
|
widget: "colorname",
|
|
5750
|
-
build(
|
|
5816
|
+
build() {
|
|
5751
5817
|
return {
|
|
5752
5818
|
column: "text",
|
|
5753
|
-
zod:
|
|
5819
|
+
zod: string$1().refine((v) => CSS_COLOR_NAMES.has(v.toLowerCase()), { message: vmsg("colorname") }),
|
|
5754
5820
|
hints: {}
|
|
5755
5821
|
};
|
|
5756
5822
|
}
|
|
@@ -5770,10 +5836,10 @@ function title(o) {
|
|
|
5770
5836
|
registerPreset("title", "string", {}, {
|
|
5771
5837
|
kind: "title",
|
|
5772
5838
|
widget: "title",
|
|
5773
|
-
build(
|
|
5839
|
+
build() {
|
|
5774
5840
|
return {
|
|
5775
5841
|
column: "text",
|
|
5776
|
-
zod:
|
|
5842
|
+
zod: string$1(),
|
|
5777
5843
|
hints: {}
|
|
5778
5844
|
};
|
|
5779
5845
|
}
|
|
@@ -5794,12 +5860,10 @@ function link(o) {
|
|
|
5794
5860
|
registerPreset("link", "string", {}, {
|
|
5795
5861
|
kind: "link",
|
|
5796
5862
|
widget: "link",
|
|
5797
|
-
build(
|
|
5798
|
-
const required = o.required ?? false;
|
|
5799
|
-
const base_z = string$1().regex(LINK_RE, { message: vmsg("pattern", { messageKey: "core.presets.link" }) });
|
|
5863
|
+
build() {
|
|
5800
5864
|
return {
|
|
5801
5865
|
column: "text",
|
|
5802
|
-
zod:
|
|
5866
|
+
zod: string$1().regex(LINK_RE, { message: vmsg("pattern", { messageKey: "core.presets.link" }) }),
|
|
5803
5867
|
hints: {
|
|
5804
5868
|
format: "url",
|
|
5805
5869
|
inputType: "url"
|
|
@@ -5992,6 +6056,38 @@ registerPreset("tag", "string", {}, {
|
|
|
5992
6056
|
}
|
|
5993
6057
|
});
|
|
5994
6058
|
/**
|
|
6059
|
+
* A location written the way it is said aloud: workshop › shelf 2 › box. A `string` fixed to
|
|
6060
|
+
* `multiple`, exactly as `f.tags` is, because a place inside a place inside a place IS a
|
|
6061
|
+
* sequence — the plurality is the type, not a modifier someone remembered to add.
|
|
6062
|
+
*
|
|
6063
|
+
* Distinct from `f.tags`, which stores the same shape: tags are an unordered SET, and a path is
|
|
6064
|
+
* an ordered CHAIN where each step is inside the one before it. Drawn as chips, that
|
|
6065
|
+
* containment — the only thing the value actually carries — is lost.
|
|
6066
|
+
*
|
|
6067
|
+
* @layer preset
|
|
6068
|
+
* @base string
|
|
6069
|
+
* @prim text
|
|
6070
|
+
* @widget path
|
|
6071
|
+
* @example f.path({ label: 'things.storage_location.fields.path' })
|
|
6072
|
+
*/
|
|
6073
|
+
function path(o) {
|
|
6074
|
+
return declare("path", {
|
|
6075
|
+
...o,
|
|
6076
|
+
multiple: true
|
|
6077
|
+
});
|
|
6078
|
+
}
|
|
6079
|
+
registerPreset("path", "string", {}, {
|
|
6080
|
+
kind: "path",
|
|
6081
|
+
widget: "path",
|
|
6082
|
+
build() {
|
|
6083
|
+
return {
|
|
6084
|
+
column: "text",
|
|
6085
|
+
zod: string$1(),
|
|
6086
|
+
hints: {}
|
|
6087
|
+
};
|
|
6088
|
+
}
|
|
6089
|
+
});
|
|
6090
|
+
/**
|
|
5995
6091
|
* Tags — `tag({ multiple: true })`.
|
|
5996
6092
|
*
|
|
5997
6093
|
* @layer preset
|
|
@@ -6184,6 +6280,34 @@ registerPreset("reminder", "date", { lead: 30 }, {
|
|
|
6184
6280
|
};
|
|
6185
6281
|
}
|
|
6186
6282
|
});
|
|
6283
|
+
/** Timetable — a set of times of day, read as a schedule rather than as a bag of values.
|
|
6284
|
+
* kind 'timetable', prim 'time', always `multiple`.
|
|
6285
|
+
*
|
|
6286
|
+
* Same shape as `f.reminder`/`f.age` over `date`: a semantic type whose renderer knows what
|
|
6287
|
+
* the values MEAN. Everything it shows beyond the times themselves — when the service starts
|
|
6288
|
+
* and ends, how many runs there are, which one is next — is derived from the values at render
|
|
6289
|
+
* time, never stored: a "next departure" is wrong the moment it is written down, exactly the
|
|
6290
|
+
* argument `f.age` already makes for an age.
|
|
6291
|
+
*
|
|
6292
|
+
* Storage is a plain multiple `time`, so a field can be switched to this from
|
|
6293
|
+
* `f.time({ multiple: true })` and back with no migration.
|
|
6294
|
+
*
|
|
6295
|
+
* @layer preset
|
|
6296
|
+
* @base time
|
|
6297
|
+
* @prim time
|
|
6298
|
+
* @widget timetable
|
|
6299
|
+
* @example f.timetable({ label: 'mod.fields.weekdays' })
|
|
6300
|
+
*/
|
|
6301
|
+
function timetable(o) {
|
|
6302
|
+
return declare("timetable", {
|
|
6303
|
+
...o,
|
|
6304
|
+
multiple: true
|
|
6305
|
+
});
|
|
6306
|
+
}
|
|
6307
|
+
registerPreset("timetable", "time", {}, {
|
|
6308
|
+
kind: "timetable",
|
|
6309
|
+
widget: "timetable"
|
|
6310
|
+
});
|
|
6187
6311
|
/** Age — date whose whole-year age (as of today) renders alongside it, e.g. a birth date.
|
|
6188
6312
|
* kind 'age', prim 'date'. The age itself is computed at RENDER time, never stored: unlike a
|
|
6189
6313
|
* `mutate`-driven computed field, it must be right on every day that passes, not only the day
|
|
@@ -6398,6 +6522,9 @@ var presets = {
|
|
|
6398
6522
|
email,
|
|
6399
6523
|
tel,
|
|
6400
6524
|
slug,
|
|
6525
|
+
path,
|
|
6526
|
+
identifier,
|
|
6527
|
+
mrz,
|
|
6401
6528
|
color,
|
|
6402
6529
|
colorname,
|
|
6403
6530
|
title,
|
|
@@ -6412,6 +6539,7 @@ var presets = {
|
|
|
6412
6539
|
duration,
|
|
6413
6540
|
reminder,
|
|
6414
6541
|
age,
|
|
6542
|
+
timetable,
|
|
6415
6543
|
percent,
|
|
6416
6544
|
year,
|
|
6417
6545
|
weight,
|
|
@@ -6420,6 +6548,7 @@ var presets = {
|
|
|
6420
6548
|
currency,
|
|
6421
6549
|
money,
|
|
6422
6550
|
internalApiToken,
|
|
6551
|
+
internalIdentityLinks,
|
|
6423
6552
|
internalOauthGrants
|
|
6424
6553
|
};
|
|
6425
6554
|
//#endregion
|
|
@@ -7069,26 +7198,38 @@ function identity(opts) {
|
|
|
7069
7198
|
}
|
|
7070
7199
|
};
|
|
7071
7200
|
}
|
|
7072
|
-
/**
|
|
7201
|
+
/** One measure out of an optional max, from ONE OR MORE named sources, with an optional verdict.
|
|
7202
|
+
*
|
|
7203
|
+
* `source` takes several entries for the same reason `f.identity`'s `channels` does — it is a
|
|
7204
|
+
* role that holds a LIST, so `view.source` is an ordered list of names rather than one name.
|
|
7205
|
+
* Two ratings of the same film out of ten are one measure read twice, and drawing them apart is
|
|
7206
|
+
* what makes them incomparable: the eye has to carry the scale between two figures instead of
|
|
7207
|
+
* reading them against a shared one. `media/title` had exactly that, two `f.score` blocks of
|
|
7208
|
+
* `max: 10` held apart inside an `f.compare`, until this took the restriction off.
|
|
7209
|
+
*
|
|
7210
|
+
* NOT `multiple`. A multiple field is an anonymous array; these are NAMED sources, and the name
|
|
7211
|
+
* is what says which reading came from where. The two are different shapes and the block wants
|
|
7212
|
+
* this one.
|
|
7073
7213
|
*
|
|
7074
7214
|
* @layer block
|
|
7075
7215
|
* @base group
|
|
7076
7216
|
* @prim —
|
|
7077
7217
|
* @widget score
|
|
7078
|
-
* @example f.score({ source: {
|
|
7218
|
+
* @example f.score({ source: { imdb: f.real({ label: '…' }), tmdb: f.real({ label: '…' }) }, max: 10 })
|
|
7079
7219
|
*/
|
|
7080
7220
|
function score(opts) {
|
|
7081
|
-
const
|
|
7221
|
+
const names = Object.keys(opts.source ?? {});
|
|
7222
|
+
if (names.length === 0) throw new Error(`[field.score] slot 'source' expects at least one entry, got 0`);
|
|
7082
7223
|
const verdict = opts.verdict !== void 0 ? slot("score", "verdict", opts.verdict) : void 0;
|
|
7083
7224
|
return {
|
|
7084
7225
|
...group({
|
|
7085
7226
|
label: opts.label,
|
|
7086
|
-
fields: merge("score", source, verdict),
|
|
7227
|
+
fields: merge("score", opts.source, verdict),
|
|
7087
7228
|
ui: { kind: "score" }
|
|
7088
7229
|
}),
|
|
7089
7230
|
view: {
|
|
7090
7231
|
kind: "score",
|
|
7091
|
-
source:
|
|
7232
|
+
source: names,
|
|
7092
7233
|
max: opts.max,
|
|
7093
7234
|
verdict: verdict && Object.keys(verdict)[0]
|
|
7094
7235
|
}
|
|
@@ -7210,6 +7351,11 @@ function balance(opts) {
|
|
|
7210
7351
|
* @base group
|
|
7211
7352
|
* @prim —
|
|
7212
7353
|
* @widget route
|
|
7354
|
+
* A `stub` is the part of the ticket that is TORN OFF and kept — a seat, a gate, a booking
|
|
7355
|
+
* reference. Declaring one makes the block a ticket rather than a line: the two halves are
|
|
7356
|
+
* separated by a perforation, and the fields in the stub sit below it. Without one the block
|
|
7357
|
+
* is exactly what it was, a route from here to there, so no existing call changes.
|
|
7358
|
+
*
|
|
7213
7359
|
* @example f.route({ from: { from: f.string({ label: '…' }) }, to: { to: f.string({ label: '…' }) } })
|
|
7214
7360
|
*/
|
|
7215
7361
|
function route(opts) {
|
|
@@ -7218,9 +7364,10 @@ function route(opts) {
|
|
|
7218
7364
|
const depart = opts.depart !== void 0 ? slot("route", "depart", opts.depart) : void 0;
|
|
7219
7365
|
const arrive = opts.arrive !== void 0 ? slot("route", "arrive", opts.arrive) : void 0;
|
|
7220
7366
|
const duration = opts.duration !== void 0 ? slot("route", "duration", opts.duration) : void 0;
|
|
7367
|
+
const stub = opts.stub ?? {};
|
|
7221
7368
|
return {
|
|
7222
7369
|
...group({
|
|
7223
|
-
fields: merge("route", from, to, depart, arrive, duration),
|
|
7370
|
+
fields: merge("route", from, to, depart, arrive, duration, stub),
|
|
7224
7371
|
ui: { kind: "route" }
|
|
7225
7372
|
}),
|
|
7226
7373
|
view: {
|
|
@@ -7229,7 +7376,8 @@ function route(opts) {
|
|
|
7229
7376
|
to: Object.keys(to)[0],
|
|
7230
7377
|
depart: depart && Object.keys(depart)[0],
|
|
7231
7378
|
arrive: arrive && Object.keys(arrive)[0],
|
|
7232
|
-
duration: duration && Object.keys(duration)[0]
|
|
7379
|
+
duration: duration && Object.keys(duration)[0],
|
|
7380
|
+
stub: Object.keys(stub)
|
|
7233
7381
|
}
|
|
7234
7382
|
};
|
|
7235
7383
|
}
|
|
@@ -7407,6 +7555,81 @@ function specimen(opts) {
|
|
|
7407
7555
|
};
|
|
7408
7556
|
}
|
|
7409
7557
|
/**
|
|
7558
|
+
* Measurements against the range they were supposed to fall in, rendered from a single
|
|
7559
|
+
* collection source — see `stampCollection`. `analyte`, `value`, `unit`, `low` and `high` are
|
|
7560
|
+
* part KEYS inside each collection row, NOT `LayoutEl` positions — the same reasoning as
|
|
7561
|
+
* `manifest`'s `quantity`/`item`.
|
|
7562
|
+
*
|
|
7563
|
+
* The point is the COMPARISON. A `f.table` over the same rows prints the bounds as two more
|
|
7564
|
+
* columns and leaves the reader to do it; here each value sits on its own band with the
|
|
7565
|
+
* reference span marked on it, so "outside the range" is seen rather than worked out. That is
|
|
7566
|
+
* also the only thing on the row worth a colour — it is what the reader has to act on.
|
|
7567
|
+
*
|
|
7568
|
+
* `unit`, `low` and `high` are optional: a measurement with no published range (a culture, a
|
|
7569
|
+
* description) still belongs in the same list and simply gets no band.
|
|
7570
|
+
*
|
|
7571
|
+
* @layer block
|
|
7572
|
+
* @base group
|
|
7573
|
+
* @prim —
|
|
7574
|
+
* @widget assay
|
|
7575
|
+
* @example f.assay({ source: { results: f.group({ scope: 'nest', multiple: true, fields: { analyte: f.string({ label: '…' }), value: f.real({ label: '…' }) } }) }, analyte: 'analyte', value: 'value' })
|
|
7576
|
+
*/
|
|
7577
|
+
function assay(opts) {
|
|
7578
|
+
return stampCollection("assay", opts.source, opts.label, {
|
|
7579
|
+
kind: "assay",
|
|
7580
|
+
analyte: opts.analyte,
|
|
7581
|
+
value: opts.value,
|
|
7582
|
+
...opts.unit ? { unit: opts.unit } : {},
|
|
7583
|
+
...opts.low ? { low: opts.low } : {},
|
|
7584
|
+
...opts.high ? { high: opts.high } : {}
|
|
7585
|
+
});
|
|
7586
|
+
}
|
|
7587
|
+
/**
|
|
7588
|
+
* Value moving from one place to another, where the MOVEMENT is the subject — not one more
|
|
7589
|
+
* labelled row among the record's fields. The sum is set large in the machine voice, and the two
|
|
7590
|
+
* ends read as a path beneath it.
|
|
7591
|
+
*
|
|
7592
|
+
* amount — what moved. The one required role, and the reason the block exists
|
|
7593
|
+
* from — where it left. Absent on money that only arrived
|
|
7594
|
+
* to — where it arrived. Absent on money that only left
|
|
7595
|
+
* meta — the record's own remaining fields, under a rule: date, category, reference
|
|
7596
|
+
*
|
|
7597
|
+
* An absent end is not drawn, and that is the whole reading: money that left an account and
|
|
7598
|
+
* arrived nowhere IS an expense. It is read off which ends the record actually has, never
|
|
7599
|
+
* guessed from the shape of a value. What the movement MEANS beyond that — whether this
|
|
7600
|
+
* particular kind of transfer is good news — is carried by the classifier's own option `tone`,
|
|
7601
|
+
* the same declaration every other coloured value in the product uses.
|
|
7602
|
+
*
|
|
7603
|
+
* Distinct from `f.route`, which also has two ends: there the journey is the subject and the
|
|
7604
|
+
* ends are places, so it carries times and a duration; here the ends are accounts and the
|
|
7605
|
+
* subject is the quantity.
|
|
7606
|
+
*
|
|
7607
|
+
* @layer block
|
|
7608
|
+
* @base group
|
|
7609
|
+
* @prim —
|
|
7610
|
+
* @widget flow
|
|
7611
|
+
* @example f.flow({ amount: { amount: f.money({ label: '…' }) }, from: { source: f.relation({ label: '…' }) } })
|
|
7612
|
+
*/
|
|
7613
|
+
function flow(opts) {
|
|
7614
|
+
const amount = slot("flow", "amount", opts.amount);
|
|
7615
|
+
const from = opts.from !== void 0 ? slot("flow", "from", opts.from) : void 0;
|
|
7616
|
+
const to = opts.to !== void 0 ? slot("flow", "to", opts.to) : void 0;
|
|
7617
|
+
return {
|
|
7618
|
+
...group({
|
|
7619
|
+
label: opts.label,
|
|
7620
|
+
fields: merge("flow", amount, from, to, opts.meta),
|
|
7621
|
+
ui: { kind: "flow" }
|
|
7622
|
+
}),
|
|
7623
|
+
view: {
|
|
7624
|
+
kind: "flow",
|
|
7625
|
+
amount: Object.keys(amount)[0],
|
|
7626
|
+
from: from && Object.keys(from)[0],
|
|
7627
|
+
to: to && Object.keys(to)[0],
|
|
7628
|
+
meta: Object.keys(opts.meta ?? {})
|
|
7629
|
+
}
|
|
7630
|
+
};
|
|
7631
|
+
}
|
|
7632
|
+
/**
|
|
7410
7633
|
* A packing/cargo manifest rendered from a single collection source — see `stampCollection`.
|
|
7411
7634
|
* `quantity` and `item` are part KEYS inside each collection row, NOT `LayoutEl` positions —
|
|
7412
7635
|
* the same reasoning as `journal`'s `date`/`text`.
|
|
@@ -7453,13 +7676,25 @@ function table(opts) {
|
|
|
7453
7676
|
} : {},
|
|
7454
7677
|
...opts.groupBy ? { groupBy: opts.groupBy } : {},
|
|
7455
7678
|
...opts.totals ? { totals: opts.totals } : {},
|
|
7679
|
+
...opts.summary ? { summary: opts.summary } : {},
|
|
7456
7680
|
...opts.numbered ? { numbered: true } : {}
|
|
7457
7681
|
});
|
|
7458
7682
|
}
|
|
7459
7683
|
/**
|
|
7460
|
-
* An
|
|
7461
|
-
*
|
|
7462
|
-
*
|
|
7684
|
+
* An identity document, drawn as the card it is: a caption and its number across the top, a
|
|
7685
|
+
* portrait beside the holder's own fields, the issuing details under a rule, and the
|
|
7686
|
+
* machine-readable strip at the foot. `view` names each role (Task 5) — see `masthead`'s own
|
|
7687
|
+
* doc comment for what an ordered name list means.
|
|
7688
|
+
*
|
|
7689
|
+
* overline — the caption at the top left ("PASSPORT", "DRIVING LICENCE")
|
|
7690
|
+
* number — the document's number, set apart at the top right
|
|
7691
|
+
* photo — the portrait. One field, rendered in a portrait frame beside the body
|
|
7692
|
+
* meta — the card's OWN fields, labelled, at each field's declared span
|
|
7693
|
+
* footer — the fields below the rule: issued, authority, record number
|
|
7694
|
+
* mrz — the machine-readable strip, set in monospace at the foot
|
|
7695
|
+
*
|
|
7696
|
+
* Every role is optional but `number`: a bank card has no `mrz`, a library card no `photo`,
|
|
7697
|
+
* and the card simply omits the part it was given nothing for.
|
|
7463
7698
|
*
|
|
7464
7699
|
* @layer block
|
|
7465
7700
|
* @base group
|
|
@@ -7470,16 +7705,21 @@ function table(opts) {
|
|
|
7470
7705
|
function idcard(opts) {
|
|
7471
7706
|
const overline = opts.overline !== void 0 ? slot("idcard", "overline", opts.overline) : void 0;
|
|
7472
7707
|
const number = slot("idcard", "number", opts.number);
|
|
7708
|
+
const photo = opts.photo !== void 0 ? slot("idcard", "photo", opts.photo) : void 0;
|
|
7709
|
+
const mrz = opts.mrz !== void 0 ? slot("idcard", "mrz", opts.mrz) : void 0;
|
|
7473
7710
|
return {
|
|
7474
7711
|
...group({
|
|
7475
|
-
fields: merge("idcard", overline, number, opts.meta),
|
|
7712
|
+
fields: merge("idcard", overline, number, photo, opts.meta, opts.footer, mrz),
|
|
7476
7713
|
ui: { kind: "idcard" }
|
|
7477
7714
|
}),
|
|
7478
7715
|
view: {
|
|
7479
7716
|
kind: "idcard",
|
|
7480
7717
|
overline: overline && Object.keys(overline)[0],
|
|
7481
7718
|
number: Object.keys(number)[0],
|
|
7482
|
-
|
|
7719
|
+
photo: photo && Object.keys(photo)[0],
|
|
7720
|
+
meta: Object.keys(opts.meta ?? {}),
|
|
7721
|
+
footer: Object.keys(opts.footer ?? {}),
|
|
7722
|
+
mrz: mrz && Object.keys(mrz)[0]
|
|
7483
7723
|
}
|
|
7484
7724
|
};
|
|
7485
7725
|
}
|
|
@@ -7564,6 +7804,8 @@ var blocks = {
|
|
|
7564
7804
|
nutrition,
|
|
7565
7805
|
specimen,
|
|
7566
7806
|
manifest,
|
|
7807
|
+
assay,
|
|
7808
|
+
flow,
|
|
7567
7809
|
table,
|
|
7568
7810
|
idcard,
|
|
7569
7811
|
properties,
|
|
@@ -8426,18 +8668,23 @@ function group(o) {
|
|
|
8426
8668
|
for (const f of fields) if (!("key" in f && f.key !== void 0) && !hasChildren(f)) throw new Error(`[field.group] a 'nest' group's children must be fields or groups, not layout elements`);
|
|
8427
8669
|
for (const k of r.unique ?? []) if (!fields.some((f) => "key" in f && f.key === k)) throw new Error(`[field.group] unique key '${k}' is not a subfield`);
|
|
8428
8670
|
} else if (o.value !== void 0) throw new Error(`[field.group] value requires scope 'nest' — a hoist group owns no children to write`);
|
|
8671
|
+
const title = v.title ?? [];
|
|
8672
|
+
if (title.length > 0) {
|
|
8673
|
+
if (!o.multiple) throw new Error(`[field.group] ui.title heads a collection's ROWS — it needs multiple: true`);
|
|
8674
|
+
for (const name of title) if (!fields.some((f) => "key" in f && f.key === name)) throw new Error(`[field.group] ui.title '${name}' is not one of its fields`);
|
|
8675
|
+
}
|
|
8429
8676
|
return {
|
|
8430
8677
|
el: "group",
|
|
8431
8678
|
scope,
|
|
8432
8679
|
multiple: o.multiple,
|
|
8433
8680
|
compute: o.value,
|
|
8434
|
-
required: o.required,
|
|
8435
8681
|
unique: r.unique,
|
|
8436
8682
|
label: o.label,
|
|
8437
8683
|
icon: o.icon,
|
|
8438
8684
|
display: v.display ?? "wrap",
|
|
8439
8685
|
kind: v.kind,
|
|
8440
8686
|
fixed: r.fixed,
|
|
8687
|
+
view: title.length > 0 ? { title } : void 0,
|
|
8441
8688
|
fields
|
|
8442
8689
|
};
|
|
8443
8690
|
}
|
|
@@ -8463,7 +8710,6 @@ function row(o) {
|
|
|
8463
8710
|
icon: o.icon,
|
|
8464
8711
|
fields: o.fields,
|
|
8465
8712
|
multiple: o.multiple,
|
|
8466
|
-
required: o.required,
|
|
8467
8713
|
rules: o.rules,
|
|
8468
8714
|
ui: { display: "scroll" }
|
|
8469
8715
|
});
|
|
@@ -8511,7 +8757,6 @@ function url(o) {
|
|
|
8511
8757
|
return group({
|
|
8512
8758
|
scope: "nest",
|
|
8513
8759
|
label: o.label,
|
|
8514
|
-
required: o.required,
|
|
8515
8760
|
ui: { kind: "url" },
|
|
8516
8761
|
fields: {
|
|
8517
8762
|
scheme: string({}),
|
|
@@ -8563,13 +8808,11 @@ function keyed(o) {
|
|
|
8563
8808
|
}),
|
|
8564
8809
|
scope: "nest",
|
|
8565
8810
|
multiple: true,
|
|
8566
|
-
required: o.required,
|
|
8567
8811
|
unique: o.unique ?? [role],
|
|
8568
8812
|
fixed: o.fixed,
|
|
8569
8813
|
view: { by: role }
|
|
8570
8814
|
};
|
|
8571
8815
|
}
|
|
8572
|
-
var isStorageGroup = (g) => g.scope === "nest";
|
|
8573
8816
|
var isCollectionGroup = (g) => g.scope === "nest" && g.multiple === true;
|
|
8574
8817
|
var isEmbeddedGroup = (g) => g.scope === "nest" && g.multiple !== true;
|
|
8575
8818
|
/**
|
|
@@ -8607,6 +8850,31 @@ function info(textKey) {
|
|
|
8607
8850
|
};
|
|
8608
8851
|
}
|
|
8609
8852
|
/**
|
|
8853
|
+
* What else points AT this record — the inverse of a relation, which is often the more useful
|
|
8854
|
+
* direction on a record page: a box is more usefully "what is in it" than "what it is in".
|
|
8855
|
+
*
|
|
8856
|
+
* Stores NOTHING and has no column: it declares where to look, and the server answers by asking
|
|
8857
|
+
* the pointing shelf. That is why it is a pseudo-element beside `divider` and `info` rather than
|
|
8858
|
+
* a field — there is no value here to validate or save.
|
|
8859
|
+
*
|
|
8860
|
+
* `from` names the pointing side explicitly (which shelf, and WHICH of its fields), never
|
|
8861
|
+
* "everything that happens to point here": a shelf may point at the same target through two
|
|
8862
|
+
* fields — a transaction has a source account and a destination account — and a panel that
|
|
8863
|
+
* merged them would answer a question nobody asked.
|
|
8864
|
+
*
|
|
8865
|
+
* @layer primitive
|
|
8866
|
+
* @prim —
|
|
8867
|
+
* @widget backrefs
|
|
8868
|
+
* @example f.backrefs({ label: 'mod.fields.storedHere', from: { library: 'things', shelf: 'item', field: 'location' } })
|
|
8869
|
+
*/
|
|
8870
|
+
function backrefs(o) {
|
|
8871
|
+
return {
|
|
8872
|
+
el: "backrefs",
|
|
8873
|
+
label: o.label,
|
|
8874
|
+
from: o.from
|
|
8875
|
+
};
|
|
8876
|
+
}
|
|
8877
|
+
/**
|
|
8610
8878
|
* Action button: invokes the handler registered in actionRegistry under the key `value`.
|
|
8611
8879
|
*
|
|
8612
8880
|
* @layer primitive
|
|
@@ -8662,7 +8930,7 @@ registerType("string", {
|
|
|
8662
8930
|
widget: "text",
|
|
8663
8931
|
build(o) {
|
|
8664
8932
|
const cfg = o.config ?? {};
|
|
8665
|
-
const min = cfg.min ??
|
|
8933
|
+
const min = cfg.min ?? 0;
|
|
8666
8934
|
return {
|
|
8667
8935
|
column: "text",
|
|
8668
8936
|
zod: stringContent((str) => {
|
|
@@ -8690,9 +8958,9 @@ registerType("string", {
|
|
|
8690
8958
|
function string(o) {
|
|
8691
8959
|
return declare("string", o);
|
|
8692
8960
|
}
|
|
8693
|
-
/** Shared by localDir/localFile's build(): a server path,
|
|
8694
|
-
function pathZod(
|
|
8695
|
-
return stringContent((s) =>
|
|
8961
|
+
/** Shared by localDir/localFile's build(): a server path, judged only when one was entered. */
|
|
8962
|
+
function pathZod(_o) {
|
|
8963
|
+
return stringContent((s) => s);
|
|
8696
8964
|
}
|
|
8697
8965
|
registerType("localDir", {
|
|
8698
8966
|
kind: "localDir",
|
|
@@ -8931,20 +9199,22 @@ registerType("time", {
|
|
|
8931
9199
|
prim: "time",
|
|
8932
9200
|
widget: "time",
|
|
8933
9201
|
build(o) {
|
|
8934
|
-
const granularity = o.config?.granularity ?? "
|
|
9202
|
+
const granularity = o.config?.granularity ?? "minute";
|
|
9203
|
+
const s = string$1(reqErr()).regex({
|
|
9204
|
+
hour: /^([01]\d|2[0-3])$/,
|
|
9205
|
+
minute: /^([01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$/,
|
|
9206
|
+
second: /^([01]\d|2[0-3]):[0-5]\d:[0-5]\d$/
|
|
9207
|
+
}[granularity], { message: vmsg("time_format") });
|
|
8935
9208
|
return {
|
|
8936
9209
|
column: "time",
|
|
8937
|
-
zod:
|
|
8938
|
-
hour: /^([01]\d|2[0-3])$/,
|
|
8939
|
-
minute: /^([01]\d|2[0-3]):[0-5]\d$/,
|
|
8940
|
-
second: /^([01]\d|2[0-3]):[0-5]\d:[0-5]\d$/
|
|
8941
|
-
}[granularity], { message: vmsg("time_format") }),
|
|
9210
|
+
zod: granularity === "minute" ? s.transform((v) => v.slice(0, 5)) : s,
|
|
8942
9211
|
hints: { granularity }
|
|
8943
9212
|
};
|
|
8944
9213
|
}
|
|
8945
9214
|
});
|
|
8946
9215
|
/**
|
|
8947
|
-
* Time-of-day value with configurable granularity ('hour' | 'minute' | 'second', default
|
|
9216
|
+
* Time-of-day value with configurable granularity ('hour' | 'minute' | 'second', default
|
|
9217
|
+
* 'minute' — the same default `f.datetime` has always had).
|
|
8948
9218
|
*
|
|
8949
9219
|
* @layer primitive
|
|
8950
9220
|
* @prim time
|
|
@@ -9349,10 +9619,9 @@ var MEASURED_ROLES = (opts) => {
|
|
|
9349
9619
|
accepts: ENUMERATED,
|
|
9350
9620
|
normalize: (d) => {
|
|
9351
9621
|
if (d && accepts(unitRole, d)) return d;
|
|
9352
|
-
const { label,
|
|
9622
|
+
const { label, value } = d?.opts ?? {};
|
|
9353
9623
|
return declare("string", {
|
|
9354
9624
|
label,
|
|
9355
|
-
required,
|
|
9356
9625
|
value,
|
|
9357
9626
|
noSearch: d?.opts.noSearch,
|
|
9358
9627
|
ui: uiOf(d?.opts),
|
|
@@ -9511,7 +9780,7 @@ registerType("geo", {
|
|
|
9511
9780
|
label: string$1().nullish()
|
|
9512
9781
|
}),
|
|
9513
9782
|
structureCode: "geo_structure",
|
|
9514
|
-
|
|
9783
|
+
acceptsEmptyRow: true
|
|
9515
9784
|
});
|
|
9516
9785
|
/**
|
|
9517
9786
|
* Geographic point composite {lat, lng, label?}; lat/lng validated to valid coordinate
|
|
@@ -9589,7 +9858,7 @@ registerType("illustrated", {
|
|
|
9589
9858
|
roles: ILLUSTRATED_ROLES,
|
|
9590
9859
|
roleZod: () => defaultRoleZod(ILLUSTRATED_ROLES),
|
|
9591
9860
|
structureCode: "illustrated_structure",
|
|
9592
|
-
|
|
9861
|
+
acceptsEmptyRow: true,
|
|
9593
9862
|
collectionView: "illustratedList",
|
|
9594
9863
|
hints: (o) => o.config ? { config: o.config } : {}
|
|
9595
9864
|
});
|
|
@@ -9633,7 +9902,7 @@ registerType("attachment", {
|
|
|
9633
9902
|
roles: ATTACHMENT_ROLES,
|
|
9634
9903
|
roleZod: () => defaultRoleZod(ATTACHMENT_ROLES),
|
|
9635
9904
|
structureCode: "attachment_structure",
|
|
9636
|
-
|
|
9905
|
+
acceptsEmptyRow: true,
|
|
9637
9906
|
collectionView: "attachmentList"
|
|
9638
9907
|
});
|
|
9639
9908
|
/**
|
|
@@ -9734,11 +10003,10 @@ function periodRole(key, label, mkSubDecl) {
|
|
|
9734
10003
|
if (d && accepts(def, d)) return d;
|
|
9735
10004
|
const canonical = mkSubDecl(label);
|
|
9736
10005
|
if (!d) return canonical;
|
|
9737
|
-
const { label: l,
|
|
10006
|
+
const { label: l, value } = d.opts;
|
|
9738
10007
|
return declare(canonical.factory, {
|
|
9739
10008
|
...canonical.opts,
|
|
9740
10009
|
label: l ?? canonical.opts.label,
|
|
9741
|
-
required,
|
|
9742
10010
|
value,
|
|
9743
10011
|
noSearch: d.opts.noSearch,
|
|
9744
10012
|
ui: uiOf(d.opts)
|
|
@@ -10022,8 +10290,7 @@ function keyValue(raw) {
|
|
|
10022
10290
|
type: valueType
|
|
10023
10291
|
}
|
|
10024
10292
|
},
|
|
10025
|
-
by: "key"
|
|
10026
|
-
required: o.required
|
|
10293
|
+
by: "key"
|
|
10027
10294
|
});
|
|
10028
10295
|
}
|
|
10029
10296
|
/** Roles of a range: the two endpoints, integer or real depending on `isInt`. */
|
|
@@ -10189,7 +10456,8 @@ var PRIMITIVES = {
|
|
|
10189
10456
|
url,
|
|
10190
10457
|
divider,
|
|
10191
10458
|
info,
|
|
10192
|
-
button
|
|
10459
|
+
button,
|
|
10460
|
+
backrefs
|
|
10193
10461
|
};
|
|
10194
10462
|
/** Assembles `f`, guaranteeing no preset/block shadows a primitive. */
|
|
10195
10463
|
function composeF(presets, blocks) {
|
|
@@ -10209,12 +10477,11 @@ var field = new Proxy({}, {
|
|
|
10209
10477
|
has: (_t, k) => k in composedField()
|
|
10210
10478
|
});
|
|
10211
10479
|
function toClient(field) {
|
|
10212
|
-
const { kind, label, agent,
|
|
10480
|
+
const { kind, label, agent, prim, hints, options, strict, relation, json, hidden, derived, parts, cache } = field;
|
|
10213
10481
|
return {
|
|
10214
10482
|
kind,
|
|
10215
10483
|
label,
|
|
10216
10484
|
...agent !== void 0 && { agent },
|
|
10217
|
-
required,
|
|
10218
10485
|
prim,
|
|
10219
10486
|
hints,
|
|
10220
10487
|
options,
|
|
@@ -10238,680 +10505,6 @@ function defineSettings(s) {
|
|
|
10238
10505
|
return materializeDef(s);
|
|
10239
10506
|
}
|
|
10240
10507
|
//#endregion
|
|
10241
|
-
//#region ../../node_modules/sift/es5m/index.js
|
|
10242
|
-
/******************************************************************************
|
|
10243
|
-
Copyright (c) Microsoft Corporation.
|
|
10244
|
-
|
|
10245
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
10246
|
-
purpose with or without fee is hereby granted.
|
|
10247
|
-
|
|
10248
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10249
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
10250
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
10251
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
10252
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
10253
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
10254
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
10255
|
-
***************************************************************************** */
|
|
10256
|
-
var extendStatics = function(d, b) {
|
|
10257
|
-
extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d, b) {
|
|
10258
|
-
d.__proto__ = b;
|
|
10259
|
-
} || function(d, b) {
|
|
10260
|
-
for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
|
|
10261
|
-
};
|
|
10262
|
-
return extendStatics(d, b);
|
|
10263
|
-
};
|
|
10264
|
-
function __extends(d, b) {
|
|
10265
|
-
if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
10266
|
-
extendStatics(d, b);
|
|
10267
|
-
function __() {
|
|
10268
|
-
this.constructor = d;
|
|
10269
|
-
}
|
|
10270
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
10271
|
-
}
|
|
10272
|
-
var typeChecker = function(type) {
|
|
10273
|
-
var typeString = "[object " + type + "]";
|
|
10274
|
-
return function(value) {
|
|
10275
|
-
return getClassName(value) === typeString;
|
|
10276
|
-
};
|
|
10277
|
-
};
|
|
10278
|
-
var getClassName = function(value) {
|
|
10279
|
-
return Object.prototype.toString.call(value);
|
|
10280
|
-
};
|
|
10281
|
-
var comparable = function(value) {
|
|
10282
|
-
if (value instanceof Date) return value.getTime();
|
|
10283
|
-
else if (isArray(value)) return value.map(comparable);
|
|
10284
|
-
else if (value && typeof value.toJSON === "function") return value.toJSON();
|
|
10285
|
-
return value;
|
|
10286
|
-
};
|
|
10287
|
-
var coercePotentiallyNull = function(value) {
|
|
10288
|
-
return value == null ? null : value;
|
|
10289
|
-
};
|
|
10290
|
-
var isArray = typeChecker("Array");
|
|
10291
|
-
var isObject = typeChecker("Object");
|
|
10292
|
-
var isFunction = typeChecker("Function");
|
|
10293
|
-
var isProperty = function(item, key) {
|
|
10294
|
-
return item.hasOwnProperty(key) && !isFunction(item[key]);
|
|
10295
|
-
};
|
|
10296
|
-
var isVanillaObject = function(value) {
|
|
10297
|
-
return value && (value.constructor === Object || value.constructor === Array || value.constructor.toString() === "function Object() { [native code] }" || value.constructor.toString() === "function Array() { [native code] }") && !value.toJSON;
|
|
10298
|
-
};
|
|
10299
|
-
var equals = function(a, b) {
|
|
10300
|
-
if (a == null && a == b) return true;
|
|
10301
|
-
if (a === b) return true;
|
|
10302
|
-
if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) return false;
|
|
10303
|
-
if (isArray(a)) {
|
|
10304
|
-
if (a.length !== b.length) return false;
|
|
10305
|
-
for (var i = 0, length_1 = a.length; i < length_1; i++) if (!equals(a[i], b[i])) return false;
|
|
10306
|
-
return true;
|
|
10307
|
-
} else if (isObject(a)) {
|
|
10308
|
-
if (Object.keys(a).length !== Object.keys(b).length) return false;
|
|
10309
|
-
for (var key in a) if (!equals(a[key], b[key])) return false;
|
|
10310
|
-
return true;
|
|
10311
|
-
}
|
|
10312
|
-
return false;
|
|
10313
|
-
};
|
|
10314
|
-
/**
|
|
10315
|
-
* Walks through each value given the context - used for nested operations. E.g:
|
|
10316
|
-
* { "person.address": { $eq: "blarg" }}
|
|
10317
|
-
*/
|
|
10318
|
-
var walkKeyPathValues = function(item, keyPath, next, depth, key, owner) {
|
|
10319
|
-
var currentKey = keyPath[depth];
|
|
10320
|
-
if (isArray(item) && isNaN(Number(currentKey)) && !isProperty(item, currentKey)) {
|
|
10321
|
-
for (var i = 0, length_1 = item.length; i < length_1; i++) if (!walkKeyPathValues(item[i], keyPath, next, depth, i, item)) return false;
|
|
10322
|
-
}
|
|
10323
|
-
if (depth === keyPath.length || item == null) return next(item, key, owner, depth === 0, depth === keyPath.length);
|
|
10324
|
-
return walkKeyPathValues(item[currentKey], keyPath, next, depth + 1, currentKey, item);
|
|
10325
|
-
};
|
|
10326
|
-
var BaseOperation = function() {
|
|
10327
|
-
function BaseOperation(params, owneryQuery, options, name) {
|
|
10328
|
-
this.params = params;
|
|
10329
|
-
this.owneryQuery = owneryQuery;
|
|
10330
|
-
this.options = options;
|
|
10331
|
-
this.name = name;
|
|
10332
|
-
this.init();
|
|
10333
|
-
}
|
|
10334
|
-
BaseOperation.prototype.init = function() {};
|
|
10335
|
-
BaseOperation.prototype.reset = function() {
|
|
10336
|
-
this.done = false;
|
|
10337
|
-
this.keep = false;
|
|
10338
|
-
};
|
|
10339
|
-
return BaseOperation;
|
|
10340
|
-
}();
|
|
10341
|
-
var GroupOperation = function(_super) {
|
|
10342
|
-
__extends(GroupOperation, _super);
|
|
10343
|
-
function GroupOperation(params, owneryQuery, options, children) {
|
|
10344
|
-
var _this = _super.call(this, params, owneryQuery, options) || this;
|
|
10345
|
-
_this.children = children;
|
|
10346
|
-
return _this;
|
|
10347
|
-
}
|
|
10348
|
-
/**
|
|
10349
|
-
*/
|
|
10350
|
-
GroupOperation.prototype.reset = function() {
|
|
10351
|
-
this.keep = false;
|
|
10352
|
-
this.done = false;
|
|
10353
|
-
for (var i = 0, length_2 = this.children.length; i < length_2; i++) this.children[i].reset();
|
|
10354
|
-
};
|
|
10355
|
-
/**
|
|
10356
|
-
*/
|
|
10357
|
-
GroupOperation.prototype.childrenNext = function(item, key, owner, root, leaf) {
|
|
10358
|
-
var done = true;
|
|
10359
|
-
var keep = true;
|
|
10360
|
-
for (var i = 0, length_3 = this.children.length; i < length_3; i++) {
|
|
10361
|
-
var childOperation = this.children[i];
|
|
10362
|
-
if (!childOperation.done) childOperation.next(item, key, owner, root, leaf);
|
|
10363
|
-
if (!childOperation.keep) keep = false;
|
|
10364
|
-
if (childOperation.done) {
|
|
10365
|
-
if (!childOperation.keep) break;
|
|
10366
|
-
} else done = false;
|
|
10367
|
-
}
|
|
10368
|
-
this.done = done;
|
|
10369
|
-
this.keep = keep;
|
|
10370
|
-
};
|
|
10371
|
-
return GroupOperation;
|
|
10372
|
-
}(BaseOperation);
|
|
10373
|
-
var NamedGroupOperation = function(_super) {
|
|
10374
|
-
__extends(NamedGroupOperation, _super);
|
|
10375
|
-
function NamedGroupOperation(params, owneryQuery, options, children, name) {
|
|
10376
|
-
var _this = _super.call(this, params, owneryQuery, options, children) || this;
|
|
10377
|
-
_this.name = name;
|
|
10378
|
-
return _this;
|
|
10379
|
-
}
|
|
10380
|
-
return NamedGroupOperation;
|
|
10381
|
-
}(GroupOperation);
|
|
10382
|
-
var QueryOperation = function(_super) {
|
|
10383
|
-
__extends(QueryOperation, _super);
|
|
10384
|
-
function QueryOperation() {
|
|
10385
|
-
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
10386
|
-
_this.propop = true;
|
|
10387
|
-
return _this;
|
|
10388
|
-
}
|
|
10389
|
-
/**
|
|
10390
|
-
*/
|
|
10391
|
-
QueryOperation.prototype.next = function(item, key, parent, root) {
|
|
10392
|
-
this.childrenNext(item, key, parent, root);
|
|
10393
|
-
};
|
|
10394
|
-
return QueryOperation;
|
|
10395
|
-
}(GroupOperation);
|
|
10396
|
-
var NestedOperation = function(_super) {
|
|
10397
|
-
__extends(NestedOperation, _super);
|
|
10398
|
-
function NestedOperation(keyPath, params, owneryQuery, options, children) {
|
|
10399
|
-
var _this = _super.call(this, params, owneryQuery, options, children) || this;
|
|
10400
|
-
_this.keyPath = keyPath;
|
|
10401
|
-
_this.propop = true;
|
|
10402
|
-
/**
|
|
10403
|
-
*/
|
|
10404
|
-
_this._nextNestedValue = function(value, key, owner, root, leaf) {
|
|
10405
|
-
_this.childrenNext(value, key, owner, root, leaf);
|
|
10406
|
-
return !_this.done;
|
|
10407
|
-
};
|
|
10408
|
-
return _this;
|
|
10409
|
-
}
|
|
10410
|
-
/**
|
|
10411
|
-
*/
|
|
10412
|
-
NestedOperation.prototype.next = function(item, key, parent) {
|
|
10413
|
-
walkKeyPathValues(item, this.keyPath, this._nextNestedValue, 0, key, parent);
|
|
10414
|
-
};
|
|
10415
|
-
return NestedOperation;
|
|
10416
|
-
}(GroupOperation);
|
|
10417
|
-
var createTester = function(a, compare) {
|
|
10418
|
-
if (a instanceof Function) return a;
|
|
10419
|
-
if (a instanceof RegExp) return function(b) {
|
|
10420
|
-
var result = typeof b === "string" && a.test(b);
|
|
10421
|
-
a.lastIndex = 0;
|
|
10422
|
-
return result;
|
|
10423
|
-
};
|
|
10424
|
-
var comparableA = comparable(a);
|
|
10425
|
-
return function(b) {
|
|
10426
|
-
return compare(comparableA, comparable(b));
|
|
10427
|
-
};
|
|
10428
|
-
};
|
|
10429
|
-
var EqualsOperation = function(_super) {
|
|
10430
|
-
__extends(EqualsOperation, _super);
|
|
10431
|
-
function EqualsOperation() {
|
|
10432
|
-
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
10433
|
-
_this.propop = true;
|
|
10434
|
-
return _this;
|
|
10435
|
-
}
|
|
10436
|
-
EqualsOperation.prototype.init = function() {
|
|
10437
|
-
this._test = createTester(this.params, this.options.compare);
|
|
10438
|
-
};
|
|
10439
|
-
EqualsOperation.prototype.next = function(item, key, parent) {
|
|
10440
|
-
if (!Array.isArray(parent) || parent.hasOwnProperty(key)) {
|
|
10441
|
-
if (this._test(item, key, parent)) {
|
|
10442
|
-
this.done = true;
|
|
10443
|
-
this.keep = true;
|
|
10444
|
-
}
|
|
10445
|
-
}
|
|
10446
|
-
};
|
|
10447
|
-
return EqualsOperation;
|
|
10448
|
-
}(BaseOperation);
|
|
10449
|
-
var numericalOperationCreator = function(createNumericalOperation) {
|
|
10450
|
-
return function(params, owneryQuery, options, name) {
|
|
10451
|
-
return createNumericalOperation(params, owneryQuery, options, name);
|
|
10452
|
-
};
|
|
10453
|
-
};
|
|
10454
|
-
var numericalOperation = function(createTester) {
|
|
10455
|
-
return numericalOperationCreator(function(params, owneryQuery, options, name) {
|
|
10456
|
-
var typeofParams = typeof comparable(params);
|
|
10457
|
-
var test = createTester(params);
|
|
10458
|
-
return new EqualsOperation(function(b) {
|
|
10459
|
-
var actualValue = coercePotentiallyNull(b);
|
|
10460
|
-
return typeof comparable(actualValue) === typeofParams && test(actualValue);
|
|
10461
|
-
}, owneryQuery, options, name);
|
|
10462
|
-
});
|
|
10463
|
-
};
|
|
10464
|
-
var createNamedOperation = function(name, params, parentQuery, options) {
|
|
10465
|
-
var operationCreator = options.operations[name];
|
|
10466
|
-
if (!operationCreator) throwUnsupportedOperation(name);
|
|
10467
|
-
return operationCreator(params, parentQuery, options, name);
|
|
10468
|
-
};
|
|
10469
|
-
var throwUnsupportedOperation = function(name) {
|
|
10470
|
-
throw new Error("Unsupported operation: ".concat(name));
|
|
10471
|
-
};
|
|
10472
|
-
var containsOperation = function(query, options) {
|
|
10473
|
-
for (var key in query) if (options.operations.hasOwnProperty(key) || key.charAt(0) === "$") return true;
|
|
10474
|
-
return false;
|
|
10475
|
-
};
|
|
10476
|
-
var createNestedOperation = function(keyPath, nestedQuery, parentKey, owneryQuery, options) {
|
|
10477
|
-
if (containsOperation(nestedQuery, options)) {
|
|
10478
|
-
var _a = createQueryOperations(nestedQuery, parentKey, options), selfOperations = _a[0];
|
|
10479
|
-
if (_a[1].length) throw new Error("Property queries must contain only operations, or exact objects.");
|
|
10480
|
-
return new NestedOperation(keyPath, nestedQuery, owneryQuery, options, selfOperations);
|
|
10481
|
-
}
|
|
10482
|
-
return new NestedOperation(keyPath, nestedQuery, owneryQuery, options, [new EqualsOperation(nestedQuery, owneryQuery, options)]);
|
|
10483
|
-
};
|
|
10484
|
-
var createQueryOperation = function(query, owneryQuery, _a) {
|
|
10485
|
-
if (owneryQuery === void 0) owneryQuery = null;
|
|
10486
|
-
var _b = _a === void 0 ? {} : _a, compare = _b.compare, operations = _b.operations;
|
|
10487
|
-
var options = {
|
|
10488
|
-
compare: compare || equals,
|
|
10489
|
-
operations: Object.assign({}, operations || {})
|
|
10490
|
-
};
|
|
10491
|
-
var _c = createQueryOperations(query, null, options), selfOperations = _c[0], nestedOperations = _c[1];
|
|
10492
|
-
var ops = [];
|
|
10493
|
-
if (selfOperations.length) ops.push(new NestedOperation([], query, owneryQuery, options, selfOperations));
|
|
10494
|
-
ops.push.apply(ops, nestedOperations);
|
|
10495
|
-
if (ops.length === 1) return ops[0];
|
|
10496
|
-
return new QueryOperation(query, owneryQuery, options, ops);
|
|
10497
|
-
};
|
|
10498
|
-
var createQueryOperations = function(query, parentKey, options) {
|
|
10499
|
-
var selfOperations = [];
|
|
10500
|
-
var nestedOperations = [];
|
|
10501
|
-
if (!isVanillaObject(query)) {
|
|
10502
|
-
selfOperations.push(new EqualsOperation(query, query, options));
|
|
10503
|
-
return [selfOperations, nestedOperations];
|
|
10504
|
-
}
|
|
10505
|
-
for (var key in query) if (options.operations.hasOwnProperty(key)) {
|
|
10506
|
-
var op = createNamedOperation(key, query[key], query, options);
|
|
10507
|
-
if (op) {
|
|
10508
|
-
if (!op.propop && parentKey && !options.operations[parentKey]) throw new Error("Malformed query. ".concat(key, " cannot be matched against property."));
|
|
10509
|
-
}
|
|
10510
|
-
if (op != null) selfOperations.push(op);
|
|
10511
|
-
} else if (key.charAt(0) === "$") throwUnsupportedOperation(key);
|
|
10512
|
-
else nestedOperations.push(createNestedOperation(key.split("."), query[key], key, query, options));
|
|
10513
|
-
return [selfOperations, nestedOperations];
|
|
10514
|
-
};
|
|
10515
|
-
var createOperationTester = function(operation) {
|
|
10516
|
-
return function(item, key, owner) {
|
|
10517
|
-
operation.reset();
|
|
10518
|
-
operation.next(item, key, owner);
|
|
10519
|
-
return operation.keep;
|
|
10520
|
-
};
|
|
10521
|
-
};
|
|
10522
|
-
var $Ne = function(_super) {
|
|
10523
|
-
__extends($Ne, _super);
|
|
10524
|
-
function $Ne() {
|
|
10525
|
-
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
10526
|
-
_this.propop = true;
|
|
10527
|
-
return _this;
|
|
10528
|
-
}
|
|
10529
|
-
$Ne.prototype.init = function() {
|
|
10530
|
-
this._test = createTester(this.params, this.options.compare);
|
|
10531
|
-
};
|
|
10532
|
-
$Ne.prototype.reset = function() {
|
|
10533
|
-
_super.prototype.reset.call(this);
|
|
10534
|
-
this.keep = true;
|
|
10535
|
-
};
|
|
10536
|
-
$Ne.prototype.next = function(item) {
|
|
10537
|
-
if (this._test(item)) {
|
|
10538
|
-
this.done = true;
|
|
10539
|
-
this.keep = false;
|
|
10540
|
-
}
|
|
10541
|
-
};
|
|
10542
|
-
return $Ne;
|
|
10543
|
-
}(BaseOperation);
|
|
10544
|
-
var $ElemMatch = function(_super) {
|
|
10545
|
-
__extends($ElemMatch, _super);
|
|
10546
|
-
function $ElemMatch() {
|
|
10547
|
-
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
10548
|
-
_this.propop = true;
|
|
10549
|
-
return _this;
|
|
10550
|
-
}
|
|
10551
|
-
$ElemMatch.prototype.init = function() {
|
|
10552
|
-
if (!this.params || typeof this.params !== "object") throw new Error("Malformed query. $elemMatch must by an object.");
|
|
10553
|
-
this._queryOperation = createQueryOperation(this.params, this.owneryQuery, this.options);
|
|
10554
|
-
};
|
|
10555
|
-
$ElemMatch.prototype.reset = function() {
|
|
10556
|
-
_super.prototype.reset.call(this);
|
|
10557
|
-
this._queryOperation.reset();
|
|
10558
|
-
};
|
|
10559
|
-
$ElemMatch.prototype.next = function(item) {
|
|
10560
|
-
if (isArray(item)) {
|
|
10561
|
-
for (var i = 0, length_1 = item.length; i < length_1; i++) {
|
|
10562
|
-
this._queryOperation.reset();
|
|
10563
|
-
var child = item[i];
|
|
10564
|
-
this._queryOperation.next(child, i, item, false);
|
|
10565
|
-
this.keep = this.keep || this._queryOperation.keep;
|
|
10566
|
-
}
|
|
10567
|
-
this.done = true;
|
|
10568
|
-
} else {
|
|
10569
|
-
this.done = false;
|
|
10570
|
-
this.keep = false;
|
|
10571
|
-
}
|
|
10572
|
-
};
|
|
10573
|
-
return $ElemMatch;
|
|
10574
|
-
}(BaseOperation);
|
|
10575
|
-
var $Not = function(_super) {
|
|
10576
|
-
__extends($Not, _super);
|
|
10577
|
-
function $Not() {
|
|
10578
|
-
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
10579
|
-
_this.propop = true;
|
|
10580
|
-
return _this;
|
|
10581
|
-
}
|
|
10582
|
-
$Not.prototype.init = function() {
|
|
10583
|
-
this._queryOperation = createQueryOperation(this.params, this.owneryQuery, this.options);
|
|
10584
|
-
};
|
|
10585
|
-
$Not.prototype.reset = function() {
|
|
10586
|
-
_super.prototype.reset.call(this);
|
|
10587
|
-
this._queryOperation.reset();
|
|
10588
|
-
};
|
|
10589
|
-
$Not.prototype.next = function(item, key, owner, root) {
|
|
10590
|
-
this._queryOperation.next(item, key, owner, root);
|
|
10591
|
-
this.done = this._queryOperation.done;
|
|
10592
|
-
this.keep = !this._queryOperation.keep;
|
|
10593
|
-
};
|
|
10594
|
-
return $Not;
|
|
10595
|
-
}(BaseOperation);
|
|
10596
|
-
var $Size = function(_super) {
|
|
10597
|
-
__extends($Size, _super);
|
|
10598
|
-
function $Size() {
|
|
10599
|
-
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
10600
|
-
_this.propop = true;
|
|
10601
|
-
return _this;
|
|
10602
|
-
}
|
|
10603
|
-
$Size.prototype.init = function() {};
|
|
10604
|
-
$Size.prototype.next = function(item) {
|
|
10605
|
-
if (isArray(item) && item.length === this.params) {
|
|
10606
|
-
this.done = true;
|
|
10607
|
-
this.keep = true;
|
|
10608
|
-
}
|
|
10609
|
-
};
|
|
10610
|
-
return $Size;
|
|
10611
|
-
}(BaseOperation);
|
|
10612
|
-
var assertGroupNotEmpty = function(values) {
|
|
10613
|
-
if (values.length === 0) throw new Error("$and/$or/$nor must be a nonempty array");
|
|
10614
|
-
};
|
|
10615
|
-
var $Or = function(_super) {
|
|
10616
|
-
__extends($Or, _super);
|
|
10617
|
-
function $Or() {
|
|
10618
|
-
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
10619
|
-
_this.propop = false;
|
|
10620
|
-
return _this;
|
|
10621
|
-
}
|
|
10622
|
-
$Or.prototype.init = function() {
|
|
10623
|
-
var _this = this;
|
|
10624
|
-
assertGroupNotEmpty(this.params);
|
|
10625
|
-
this._ops = this.params.map(function(op) {
|
|
10626
|
-
return createQueryOperation(op, null, _this.options);
|
|
10627
|
-
});
|
|
10628
|
-
};
|
|
10629
|
-
$Or.prototype.reset = function() {
|
|
10630
|
-
this.done = false;
|
|
10631
|
-
this.keep = false;
|
|
10632
|
-
for (var i = 0, length_2 = this._ops.length; i < length_2; i++) this._ops[i].reset();
|
|
10633
|
-
};
|
|
10634
|
-
$Or.prototype.next = function(item, key, owner) {
|
|
10635
|
-
var done = false;
|
|
10636
|
-
var success = false;
|
|
10637
|
-
for (var i = 0, length_3 = this._ops.length; i < length_3; i++) {
|
|
10638
|
-
var op = this._ops[i];
|
|
10639
|
-
op.next(item, key, owner);
|
|
10640
|
-
if (op.keep) {
|
|
10641
|
-
done = true;
|
|
10642
|
-
success = op.keep;
|
|
10643
|
-
break;
|
|
10644
|
-
}
|
|
10645
|
-
}
|
|
10646
|
-
this.keep = success;
|
|
10647
|
-
this.done = done;
|
|
10648
|
-
};
|
|
10649
|
-
return $Or;
|
|
10650
|
-
}(BaseOperation);
|
|
10651
|
-
var $Nor = function(_super) {
|
|
10652
|
-
__extends($Nor, _super);
|
|
10653
|
-
function $Nor() {
|
|
10654
|
-
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
10655
|
-
_this.propop = false;
|
|
10656
|
-
return _this;
|
|
10657
|
-
}
|
|
10658
|
-
$Nor.prototype.next = function(item, key, owner) {
|
|
10659
|
-
_super.prototype.next.call(this, item, key, owner);
|
|
10660
|
-
this.keep = !this.keep;
|
|
10661
|
-
};
|
|
10662
|
-
return $Nor;
|
|
10663
|
-
}($Or);
|
|
10664
|
-
var $In = function(_super) {
|
|
10665
|
-
__extends($In, _super);
|
|
10666
|
-
function $In() {
|
|
10667
|
-
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
10668
|
-
_this.propop = true;
|
|
10669
|
-
return _this;
|
|
10670
|
-
}
|
|
10671
|
-
$In.prototype.init = function() {
|
|
10672
|
-
var _this = this;
|
|
10673
|
-
var params = Array.isArray(this.params) ? this.params : [this.params];
|
|
10674
|
-
this._testers = params.map(function(value) {
|
|
10675
|
-
if (containsOperation(value, _this.options)) throw new Error("cannot nest $ under ".concat(_this.name.toLowerCase()));
|
|
10676
|
-
return createTester(value, _this.options.compare);
|
|
10677
|
-
});
|
|
10678
|
-
};
|
|
10679
|
-
$In.prototype.next = function(item, key, owner) {
|
|
10680
|
-
var done = false;
|
|
10681
|
-
var success = false;
|
|
10682
|
-
for (var i = 0, length_4 = this._testers.length; i < length_4; i++) {
|
|
10683
|
-
var test = this._testers[i];
|
|
10684
|
-
if (test(item)) {
|
|
10685
|
-
done = true;
|
|
10686
|
-
success = true;
|
|
10687
|
-
break;
|
|
10688
|
-
}
|
|
10689
|
-
}
|
|
10690
|
-
this.keep = success;
|
|
10691
|
-
this.done = done;
|
|
10692
|
-
};
|
|
10693
|
-
return $In;
|
|
10694
|
-
}(BaseOperation);
|
|
10695
|
-
var $Nin = function(_super) {
|
|
10696
|
-
__extends($Nin, _super);
|
|
10697
|
-
function $Nin(params, ownerQuery, options, name) {
|
|
10698
|
-
var _this = _super.call(this, params, ownerQuery, options, name) || this;
|
|
10699
|
-
_this.propop = true;
|
|
10700
|
-
_this._in = new $In(params, ownerQuery, options, name);
|
|
10701
|
-
return _this;
|
|
10702
|
-
}
|
|
10703
|
-
$Nin.prototype.next = function(item, key, owner, root) {
|
|
10704
|
-
this._in.next(item, key, owner);
|
|
10705
|
-
if (isArray(owner) && !root) {
|
|
10706
|
-
if (this._in.keep) {
|
|
10707
|
-
this.keep = false;
|
|
10708
|
-
this.done = true;
|
|
10709
|
-
} else if (key == owner.length - 1) {
|
|
10710
|
-
this.keep = true;
|
|
10711
|
-
this.done = true;
|
|
10712
|
-
}
|
|
10713
|
-
} else {
|
|
10714
|
-
this.keep = !this._in.keep;
|
|
10715
|
-
this.done = true;
|
|
10716
|
-
}
|
|
10717
|
-
};
|
|
10718
|
-
$Nin.prototype.reset = function() {
|
|
10719
|
-
_super.prototype.reset.call(this);
|
|
10720
|
-
this._in.reset();
|
|
10721
|
-
};
|
|
10722
|
-
return $Nin;
|
|
10723
|
-
}(BaseOperation);
|
|
10724
|
-
var $Exists = function(_super) {
|
|
10725
|
-
__extends($Exists, _super);
|
|
10726
|
-
function $Exists() {
|
|
10727
|
-
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
10728
|
-
_this.propop = true;
|
|
10729
|
-
return _this;
|
|
10730
|
-
}
|
|
10731
|
-
$Exists.prototype.next = function(item, key, owner, root, leaf) {
|
|
10732
|
-
if (!leaf) {
|
|
10733
|
-
this.done = true;
|
|
10734
|
-
this.keep = !this.params;
|
|
10735
|
-
} else if (owner.hasOwnProperty(key) === this.params) {
|
|
10736
|
-
this.done = true;
|
|
10737
|
-
this.keep = true;
|
|
10738
|
-
}
|
|
10739
|
-
};
|
|
10740
|
-
return $Exists;
|
|
10741
|
-
}(BaseOperation);
|
|
10742
|
-
var $And = function(_super) {
|
|
10743
|
-
__extends($And, _super);
|
|
10744
|
-
function $And(params, owneryQuery, options, name) {
|
|
10745
|
-
var _this = _super.call(this, params, owneryQuery, options, params.map(function(query) {
|
|
10746
|
-
return createQueryOperation(query, owneryQuery, options);
|
|
10747
|
-
}), name) || this;
|
|
10748
|
-
_this.propop = false;
|
|
10749
|
-
assertGroupNotEmpty(params);
|
|
10750
|
-
return _this;
|
|
10751
|
-
}
|
|
10752
|
-
$And.prototype.next = function(item, key, owner, root) {
|
|
10753
|
-
this.childrenNext(item, key, owner, root);
|
|
10754
|
-
};
|
|
10755
|
-
return $And;
|
|
10756
|
-
}(NamedGroupOperation);
|
|
10757
|
-
var $All = function(_super) {
|
|
10758
|
-
__extends($All, _super);
|
|
10759
|
-
function $All(params, owneryQuery, options, name) {
|
|
10760
|
-
var _this = _super.call(this, params, owneryQuery, options, params.map(function(query) {
|
|
10761
|
-
return createQueryOperation(query, owneryQuery, options);
|
|
10762
|
-
}), name) || this;
|
|
10763
|
-
_this.propop = true;
|
|
10764
|
-
return _this;
|
|
10765
|
-
}
|
|
10766
|
-
$All.prototype.next = function(item, key, owner, root) {
|
|
10767
|
-
this.childrenNext(item, key, owner, root);
|
|
10768
|
-
};
|
|
10769
|
-
return $All;
|
|
10770
|
-
}(NamedGroupOperation);
|
|
10771
|
-
var $eq = function(params, owneryQuery, options) {
|
|
10772
|
-
return new EqualsOperation(params, owneryQuery, options);
|
|
10773
|
-
};
|
|
10774
|
-
var $ne = function(params, owneryQuery, options, name) {
|
|
10775
|
-
return new $Ne(params, owneryQuery, options, name);
|
|
10776
|
-
};
|
|
10777
|
-
var $or = function(params, owneryQuery, options, name) {
|
|
10778
|
-
return new $Or(params, owneryQuery, options, name);
|
|
10779
|
-
};
|
|
10780
|
-
var $nor = function(params, owneryQuery, options, name) {
|
|
10781
|
-
return new $Nor(params, owneryQuery, options, name);
|
|
10782
|
-
};
|
|
10783
|
-
var $elemMatch = function(params, owneryQuery, options, name) {
|
|
10784
|
-
return new $ElemMatch(params, owneryQuery, options, name);
|
|
10785
|
-
};
|
|
10786
|
-
var $nin = function(params, owneryQuery, options, name) {
|
|
10787
|
-
return new $Nin(params, owneryQuery, options, name);
|
|
10788
|
-
};
|
|
10789
|
-
var $in = function(params, owneryQuery, options, name) {
|
|
10790
|
-
return new $In(params, owneryQuery, options, name);
|
|
10791
|
-
};
|
|
10792
|
-
var $lt = numericalOperation(function(params) {
|
|
10793
|
-
return function(b) {
|
|
10794
|
-
return b != null && b < params;
|
|
10795
|
-
};
|
|
10796
|
-
});
|
|
10797
|
-
var $lte = numericalOperation(function(params) {
|
|
10798
|
-
return function(b) {
|
|
10799
|
-
return b === params || b <= params;
|
|
10800
|
-
};
|
|
10801
|
-
});
|
|
10802
|
-
var $gt = numericalOperation(function(params) {
|
|
10803
|
-
return function(b) {
|
|
10804
|
-
return b != null && b > params;
|
|
10805
|
-
};
|
|
10806
|
-
});
|
|
10807
|
-
var $gte = numericalOperation(function(params) {
|
|
10808
|
-
return function(b) {
|
|
10809
|
-
return b === params || b >= params;
|
|
10810
|
-
};
|
|
10811
|
-
});
|
|
10812
|
-
var $mod = function(_a, owneryQuery, options) {
|
|
10813
|
-
var mod = _a[0], equalsValue = _a[1];
|
|
10814
|
-
return new EqualsOperation(function(b) {
|
|
10815
|
-
return comparable(b) % mod === equalsValue;
|
|
10816
|
-
}, owneryQuery, options);
|
|
10817
|
-
};
|
|
10818
|
-
var $exists = function(params, owneryQuery, options, name) {
|
|
10819
|
-
return new $Exists(params, owneryQuery, options, name);
|
|
10820
|
-
};
|
|
10821
|
-
var $regex = function(pattern, owneryQuery, options) {
|
|
10822
|
-
return new EqualsOperation(new RegExp(pattern, owneryQuery.$options), owneryQuery, options);
|
|
10823
|
-
};
|
|
10824
|
-
var $not = function(params, owneryQuery, options, name) {
|
|
10825
|
-
return new $Not(params, owneryQuery, options, name);
|
|
10826
|
-
};
|
|
10827
|
-
var typeAliases = {
|
|
10828
|
-
number: function(v) {
|
|
10829
|
-
return typeof v === "number";
|
|
10830
|
-
},
|
|
10831
|
-
string: function(v) {
|
|
10832
|
-
return typeof v === "string";
|
|
10833
|
-
},
|
|
10834
|
-
bool: function(v) {
|
|
10835
|
-
return typeof v === "boolean";
|
|
10836
|
-
},
|
|
10837
|
-
array: function(v) {
|
|
10838
|
-
return Array.isArray(v);
|
|
10839
|
-
},
|
|
10840
|
-
null: function(v) {
|
|
10841
|
-
return v === null;
|
|
10842
|
-
},
|
|
10843
|
-
timestamp: function(v) {
|
|
10844
|
-
return v instanceof Date;
|
|
10845
|
-
}
|
|
10846
|
-
};
|
|
10847
|
-
var $type = function(clazz, owneryQuery, options) {
|
|
10848
|
-
return new EqualsOperation(function(b) {
|
|
10849
|
-
if (typeof clazz === "string") {
|
|
10850
|
-
if (!typeAliases[clazz]) throw new Error("Type alias does not exist");
|
|
10851
|
-
return typeAliases[clazz](b);
|
|
10852
|
-
}
|
|
10853
|
-
return b != null ? b instanceof clazz || b.constructor === clazz : false;
|
|
10854
|
-
}, owneryQuery, options);
|
|
10855
|
-
};
|
|
10856
|
-
var $and = function(params, ownerQuery, options, name) {
|
|
10857
|
-
return new $And(params, ownerQuery, options, name);
|
|
10858
|
-
};
|
|
10859
|
-
var $all = function(params, ownerQuery, options, name) {
|
|
10860
|
-
return new $All(params, ownerQuery, options, name);
|
|
10861
|
-
};
|
|
10862
|
-
var $size = function(params, ownerQuery, options) {
|
|
10863
|
-
return new $Size(params, ownerQuery, options, "$size");
|
|
10864
|
-
};
|
|
10865
|
-
var $options = function() {
|
|
10866
|
-
return null;
|
|
10867
|
-
};
|
|
10868
|
-
var $where = function(params, ownerQuery, options) {
|
|
10869
|
-
var test;
|
|
10870
|
-
if (isFunction(params)) test = params;
|
|
10871
|
-
else if (!process.env.CSP_ENABLED) test = new Function("obj", "return " + params);
|
|
10872
|
-
else throw new Error("In CSP mode, sift does not support strings in \"$where\" condition");
|
|
10873
|
-
return new EqualsOperation(function(b) {
|
|
10874
|
-
return test.bind(b)(b);
|
|
10875
|
-
}, ownerQuery, options);
|
|
10876
|
-
};
|
|
10877
|
-
var defaultOperations = /*#__PURE__*/ Object.freeze({
|
|
10878
|
-
__proto__: null,
|
|
10879
|
-
$Size,
|
|
10880
|
-
$all,
|
|
10881
|
-
$and,
|
|
10882
|
-
$elemMatch,
|
|
10883
|
-
$eq,
|
|
10884
|
-
$exists,
|
|
10885
|
-
$gt,
|
|
10886
|
-
$gte,
|
|
10887
|
-
$in,
|
|
10888
|
-
$lt,
|
|
10889
|
-
$lte,
|
|
10890
|
-
$mod,
|
|
10891
|
-
$ne,
|
|
10892
|
-
$nin,
|
|
10893
|
-
$nor,
|
|
10894
|
-
$not,
|
|
10895
|
-
$options,
|
|
10896
|
-
$or,
|
|
10897
|
-
$regex,
|
|
10898
|
-
$size,
|
|
10899
|
-
$type,
|
|
10900
|
-
$where
|
|
10901
|
-
});
|
|
10902
|
-
var createDefaultQueryOperation = function(query, ownerQuery, _a) {
|
|
10903
|
-
var _b = _a === void 0 ? {} : _a, compare = _b.compare, operations = _b.operations;
|
|
10904
|
-
return createQueryOperation(query, ownerQuery, {
|
|
10905
|
-
compare,
|
|
10906
|
-
operations: Object.assign({}, defaultOperations, operations || {})
|
|
10907
|
-
});
|
|
10908
|
-
};
|
|
10909
|
-
var createDefaultQueryTester = function(query, options) {
|
|
10910
|
-
if (options === void 0) options = {};
|
|
10911
|
-
return createOperationTester(createDefaultQueryOperation(query, null, options));
|
|
10912
|
-
};
|
|
10913
|
-
createDefaultQueryTester.createEqualsOperation;
|
|
10914
|
-
//#endregion
|
|
10915
10508
|
//#region ../sdk/src/shelf.ts
|
|
10916
10509
|
/** Flat [storageKey, FieldMeta] pairs of the parent table's columns.
|
|
10917
10510
|
* layout group → flattened; embedded group → prefix `key__`; collection → skipped. */
|
|
@@ -10949,43 +10542,6 @@ function assertNoKeylessCompute(items, owner) {
|
|
|
10949
10542
|
}
|
|
10950
10543
|
}
|
|
10951
10544
|
/**
|
|
10952
|
-
* Warns (does not throw) about the ONE composite shape mixed ownership is still wrong for: a
|
|
10953
|
-
* MANDATED client-owned stored part beside a server-owned one — one computed-and-stored (the
|
|
10954
|
-
* server writes that column) next to a plain stored one (the client writes that one) that the
|
|
10955
|
-
* declaration demands a value for.
|
|
10956
|
-
*
|
|
10957
|
-
* Mixed ownership itself is supported: the write path MATERIALIZES such a composite and
|
|
10958
|
-
* computes the server's part even when the write does not carry the field, leaving the
|
|
10959
|
-
* client's columns as they were (THE ABSENT-COMPOSITE RULE in
|
|
10960
|
-
* `@coffer-org/server/part-injection`). What a MANDATE adds is a demand the materialized value
|
|
10961
|
-
* cannot honour: the half-value the server produces on its own — the computed column filled,
|
|
10962
|
-
* the client's empty — reads back as `{value: 5, unit: null}` and is rejected by the
|
|
10963
|
-
* composite's own zod, yet it is non-null enough to satisfy the required check on the next
|
|
10964
|
-
* PATCH. The write path therefore refuses to materialize that one combination, and this names
|
|
10965
|
-
* it rather than leaving the author to wonder why the computed part never fills.
|
|
10966
|
-
*
|
|
10967
|
-
* The mandate is read through `mandatedClientParts`, which counts the FIELD's `required` AND
|
|
10968
|
-
* each OVERRIDDEN FILLING's own — `partsRowShape` honours both, so a check that read only the
|
|
10969
|
-
* field let `fields: { unit: f.string({ required: true }) }` through silently.
|
|
10970
|
-
*
|
|
10971
|
-
* Recurses into every group — an embedded group's composite and a collection row's carry
|
|
10972
|
-
* exactly the same mandate as a top-level one.
|
|
10973
|
-
*/
|
|
10974
|
-
function warnMixedOwnedParts(items, owner, path = "") {
|
|
10975
|
-
for (const it of items) {
|
|
10976
|
-
if (hasChildren(it)) {
|
|
10977
|
-
warnMixedOwnedParts(it.fields, owner, isStorageGroup(it) ? `${path}${it.key}.` : path);
|
|
10978
|
-
continue;
|
|
10979
|
-
}
|
|
10980
|
-
if (!(hasValue(it) && it.key !== void 0) || !it.type.parts) continue;
|
|
10981
|
-
const mixed = mixedOwnedStoredParts(it.type.parts);
|
|
10982
|
-
if (!mixed) continue;
|
|
10983
|
-
const mandated = mandatedClientParts(it.type.required, it.type.parts);
|
|
10984
|
-
if (!mandated.length) continue;
|
|
10985
|
-
console.warn(`${owner}: composite '${path}${it.key}' mandates a client-owned stored part (${mandated.join(", ")}) and mixes it with a server-owned stored part (${mixed.server.join(", ")}) — a mandated part is the client's to declare, so the write path does NOT materialize this composite and the computed part stays absent until a client sends the field. Either drop \`required\` (from the field or from the ${mandated.join("/")} filling), or give every stored part a \`value\` (the composite becomes fully server-owned).`);
|
|
10986
|
-
}
|
|
10987
|
-
}
|
|
10988
|
-
/**
|
|
10989
10545
|
* The declaration-time checks that are about a FIELD LIST, not about a shelf: they read
|
|
10990
10546
|
* `fields` and nothing else, so they are equally true of an extend's fields — an extend
|
|
10991
10547
|
* stores composites in its own table through the very same write path (`upsertExtendRecord`
|
|
@@ -10999,7 +10555,6 @@ function warnMixedOwnedParts(items, owner, path = "") {
|
|
|
10999
10555
|
*/
|
|
11000
10556
|
function checkFieldDeclaration(fields, owner) {
|
|
11001
10557
|
assertNoKeylessCompute(fields, owner);
|
|
11002
|
-
warnMixedOwnedParts(fields, owner);
|
|
11003
10558
|
}
|
|
11004
10559
|
function defineShelf(m) {
|
|
11005
10560
|
const built = materializeDef(m);
|
|
@@ -11068,42 +10623,42 @@ var bus_route_default = defineShelf({
|
|
|
11068
10623
|
] },
|
|
11069
10624
|
fields: {
|
|
11070
10625
|
name: field.title({ label: "core.fields.name" }),
|
|
10626
|
+
/**
|
|
10627
|
+
* What this route IS, read before anything else: its number, its two ends and the
|
|
10628
|
+
* stop these timetables are measured at. They already drew as one row — the spans
|
|
10629
|
+
* said so — but below the description and with their labels above. A stats cell
|
|
10630
|
+
* inverts that and makes them the record's headline, which is what they are.
|
|
10631
|
+
*/
|
|
10632
|
+
route: field.stats({ fields: {
|
|
10633
|
+
route_number: field.int({ label: "transit.bus_route.fields.route_number" }),
|
|
10634
|
+
from: field.string({
|
|
10635
|
+
label: "transit.bus_route.fields.from",
|
|
10636
|
+
rules: { max: 100 }
|
|
10637
|
+
}),
|
|
10638
|
+
to: field.string({
|
|
10639
|
+
label: "transit.bus_route.fields.to",
|
|
10640
|
+
rules: { max: 100 }
|
|
10641
|
+
}),
|
|
10642
|
+
stop: field.string({
|
|
10643
|
+
label: "transit.bus_route.fields.stop",
|
|
10644
|
+
rules: { max: 200 }
|
|
10645
|
+
})
|
|
10646
|
+
} }),
|
|
10647
|
+
hairline: field.divider({}),
|
|
11071
10648
|
description: field.text({
|
|
11072
10649
|
label: "transit.bus_route.fields.description",
|
|
11073
10650
|
rules: { max: 1e3 }
|
|
11074
10651
|
}),
|
|
11075
|
-
|
|
11076
|
-
label: "transit.bus_route.fields.route_number",
|
|
11077
|
-
ui: { span: 3 }
|
|
11078
|
-
}),
|
|
11079
|
-
from: field.string({
|
|
11080
|
-
label: "transit.bus_route.fields.from",
|
|
11081
|
-
rules: { max: 100 },
|
|
11082
|
-
ui: { span: 3 }
|
|
11083
|
-
}),
|
|
11084
|
-
to: field.string({
|
|
11085
|
-
label: "transit.bus_route.fields.to",
|
|
11086
|
-
rules: { max: 100 },
|
|
11087
|
-
ui: { span: 3 }
|
|
11088
|
-
}),
|
|
11089
|
-
stop: field.string({
|
|
11090
|
-
label: "transit.bus_route.fields.stop",
|
|
11091
|
-
rules: { max: 200 },
|
|
11092
|
-
ui: { span: 3 }
|
|
11093
|
-
}),
|
|
11094
|
-
weekday_times: field.time({
|
|
10652
|
+
weekday_times: field.timetable({
|
|
11095
10653
|
label: "transit.bus_route.fields.weekday_times",
|
|
11096
|
-
multiple: true,
|
|
11097
10654
|
ui: { span: 12 }
|
|
11098
10655
|
}),
|
|
11099
|
-
saturday_times: field.
|
|
10656
|
+
saturday_times: field.timetable({
|
|
11100
10657
|
label: "transit.bus_route.fields.saturday_times",
|
|
11101
|
-
multiple: true,
|
|
11102
10658
|
ui: { span: 6 }
|
|
11103
10659
|
}),
|
|
11104
|
-
sunday_times: field.
|
|
10660
|
+
sunday_times: field.timetable({
|
|
11105
10661
|
label: "transit.bus_route.fields.sunday_times",
|
|
11106
|
-
multiple: true,
|
|
11107
10662
|
ui: { span: 6 }
|
|
11108
10663
|
}),
|
|
11109
10664
|
tags: field.tags({ label: "transit.bus_route.fields.tags" }),
|
|
@@ -11119,6 +10674,8 @@ var src_default = definePlugin({
|
|
|
11119
10674
|
id: "transit",
|
|
11120
10675
|
version: "1.0.0",
|
|
11121
10676
|
dependsOn: [],
|
|
10677
|
+
label: "transit.plugin.label",
|
|
10678
|
+
description: "transit.plugin.description",
|
|
11122
10679
|
libraries: [{
|
|
11123
10680
|
meta: defineLibrary({
|
|
11124
10681
|
id: "transit",
|