@pipelex/mthds-form 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dist/chunk-AZZAAGNX.js +194 -0
- package/dist/chunk-AZZAAGNX.js.map +1 -0
- package/dist/{chunk-IIU3YK4O.js → chunk-DARLDVJM.js} +3 -3
- package/dist/{chunk-IIU3YK4O.js.map → chunk-DARLDVJM.js.map} +1 -1
- package/dist/{chunk-R7B7ID25.js → chunk-IUWLOSAM.js} +4 -4
- package/dist/{chunk-R7B7ID25.js.map → chunk-IUWLOSAM.js.map} +1 -1
- package/dist/chunk-KG4IYFWI.js +2721 -0
- package/dist/chunk-KG4IYFWI.js.map +1 -0
- package/dist/{chunk-J4L32LD6.js → chunk-KIEOLP2L.js} +3 -3
- package/dist/{chunk-J4L32LD6.js.map → chunk-KIEOLP2L.js.map} +1 -1
- package/dist/{chunk-4BSBBG2T.js → chunk-S4CB423P.js} +3 -3
- package/dist/{chunk-4BSBBG2T.js.map → chunk-S4CB423P.js.map} +1 -1
- package/dist/{chunk-XYQ7NXQZ.js → chunk-WYH56SOZ.js} +2 -2
- package/dist/chunk-WYH56SOZ.js.map +1 -0
- package/dist/{chunk-YEVVR6FE.js → chunk-Y2ND6W4W.js} +3 -3
- package/dist/{chunk-YEVVR6FE.js.map → chunk-Y2ND6W4W.js.map} +1 -1
- package/dist/{chunk-T4NSAGOS.js → chunk-YABRYTQ4.js} +4 -4
- package/dist/{chunk-T4NSAGOS.js.map → chunk-YABRYTQ4.js.map} +1 -1
- package/dist/core/contracts.d.ts +4 -4
- package/dist/core/contracts.js +1 -1
- package/dist/core/derive.js +2 -2
- package/dist/core/gate.js +3 -3
- package/dist/core/gating-fields.js +2 -2
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +8 -8
- package/dist/core/native-content.d.ts +56 -9
- package/dist/core/native-content.js +1 -1
- package/dist/core/output-form.js +2 -2
- package/dist/core/stuff-files.js +2 -2
- package/dist/core/values.js +3 -3
- package/dist/field-renderer-BSU2hMf6.d.ts +34 -0
- package/dist/generative/index.d.ts +2013 -0
- package/dist/generative/index.js +3171 -0
- package/dist/generative/index.js.map +1 -0
- package/dist/react/index.d.ts +42 -36
- package/dist/react/index.js +8 -2614
- package/dist/react/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/ui-designer.mthds +304 -0
- package/package.json +19 -7
- package/dist/chunk-45C2MKK6.js +0 -94
- package/dist/chunk-45C2MKK6.js.map +0 -1
- package/dist/chunk-XYQ7NXQZ.js.map +0 -1
package/dist/chunk-45C2MKK6.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { ownProp, hasOwnProp } from './chunk-V3OV2XQT.js';
|
|
2
|
-
|
|
3
|
-
// src/core/native-content.ts
|
|
4
|
-
function isRecord(value) {
|
|
5
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
-
}
|
|
7
|
-
function readText(record, key) {
|
|
8
|
-
const value = ownProp(record, key);
|
|
9
|
-
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
10
|
-
}
|
|
11
|
-
function readNumber(record, key) {
|
|
12
|
-
const value = ownProp(record, key);
|
|
13
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
14
|
-
}
|
|
15
|
-
function readDocumentContent(value) {
|
|
16
|
-
if (!isRecord(value)) return void 0;
|
|
17
|
-
const url = readText(value, "url");
|
|
18
|
-
if (url === void 0) return void 0;
|
|
19
|
-
return {
|
|
20
|
-
url,
|
|
21
|
-
publicUrl: readText(value, "public_url"),
|
|
22
|
-
mimeType: readText(value, "mime_type"),
|
|
23
|
-
filename: readText(value, "filename"),
|
|
24
|
-
title: readText(value, "title"),
|
|
25
|
-
snippet: readText(value, "snippet")
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
function readImageContent(value) {
|
|
29
|
-
if (!isRecord(value)) return void 0;
|
|
30
|
-
const url = readText(value, "url");
|
|
31
|
-
if (url === void 0) return void 0;
|
|
32
|
-
return {
|
|
33
|
-
url,
|
|
34
|
-
publicUrl: readText(value, "public_url"),
|
|
35
|
-
caption: readText(value, "caption"),
|
|
36
|
-
mimeType: readText(value, "mime_type"),
|
|
37
|
-
filename: readText(value, "filename"),
|
|
38
|
-
width: readNumber(value, "width"),
|
|
39
|
-
height: readNumber(value, "height"),
|
|
40
|
-
sourcePrompt: readText(value, "source_prompt")
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
function readHtmlContent(value) {
|
|
44
|
-
if (!isRecord(value)) return void 0;
|
|
45
|
-
const innerHtml = readText(value, "inner_html");
|
|
46
|
-
if (innerHtml === void 0) return void 0;
|
|
47
|
-
return { innerHtml, cssClass: readText(value, "css_class") };
|
|
48
|
-
}
|
|
49
|
-
var NATIVE_HTML_CONCEPT_REF = "native.Html";
|
|
50
|
-
var NATIVE_DATE_CONCEPT_REF = "native.Date";
|
|
51
|
-
var NATIVE_COMPOSITE_CONCEPT_REF = "native.Composite";
|
|
52
|
-
function readCompositeContent(value) {
|
|
53
|
-
if (!isRecord(value)) return void 0;
|
|
54
|
-
return Object.entries(value).map(([name, member]) => ({ name, value: member }));
|
|
55
|
-
}
|
|
56
|
-
function isNativeHtmlNode(node) {
|
|
57
|
-
return refinesNative(node, NATIVE_HTML_CONCEPT_REF);
|
|
58
|
-
}
|
|
59
|
-
function isNativeDateNode(node) {
|
|
60
|
-
return refinesNative(node, NATIVE_DATE_CONCEPT_REF);
|
|
61
|
-
}
|
|
62
|
-
function isNativeCompositeNode(node) {
|
|
63
|
-
return refinesNative(node, NATIVE_COMPOSITE_CONCEPT_REF);
|
|
64
|
-
}
|
|
65
|
-
function refinesNative(node, ref) {
|
|
66
|
-
if (node.conceptRef === ref) return true;
|
|
67
|
-
return node.refines?.includes(ref) ?? false;
|
|
68
|
-
}
|
|
69
|
-
function readDateContent(value) {
|
|
70
|
-
if (typeof value === "string") {
|
|
71
|
-
return value.length > 0 ? { date: value } : void 0;
|
|
72
|
-
}
|
|
73
|
-
if (!isRecord(value)) return void 0;
|
|
74
|
-
const inner = ownProp(value, "date");
|
|
75
|
-
const date = typeof inner === "string" ? inner : isRecord(inner) ? readText(inner, "date") : void 0;
|
|
76
|
-
if (date === void 0) return void 0;
|
|
77
|
-
return { date, time: readText(value, "time") };
|
|
78
|
-
}
|
|
79
|
-
function formatDateContent(content) {
|
|
80
|
-
return content.time ? `${content.date} ${content.time}` : content.date;
|
|
81
|
-
}
|
|
82
|
-
function isViewableUrl(url) {
|
|
83
|
-
if (!url) return false;
|
|
84
|
-
if (/^\/(?!\/)/.test(url)) return true;
|
|
85
|
-
return /^https?:/i.test(url) || /^data:/i.test(url) || /^blob:/i.test(url);
|
|
86
|
-
}
|
|
87
|
-
var TYPED_SCALAR_MARKERS = ["__class__", "__module__"];
|
|
88
|
-
function hasTypedScalarMarkers(value) {
|
|
89
|
-
return isRecord(value) && TYPED_SCALAR_MARKERS.every((marker) => hasOwnProp(value, marker));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export { NATIVE_COMPOSITE_CONCEPT_REF, NATIVE_DATE_CONCEPT_REF, NATIVE_HTML_CONCEPT_REF, TYPED_SCALAR_MARKERS, formatDateContent, hasTypedScalarMarkers, isNativeCompositeNode, isNativeDateNode, isNativeHtmlNode, isViewableUrl, readCompositeContent, readDateContent, readDocumentContent, readHtmlContent, readImageContent };
|
|
93
|
-
//# sourceMappingURL=chunk-45C2MKK6.js.map
|
|
94
|
-
//# sourceMappingURL=chunk-45C2MKK6.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/native-content.ts"],"names":[],"mappings":"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","file":"chunk-45C2MKK6.js","sourcesContent":["/**\n * How to READ the native content models — the result side's twin of\n * `./file-formats`.\n *\n * A renderer handed a result knows the field's `kind` from the descriptor, and\n * for the kinds whose value is a structured content model rather than a bare\n * scalar (`document`, `image`, `date`) it must then read that model's members.\n * **That is reading the standard, not sniffing at it.** The distinction is the\n * whole reason this module exists as data rather than as heuristics inside a\n * control: a reader keyed by a STATED kind consults a pinned definition, where\n * a reader that works out *which* kind it is holding by counting properties is\n * guessing — and guessing is exactly what [../../docs/derivation-swap.md]\n * records removing from the input side.\n *\n * ## Where each shape comes from\n *\n * `native.Image` and `native.Document` are pinned by the standard, in\n * `docs/spec/native-concepts.md` § \"The Pinned Set (MTHDS 1.0.0)\". Both carry a\n * required `url` — a storage URI, an HTTP(S) URL, or a base64 data URL — and\n * optional presentation members beside it. Nothing here adds a member the spec\n * does not state.\n *\n * `native.Date` is pinned the same way (`{date, time}`), but a `date` FIELD\n * inside a structured concept is not a `native.Date` value: it is a python\n * `datetime.date`, and the serialization layer stamps it with its class. So a\n * date arrives in one of three legal shapes, all three of which a run really\n * produces:\n *\n * \"2026-03-14\" a plain ISO string\n * { date: \"2026-03-14\", __class__: \"date\", … } a typed scalar\n * { date: \"2026-03-14\", time: \"15:40:00\" } native.Date\n *\n * The typed-scalar envelope is the one shape the standard does NOT pin — it is\n * a serialization fact, measured off a real run rather than read off a spec —\n * and it is called out as such here so nobody mistakes it for normative.\n *\n * This module lives in core, not beside the control that renders it, for the\n * reason `file-formats.ts` established: a host that shows a result its own way\n * needs the same answer the control uses, and two copies of an answer is two\n * places for it to drift. Pure data and pure functions — no React.\n */\n\nimport { hasOwnProp, ownProp } from './own-property';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** A member the content models declare as `type = \"text\"`, when it is one. */\nfunction readText(record: Record<string, unknown>, key: string): string | undefined {\n const value = ownProp(record, key);\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction readNumber(record: Record<string, unknown>, key: string): number | undefined {\n const value = ownProp(record, key);\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\n/**\n * `native.Document`, read.\n *\n * `url` is the only required member; everything else is a producer's courtesy,\n * so a reader that demands any of them describes a value the standard permits\n * as malformed.\n */\nexport interface DocumentContentView {\n url: string;\n publicUrl?: string;\n mimeType?: string;\n filename?: string;\n title?: string;\n snippet?: string;\n}\n\n/** `native.Image`, read. `width`/`height` are optional but PAIRED by the spec. */\nexport interface ImageContentView {\n url: string;\n publicUrl?: string;\n caption?: string;\n mimeType?: string;\n filename?: string;\n width?: number;\n height?: number;\n sourcePrompt?: string;\n}\n\n/** `native.Date` (and the typed-scalar envelope a nested `date` field arrives in). */\nexport interface DateContentView {\n /** ISO 8601 calendar date, `YYYY-MM-DD`. */\n date: string;\n /** ISO 8601 time of day, present only when the source stated one. */\n time?: string;\n}\n\n/**\n * Read a `document`-kind value. `undefined` when the value carries no `url`,\n * which is the one member the standard requires — a caller renders its own\n * absence rather than being handed a half-value to test.\n */\nexport function readDocumentContent(value: unknown): DocumentContentView | undefined {\n if (!isRecord(value)) return undefined;\n const url = readText(value, 'url');\n if (url === undefined) return undefined;\n return {\n url,\n publicUrl: readText(value, 'public_url'),\n mimeType: readText(value, 'mime_type'),\n filename: readText(value, 'filename'),\n title: readText(value, 'title'),\n snippet: readText(value, 'snippet'),\n };\n}\n\n/** Read an `image`-kind value. Same contract as `readDocumentContent`. */\nexport function readImageContent(value: unknown): ImageContentView | undefined {\n if (!isRecord(value)) return undefined;\n const url = readText(value, 'url');\n if (url === undefined) return undefined;\n return {\n url,\n publicUrl: readText(value, 'public_url'),\n caption: readText(value, 'caption'),\n mimeType: readText(value, 'mime_type'),\n filename: readText(value, 'filename'),\n width: readNumber(value, 'width'),\n height: readNumber(value, 'height'),\n sourcePrompt: readText(value, 'source_prompt'),\n };\n}\n\n/**\n * `native.Html`, read.\n *\n * The only content model here that is NOT reached by a field kind, and the\n * reason is a deliberate decision of the standard: the kind vocabulary has no\n * `html` member, so a `native.Html` value is an `object` node over its two\n * declared fields. That is right for the descriptor — the kinds name how a value\n * is ENTERED, and markup is entered as text — and wrong for a result view, which\n * would otherwise print a page's source at a reader.\n *\n * So this one is keyed by CONCEPT rather than by kind, through\n * `isNativeHtmlNode` below. That is a membership test on facts the descriptor\n * states (`concept_ref`, `refines`), which the standard's own page calls out as\n * the supported way to ask \"does this refine `native.X`?\" — the opposite of\n * inspecting a value to guess what it is.\n */\nexport interface HtmlContentView {\n /** The markup itself. The one required member. */\n innerHtml: string;\n /** A class name for a wrapper a consumer may put around it, when stated. */\n cssClass?: string;\n}\n\n/** Read an `native.Html` value. `undefined` when it carries no markup. */\nexport function readHtmlContent(value: unknown): HtmlContentView | undefined {\n if (!isRecord(value)) return undefined;\n const innerHtml = readText(value, 'inner_html');\n if (innerHtml === undefined) return undefined;\n return { innerHtml, cssClass: readText(value, 'css_class') };\n}\n\n/** The concept refs whose content model is multi-property, spelled once each. */\nexport const NATIVE_HTML_CONCEPT_REF = 'native.Html';\nexport const NATIVE_DATE_CONCEPT_REF = 'native.Date';\nexport const NATIVE_COMPOSITE_CONCEPT_REF = 'native.Composite';\n\n/** One member of a composite: the name it was composed under, and its content. */\nexport interface CompositeMember {\n name: string;\n value: unknown;\n}\n\n/**\n * Read a `native.Composite` — a named composition of contents.\n *\n * The members are returned in the order the payload states them, which is the\n * order the method composed them in and the only order there is: a composite\n * declares no fields, so there is no authored order to prefer over it.\n *\n * `undefined` for anything that is not a record, so the caller falls back.\n */\nexport function readCompositeContent(value: unknown): CompositeMember[] | undefined {\n if (!isRecord(value)) return undefined;\n return Object.entries(value).map(([name, member]) => ({ name, value: member }));\n}\n\n/**\n * Whether a descriptor node carries markup — its concept IS `native.Html`, or\n * refines it.\n *\n * The refinement chain is checked, not just the leaf, because a method may\n * declare `legal.ClauseMarkup` refining `native.Html` and a reader of that result\n * wants the markup rendered just the same. `refines` is on the wire for exactly\n * this question.\n */\nexport function isNativeHtmlNode(node: {\n conceptRef?: string;\n refines?: readonly string[];\n}): boolean {\n return refinesNative(node, NATIVE_HTML_CONCEPT_REF);\n}\n\n/**\n * Whether a node IS a `native.Date` — the other content model the kind\n * vocabulary cannot name.\n *\n * `native.Date` is `{date, time}`, two properties, so nothing unwraps it and its\n * node is an `object`. Correct for the descriptor and wrong for a reader: a date\n * result rendered structurally is a two-field card whose second field says \"not\n * provided\", where the answer is a date. The `date` ARM already reads exactly\n * this model — `readDateContent` takes `{date, time}` — it just never fires,\n * because the kind says `object`.\n *\n * A `date` FIELD inside a structure is a different thing and needs none of this:\n * it carries `kind: \"date\"` already.\n */\nexport function isNativeDateNode(node: {\n conceptRef?: string;\n refines?: readonly string[];\n}): boolean {\n return refinesNative(node, NATIVE_DATE_CONCEPT_REF);\n}\n\n/**\n * Whether a node is a `native.Composite` — a named bag of contents.\n *\n * The third concept the kind vocabulary cannot name, and the one where it is\n * least able to: a composite declares no members at all, so its descriptor is\n * `kind: \"unknown\"` and its payload schema is `{additionalProperties: true}`\n * with no properties. Both are TRUE — the standard's escape hatch, honestly\n * used — and both leave a renderer with nothing to read, so the default\n * fallback prints the whole thing as a JSON blob.\n *\n * That is the worst available answer to a value that is, by definition, a map\n * of ordinary `StuffContent`s. Keyed by concept, a renderer can at least show\n * the members as the named things they are. See `CompositeValue`.\n */\nexport function isNativeCompositeNode(node: {\n conceptRef?: string;\n refines?: readonly string[];\n}): boolean {\n return refinesNative(node, NATIVE_COMPOSITE_CONCEPT_REF);\n}\n\n/** Its concept IS the named native, or refines it. */\nfunction refinesNative(\n node: { conceptRef?: string; refines?: readonly string[] },\n ref: string,\n): boolean {\n if (node.conceptRef === ref) return true;\n return node.refines?.includes(ref) ?? false;\n}\n\n/**\n * Read a `date`-kind value, in any of the three shapes a run produces.\n *\n * The `date` member is read one level deep, because `native.Date`'s own `date`\n * member is a `datetime.date` and therefore arrives inside the same typed-scalar\n * envelope the whole value may already be wrapped in. One level is enough and\n * the recursion is bounded on purpose: a second envelope would be a\n * serialization bug, and following it forever would turn one into a hang.\n */\nexport function readDateContent(value: unknown): DateContentView | undefined {\n if (typeof value === 'string') {\n return value.length > 0 ? { date: value } : undefined;\n }\n if (!isRecord(value)) return undefined;\n\n const inner = ownProp(value, 'date');\n const date =\n typeof inner === 'string' ? inner : isRecord(inner) ? readText(inner, 'date') : undefined;\n if (date === undefined) return undefined;\n return { date, time: readText(value, 'time') };\n}\n\n/** `{date}` / `{date, time}` as one line, which is how both are read aloud. */\nexport function formatDateContent(content: DateContentView): string {\n return content.time ? `${content.date} ${content.time}` : content.date;\n}\n\n/**\n * Whether a browser can paint this URL as-is.\n *\n * A `pipelex-storage://` reference cannot be resolved client-side — that is the\n * upload seam's job (see [../../docs/upload-seam.md]) — so a renderer with no\n * resolver must show the reference rather than a broken `<img>`. `file:` is\n * deliberately NOT viewable: a run on a developer's machine writes one, and a\n * browser refuses to load it from a page served over http.\n *\n * **A root-relative path counts**, and leaving it out was a real bug rather\n * than an omission. A host's URL resolver naturally hands back a path on its\n * OWN origin — `/api/assets/…`, an authenticated route that streams the object\n * — which is the whole point of resolving rather than exposing storage. This\n * predicate rejected it for having no scheme, so the resolved URL was thrown\n * away and the arms fell back to the payload's `public_url`: a presigned URL\n * that had already expired. The image stayed broken with the fix in place.\n *\n * `//host/path` is deliberately excluded. It is protocol-relative, so it points\n * at another origin while looking like a path.\n */\nexport function isViewableUrl(url: string | undefined): url is string {\n if (!url) return false;\n if (/^\\/(?!\\/)/.test(url)) return true;\n return /^https?:/i.test(url) || /^data:/i.test(url) || /^blob:/i.test(url);\n}\n\n/**\n * The typed-scalar markers the serialization layer stamps onto a value.\n *\n * Exported so a host can recognise (and strip) them; nothing in the kernel\n * BRANCHES on them, which is the point — a reader keyed by these would be\n * reading the serializer instead of the standard.\n */\nexport const TYPED_SCALAR_MARKERS = ['__class__', '__module__'] as const;\n\n/** Whether a record carries the typed-scalar markers. Informational. */\nexport function hasTypedScalarMarkers(value: unknown): boolean {\n return isRecord(value) && TYPED_SCALAR_MARKERS.every((marker) => hasOwnProp(value, marker));\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/contracts.ts"],"names":[],"mappings":";;;AA4DO,SAAS,YAAA,CAAa,QAAgB,QAAA,EAA0B;AACrE,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,QAAQ,CAAA,CAAA;AAC9B;AAkBO,SAAS,iBAAA,CACd,eAAA,EACA,MAAA,EACA,QAAA,EAC4B;AAC5B,EAAA,IAAI,CAAC,eAAA,IAAmB,CAAC,QAAA,EAAU,OAAO,MAAA;AAC1C,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAM,QAAQ,OAAA,CAAQ,eAAA,EAAiB,YAAA,CAAa,MAAA,EAAQ,QAAQ,CAAC,CAAA;AACrE,IAAA,IAAI,OAAO,OAAO,KAAA;AAAA,EACpB;AACA,EAAA,OAAO,OAAA,CAAQ,iBAAiB,QAAQ,CAAA;AAC1C;AAWO,SAAS,gBAAgB,KAAA,EAAmC;AACjE,EAAA,OAAO,MAAM,QAAA,KAAa,UAAA;AAC5B;AAcO,SAAS,cAAc,KAAA,EAAmC;AAC/D,EAAA,OAAQ,KAAA,CAAM,aAAgD,IAAA,KAAS,OAAA;AACzE;AASO,SAAS,kBAAkB,KAAA,EAAmC;AACnE,EAAA,OAAO,MAAM,YAAA,KAAiB,OAAA;AAChC;AAqBO,SAAS,kBAAkB,KAAA,EAAmC;AACnE,EAAA,IAAI,eAAA,CAAgB,KAAK,CAAA,EAAG,OAAO,KAAA;AACnC,EAAA,OAAO,CAAC,aAAA,CAAc,KAAK,CAAA,IAAK,kBAAkB,KAAK,CAAA;AACzD","file":"chunk-XYQ7NXQZ.js","sourcesContent":["/**\n * The `pipe_io_contracts` types and the kernel's gating predicates over them.\n *\n * The types are the STANDARD'S, imported from `mthds/protocol` and re-exported\n * under the names this package has always exported. `pipe_io_contracts` is an\n * MTHDS artifact - the standard specifies it (the \"Pipe I/O Contracts\" page)\n * and its TypeScript client declares it - so this module states no shape of its\n * own any more. What it keeps is the half that is genuinely the kernel's: the\n * predicates that turn a declared slot into a gating answer, and the lookup\n * that tolerates both key conventions a real payload arrives with.\n *\n * `mthds` is a TYPES-ONLY peer dependency: every import here is `import type`,\n * so nothing survives into `dist/` and no consumer ships the standard's CLI.\n * `scripts/assert-bundle.mjs` holds that on the built graph and lint holds it\n * on the source. See docs/dependency-budget.md.\n *\n * The map itself is keyed by namespaced pipe ref (`<domain>.<pipe_code>`),\n * NOT bare pipe code - use `getPipeIOContract` to look entries up by the bare\n * codes the UI tracks.\n */\n\nimport type {\n IOMultiplicity,\n PipeInputContract,\n PipeIOContract,\n PipeIOContracts,\n PipeOutputContract,\n PresenceMarker,\n} from 'mthds/protocol';\n\nimport { ownProp } from './own-property';\n\nexport type {\n IOMultiplicity,\n PipeInputContract,\n PipeIOContract,\n PipeIOContracts,\n PipeOutputContract,\n};\n\n/**\n * The authored presence marker on an input slot, verbatim - the standard's\n * `PresenceMarker` under the name this package exports.\n *\n * - `plain` - no marker: the caller must supply the input.\n * - `optional` (`?`) - the caller may omit it and the pipe handles the absence\n * itself.\n * - `force` (`!`) - a use-site assertion that the value IS present. It must be\n * supplied, exactly like `plain`; the distinction is the authored assertion,\n * which lint and graph surfaces read and a form does not.\n *\n * Kept as an alias rather than renamed because a consumer imports it by this\n * name; a host that would rather read the standard's spelling has `mthds`\n * installed through this package's peer and can import `PresenceMarker`\n * straight from `mthds/protocol`.\n */\nexport type InputPresence = PresenceMarker;\n\n/** Namespaced pipe ref (`<domain>.<pipe_code>`) - the identity convention the\n * validate artifacts key on. */\nexport function buildPipeRef(domain: string, pipeCode: string): string {\n return `${domain}.${pipeCode}`;\n}\n\n/**\n * Look up a pipe's IO contract by pipe code, tolerant of both key conventions.\n *\n * The map may be keyed by namespaced `pipe_ref` (`<domain>.<code>`, the\n * canonical convention) OR by bare pipe code - the current hosted `/validate`\n * keys `pipe_structures` by bare code, and methods persisted before the\n * pipe_ref re-keying also carry bare-code keys. Try the namespaced ref first\n * (when the caller supplies a domain), then fall back to the bare code.\n * Returns `undefined` (never crashes) when neither matches.\n *\n * Both lookups read OWN properties only. A bare index returned the inherited\n * `Object` constructor for a pipe code named `constructor` (or `toString`, …) -\n * a truthy non-contract that sailed straight through the `if (!contract)` guard\n * hosts are shown writing, so a pipe that does not exist rendered as one taking\n * no inputs instead of reaching the host's not-found path. See `ownProp`.\n */\nexport function getPipeIOContract(\n pipeIoContracts: PipeIOContracts | null | undefined,\n domain: string | null | undefined,\n pipeCode: string | null | undefined,\n): PipeIOContract | undefined {\n if (!pipeIoContracts || !pipeCode) return undefined;\n if (domain) {\n const byRef = ownProp(pipeIoContracts, buildPipeRef(domain, pipeCode));\n if (byRef) return byRef;\n }\n return ownProp(pipeIoContracts, pipeCode);\n}\n\n/**\n * True when the method declared the input omittable (`?`).\n *\n * The ONE reader of `presence` in the package: everything that asks \"may this\n * be absent?\" - the descriptor's `required`, the gate's `required` list, the\n * payload builders that omit an unfilled input - goes through here, so a\n * marker the wire adds later cannot mean one thing on one surface and another\n * elsewhere. `force` (`!`) reads as NOT optional, like `plain`.\n */\nexport function isOptionalInput(input: PipeInputContract): boolean {\n return input.presence === 'optional';\n}\n\n/**\n * True when the input carries a plural concept (`Image[]`, `Image[3]`): its\n * JSON Schema is an array wrapper.\n *\n * Deliberately a SCHEMA test rather than a read of the declared `multiplicity`,\n * even though the wire now states both. The schema is what `buildRunFields`\n * maps and therefore what the user is shown; a predicate reading the other\n * field could disagree with the rendered control, which is the exact failure\n * mode `mustBeFilled` (readiness.ts) exists to prevent. The two agree by\n * construction upstream - the engine wraps the schema in an array exactly when\n * it reports `variable` or `fixed`.\n */\nexport function isPluralInput(input: PipeInputContract): boolean {\n return (input.json_schema as { type?: unknown } | undefined)?.type === 'array';\n}\n\n/**\n * True when the slot declares an EXACT number of items (`Concept[N]`), whose\n * count is `item_count`.\n *\n * The distinction that matters to the gate: a variable list can legitimately be\n * empty, a fixed one cannot.\n */\nexport function isFixedCountInput(input: PipeInputContract): boolean {\n return input.multiplicity === 'fixed';\n}\n\n/**\n * True when the user MUST put a value in before a run can start.\n *\n * Two declarations relieve an input of that duty, for different reasons:\n * - **optional (`?`)** - the method itself states the caller may omit it;\n * - **variable-plural (`[]`)** - the empty list is a legitimate value and the\n * language cannot declare \"at least one\", so gating on it would invent a\n * constraint the method never made.\n *\n * Everything else gates: `plain`, `force` (`!`), and a **fixed-count** list\n * (`[N]`), which is a list whose empty form the method has explicitly ruled out.\n * This is the derivation the input-form descriptor spec states for `gating`.\n *\n * Emptiness is all this predicate answers for - WHETHER a slot gates, never how\n * much it needs. A fixed-count list that holds fewer items than it declares\n * gates here and is refused by `fieldFilled`, which reads the declared count off\n * the descriptor's `itemCount`, and by the gate's ajv pass on the schema's\n * `minItems`. All three read the one number the method stated.\n */\nexport function inputMustBeFilled(input: PipeInputContract): boolean {\n if (isOptionalInput(input)) return false;\n return !isPluralInput(input) || isFixedCountInput(input);\n}\n"]}
|