@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.
Files changed (124) hide show
  1. package/association-types.d.ts +20 -20
  2. package/associations-client.d.ts +4 -4
  3. package/associations-client.js +3 -10
  4. package/attribution-types.d.ts +3 -3
  5. package/brand-most-sampled-types.d.ts +4 -4
  6. package/brand-types.d.ts +6 -6
  7. package/brands-client.d.ts +4 -4
  8. package/brands-client.js +9 -13
  9. package/browse-types.d.ts +8 -8
  10. package/by-colour-types.d.ts +18 -18
  11. package/by-spec-types.d.ts +14 -14
  12. package/catalog-discovery-types.d.ts +14 -14
  13. package/catalogue-client.d.ts +4 -4
  14. package/catalogue-client.js +38 -37
  15. package/catalogue-types.d.ts +4 -4
  16. package/citation-types.d.ts +4 -4
  17. package/client-browse.d.ts +4 -4
  18. package/client-browse.js +24 -25
  19. package/client-config.d.ts +2 -2
  20. package/client-exploration.d.ts +3 -3
  21. package/client-exploration.js +4 -6
  22. package/client-source-material-comments.d.ts +4 -4
  23. package/client-source-material-comments.js +4 -38
  24. package/client-vocabulary.d.ts +8 -8
  25. package/client-vocabulary.js +20 -30
  26. package/client.d.ts +11 -45
  27. package/client.js +143 -188
  28. package/codes-client.d.ts +2 -2
  29. package/codes-client.js +8 -8
  30. package/codes-types.d.ts +34 -34
  31. package/colour-aggregate-types.d.ts +24 -24
  32. package/colours-client.d.ts +2 -2
  33. package/colours-client.js +15 -15
  34. package/compare-types.d.ts +10 -10
  35. package/composition-client.d.ts +3 -3
  36. package/composition-client.js +8 -7
  37. package/composition-types.d.ts +12 -12
  38. package/coordinate-client.d.ts +2 -2
  39. package/coordinate-client.js +1 -13
  40. package/corpus-scope-types.d.ts +3 -3
  41. package/corpus-scope-types.js +1 -25
  42. package/correction-types.d.ts +10 -10
  43. package/demand-batch-types.d.ts +18 -18
  44. package/demand-types.d.ts +24 -24
  45. package/errors.d.ts +12 -12
  46. package/errors.js +53 -52
  47. package/exploration-types.d.ts +29 -22
  48. package/fan-deck-types.d.ts +6 -6
  49. package/http-transport.d.ts +13 -21
  50. package/http-transport.js +31 -28
  51. package/identify-types.d.ts +10 -10
  52. package/index.d.ts +0 -6
  53. package/index.js +0 -2
  54. package/match-rejection-types.d.ts +6 -6
  55. package/match-stream-types.d.ts +32 -32
  56. package/match-stream.d.ts +2 -2
  57. package/match-stream.js +55 -41
  58. package/match-types.d.ts +8 -8
  59. package/material-asset-types.d.ts +26 -26
  60. package/material-block-types.d.ts +6 -6
  61. package/material-query-plan-types.d.ts +26 -26
  62. package/material-resources-client.d.ts +5 -5
  63. package/material-resources-client.js +10 -20
  64. package/material-types.d.ts +12 -12
  65. package/ndjson.js +16 -8
  66. package/operations.d.ts +6 -6
  67. package/operations.js +9 -39
  68. package/package.json +2 -2
  69. package/palette-completion-types.d.ts +22 -22
  70. package/palette-search-types.d.ts +28 -28
  71. package/query-understanding-types.d.ts +43 -36
  72. package/render-assets-types.d.ts +8 -8
  73. package/resolve-client.d.ts +2 -2
  74. package/resolve-client.js +4 -6
  75. package/resolve-colour-types.d.ts +22 -6
  76. package/resolve-types.d.ts +10 -10
  77. package/run-types.d.ts +70 -70
  78. package/runs.d.ts +13 -26
  79. package/runs.js +77 -89
  80. package/samplize-catalogue-types.d.ts +18 -18
  81. package/samplize-colorvec.d.ts +20 -20
  82. package/samplize-colorvec.js +66 -42
  83. package/schema-resource-types.d.ts +38 -38
  84. package/schema-resource-types.js +5 -5
  85. package/search-card-types.d.ts +14 -5
  86. package/search-collapse-types.d.ts +4 -4
  87. package/search-mood-types.d.ts +2 -2
  88. package/search-refinement-types.d.ts +8 -8
  89. package/search-request-types.d.ts +6 -6
  90. package/search-response-receipt-types.d.ts +135 -34
  91. package/search-response-types.d.ts +2 -2
  92. package/search-result-validation.d.ts +3 -3
  93. package/search-result-validation.js +53 -36
  94. package/search-window-types.d.ts +2 -2
  95. package/slot-pool-types.d.ts +20 -20
  96. package/source-material-validation.d.ts +3 -3
  97. package/source-material-validation.js +35 -39
  98. package/spec-facet-types.d.ts +10 -10
  99. package/spec-types.d.ts +6 -6
  100. package/specifications.d.ts +9 -25
  101. package/specifications.js +15 -21
  102. package/sse.d.ts +2 -2
  103. package/sse.js +32 -16
  104. package/substitute-types.d.ts +22 -22
  105. package/suggest-types.d.ts +7 -7
  106. package/suggest-types.js +3 -3
  107. package/taxonomy-coverage-types.d.ts +8 -8
  108. package/types.d.ts +119 -119
  109. package/validation.d.ts +26 -26
  110. package/validation.js +97 -92
  111. package/webmcp.d.ts +2 -2
  112. package/webmcp.generated.js +94 -87
  113. package/project-types.d.ts +0 -79
  114. package/project-types.js +0 -9
  115. package/projects.d.ts +0 -13
  116. package/projects.js +0 -46
  117. package/run-events.d.ts +0 -106
  118. package/run-events.js +0 -32
  119. package/schedule-reference-types.d.ts +0 -46
  120. package/schedule-reference-types.js +0 -1
  121. package/schedule-references-client.d.ts +0 -14
  122. package/schedule-references-client.js +0 -26
  123. package/schedule-types.d.ts +0 -261
  124. package/schedule-types.js +0 -1
@@ -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 function selectSamplizeEligiblePaints(paints, input) {
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
- const low = input.lightnessMin ?? 0, high = input.lightnessMax ?? 1;
26
- const cool = input.temperatureMin ?? -0.4, warm = input.temperatureMax ?? 0.4;
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
- if (p.variantId === reference.variantId)
40
+ }
41
+ if (p.variantId === reference.variantId) {
35
42
  return false;
36
- if (input.direction === "lighter")
43
+ }
44
+ if (input.direction === "lighter") {
37
45
  return p.oklab.L > reference.oklab.L;
38
- if (input.direction === "darker")
46
+ }
47
+ if (input.direction === "darker") {
39
48
  return p.oklab.L < reference.oklab.L;
40
- if (input.direction === "muted")
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 { reference, eligible, counts };
62
- }
75
+ return { counts, eligible, reference };
76
+ };
63
77
  /** Official portable MG ranking over its complete versioned sampling-channel projection. */
64
- export function createSamplizeColorVecIndex(cache) {
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
- .sort((a, b) => b.proportion - a.proportion || identityOrder(a.hex, b.hex));
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
- paints: [],
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].sort((a, b) => b.remainder - a.remainder || a.position - b.position))
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], score = embeddingCosineSimilarity(paint.vector, best.vector);
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], next = embeddingCosineSimilarity(paint.vector, candidate.vector);
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
- .sort((a, b) => b.proportion - a.proportion || a.position - b.position)
162
+ .toSorted((a, b) => b.proportion - a.proportion || a.position - b.position)
139
163
  .map((p) => {
140
164
  const ids = p.paints
141
- .sort((a, b) => b.score - a.score || identityOrder(a.id, b.id))
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
- ids,
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
- countBasis: "complete-catalogue",
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 verticals: "list_schema_verticals";
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 sourceRequirements: "list_schema_source_requirements";
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 interface SchemaLifecycle {
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 interface SchemaExternalMapping {
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 interface SchemaBlockItem {
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 interface SchemaAttributeItem {
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 interface SchemaVerticalItem {
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 interface SchemaProductTypeBlock {
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 interface SchemaProductTypeItem {
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 interface SchemaUnitItem {
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 interface SchemaValueDictionaryTerm {
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 interface SchemaValueDictionaryItem {
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 interface SchemaSourceRequirementItem {
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" | "declared">;
133
+ sourceBasis?: OpenEnum<"declared" | "derived">;
134
134
  semanticId: string;
135
135
  lifecycle: SchemaLifecycle;
136
- }
137
- export interface SchemaProductTypeTemplateBlock {
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 interface SchemaProductTypeTemplateItem {
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 interface SchemaMappingItem {
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 interface SchemaResourceItemMap {
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 interface SchemaResourceResponse<K extends SchemaResource = SchemaResource> {
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
+ };
@@ -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
- verticals: "list_schema_verticals",
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
- sourceRequirements: "list_schema_source_requirements",
15
- productTypeTemplates: "list_schema_product_type_templates",
16
- mappings: "list_schema_mappings",
16
+ verticals: "list_schema_verticals",
17
17
  };
@@ -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 + score.
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 interface SearchCardItem {
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 interface SearchCardResponse extends Omit<SearchResponse, "data"> {
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 interface CollapsedVariant {
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 interface SearchAnatomyMember {
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
+ };
@@ -1,6 +1,6 @@
1
1
  /** What a standard search did, and did not, recognize as a governed mood. */
2
- export interface MoodInterpretation {
2
+ export type MoodInterpretation = {
3
3
  query: string | null;
4
4
  moodId: string | null;
5
5
  supersededMoodId: string | null;
6
- }
6
+ };
@@ -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 interface SearchFilterTrust {
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 interface SearchSuggestion {
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 interface SearchInterpretation {
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 interface SearchDisambiguation {
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 interface SearchInput {
18
+ export type SearchInput = {
19
19
  text?: string;
20
- textModes?: Array<OpenEnum<"visual" | "lexical">>;
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
- /** Page size — the size of ONE page, never a bound on the match set. */
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 interface SearchGetParams {
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
+ };