@instruments/materialgraph 0.24.0 → 0.26.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/association-types.d.ts +20 -20
- package/associations-client.d.ts +4 -4
- package/associations-client.js +3 -10
- package/attribution-types.d.ts +3 -3
- package/brand-most-sampled-types.d.ts +4 -4
- package/brand-types.d.ts +6 -6
- package/brands-client.d.ts +4 -4
- package/brands-client.js +9 -13
- package/browse-types.d.ts +8 -8
- package/by-colour-types.d.ts +18 -18
- package/by-spec-types.d.ts +14 -14
- package/catalog-discovery-types.d.ts +14 -14
- package/catalogue-client.d.ts +4 -4
- package/catalogue-client.js +38 -37
- package/catalogue-types.d.ts +4 -4
- package/citation-types.d.ts +4 -4
- package/client-browse.d.ts +4 -4
- package/client-browse.js +24 -25
- package/client-config.d.ts +2 -2
- package/client-exploration.d.ts +3 -3
- package/client-exploration.js +4 -6
- package/client-source-material-comments.d.ts +4 -4
- package/client-source-material-comments.js +4 -38
- package/client-vocabulary.d.ts +8 -8
- package/client-vocabulary.js +20 -30
- package/client.d.ts +11 -45
- package/client.js +143 -188
- package/codes-client.d.ts +2 -2
- package/codes-client.js +8 -8
- package/codes-types.d.ts +34 -34
- package/colour-aggregate-types.d.ts +24 -24
- package/colours-client.d.ts +2 -2
- package/colours-client.js +15 -15
- package/compare-types.d.ts +10 -10
- package/composition-client.d.ts +3 -3
- package/composition-client.js +8 -7
- package/composition-types.d.ts +12 -12
- package/coordinate-client.d.ts +2 -2
- package/coordinate-client.js +1 -13
- package/corpus-scope-types.d.ts +3 -3
- package/corpus-scope-types.js +1 -25
- package/correction-types.d.ts +10 -10
- package/demand-batch-types.d.ts +18 -18
- package/demand-types.d.ts +24 -24
- package/errors.d.ts +12 -12
- package/errors.js +53 -52
- package/exploration-types.d.ts +29 -22
- package/fan-deck-types.d.ts +6 -6
- package/http-transport.d.ts +13 -21
- package/http-transport.js +31 -28
- package/identify-types.d.ts +10 -10
- package/index.d.ts +0 -6
- package/index.js +0 -2
- package/match-rejection-types.d.ts +6 -6
- package/match-stream-types.d.ts +32 -32
- package/match-stream.d.ts +2 -2
- package/match-stream.js +55 -41
- package/match-types.d.ts +8 -8
- package/material-asset-types.d.ts +26 -26
- package/material-block-types.d.ts +6 -6
- package/material-query-plan-types.d.ts +26 -26
- package/material-resources-client.d.ts +5 -5
- package/material-resources-client.js +10 -20
- package/material-types.d.ts +12 -12
- package/ndjson.js +16 -8
- package/operations.d.ts +6 -6
- package/operations.js +9 -39
- package/package.json +2 -2
- package/palette-completion-types.d.ts +22 -22
- package/palette-search-types.d.ts +28 -28
- package/query-understanding-types.d.ts +43 -36
- package/render-assets-types.d.ts +8 -8
- package/resolve-client.d.ts +2 -2
- package/resolve-client.js +4 -6
- package/resolve-colour-types.d.ts +22 -6
- package/resolve-types.d.ts +10 -10
- package/run-types.d.ts +70 -70
- package/runs.d.ts +13 -26
- package/runs.js +77 -89
- package/samplize-catalogue-types.d.ts +18 -18
- package/samplize-colorvec.d.ts +20 -20
- package/samplize-colorvec.js +66 -42
- package/schema-resource-types.d.ts +38 -38
- package/schema-resource-types.js +5 -5
- package/search-card-types.d.ts +14 -5
- package/search-collapse-types.d.ts +4 -4
- package/search-mood-types.d.ts +2 -2
- package/search-refinement-types.d.ts +8 -8
- package/search-request-types.d.ts +6 -6
- package/search-response-receipt-types.d.ts +135 -34
- package/search-response-types.d.ts +2 -2
- package/search-result-validation.d.ts +3 -3
- package/search-result-validation.js +53 -36
- package/search-window-types.d.ts +2 -2
- package/slot-pool-types.d.ts +20 -20
- package/source-material-validation.d.ts +3 -3
- package/source-material-validation.js +35 -39
- package/spec-facet-types.d.ts +10 -10
- package/spec-types.d.ts +6 -6
- package/specifications.d.ts +9 -25
- package/specifications.js +15 -21
- package/sse.d.ts +2 -2
- package/sse.js +32 -16
- package/substitute-types.d.ts +22 -22
- package/suggest-types.d.ts +7 -7
- package/suggest-types.js +3 -3
- package/taxonomy-coverage-types.d.ts +8 -8
- package/types.d.ts +119 -119
- package/validation.d.ts +26 -26
- package/validation.js +97 -92
- package/webmcp.d.ts +2 -2
- package/webmcp.generated.js +94 -87
- package/project-types.d.ts +0 -79
- package/project-types.js +0 -9
- package/projects.d.ts +0 -13
- package/projects.js +0 -46
- package/run-events.d.ts +0 -106
- package/run-events.js +0 -32
- package/schedule-reference-types.d.ts +0 -46
- package/schedule-reference-types.js +0 -1
- package/schedule-references-client.d.ts +0 -14
- package/schedule-references-client.js +0 -26
- package/schedule-types.d.ts +0 -261
- package/schedule-types.js +0 -1
package/samplize-colorvec.js
CHANGED
|
@@ -3,43 +3,54 @@ export const SAMPLIZE_COLORVEC_RANKING_VERSION = "solid-colorvec-cosine-v2";
|
|
|
3
3
|
export const SAMPLIZE_COLORVEC_EMBEDDING_VERSION = EMBEDDING_VERSION;
|
|
4
4
|
const decodeVector = (encoded) => {
|
|
5
5
|
const bytes = Uint8Array.from(atob(encoded), (c) => c.charCodeAt(0));
|
|
6
|
-
if (bytes.length !== EMBEDDING_VECTOR_SIZE * 4)
|
|
6
|
+
if (bytes.length !== EMBEDDING_VECTOR_SIZE * 4) {
|
|
7
7
|
throw new Error("Invalid colour vector size.");
|
|
8
|
+
}
|
|
8
9
|
const view = new DataView(bytes.buffer);
|
|
9
10
|
return Array.from({ length: EMBEDDING_VECTOR_SIZE }, (_, i) => view.getFloat32(i * 4, true));
|
|
10
11
|
};
|
|
11
12
|
const facets = ["brand", "family", "lightness", "intensity"];
|
|
12
13
|
const identityOrder = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|
|
13
14
|
export const samplizeSolidColorVector = (hex) => {
|
|
14
|
-
if (!/^#[0-9a-f]{6}$/i.test(hex))
|
|
15
|
+
if (!/^#[0-9a-f]{6}$/i.test(hex)) {
|
|
15
16
|
throw new Error("A six-digit published colour is required.");
|
|
17
|
+
}
|
|
16
18
|
return paletteToEmbedding([{ hex, proportion: 1 }], { validateOklab: true });
|
|
17
19
|
};
|
|
18
20
|
/** Canonical constraints are shared by full-cache similarity and constrained text retrieval. */
|
|
19
|
-
export
|
|
21
|
+
export const selectSamplizeEligiblePaints = (paints, input) => {
|
|
20
22
|
const reference = input.reference
|
|
21
23
|
? paints.find((p) => p.variantId === input.reference)
|
|
22
24
|
: undefined;
|
|
23
|
-
if (input.reference && !reference)
|
|
25
|
+
if (input.reference && !reference) {
|
|
24
26
|
throw new Error("The reference is absent from this catalogue version.");
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
+
}
|
|
28
|
+
const low = input.lightnessMin ?? 0;
|
|
29
|
+
const high = input.lightnessMax ?? 1;
|
|
30
|
+
const cool = input.temperatureMin ?? -0.4;
|
|
31
|
+
const warm = input.temperatureMax ?? 0.4;
|
|
27
32
|
if (![low, high, cool, warm].every(Number.isFinite) ||
|
|
28
33
|
low > high ||
|
|
29
|
-
cool > warm)
|
|
34
|
+
cool > warm) {
|
|
30
35
|
throw new Error("Appearance ranges must be finite and ordered.");
|
|
36
|
+
}
|
|
31
37
|
const candidates = paints.filter((p) => {
|
|
32
|
-
if (!reference)
|
|
38
|
+
if (!reference) {
|
|
33
39
|
return true;
|
|
34
|
-
|
|
40
|
+
}
|
|
41
|
+
if (p.variantId === reference.variantId) {
|
|
35
42
|
return false;
|
|
36
|
-
|
|
43
|
+
}
|
|
44
|
+
if (input.direction === "lighter") {
|
|
37
45
|
return p.oklab.L > reference.oklab.L;
|
|
38
|
-
|
|
46
|
+
}
|
|
47
|
+
if (input.direction === "darker") {
|
|
39
48
|
return p.oklab.L < reference.oklab.L;
|
|
40
|
-
|
|
49
|
+
}
|
|
50
|
+
if (input.direction === "muted") {
|
|
41
51
|
return (Math.hypot(p.oklab.a, p.oklab.b) <
|
|
42
52
|
Math.hypot(reference.oklab.a, reference.oklab.b));
|
|
53
|
+
}
|
|
43
54
|
return true;
|
|
44
55
|
});
|
|
45
56
|
const matches = (p, omit) => p.oklab.L >= low &&
|
|
@@ -50,25 +61,30 @@ export function selectSamplizeEligiblePaints(paints, input) {
|
|
|
50
61
|
const counts = {
|
|
51
62
|
brand: {},
|
|
52
63
|
family: {},
|
|
53
|
-
lightness: {},
|
|
54
64
|
intensity: {},
|
|
65
|
+
lightness: {},
|
|
55
66
|
};
|
|
56
|
-
for (const p of candidates)
|
|
57
|
-
for (const f of facets)
|
|
58
|
-
if (matches(p, f))
|
|
67
|
+
for (const p of candidates) {
|
|
68
|
+
for (const f of facets) {
|
|
69
|
+
if (matches(p, f)) {
|
|
59
70
|
counts[f][p[f]] = (counts[f][p[f]] ?? 0) + 1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
60
74
|
const eligible = candidates.filter((p) => matches(p));
|
|
61
|
-
return {
|
|
62
|
-
}
|
|
75
|
+
return { counts, eligible, reference };
|
|
76
|
+
};
|
|
63
77
|
/** Official portable MG ranking over its complete versioned sampling-channel projection. */
|
|
64
|
-
export
|
|
78
|
+
export const createSamplizeColorVecIndex = (cache) => {
|
|
65
79
|
if (cache.embeddingVersion !== EMBEDDING_VERSION ||
|
|
66
|
-
cache.rankingVersion !== SAMPLIZE_COLORVEC_RANKING_VERSION)
|
|
80
|
+
cache.rankingVersion !== SAMPLIZE_COLORVEC_RANKING_VERSION) {
|
|
67
81
|
throw new Error("The colour cache uses an incompatible embedding or ranking version. Refresh it before searching.");
|
|
82
|
+
}
|
|
68
83
|
if (!cache.sourceVersion ||
|
|
69
84
|
!cache.dictionaryVersion ||
|
|
70
|
-
!Number.isFinite(Date.parse(cache.generatedAt)))
|
|
85
|
+
!Number.isFinite(Date.parse(cache.generatedAt))) {
|
|
71
86
|
throw new Error("The colour cache is missing its provenance.");
|
|
87
|
+
}
|
|
72
88
|
const paints = cache.paints.map((p) => ({
|
|
73
89
|
...p,
|
|
74
90
|
vector: typeof p.vector === "string" ? decodeVector(p.vector) : p.vector,
|
|
@@ -78,8 +94,9 @@ export function createSamplizeColorVecIndex(cache) {
|
|
|
78
94
|
if (identities.has(paint.variantId) ||
|
|
79
95
|
paint.vector.length !== EMBEDDING_VECTOR_SIZE ||
|
|
80
96
|
!paint.vector.every(Number.isFinite) ||
|
|
81
|
-
![paint.oklab.L, paint.oklab.a, paint.oklab.b].every(Number.isFinite))
|
|
97
|
+
![paint.oklab.L, paint.oklab.a, paint.oklab.b].every(Number.isFinite)) {
|
|
82
98
|
throw new Error("The colour cache contains invalid or duplicate paint records.");
|
|
99
|
+
}
|
|
83
100
|
identities.add(paint.variantId);
|
|
84
101
|
}
|
|
85
102
|
const vectors = new Map();
|
|
@@ -88,8 +105,9 @@ export function createSamplizeColorVecIndex(cache) {
|
|
|
88
105
|
let value = vectors.get(key);
|
|
89
106
|
if (!value) {
|
|
90
107
|
value = samplizeSolidColorVector(hex);
|
|
91
|
-
if (vectors.size >= 512)
|
|
108
|
+
if (vectors.size >= 512) {
|
|
92
109
|
vectors.delete(vectors.keys().next().value);
|
|
110
|
+
}
|
|
93
111
|
vectors.set(key, value);
|
|
94
112
|
}
|
|
95
113
|
return value;
|
|
@@ -97,36 +115,42 @@ export function createSamplizeColorVecIndex(cache) {
|
|
|
97
115
|
return {
|
|
98
116
|
search(input) {
|
|
99
117
|
const limit = input.limit ?? 48;
|
|
100
|
-
if (!Number.isInteger(limit) || limit < 1 || limit > 100)
|
|
118
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 100) {
|
|
101
119
|
throw new Error("Choose between 1 and 100 suggestions.");
|
|
120
|
+
}
|
|
102
121
|
const { reference, eligible, counts } = selectSamplizeEligiblePaints(paints, input);
|
|
103
122
|
const palette = (input.palette?.length
|
|
104
123
|
? input.palette
|
|
105
124
|
: [{ hex: input.hex ?? reference?.hex ?? "", proportion: 1 }])
|
|
106
125
|
.map((p) => ({ ...p, hex: p.hex.toLowerCase() }))
|
|
107
|
-
.
|
|
126
|
+
.toSorted((a, b) => b.proportion - a.proportion || identityOrder(a.hex, b.hex));
|
|
108
127
|
if (palette.length > 12 ||
|
|
109
128
|
palette.some((p) => !Number.isFinite(p.proportion) ||
|
|
110
129
|
p.proportion <= 0 ||
|
|
111
|
-
p.proportion > 1))
|
|
130
|
+
p.proportion > 1)) {
|
|
112
131
|
throw new Error("Supply up to twelve positive image colour shares.");
|
|
132
|
+
}
|
|
113
133
|
const total = palette.reduce((sum, p) => sum + p.proportion, 0);
|
|
114
134
|
const buckets = palette.map((p, position) => ({
|
|
115
135
|
...p,
|
|
136
|
+
paints: [],
|
|
116
137
|
position,
|
|
117
|
-
vector: vectorFor(p.hex),
|
|
118
138
|
quota: Math.floor((limit * p.proportion) / total),
|
|
119
139
|
remainder: ((limit * p.proportion) / total) % 1,
|
|
120
|
-
|
|
140
|
+
vector: vectorFor(p.hex),
|
|
121
141
|
}));
|
|
122
142
|
let remaining = limit - buckets.reduce((sum, p) => sum + p.quota, 0);
|
|
123
|
-
for (const p of [...buckets].
|
|
124
|
-
if (remaining-- > 0)
|
|
143
|
+
for (const p of [...buckets].toSorted((a, b) => b.remainder - a.remainder || a.position - b.position)) {
|
|
144
|
+
if (remaining-- > 0) {
|
|
125
145
|
p.quota++;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
126
148
|
for (const paint of eligible) {
|
|
127
|
-
let best = buckets[0]
|
|
149
|
+
let best = buckets[0];
|
|
150
|
+
let score = embeddingCosineSimilarity(paint.vector, best.vector);
|
|
128
151
|
for (let i = 1; i < buckets.length; i++) {
|
|
129
|
-
const candidate = buckets[i]
|
|
152
|
+
const candidate = buckets[i];
|
|
153
|
+
const next = embeddingCosineSimilarity(paint.vector, candidate.vector);
|
|
130
154
|
if (next > score) {
|
|
131
155
|
best = candidate;
|
|
132
156
|
score = next;
|
|
@@ -135,33 +159,33 @@ export function createSamplizeColorVecIndex(cache) {
|
|
|
135
159
|
best.paints.push({ id: paint.variantId, score });
|
|
136
160
|
}
|
|
137
161
|
const groups = buckets
|
|
138
|
-
.
|
|
162
|
+
.toSorted((a, b) => b.proportion - a.proportion || a.position - b.position)
|
|
139
163
|
.map((p) => {
|
|
140
164
|
const ids = p.paints
|
|
141
|
-
.
|
|
165
|
+
.toSorted((a, b) => b.score - a.score || identityOrder(a.id, b.id))
|
|
142
166
|
.slice(0, p.quota)
|
|
143
167
|
.map((paint) => paint.id);
|
|
144
168
|
return {
|
|
145
169
|
hex: p.hex,
|
|
170
|
+
ids,
|
|
146
171
|
proportion: p.proportion,
|
|
147
172
|
quota: p.quota,
|
|
148
|
-
ids,
|
|
149
173
|
shortfall: p.quota - ids.length,
|
|
150
174
|
};
|
|
151
175
|
});
|
|
152
176
|
const ids = groups.flatMap((p) => p.ids);
|
|
153
177
|
return {
|
|
154
|
-
|
|
155
|
-
groups,
|
|
156
|
-
limited: eligible.length > ids.length,
|
|
157
|
-
eligibleCount: eligible.length,
|
|
178
|
+
countBasis: "complete-catalogue",
|
|
158
179
|
counts,
|
|
159
|
-
sourceVersion: cache.sourceVersion,
|
|
160
180
|
dictionaryVersion: cache.dictionaryVersion,
|
|
181
|
+
eligibleCount: eligible.length,
|
|
161
182
|
embeddingVersion: cache.embeddingVersion,
|
|
183
|
+
groups,
|
|
184
|
+
ids,
|
|
185
|
+
limited: eligible.length > ids.length,
|
|
162
186
|
rankingVersion: cache.rankingVersion,
|
|
163
|
-
|
|
187
|
+
sourceVersion: cache.sourceVersion,
|
|
164
188
|
};
|
|
165
189
|
},
|
|
166
190
|
};
|
|
167
|
-
}
|
|
191
|
+
};
|
|
@@ -8,40 +8,40 @@ export type SchemaResource = "blocks" | "attributes" | "verticals" | "productTyp
|
|
|
8
8
|
* it must cover cannot drift apart.
|
|
9
9
|
*/
|
|
10
10
|
export declare const SCHEMA_RESOURCE_OPERATION_IDS: {
|
|
11
|
-
readonly blocks: "list_schema_blocks";
|
|
12
11
|
readonly attributes: "list_schema_attributes";
|
|
13
|
-
readonly
|
|
12
|
+
readonly blocks: "list_schema_blocks";
|
|
13
|
+
readonly mappings: "list_schema_mappings";
|
|
14
|
+
readonly productTypeTemplates: "list_schema_product_type_templates";
|
|
14
15
|
readonly productTypes: "list_schema_product_types";
|
|
16
|
+
readonly sourceRequirements: "list_schema_source_requirements";
|
|
15
17
|
readonly units: "list_schema_units";
|
|
16
18
|
readonly valueDictionaries: "list_schema_value_dictionaries";
|
|
17
|
-
readonly
|
|
18
|
-
readonly productTypeTemplates: "list_schema_product_type_templates";
|
|
19
|
-
readonly mappings: "list_schema_mappings";
|
|
19
|
+
readonly verticals: "list_schema_verticals";
|
|
20
20
|
};
|
|
21
21
|
export type SchemaResourceRequest = SchemaResource;
|
|
22
|
-
export
|
|
22
|
+
export type SchemaLifecycle = {
|
|
23
23
|
status: OpenEnum<"draft" | "active" | "deprecated">;
|
|
24
24
|
introducedIn: string;
|
|
25
25
|
deprecatedIn?: string;
|
|
26
26
|
supersededBy?: string;
|
|
27
|
-
}
|
|
28
|
-
export
|
|
27
|
+
};
|
|
28
|
+
export type SchemaExternalMapping = {
|
|
29
29
|
target: OpenEnum<"schema_org" | "ifc_pset" | "bsdd" | "iso_23387" | "eclass" | "gs1_gdm" | "gdsn" | "etim" | "uniclass">;
|
|
30
30
|
targetPath: string;
|
|
31
31
|
mappingType: OpenEnum<"direct" | "transform" | "derived" | "classification" | "semantic">;
|
|
32
32
|
notes?: string;
|
|
33
|
-
}
|
|
34
|
-
export
|
|
33
|
+
};
|
|
34
|
+
export type SchemaBlockItem = {
|
|
35
35
|
id: string;
|
|
36
36
|
semanticId: string;
|
|
37
37
|
lifecycle: SchemaLifecycle;
|
|
38
38
|
name: string;
|
|
39
39
|
description: string;
|
|
40
40
|
attributeIds: string[];
|
|
41
|
-
}
|
|
41
|
+
};
|
|
42
42
|
export type KnownSchemaQuantityKind = "length" | "area" | "volume" | "mass" | "time" | "temperature" | "currency" | "ratio" | "density" | "coverage" | "emissions" | "force" | "power" | "voltage" | "current" | "frequency" | "luminous_flux" | "color_temperature" | "count" | "unitless";
|
|
43
43
|
export type SchemaQuantityKind = OpenEnum<KnownSchemaQuantityKind>;
|
|
44
|
-
export
|
|
44
|
+
export type SchemaAttributeItem = {
|
|
45
45
|
id: string;
|
|
46
46
|
semanticId: string;
|
|
47
47
|
lifecycle: SchemaLifecycle;
|
|
@@ -58,14 +58,14 @@ export interface SchemaAttributeItem {
|
|
|
58
58
|
comparable: boolean;
|
|
59
59
|
usedInBlocks: string[];
|
|
60
60
|
enumValues: string[] | null;
|
|
61
|
-
}
|
|
62
|
-
export
|
|
61
|
+
};
|
|
62
|
+
export type SchemaVerticalItem = {
|
|
63
63
|
id: string;
|
|
64
64
|
displayName: string;
|
|
65
65
|
description: string;
|
|
66
|
-
}
|
|
66
|
+
};
|
|
67
67
|
export type SchemaApplicability = OpenEnum<"required" | "recommended" | "optional" | "unusual">;
|
|
68
|
-
export
|
|
68
|
+
export type SchemaProductTypeBlock = {
|
|
69
69
|
blockId: string;
|
|
70
70
|
applicability: SchemaApplicability;
|
|
71
71
|
requiredAttributes?: string[];
|
|
@@ -74,8 +74,8 @@ export interface SchemaProductTypeBlock {
|
|
|
74
74
|
completenessWeight?: number;
|
|
75
75
|
notes?: string;
|
|
76
76
|
optional?: boolean;
|
|
77
|
-
}
|
|
78
|
-
export
|
|
77
|
+
};
|
|
78
|
+
export type SchemaProductTypeItem = {
|
|
79
79
|
id: string;
|
|
80
80
|
name: string;
|
|
81
81
|
description?: string;
|
|
@@ -85,8 +85,8 @@ export interface SchemaProductTypeItem {
|
|
|
85
85
|
productTypeSpecificAttributes?: string[];
|
|
86
86
|
semanticId: string;
|
|
87
87
|
lifecycle: SchemaLifecycle;
|
|
88
|
-
}
|
|
89
|
-
export
|
|
88
|
+
};
|
|
89
|
+
export type SchemaUnitItem = {
|
|
90
90
|
id: string;
|
|
91
91
|
name: string;
|
|
92
92
|
symbol: string;
|
|
@@ -99,8 +99,8 @@ export interface SchemaUnitItem {
|
|
|
99
99
|
notes?: string;
|
|
100
100
|
semanticId: string;
|
|
101
101
|
lifecycle: SchemaLifecycle;
|
|
102
|
-
}
|
|
103
|
-
export
|
|
102
|
+
};
|
|
103
|
+
export type SchemaValueDictionaryTerm = {
|
|
104
104
|
id: string;
|
|
105
105
|
label: string;
|
|
106
106
|
aliases?: string[];
|
|
@@ -108,20 +108,20 @@ export interface SchemaValueDictionaryTerm {
|
|
|
108
108
|
externalMappings?: SchemaExternalMapping[];
|
|
109
109
|
semanticId: string;
|
|
110
110
|
lifecycle: SchemaLifecycle;
|
|
111
|
-
}
|
|
112
|
-
export
|
|
111
|
+
};
|
|
112
|
+
export type SchemaValueDictionaryItem = {
|
|
113
113
|
id: string;
|
|
114
114
|
name: string;
|
|
115
115
|
description: string;
|
|
116
116
|
terms: SchemaValueDictionaryTerm[];
|
|
117
117
|
semanticId: string;
|
|
118
118
|
lifecycle: SchemaLifecycle;
|
|
119
|
-
}
|
|
119
|
+
};
|
|
120
120
|
export type KnownSchemaSourceType = "manufacturer_page" | "technical_data_sheet" | "safety_data_sheet" | "test_report" | "certificate" | "image" | "commerce_page" | "catalog_pdf" | "derived_analysis";
|
|
121
121
|
export type SchemaSourceType = OpenEnum<KnownSchemaSourceType>;
|
|
122
122
|
export type KnownSchemaSourceMethod = "manual_review" | "agent_extract" | "pdf_extract" | "image_analysis" | "html_scrape" | "structured_feed" | "calculation";
|
|
123
123
|
export type SchemaSourceMethod = OpenEnum<KnownSchemaSourceMethod>;
|
|
124
|
-
export
|
|
124
|
+
export type SchemaSourceRequirementItem = {
|
|
125
125
|
id: string;
|
|
126
126
|
name: string;
|
|
127
127
|
description: string;
|
|
@@ -130,11 +130,11 @@ export interface SchemaSourceRequirementItem {
|
|
|
130
130
|
minConfidence: number;
|
|
131
131
|
reviewRequired: boolean;
|
|
132
132
|
freshnessDays?: number;
|
|
133
|
-
sourceBasis?: OpenEnum<"declared" | "derived"
|
|
133
|
+
sourceBasis?: OpenEnum<"declared" | "derived">;
|
|
134
134
|
semanticId: string;
|
|
135
135
|
lifecycle: SchemaLifecycle;
|
|
136
|
-
}
|
|
137
|
-
export
|
|
136
|
+
};
|
|
137
|
+
export type SchemaProductTypeTemplateBlock = {
|
|
138
138
|
blockId: string;
|
|
139
139
|
applicability: SchemaApplicability;
|
|
140
140
|
requiredAttributes?: string[];
|
|
@@ -142,8 +142,8 @@ export interface SchemaProductTypeTemplateBlock {
|
|
|
142
142
|
sourceRequirementId?: string;
|
|
143
143
|
completenessWeight?: number;
|
|
144
144
|
notes?: string;
|
|
145
|
-
}
|
|
146
|
-
export
|
|
145
|
+
};
|
|
146
|
+
export type SchemaProductTypeTemplateItem = {
|
|
147
147
|
id: string;
|
|
148
148
|
name: string;
|
|
149
149
|
productTypeId: string;
|
|
@@ -152,8 +152,8 @@ export interface SchemaProductTypeTemplateItem {
|
|
|
152
152
|
notes?: string;
|
|
153
153
|
semanticId: string;
|
|
154
154
|
lifecycle: SchemaLifecycle;
|
|
155
|
-
}
|
|
156
|
-
export
|
|
155
|
+
};
|
|
156
|
+
export type SchemaMappingItem = {
|
|
157
157
|
target: SchemaExternalMapping["target"];
|
|
158
158
|
subjectKind?: OpenEnum<"attribute" | "block" | "product_type" | "template" | "unit" | "value_dictionary" | "value_dictionary_term">;
|
|
159
159
|
subjectId?: string;
|
|
@@ -161,8 +161,8 @@ export interface SchemaMappingItem {
|
|
|
161
161
|
targetPath: string;
|
|
162
162
|
mappingType: SchemaExternalMapping["mappingType"];
|
|
163
163
|
notes?: string;
|
|
164
|
-
}
|
|
165
|
-
export
|
|
164
|
+
};
|
|
165
|
+
export type SchemaResourceItemMap = {
|
|
166
166
|
blocks: SchemaBlockItem;
|
|
167
167
|
attributes: SchemaAttributeItem;
|
|
168
168
|
verticals: SchemaVerticalItem;
|
|
@@ -172,10 +172,10 @@ export interface SchemaResourceItemMap {
|
|
|
172
172
|
sourceRequirements: SchemaSourceRequirementItem;
|
|
173
173
|
productTypeTemplates: SchemaProductTypeTemplateItem;
|
|
174
174
|
mappings: SchemaMappingItem;
|
|
175
|
-
}
|
|
176
|
-
export
|
|
175
|
+
};
|
|
176
|
+
export type SchemaResourceResponse<K extends SchemaResource = SchemaResource> = {
|
|
177
177
|
kind: K;
|
|
178
178
|
schemaVersion: string;
|
|
179
179
|
items: SchemaResourceItemMap[K][];
|
|
180
180
|
totalCount: number;
|
|
181
|
-
}
|
|
181
|
+
};
|
package/schema-resource-types.js
CHANGED
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
* it must cover cannot drift apart.
|
|
6
6
|
*/
|
|
7
7
|
export const SCHEMA_RESOURCE_OPERATION_IDS = {
|
|
8
|
-
blocks: "list_schema_blocks",
|
|
9
8
|
attributes: "list_schema_attributes",
|
|
10
|
-
|
|
9
|
+
blocks: "list_schema_blocks",
|
|
10
|
+
mappings: "list_schema_mappings",
|
|
11
|
+
productTypeTemplates: "list_schema_product_type_templates",
|
|
11
12
|
productTypes: "list_schema_product_types",
|
|
13
|
+
sourceRequirements: "list_schema_source_requirements",
|
|
12
14
|
units: "list_schema_units",
|
|
13
15
|
valueDictionaries: "list_schema_value_dictionaries",
|
|
14
|
-
|
|
15
|
-
productTypeTemplates: "list_schema_product_type_templates",
|
|
16
|
-
mappings: "list_schema_mappings",
|
|
16
|
+
verticals: "list_schema_verticals",
|
|
17
17
|
};
|
package/search-card-types.d.ts
CHANGED
|
@@ -11,14 +11,15 @@
|
|
|
11
11
|
import type { ProductId, VariantId } from "./identifiers.js";
|
|
12
12
|
import type { OpenEnum, SearchData, SearchResponse } from "./types.js";
|
|
13
13
|
/**
|
|
14
|
-
* The lean `view:"card"` result item — identity + name + thumbnail +
|
|
14
|
+
* The lean `view:"card"` result item — identity + name + code + thumbnail +
|
|
15
|
+
* score.
|
|
15
16
|
*
|
|
16
17
|
* A PROJECTION, not a smaller answer: a field the card omits (palette, verdict,
|
|
17
18
|
* signals, availability) is unread here, never known-absent. Re-read the same
|
|
18
19
|
* `variantId` at `view: "full"` or via `material()` before claiming anything the
|
|
19
20
|
* card does not carry.
|
|
20
21
|
*/
|
|
21
|
-
export
|
|
22
|
+
export type SearchCardItem = {
|
|
22
23
|
/** Accepted sampleability fact. Absent means unknown, never false. */
|
|
23
24
|
sampleable?: boolean;
|
|
24
25
|
/** Opaque — round-trip verbatim. */
|
|
@@ -30,6 +31,14 @@ export interface SearchCardItem {
|
|
|
30
31
|
name: string;
|
|
31
32
|
variantName: string | null;
|
|
32
33
|
imageUrl: string | null;
|
|
34
|
+
/**
|
|
35
|
+
* The manufacturer's own item code, the same key the full item carries.
|
|
36
|
+
* Reach for it when two cards read alike: `name` is the PRODUCT name, and a
|
|
37
|
+
* paint product is a whole collection, so brand, product name and variant
|
|
38
|
+
* name together are shared by most of the catalogue. ABSENT means no code is
|
|
39
|
+
* recorded, never that the variant cannot be ordered.
|
|
40
|
+
*/
|
|
41
|
+
manufacturerCode?: string;
|
|
33
42
|
projectSaveCapability?: "allowed";
|
|
34
43
|
sourceStatus?: "provisional";
|
|
35
44
|
score: number;
|
|
@@ -45,11 +54,11 @@ export interface SearchCardItem {
|
|
|
45
54
|
* attribute rather than a list of candidates.
|
|
46
55
|
*/
|
|
47
56
|
attributes?: Record<string, string | string[] | null>;
|
|
48
|
-
}
|
|
57
|
+
};
|
|
49
58
|
/** The `view:"card"` response form — the lean grid projection of {@link SearchResponse}. */
|
|
50
|
-
export
|
|
59
|
+
export type SearchCardResponse = {
|
|
51
60
|
data: Omit<SearchData, "view" | "results"> & {
|
|
52
61
|
view: OpenEnum<"card">;
|
|
53
62
|
results: SearchCardItem[];
|
|
54
63
|
};
|
|
55
|
-
}
|
|
64
|
+
} & Omit<SearchResponse, "data">;
|
|
@@ -31,7 +31,7 @@ import type { SearchResultSignals } from "./types.js";
|
|
|
31
31
|
* engine issues for the card only. Fetch the variant by `variantId` when you
|
|
32
32
|
* need its full record.
|
|
33
33
|
*/
|
|
34
|
-
export
|
|
34
|
+
export type CollapsedVariant = {
|
|
35
35
|
/** Opaque — round-trip verbatim. */
|
|
36
36
|
variantId: VariantId;
|
|
37
37
|
/** The variant's own label; for paint, the colourway name. Null when unnamed. */
|
|
@@ -52,18 +52,18 @@ export interface CollapsedVariant {
|
|
|
52
52
|
materialBankId?: string;
|
|
53
53
|
/** This variant's own mode-primary score — the value the array is ordered by. */
|
|
54
54
|
score: number;
|
|
55
|
-
}
|
|
55
|
+
};
|
|
56
56
|
/**
|
|
57
57
|
* One member of a collapsed result's `SearchResultItem.anatomy` — the
|
|
58
58
|
* EXPLAIN-only readout of the same grouping {@link CollapsedVariant} publishes.
|
|
59
59
|
* Where a collapsed variant is what a surface renders, this is what an operator
|
|
60
60
|
* inspects: it carries the per-arm `signals` that made the variant a candidate.
|
|
61
61
|
*/
|
|
62
|
-
export
|
|
62
|
+
export type SearchAnatomyMember = {
|
|
63
63
|
/** Opaque — round-trip verbatim. */
|
|
64
64
|
variantId: VariantId;
|
|
65
65
|
variantName: string | null;
|
|
66
66
|
color: string | null;
|
|
67
67
|
score: number;
|
|
68
68
|
signals: SearchResultSignals;
|
|
69
|
-
}
|
|
69
|
+
};
|
package/search-mood-types.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ import type { SearchInput } from "./types.js";
|
|
|
23
23
|
* of this object — without it, "no GREENGUARD results" reads as "nobody is
|
|
24
24
|
* certified" when it means "nobody is certified TO THIS EVIDENTIAL STANDARD".
|
|
25
25
|
*/
|
|
26
|
-
export
|
|
26
|
+
export type SearchFilterTrust = {
|
|
27
27
|
/** Confidence floor, 0–1. A value below it is excluded, not marked failed. */
|
|
28
28
|
minConfidence?: number;
|
|
29
29
|
/**
|
|
@@ -45,7 +45,7 @@ export interface SearchFilterTrust {
|
|
|
45
45
|
sourceBasis?: "catalog_feed" | "declared" | "derived";
|
|
46
46
|
/** Fold the attribute's own registry confidence requirement in, server-side. */
|
|
47
47
|
meetsRequirement?: true;
|
|
48
|
-
}
|
|
48
|
+
};
|
|
49
49
|
/**
|
|
50
50
|
* One HARD criterion. Applied as a restriction BEFORE ranking, so a filtered
|
|
51
51
|
* search's empty result means "nothing on record satisfies this", never "nothing
|
|
@@ -97,13 +97,13 @@ export type SearchFilter = {
|
|
|
97
97
|
trust?: SearchFilterTrust;
|
|
98
98
|
};
|
|
99
99
|
/** One structured refinement returned with a search response. */
|
|
100
|
-
export
|
|
100
|
+
export type SearchSuggestion = {
|
|
101
101
|
label: string;
|
|
102
102
|
/** Complete replacement request, not a partial patch. */
|
|
103
103
|
request: SearchInput;
|
|
104
|
-
}
|
|
104
|
+
};
|
|
105
105
|
/** One reading a {@link SearchDisambiguation} offers. */
|
|
106
|
-
export
|
|
106
|
+
export type SearchInterpretation = {
|
|
107
107
|
id: string;
|
|
108
108
|
label: string;
|
|
109
109
|
kind: string;
|
|
@@ -113,7 +113,7 @@ export interface SearchInterpretation {
|
|
|
113
113
|
hex?: string;
|
|
114
114
|
/** Complete replacement request, not a partial patch. */
|
|
115
115
|
request: SearchInput;
|
|
116
|
-
}
|
|
116
|
+
};
|
|
117
117
|
/** The governed ambiguity classes emitted by MaterialGraph search. */
|
|
118
118
|
export type SearchDisambiguationKind = "compliance-phrase" | "colour-material" | "paint-colour" | "paint-identity";
|
|
119
119
|
/**
|
|
@@ -124,10 +124,10 @@ export type SearchDisambiguationKind = "compliance-phrase" | "colour-material" |
|
|
|
124
124
|
* so choosing a reading is a re-issue rather than a patch. Ignoring this block does not
|
|
125
125
|
* make the ambiguity go away — it makes it invisible to the person who asked.
|
|
126
126
|
*/
|
|
127
|
-
export
|
|
127
|
+
export type SearchDisambiguation = {
|
|
128
128
|
/** Compliance, colour-material, paint-colour, or paint-identity ambiguity. */
|
|
129
129
|
kind: SearchDisambiguationKind;
|
|
130
130
|
/** The ambiguous term or phrase. */
|
|
131
131
|
term: string;
|
|
132
132
|
interpretations: SearchInterpretation[];
|
|
133
|
-
}
|
|
133
|
+
};
|
|
@@ -15,9 +15,9 @@ import type { ColourInput, OpenEnum, SearchImageInput } from "./types.js";
|
|
|
15
15
|
* optional; supply at least one signal (`text`, `colours`, `mood`, `similarTo`,
|
|
16
16
|
* or `image`). Passed through to the server verbatim.
|
|
17
17
|
*/
|
|
18
|
-
export
|
|
18
|
+
export type SearchInput = {
|
|
19
19
|
text?: string;
|
|
20
|
-
textModes?:
|
|
20
|
+
textModes?: OpenEnum<"visual" | "lexical">[];
|
|
21
21
|
colours?: ColourInput[];
|
|
22
22
|
colourLogic?: OpenEnum<"all" | "any">;
|
|
23
23
|
colourTolerance?: OpenEnum<"tight" | "normal" | "loose">;
|
|
@@ -122,7 +122,7 @@ export interface SearchInput {
|
|
|
122
122
|
* demotes a failed/missing preferred hit WITHIN its page only.
|
|
123
123
|
*/
|
|
124
124
|
preferences?: SearchFilter[];
|
|
125
|
-
/**
|
|
125
|
+
/** Results per page (default 60, max 60), never a bound on the match set. */
|
|
126
126
|
limit?: number;
|
|
127
127
|
/** The previous response's `cursor`, passed back verbatim. Never synthesise one. */
|
|
128
128
|
cursor?: Cursor;
|
|
@@ -210,9 +210,9 @@ export interface SearchInput {
|
|
|
210
210
|
* cards, which are orderable samples and never specifiable materials.
|
|
211
211
|
*/
|
|
212
212
|
includeSamplingArtifacts?: boolean;
|
|
213
|
-
}
|
|
213
|
+
};
|
|
214
214
|
/** Query-string params for the GET `/search` form. */
|
|
215
|
-
export
|
|
215
|
+
export type SearchGetParams = {
|
|
216
216
|
q?: string;
|
|
217
217
|
colours?: string;
|
|
218
218
|
logic?: OpenEnum<"all" | "any">;
|
|
@@ -242,4 +242,4 @@ export interface SearchGetParams {
|
|
|
242
242
|
orderBy?: string;
|
|
243
243
|
/** Comma-separated attribute ids — the `returnAttributes` list. */
|
|
244
244
|
returnAttributes?: string;
|
|
245
|
-
}
|
|
245
|
+
};
|