@plurnk/plurnk-schemes 1.3.12 → 1.5.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 +43 -17
- package/SPEC.md +368 -86
- package/dist/Manifest.d.ts +6 -0
- package/dist/Manifest.d.ts.map +1 -0
- package/dist/Manifest.js +115 -0
- package/dist/Manifest.js.map +1 -0
- package/dist/Matcher.d.ts +5 -6
- package/dist/Matcher.d.ts.map +1 -1
- package/dist/Matcher.js +51 -59
- package/dist/Matcher.js.map +1 -1
- package/dist/MimetypeClassifier.d.ts +1 -1
- package/dist/MimetypeClassifier.d.ts.map +1 -1
- package/dist/MimetypeClassifier.js +11 -15
- package/dist/MimetypeClassifier.js.map +1 -1
- package/dist/NetworkAddress.d.ts +13 -0
- package/dist/NetworkAddress.d.ts.map +1 -0
- package/dist/NetworkAddress.js +43 -0
- package/dist/NetworkAddress.js.map +1 -0
- package/dist/OutputScheme.d.ts.map +1 -1
- package/dist/OutputScheme.js +5 -6
- package/dist/OutputScheme.js.map +1 -1
- package/dist/PacketSections.d.ts +6 -0
- package/dist/PacketSections.d.ts.map +1 -0
- package/dist/PacketSections.js +42 -0
- package/dist/PacketSections.js.map +1 -0
- package/dist/PathMimetype.js +9 -9
- package/dist/PathMimetype.js.map +1 -1
- package/dist/Results.d.ts +42 -8
- package/dist/Results.d.ts.map +1 -1
- package/dist/Results.js +132 -44
- package/dist/Results.js.map +1 -1
- package/dist/SchemeDiscovery.d.ts +2 -0
- package/dist/SchemeDiscovery.d.ts.map +1 -1
- package/dist/SchemeDiscovery.js +40 -42
- package/dist/SchemeDiscovery.js.map +1 -1
- package/dist/SchemeResolver.d.ts.map +1 -1
- package/dist/SchemeResolver.js +4 -5
- package/dist/SchemeResolver.js.map +1 -1
- package/dist/Slicer.d.ts +27 -14
- package/dist/Slicer.d.ts.map +1 -1
- package/dist/Slicer.js +382 -374
- package/dist/Slicer.js.map +1 -1
- package/dist/Summarize.js +3 -3
- package/dist/Summarize.js.map +1 -1
- package/dist/ctx.d.ts +70 -67
- package/dist/ctx.d.ts.map +1 -1
- package/dist/edit-receipt.d.ts +39 -0
- package/dist/edit-receipt.d.ts.map +1 -0
- package/dist/edit-receipt.js +2 -0
- package/dist/edit-receipt.js.map +1 -0
- package/dist/handler.d.ts +13 -10
- package/dist/handler.d.ts.map +1 -1
- package/dist/handler.js +7 -5
- package/dist/handler.js.map +1 -1
- package/dist/index.d.ts +14 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/packet.d.ts +2 -3
- package/dist/packet.d.ts.map +1 -1
- package/dist/packet.js +2 -20
- package/dist/packet.js.map +1 -1
- package/dist/types.d.ts +3 -11
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -7
- package/dist/types.js.map +1 -1
- package/package.json +10 -8
- package/dist/DefaultRead.d.ts +0 -11
- package/dist/DefaultRead.d.ts.map +0 -1
- package/dist/DefaultRead.js +0 -27
- package/dist/DefaultRead.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Manifest.d.ts","sourceRoot":"","sources":["../src/Manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,cAAc,EAAc,MAAM,YAAY,CAAC;AAuBjF,MAAM,CAAC,OAAO,OAAO,QAAQ;;IACzB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,cAAc,CA8CjE;CAgDJ"}
|
package/dist/Manifest.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
const WRITERS = new Set(["model", "client", "plurnk", "plugin"]);
|
|
2
|
+
const CATEGORIES = new Set(["data", "logging", "control"]);
|
|
3
|
+
const MANIFEST_FIELD_NAMES = new Set(Object.keys({
|
|
4
|
+
name: true,
|
|
5
|
+
channels: true,
|
|
6
|
+
defaultChannel: true,
|
|
7
|
+
category: true,
|
|
8
|
+
writableBy: true,
|
|
9
|
+
volatile: true,
|
|
10
|
+
modelVisible: true,
|
|
11
|
+
folderScopes: true,
|
|
12
|
+
foldedByDefault: true,
|
|
13
|
+
flags: true,
|
|
14
|
+
example: true,
|
|
15
|
+
documentation: true,
|
|
16
|
+
glyph: true,
|
|
17
|
+
storedScheme: true,
|
|
18
|
+
}));
|
|
19
|
+
const FLAG_AFFINITIES = ["excludedInAsk", "requiresWeb", "requiresInteraction"];
|
|
20
|
+
const FLAG_AFFINITY_NAMES = new Set(FLAG_AFFINITIES);
|
|
21
|
+
export default class Manifest {
|
|
22
|
+
static of(handler, expectedName) {
|
|
23
|
+
if (typeof handler !== "object" || handler === null) {
|
|
24
|
+
throw new Error("scheme handler must be an object");
|
|
25
|
+
}
|
|
26
|
+
const instance = handler;
|
|
27
|
+
const value = instance.manifest ?? instance.constructor?.manifest;
|
|
28
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
29
|
+
throw new Error(`scheme '${expectedName ?? "unknown"}' must declare a static or instance manifest`);
|
|
30
|
+
}
|
|
31
|
+
const manifest = value;
|
|
32
|
+
const name = Manifest.#string(manifest, "name");
|
|
33
|
+
const unknown = Object.keys(manifest).find((field) => !MANIFEST_FIELD_NAMES.has(field));
|
|
34
|
+
if (unknown !== undefined) {
|
|
35
|
+
throw new Error(`scheme '${name}' manifest has unknown field '${unknown}'`);
|
|
36
|
+
}
|
|
37
|
+
if (expectedName !== undefined && name !== expectedName) {
|
|
38
|
+
throw new Error(`scheme identity mismatch: registered '${expectedName}', manifest declares '${name}'`);
|
|
39
|
+
}
|
|
40
|
+
const channels = manifest.channels;
|
|
41
|
+
if (typeof channels !== "object" || channels === null || Array.isArray(channels)
|
|
42
|
+
|| !Object.entries(channels).every(([channel, mimetype]) => channel.length > 0
|
|
43
|
+
&& channel === channel.toLowerCase()
|
|
44
|
+
&& typeof mimetype === "string"
|
|
45
|
+
&& mimetype.length > 0)) {
|
|
46
|
+
throw new Error(`scheme '${name}' manifest.channels must map lowercase channel names to non-empty mimetypes`);
|
|
47
|
+
}
|
|
48
|
+
const defaultChannel = Manifest.#string(manifest, "defaultChannel", true);
|
|
49
|
+
if (Object.keys(channels).length > 0 && !Object.hasOwn(channels, defaultChannel)) {
|
|
50
|
+
throw new Error(`scheme '${name}' manifest.defaultChannel '${defaultChannel}' is not declared in channels`);
|
|
51
|
+
}
|
|
52
|
+
if (!CATEGORIES.has(manifest.category)) {
|
|
53
|
+
throw new Error(`scheme '${name}' manifest.category must be data, logging, or control`);
|
|
54
|
+
}
|
|
55
|
+
const writableBy = manifest.writableBy;
|
|
56
|
+
if (!Array.isArray(writableBy)
|
|
57
|
+
|| !writableBy.every((writer) => typeof writer === "string" && WRITERS.has(writer))
|
|
58
|
+
|| new Set(writableBy).size !== writableBy.length) {
|
|
59
|
+
throw new Error(`scheme '${name}' manifest.writableBy must contain unique writer tiers`);
|
|
60
|
+
}
|
|
61
|
+
Manifest.#boolean(manifest, "volatile");
|
|
62
|
+
Manifest.#boolean(manifest, "modelVisible");
|
|
63
|
+
for (const field of ["folderScopes", "foldedByDefault"])
|
|
64
|
+
Manifest.#optionalBoolean(manifest, field);
|
|
65
|
+
for (const field of ["example", "documentation", "storedScheme"])
|
|
66
|
+
Manifest.#optionalString(manifest, field);
|
|
67
|
+
Manifest.#optionalNonemptyString(manifest, "glyph");
|
|
68
|
+
Manifest.#flags(manifest.flags, name);
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
static #string(record, field, emptyAllowed = false) {
|
|
72
|
+
const value = record[field];
|
|
73
|
+
if (typeof value !== "string" || (!emptyAllowed && value.length === 0)) {
|
|
74
|
+
throw new Error(`scheme manifest.${field} must be ${emptyAllowed ? "a string" : "a non-empty string"}`);
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
static #boolean(record, field) {
|
|
79
|
+
if (typeof record[field] !== "boolean")
|
|
80
|
+
throw new Error(`scheme manifest.${field} must be boolean`);
|
|
81
|
+
}
|
|
82
|
+
static #optionalBoolean(record, field) {
|
|
83
|
+
if (record[field] !== undefined && typeof record[field] !== "boolean") {
|
|
84
|
+
throw new Error(`scheme manifest.${field} must be boolean when present`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
static #optionalString(record, field) {
|
|
88
|
+
if (record[field] !== undefined && typeof record[field] !== "string") {
|
|
89
|
+
throw new Error(`scheme manifest.${field} must be a string when present`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
static #optionalNonemptyString(record, field) {
|
|
93
|
+
if (record[field] !== undefined && (typeof record[field] !== "string" || record[field].length === 0)) {
|
|
94
|
+
throw new Error(`scheme manifest.${field} must be a non-empty string when present`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
static #flags(value, name) {
|
|
98
|
+
if (value === undefined)
|
|
99
|
+
return;
|
|
100
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
101
|
+
throw new Error(`scheme '${name}' manifest.flags must be an object`);
|
|
102
|
+
}
|
|
103
|
+
const flags = value;
|
|
104
|
+
const unknown = Object.keys(flags).find((field) => !FLAG_AFFINITY_NAMES.has(field));
|
|
105
|
+
if (unknown !== undefined) {
|
|
106
|
+
throw new Error(`scheme '${name}' manifest.flags has unknown field '${unknown}'`);
|
|
107
|
+
}
|
|
108
|
+
for (const field of FLAG_AFFINITIES) {
|
|
109
|
+
if (flags[field] !== undefined && typeof flags[field] !== "boolean") {
|
|
110
|
+
throw new Error(`scheme '${name}' manifest.flags.${field} must be boolean`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=Manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Manifest.js","sourceRoot":"","sources":["../src/Manifest.ts"],"names":[],"mappings":"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"}
|
package/dist/Matcher.d.ts
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import type { MatcherBody } from "@plurnk/plurnk-
|
|
1
|
+
import type { MatcherBody } from "@plurnk/plurnk-contracts";
|
|
2
2
|
import type { Mimetypes } from "@plurnk/plurnk-mimetypes";
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { type MatchEvidence, type SchemeResult } from "./Results.ts";
|
|
4
|
+
export interface MatchResult extends SchemeResult {
|
|
5
5
|
body?: string;
|
|
6
|
-
matches?:
|
|
7
|
-
error?: string;
|
|
6
|
+
matches?: ReadonlyArray<MatchEvidence>;
|
|
8
7
|
mimetype?: string;
|
|
9
8
|
reason?: string;
|
|
10
9
|
}
|
|
11
10
|
export default class Matcher {
|
|
12
11
|
#private;
|
|
13
|
-
static matchAgainstContent(body: MatcherBody, content: string, mimetype: string, mimetypes: Mimetypes
|
|
12
|
+
static matchAgainstContent(body: MatcherBody, content: string, mimetype: string, mimetypes: Mimetypes): Promise<MatchResult>;
|
|
14
13
|
}
|
|
15
14
|
//# sourceMappingURL=Matcher.d.ts.map
|
package/dist/Matcher.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Matcher.d.ts","sourceRoot":"","sources":["../src/Matcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Matcher.d.ts","sourceRoot":"","sources":["../src/Matcher.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAiC,MAAM,0BAA0B,CAAC;AAOzF,OAAgB,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAE9E,MAAM,WAAW,WAAY,SAAQ,YAAY;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,CAAC,OAAO,OAAO,OAAO;;IA+CxB,OAAa,mBAAmB,CAC5B,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,SAAS,GACrB,OAAO,CAAC,WAAW,CAAC,CAqEtB;CACJ"}
|
package/dist/Matcher.js
CHANGED
|
@@ -1,62 +1,44 @@
|
|
|
1
|
-
// Body-matcher adapter
|
|
2
|
-
// dialect
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
1
|
+
// {§matcher-dispatch} Body-matcher operation adapter. Mimetypes owns handler
|
|
2
|
+
// resolution, dialect execution, and evidence; this layer maps its typed
|
|
3
|
+
// outcomes to the universal scheme-result contract. PLURNK callers pass the
|
|
4
|
+
// grammar's parsed dialect, while standalone raw strings retain framework
|
|
5
|
+
// classification.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// Information") — content was produced, but not in the structured form the
|
|
10
|
-
// matcher requested; the model sees raw text + a `reason` and chooses
|
|
11
|
-
// retry/fallback/fix-source. Choice ratified by user (#172).
|
|
7
|
+
// Status 203 preserves readable content when its requested structural
|
|
8
|
+
// projection cannot be parsed; the owning mapping lives in {§matcher-dispatch}.
|
|
12
9
|
import { UnsupportedDialectError, InvalidExpressionError, QueryParseFailureError, } from "@plurnk/plurnk-mimetypes";
|
|
13
10
|
import { TEXT_PRIMITIVE_MIMETYPE } from "./MimetypeClassifier.js";
|
|
11
|
+
import Results from "./Results.js";
|
|
14
12
|
export default class Matcher {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// holds (a multi-line value would otherwise break the `<L><K>` pick-Kth
|
|
18
|
-
// composition that matcher-then-slice depends on).
|
|
19
|
-
static #renderValue(value) {
|
|
20
|
-
return typeof value === "string" && !value.includes("\n") ? value : JSON.stringify(value);
|
|
21
|
-
}
|
|
22
|
-
// Render matches as the model-facing `<source-line>:\t<line-content>` form,
|
|
23
|
-
// one source line per entry — the `N:\t` convention READ emits. A matcher
|
|
24
|
-
// SELECTS a location; READ returns the SOURCE LINE at that location, never an
|
|
25
|
-
// extracted value (grammar contract plurnk.md:31, schemes#27). A regex hit on
|
|
26
|
-
// `### §grinder …` renders that whole line, not the matched token `grinder`.
|
|
27
|
-
//
|
|
28
|
-
// The hit's source footprint is `lines[]` (mimetypes #41: structural dialects
|
|
29
|
-
// self-provide it, symmetric with regex/glob). We anchor on the first span's
|
|
30
|
-
// start line and emit the SOURCE line text there. Deduped by source line — a
|
|
31
|
-
// line matched twice appears once (e.g. two regex hits on one line). A
|
|
32
|
-
// footprint-less match — an xpath computed scalar (count()/string()/sum()/…)
|
|
33
|
-
// that lives nowhere in the source — has no line to return, so it renders its
|
|
34
|
-
// value bare; the framework never fakes a line for it, and neither do we.
|
|
35
|
-
//
|
|
36
|
-
// Line lookup uses SLICE coordinates (the `content` the matcher ran against),
|
|
37
|
-
// while the displayed number is SOURCE coordinates (`+ baseLine - 1`) — so an
|
|
38
|
-
// `<L>`-sliced match reports its original-source line but reads text from the
|
|
39
|
-
// slice in hand. `matching` (the resolved query path) is never surfaced.
|
|
40
|
-
static #renderMatches(matches, content, baseLine) {
|
|
41
|
-
const sliceLines = content.split("\n");
|
|
42
|
-
const offset = baseLine - 1;
|
|
13
|
+
static #evidence(matches) {
|
|
14
|
+
const evidence = [];
|
|
43
15
|
const seen = new Set();
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
16
|
+
for (const match of matches) {
|
|
17
|
+
const regions = match.regions ?? [];
|
|
18
|
+
if (regions.length === 0 && match.matching !== undefined) {
|
|
19
|
+
const item = Results.assertMatchEvidence({ locator: match.matching });
|
|
20
|
+
const key = JSON.stringify(item);
|
|
21
|
+
if (!seen.has(key)) {
|
|
22
|
+
seen.add(key);
|
|
23
|
+
evidence.push(item);
|
|
24
|
+
}
|
|
49
25
|
continue;
|
|
50
26
|
}
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
27
|
+
for (const region of regions) {
|
|
28
|
+
const item = Results.assertMatchEvidence({
|
|
29
|
+
...(match.matching === undefined ? {} : { locator: match.matching }),
|
|
30
|
+
region,
|
|
31
|
+
});
|
|
32
|
+
const key = JSON.stringify(item);
|
|
33
|
+
if (seen.has(key))
|
|
34
|
+
continue;
|
|
35
|
+
seen.add(key);
|
|
36
|
+
evidence.push(item);
|
|
37
|
+
}
|
|
56
38
|
}
|
|
57
|
-
return
|
|
39
|
+
return evidence;
|
|
58
40
|
}
|
|
59
|
-
// Hand the framework the ALREADY-PARSED matcher
|
|
41
|
+
// {§matcher-dispatch} Hand the framework the ALREADY-PARSED matcher, not the raw
|
|
60
42
|
// string — the grammar owns the matcher syntax, so re-classifying `raw`
|
|
61
43
|
// inside mimetypes is a second parser for one syntax and a silent drift
|
|
62
44
|
// surface (a body the grammar parsed as regex that re-classifies as xpath:
|
|
@@ -73,22 +55,18 @@ export default class Matcher {
|
|
|
73
55
|
default: return body.raw;
|
|
74
56
|
}
|
|
75
57
|
}
|
|
76
|
-
static async matchAgainstContent(body, content, mimetype, mimetypes
|
|
58
|
+
static async matchAgainstContent(body, content, mimetype, mimetypes) {
|
|
77
59
|
try {
|
|
78
60
|
// Pass the parsed matcher (declared dialect authoritative) + `hint`
|
|
79
61
|
// (source mimetype, so the framework picks the right per-mimetype
|
|
80
62
|
// handler without re-detecting from content). No re-parse, no drift.
|
|
81
63
|
const rawMatches = await mimetypes.query({ content, hint: mimetype }, Matcher.#parsedMatcher(body));
|
|
82
64
|
if (rawMatches.length === 0) {
|
|
83
|
-
return { status: 204, matches:
|
|
65
|
+
return { status: 204, matches: [] };
|
|
84
66
|
}
|
|
85
|
-
// Render to deduped source lines; `matches` counts the lines the model
|
|
86
|
-
// sees (post-dedup), not raw hits — a line matched twice is one result.
|
|
87
|
-
const rendered = Matcher.#renderMatches(rawMatches, content, baseLine);
|
|
88
67
|
return {
|
|
89
68
|
status: 200,
|
|
90
|
-
|
|
91
|
-
matches: rendered.length,
|
|
69
|
+
matches: Matcher.#evidence(rawMatches),
|
|
92
70
|
};
|
|
93
71
|
}
|
|
94
72
|
catch (err) {
|
|
@@ -98,10 +76,24 @@ export default class Matcher {
|
|
|
98
76
|
// sets each error subclass's `.name` to its class name.
|
|
99
77
|
const name = err instanceof Error ? err.name : "";
|
|
100
78
|
if (name === "UnsupportedDialectError" || err instanceof UnsupportedDialectError) {
|
|
101
|
-
|
|
79
|
+
const unsupportedMimetype = typeof err.mimetype === "string"
|
|
80
|
+
? err.mimetype
|
|
81
|
+
: mimetype;
|
|
82
|
+
return Results.failure("schemes:matcher", "unsupported-dialect", 415, `The ${body.dialect} matcher is not supported for ${unsupportedMimetype}.`, {}, {
|
|
83
|
+
stage: "matcher",
|
|
84
|
+
dialect: body.dialect,
|
|
85
|
+
mimetype: unsupportedMimetype,
|
|
86
|
+
recovery: "Use a matcher supported by the resource mimetype.",
|
|
87
|
+
retryable: false,
|
|
88
|
+
});
|
|
102
89
|
}
|
|
103
90
|
if (name === "InvalidExpressionError" || err instanceof InvalidExpressionError) {
|
|
104
|
-
return
|
|
91
|
+
return Results.failure("schemes:matcher", "invalid-expression", 400, `The ${body.dialect} matcher expression is invalid.`, {}, {
|
|
92
|
+
stage: "matcher",
|
|
93
|
+
dialect: body.dialect,
|
|
94
|
+
recovery: "Correct or remove the matcher.",
|
|
95
|
+
retryable: false,
|
|
96
|
+
});
|
|
105
97
|
}
|
|
106
98
|
if (name === "QueryParseFailureError" || err instanceof QueryParseFailureError) {
|
|
107
99
|
// 203 soft fallback: return raw content as text so the model
|
package/dist/Matcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Matcher.js","sourceRoot":"","sources":["../src/Matcher.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"Matcher.js","sourceRoot":"","sources":["../src/Matcher.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,yEAAyE;AACzE,4EAA4E;AAC5E,0EAA0E;AAC1E,kBAAkB;AAClB,EAAE;AACF,sEAAsE;AACtE,gFAAgF;AAIhF,OAAO,EACH,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,OAAkD,MAAM,cAAc,CAAC;AAS9E,MAAM,CAAC,OAAO,OAAO,OAAO;IACxB,MAAM,CAAC,SAAS,CAAC,OAA8B;QAC3C,MAAM,QAAQ,GAAoB,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;YACpC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACvD,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACtE,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACjC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBACjB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBACd,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACxB,CAAC;gBACD,SAAS;YACb,CAAC;YACD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAAC;oBACrC,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACpE,MAAM;iBACT,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACjC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,SAAS;gBAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACd,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,CAAC;QACL,CAAC;QACD,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,iFAAiF;IACjF,wEAAwE;IACxE,wEAAwE;IACxE,2EAA2E;IAC3E,6EAA6E;IAC7E,wEAAwE;IACxE,2EAA2E;IAC3E,+CAA+C;IAC/C,MAAM,CAAC,cAAc,CAAC,IAAiB;QACnC,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;YACnB,KAAK,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YACpF,KAAK,MAAM,CAAC;YACZ,KAAK,OAAO,CAAC;YACb,KAAK,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;YACrE,SAAS,OAAO,IAAI,CAAC,GAAG,CAAC;QAC7B,CAAC;IACL,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAC5B,IAAiB,EACjB,OAAe,EACf,QAAgB,EAChB,SAAoB;QAEpB,IAAI,CAAC;YACD,oEAAoE;YACpE,kEAAkE;YAClE,qEAAqE;YACrE,MAAM,UAAU,GAAiB,MAAM,SAAS,CAAC,KAAK,CAClD,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAC3B,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,CAC/B,CAAC;YACF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YACxC,CAAC;YACD,OAAO;gBACH,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC;aACzC,CAAC;QACN,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,oEAAoE;YACpE,iEAAiE;YACjE,sEAAsE;YACtE,wDAAwD;YACxD,MAAM,IAAI,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,IAAI,IAAI,KAAK,yBAAyB,IAAI,GAAG,YAAY,uBAAuB,EAAE,CAAC;gBAC/E,MAAM,mBAAmB,GAAG,OAAQ,GAA8B,CAAC,QAAQ,KAAK,QAAQ;oBACpF,CAAC,CAAE,GAA4B,CAAC,QAAQ;oBACxC,CAAC,CAAC,QAAQ,CAAC;gBACf,OAAO,OAAO,CAAC,OAAO,CAClB,iBAAiB,EACjB,qBAAqB,EACrB,GAAG,EACH,OAAO,IAAI,CAAC,OAAO,iCAAiC,mBAAmB,GAAG,EAC1E,EAAE,EACF;oBACI,KAAK,EAAE,SAAS;oBAChB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,QAAQ,EAAE,mBAAmB;oBAC7B,QAAQ,EAAE,mDAAmD;oBAC7D,SAAS,EAAE,KAAK;iBACnB,CACJ,CAAC;YACN,CAAC;YACD,IAAI,IAAI,KAAK,wBAAwB,IAAI,GAAG,YAAY,sBAAsB,EAAE,CAAC;gBAC7E,OAAO,OAAO,CAAC,OAAO,CAClB,iBAAiB,EACjB,oBAAoB,EACpB,GAAG,EACH,OAAO,IAAI,CAAC,OAAO,iCAAiC,EACpD,EAAE,EACF;oBACI,KAAK,EAAE,SAAS;oBAChB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,QAAQ,EAAE,gCAAgC;oBAC1C,SAAS,EAAE,KAAK;iBACnB,CACJ,CAAC;YACN,CAAC;YACD,IAAI,IAAI,KAAK,wBAAwB,IAAI,GAAG,YAAY,sBAAsB,EAAE,CAAC;gBAC7E,6DAA6D;gBAC7D,2DAA2D;gBAC3D,OAAO;oBACH,MAAM,EAAE,GAAG;oBACX,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,uBAAuB;oBACjC,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBAC3D,CAAC;YACN,CAAC;YACD,gEAAgE;YAChE,MAAM,GAAG,CAAC;QACd,CAAC;IACL,CAAC;CACJ"}
|
|
@@ -2,7 +2,7 @@ export declare const TEXT_PRIMITIVE_MIMETYPE = "text/markdown";
|
|
|
2
2
|
export default class MimetypeClassifier {
|
|
3
3
|
static isBinary(mimetype: string): boolean;
|
|
4
4
|
static isJson(mimetype: string): boolean;
|
|
5
|
-
static
|
|
5
|
+
static isHtml(mimetype: string): boolean;
|
|
6
6
|
static normalizeAutoText(mimetype: string | null | undefined): string;
|
|
7
7
|
}
|
|
8
8
|
//# sourceMappingURL=MimetypeClassifier.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MimetypeClassifier.d.ts","sourceRoot":"","sources":["../src/MimetypeClassifier.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MimetypeClassifier.d.ts","sourceRoot":"","sources":["../src/MimetypeClassifier.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,uBAAuB,kBAAkB,CAAC;AAEvD,MAAM,CAAC,OAAO,OAAO,kBAAkB;IAEnC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzC;IAKD,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEvC;IAGD,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEvC;IAMD,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAKpE;CACJ"}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
// Mimetype classifiers used at op-handler boundaries.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// drift surface (schemes#28: NDJSON classified binary → READ 415). The 44-case
|
|
7
|
-
// truth table those tables encoded was absorbed upstream byte-for-byte; the
|
|
8
|
-
// unit suite here remains as the conformance guard on that absorption.
|
|
3
|
+
// Binary/text taxonomy delegates to @plurnk/plurnk-mimetypes. This adapter is
|
|
4
|
+
// the registry-free surface; a consumer with a configured Mimetypes service
|
|
5
|
+
// uses Mimetypes.classify() so installed handler declarations remain authoritative.
|
|
9
6
|
//
|
|
10
|
-
// What stays
|
|
11
|
-
// isJson
|
|
7
|
+
// {§mimetype-classifier} What stays local is scheme semantics, not filetype fact:
|
|
8
|
+
// isJson - JSON receipt summarization (RFC 6839).
|
|
12
9
|
// normalizeAutoText — the text-primitive policy (auto-derived text is markdown).
|
|
13
10
|
import { classifyMimetype } from "@plurnk/plurnk-mimetypes";
|
|
14
11
|
// Text primitive for the agent contract: text/markdown is the default
|
|
@@ -21,20 +18,19 @@ import { classifyMimetype } from "@plurnk/plurnk-mimetypes";
|
|
|
21
18
|
// markdown?"
|
|
22
19
|
export const TEXT_PRIMITIVE_MIMETYPE = "text/markdown";
|
|
23
20
|
export default class MimetypeClassifier {
|
|
24
|
-
//
|
|
21
|
+
// Pure taxonomy for registry-free boundaries (SPEC {§mimetype-classifier}).
|
|
25
22
|
static isBinary(mimetype) {
|
|
26
23
|
return classifyMimetype(mimetype).binary;
|
|
27
24
|
}
|
|
28
|
-
// JSON-family check
|
|
29
|
-
// (Slicer.jsonItems) over line slicer (Slicer.lines) for JSON sources.
|
|
25
|
+
// JSON-family check used by receipt summarization.
|
|
30
26
|
// Matches application/json plus +json suffix variants per RFC 6839.
|
|
31
|
-
// Scheme semantics, deliberately NOT delegated
|
|
27
|
+
// {§mimetype-classifier} Scheme semantics, deliberately NOT delegated.
|
|
32
28
|
static isJson(mimetype) {
|
|
33
29
|
return mimetype === "application/json" || mimetype.endsWith("+json");
|
|
34
30
|
}
|
|
35
|
-
//
|
|
36
|
-
static
|
|
37
|
-
return
|
|
31
|
+
// Exact normalized HTML family used by web acquisition {§html-materialization}.
|
|
32
|
+
static isHtml(mimetype) {
|
|
33
|
+
return mimetype === "text/html" || mimetype === "application/xhtml+xml";
|
|
38
34
|
}
|
|
39
35
|
// Normalize an auto-derived text mimetype to the text primitive.
|
|
40
36
|
// Use at any consumer-side auto-derivation point (file scheme
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MimetypeClassifier.js","sourceRoot":"","sources":["../src/MimetypeClassifier.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"MimetypeClassifier.js","sourceRoot":"","sources":["../src/MimetypeClassifier.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,oFAAoF;AACpF,EAAE;AACF,kFAAkF;AAClF,8DAA8D;AAC9D,mFAAmF;AAEnF,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,sEAAsE;AACtE,oEAAoE;AACpE,mEAAmE;AACnE,wEAAwE;AACxE,wEAAwE;AACxE,qEAAqE;AACrE,gEAAgE;AAChE,aAAa;AACb,MAAM,CAAC,MAAM,uBAAuB,GAAG,eAAe,CAAC;AAEvD,MAAM,CAAC,OAAO,OAAO,kBAAkB;IACnC,4EAA4E;IAC5E,MAAM,CAAC,QAAQ,CAAC,QAAgB;QAC5B,OAAO,gBAAgB,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC;IAC7C,CAAC;IAED,mDAAmD;IACnD,oEAAoE;IACpE,uEAAuE;IACvE,MAAM,CAAC,MAAM,CAAC,QAAgB;QAC1B,OAAO,QAAQ,KAAK,kBAAkB,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACzE,CAAC;IAED,gFAAgF;IAChF,MAAM,CAAC,MAAM,CAAC,QAAgB;QAC1B,OAAO,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,uBAAuB,CAAC;IAC5E,CAAC;IAED,iEAAiE;IACjE,8DAA8D;IAC9D,wEAAwE;IACxE,2BAA2B;IAC3B,MAAM,CAAC,iBAAiB,CAAC,QAAmC;QACxD,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC9F,OAAO,uBAAuB,CAAC;QACnC,CAAC;QACD,OAAO,QAAQ,CAAC;IACpB,CAAC;CACJ"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type UrlPath } from "@plurnk/plurnk-contracts";
|
|
2
|
+
/** Canonical, non-secret identity and transport form for network targets. {§network-address} */
|
|
3
|
+
export default class NetworkAddress {
|
|
4
|
+
readonly scheme: string;
|
|
5
|
+
readonly pathname: string;
|
|
6
|
+
readonly url: string;
|
|
7
|
+
readonly hasCredentials: boolean;
|
|
8
|
+
private constructor();
|
|
9
|
+
static supports(scheme: string): boolean;
|
|
10
|
+
static from(target: UrlPath): NetworkAddress;
|
|
11
|
+
static render(scheme: string, pathname: string): string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=NetworkAddress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkAddress.d.ts","sourceRoot":"","sources":["../src/NetworkAddress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAIpE,gGAAgG;AAChG,MAAM,CAAC,OAAO,OAAO,cAAc;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IAEjC,OAAO,eAgBN;IAED,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEvC;IAED,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,CAE3C;IAED,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAatD;CACJ"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { PathSyntax } from "@plurnk/plurnk-contracts";
|
|
2
|
+
const NETWORK_SCHEMES = new Set(["http", "https", "ws", "wss"]);
|
|
3
|
+
/** Canonical, non-secret identity and transport form for network targets. {§network-address} */
|
|
4
|
+
export default class NetworkAddress {
|
|
5
|
+
scheme;
|
|
6
|
+
pathname;
|
|
7
|
+
url;
|
|
8
|
+
hasCredentials;
|
|
9
|
+
constructor(target) {
|
|
10
|
+
const scheme = target.scheme.toLowerCase();
|
|
11
|
+
if (!NetworkAddress.supports(scheme)) {
|
|
12
|
+
throw new TypeError(`unsupported network scheme: ${target.scheme}`);
|
|
13
|
+
}
|
|
14
|
+
if (target.hostname === null) {
|
|
15
|
+
throw new TypeError(`${scheme} target requires an authority`);
|
|
16
|
+
}
|
|
17
|
+
const authority = `${target.hostname}${target.port === null ? "" : `:${target.port}`}`;
|
|
18
|
+
const query = target.query === null ? "" : `?${target.query}`;
|
|
19
|
+
this.scheme = scheme;
|
|
20
|
+
this.pathname = PathSyntax.decodeParens(`/${authority}${target.pathname}`) + query;
|
|
21
|
+
this.url = `${scheme}://${authority}${target.pathname}${query}`;
|
|
22
|
+
this.hasCredentials = target.username !== null || target.password !== null;
|
|
23
|
+
}
|
|
24
|
+
static supports(scheme) {
|
|
25
|
+
return NETWORK_SCHEMES.has(scheme.toLowerCase());
|
|
26
|
+
}
|
|
27
|
+
static from(target) {
|
|
28
|
+
return new NetworkAddress(target);
|
|
29
|
+
}
|
|
30
|
+
static render(scheme, pathname) {
|
|
31
|
+
if (!NetworkAddress.supports(scheme)) {
|
|
32
|
+
throw new TypeError(`unsupported network scheme: ${scheme}`);
|
|
33
|
+
}
|
|
34
|
+
if (!pathname.startsWith("/")) {
|
|
35
|
+
throw new TypeError("network entry pathname must begin with `/`");
|
|
36
|
+
}
|
|
37
|
+
const queryStart = pathname.indexOf("?");
|
|
38
|
+
const path = queryStart === -1 ? pathname : pathname.slice(0, queryStart);
|
|
39
|
+
const query = queryStart === -1 ? "" : pathname.slice(queryStart);
|
|
40
|
+
return PathSyntax.escapeTarget(`${scheme.toLowerCase()}://${PathSyntax.encodeParens(path.slice(1))}${query}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=NetworkAddress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkAddress.js","sourceRoot":"","sources":["../src/NetworkAddress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAgB,MAAM,0BAA0B,CAAC;AAEpE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;AAEhE,gGAAgG;AAChG,MAAM,CAAC,OAAO,OAAO,cAAc;IACtB,MAAM,CAAS;IACf,QAAQ,CAAS;IACjB,GAAG,CAAS;IACZ,cAAc,CAAU;IAEjC,YAAoB,MAAe;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,SAAS,CAAC,+BAA+B,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC3B,MAAM,IAAI,SAAS,CAAC,GAAG,MAAM,+BAA+B,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,SAAS,GAAG,GAAG,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACvF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAE9D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,YAAY,CAAC,IAAI,SAAS,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,KAAK,CAAC;QACnF,IAAI,CAAC,GAAG,GAAG,GAAG,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,GAAG,KAAK,EAAE,CAAC;QAChE,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,QAAQ,KAAK,IAAI,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,CAAC;IAC/E,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,MAAc;QAC1B,OAAO,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,MAAe;QACvB,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,MAAc,EAAE,QAAgB;QAC1C,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,SAAS,CAAC,+BAA+B,MAAM,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,SAAS,CAAC,4CAA4C,CAAC,CAAC;QACtE,CAAC;QACD,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAC1E,MAAM,KAAK,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAClE,OAAO,UAAU,CAAC,YAAY,CAC1B,GAAG,MAAM,CAAC,WAAW,EAAE,MAAM,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CAChF,CAAC;IACN,CAAC;CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OutputScheme.d.ts","sourceRoot":"","sources":["../src/OutputScheme.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"OutputScheme.d.ts","sourceRoot":"","sources":["../src/OutputScheme.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,CAAC,OAAO,OAAO,YAAY;IAO7B,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,cAAc,CAc5D;CACJ"}
|
package/dist/OutputScheme.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
// Derive an output-scheme manifest from an executor's
|
|
2
|
-
//
|
|
1
|
+
// {§executor-scheme-output} Derive an output-scheme manifest from an executor's
|
|
2
|
+
// per-tag runtime declaration. An
|
|
3
3
|
// executor authors NO SchemeManifest: its `plurnk.runtimes[]` entry already
|
|
4
|
-
// carries name / glyph / example / output-channels, and everything else is the
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// carries name / glyph / example / output-channels, and everything else is the shared
|
|
5
|
+
// read-only-output default. So `EXEC[sh]` gets `sh://` for free, and a multi-tag
|
|
6
|
+
// executor (search/news/images) derives a distinct manifest per tag.
|
|
7
7
|
export default class OutputScheme {
|
|
8
8
|
// The read-only-output default. An executor-scheme is a read-VIEW over
|
|
9
9
|
// produced output: model never writes it (`writableBy: ["plugin"]`), it
|
|
@@ -17,7 +17,6 @@ export default class OutputScheme {
|
|
|
17
17
|
channels: decl.channels,
|
|
18
18
|
defaultChannel: decl.defaultChannel,
|
|
19
19
|
category: "data",
|
|
20
|
-
scope: "workspace",
|
|
21
20
|
writableBy: ["plugin"],
|
|
22
21
|
volatile: true,
|
|
23
22
|
modelVisible: true,
|
package/dist/OutputScheme.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OutputScheme.js","sourceRoot":"","sources":["../src/OutputScheme.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"OutputScheme.js","sourceRoot":"","sources":["../src/OutputScheme.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,kCAAkC;AAClC,4EAA4E;AAC5E,sFAAsF;AACtF,iFAAiF;AACjF,qEAAqE;AAcrE,MAAM,CAAC,OAAO,OAAO,YAAY;IAC7B,uEAAuE;IACvE,wEAAwE;IACxE,6EAA6E;IAC7E,wEAAwE;IACxE,qEAAqE;IACrE,0EAA0E;IAC1E,MAAM,CAAC,mBAAmB,CAAC,IAAiB;QACxC,OAAO;YACH,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,QAAQ,EAAE,MAAM;YAChB,UAAU,EAAE,CAAC,QAAQ,CAAC;YACtB,QAAQ,EAAE,IAAI;YACd,YAAY,EAAE,IAAI;YAClB,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,IAAI;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;SACxB,CAAC;IACN,CAAC;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PacketSections.d.ts","sourceRoot":"","sources":["../src/PacketSections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAKtD,MAAM,CAAC,OAAO,OAAO,cAAc;;IAC/B,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,SAA0B,GAAG,kBAAkB,EAAE,CAY3F;CAuBJ"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const FIELDS = ["name", "slot", "header", "content"];
|
|
2
|
+
const FIELD_NAMES = new Set(FIELDS);
|
|
3
|
+
export default class PacketSections {
|
|
4
|
+
static assertDrafts(value, subject = "packet section drafts") {
|
|
5
|
+
if (!Array.isArray(value))
|
|
6
|
+
throw new TypeError(`${subject} must be an array`);
|
|
7
|
+
const names = new Set();
|
|
8
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
9
|
+
const section = PacketSections.#assertDraft(value[index], `${subject}[${index}]`);
|
|
10
|
+
if (names.has(section.name)) {
|
|
11
|
+
throw new TypeError(`${subject} has duplicate section name '${section.name}'`);
|
|
12
|
+
}
|
|
13
|
+
names.add(section.name);
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
static #assertDraft(value, subject) {
|
|
18
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
19
|
+
throw new TypeError(`${subject} must be an object`);
|
|
20
|
+
}
|
|
21
|
+
const section = value;
|
|
22
|
+
const missing = FIELDS.find((field) => !Object.hasOwn(section, field));
|
|
23
|
+
if (missing !== undefined)
|
|
24
|
+
throw new TypeError(`${subject} is missing field '${missing}'`);
|
|
25
|
+
const unexpected = Object.keys(section).find((field) => !FIELD_NAMES.has(field));
|
|
26
|
+
if (unexpected !== undefined)
|
|
27
|
+
throw new TypeError(`${subject} has unexpected field '${unexpected}'`);
|
|
28
|
+
if (typeof section.name !== "string" || section.name.length === 0) {
|
|
29
|
+
throw new TypeError(`${subject}.name must be a non-empty string`);
|
|
30
|
+
}
|
|
31
|
+
if (section.slot !== "system" && section.slot !== "user") {
|
|
32
|
+
throw new TypeError(`${subject}.slot must be system or user`);
|
|
33
|
+
}
|
|
34
|
+
if (section.header !== null && typeof section.header !== "string") {
|
|
35
|
+
throw new TypeError(`${subject}.header must be a string or null`);
|
|
36
|
+
}
|
|
37
|
+
if (typeof section.content !== "string")
|
|
38
|
+
throw new TypeError(`${subject}.content must be a string`);
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=PacketSections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PacketSections.js","sourceRoot":"","sources":["../src/PacketSections.ts"],"names":[],"mappings":"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"}
|