@instruments/materialgraph 3.1.0 → 3.2.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 (55) hide show
  1. package/association-types.d.ts +20 -20
  2. package/brand-types.d.ts +6 -6
  3. package/by-spec-types.d.ts +6 -6
  4. package/catalog-discovery-types.d.ts +4 -4
  5. package/categories-client.d.ts +3 -3
  6. package/category-types.d.ts +18 -18
  7. package/client-config.d.ts +2 -2
  8. package/client-response-schema.d.ts +2 -2
  9. package/client-response-schema.js +4 -4
  10. package/client-vocabulary.js +1 -1
  11. package/client.js +8 -10
  12. package/color-profiles-types.d.ts +8 -8
  13. package/color-wire-types.d.ts +6 -6
  14. package/colors-client.d.ts +3 -3
  15. package/discovery-context-types.d.ts +8 -8
  16. package/errors.d.ts +12 -13
  17. package/errors.js +84 -74
  18. package/find-sampled-together-types.d.ts +6 -6
  19. package/find-variants-by-color-types.d.ts +30 -30
  20. package/find-variants-by-vector-types.d.ts +13 -13
  21. package/get-variant-types.d.ts +6 -6
  22. package/http-transport.d.ts +14 -10
  23. package/http-transport.js +14 -12
  24. package/image-reference-types.d.ts +2 -2
  25. package/json.d.ts +18 -0
  26. package/json.js +36 -0
  27. package/list-enum-values-types.d.ts +8 -8
  28. package/list-sampled-together-pairs-types.d.ts +6 -6
  29. package/list-variant-facets-types.d.ts +8 -8
  30. package/list-variants-types.d.ts +40 -31
  31. package/material-asset-types.d.ts +26 -26
  32. package/material-block-types.d.ts +6 -6
  33. package/material-types.d.ts +6 -6
  34. package/nearest-paints-types.d.ts +8 -8
  35. package/operation-responses.d.ts +2 -2
  36. package/operations.d.ts +1 -1
  37. package/operations.js +1 -1
  38. package/package.json +1 -1
  39. package/parse-operation-response.d.ts +4 -3
  40. package/parse-operation-response.js +112 -135
  41. package/resolve-color-types.d.ts +6 -6
  42. package/resolve-variant-types.d.ts +10 -10
  43. package/response-schema-catalog.d.ts +8 -0
  44. package/response-schema-catalog.js +82 -0
  45. package/response-schemas.d.ts +32 -3
  46. package/response-schemas.generated.js +26 -26
  47. package/response-schemas.js +5 -77
  48. package/schema-resource-types.d.ts +12 -12
  49. package/search-catalog-subset-types.d.ts +2 -2
  50. package/search-variants-types.d.ts +12 -12
  51. package/source-material-types.d.ts +6 -6
  52. package/source-material.js +2 -32
  53. package/types.d.ts +38 -38
  54. package/webmcp.d.ts +10 -4
  55. package/webmcp.generated.js +5 -4
@@ -6,7 +6,7 @@
6
6
  * or an existing variant's own image. Exactly one field is set per call; the
7
7
  * server refuses more than one.
8
8
  */
9
- export type ImageReferenceInput = {
9
+ export interface ImageReferenceInput {
10
10
  /** Catalog asset id. */
11
11
  assetId?: string;
12
12
  /** Upload id (`smf_...`) from source-material. */
@@ -15,4 +15,4 @@ export type ImageReferenceInput = {
15
15
  url?: string;
16
16
  /** Variant whose image to use. */
17
17
  variantId?: string;
18
- };
18
+ }
package/json.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ import type { JsonValue } from "./json-value-types.js";
2
+ /** A JSON object: string keys, JSON values. */
3
+ export interface JsonObject {
4
+ [key: string]: JsonValue;
5
+ }
6
+ export type JsonKind = "array" | "boolean" | "null" | "number" | "object" | "string" | "undefined";
7
+ /** What a parsed JSON value is, or `undefined` for a key an object lacks. */
8
+ export declare const jsonKind: (value: JsonValue | undefined) => JsonKind;
9
+ export declare const isJsonObject: (value: JsonValue | undefined) => value is JsonObject;
10
+ export declare const isJsonString: (value: JsonValue | undefined) => value is string;
11
+ export declare const isJsonNumber: (value: JsonValue | undefined) => value is number;
12
+ /** Parses JSON text; throws on text that is not JSON. */
13
+ export declare const parseJson: (text: string) => JsonValue;
14
+ /**
15
+ * Reads a value of unknown origin as the JSON it would serialize to. A value
16
+ * JSON cannot represent, such as a `bigint`, reads as absent.
17
+ */
18
+ export declare const toJsonValue: (value: unknown) => JsonValue | undefined;
package/json.js ADDED
@@ -0,0 +1,36 @@
1
+ /** What a parsed JSON value is, or `undefined` for a key an object lacks. */
2
+ export const jsonKind = (value) => {
3
+ if (value === null) {
4
+ return "null";
5
+ }
6
+ if (Array.isArray(value)) {
7
+ return "array";
8
+ }
9
+ // oxlint-disable-next-line anti-slop/no-runtime-typeof -- This is the one place a parsed JSON value is classified; every other check calls it.
10
+ const kind = typeof value;
11
+ if (kind === "boolean" || kind === "number" || kind === "string") {
12
+ return kind;
13
+ }
14
+ return kind === "undefined" ? "undefined" : "object";
15
+ };
16
+ export const isJsonObject = (value) => jsonKind(value) === "object";
17
+ export const isJsonString = (value) => jsonKind(value) === "string";
18
+ export const isJsonNumber = (value) => jsonKind(value) === "number";
19
+ /** Parses JSON text; throws on text that is not JSON. */
20
+ export const parseJson = (text) =>
21
+ // oxlint-disable-next-line typescript/no-unsafe-return -- `JSON.parse` returns exactly the values `JsonValue` names.
22
+ JSON.parse(text);
23
+ /**
24
+ * Reads a value of unknown origin as the JSON it would serialize to. A value
25
+ * JSON cannot represent, such as a `bigint`, reads as absent.
26
+ */
27
+ // oxlint-disable-next-line anti-slop/no-unknown-parameters -- A published caller may pass any body; this is where it becomes JSON.
28
+ export const toJsonValue = (value) => {
29
+ try {
30
+ const text = JSON.stringify(value);
31
+ return text === undefined ? undefined : parseJson(text);
32
+ }
33
+ catch {
34
+ return undefined;
35
+ }
36
+ };
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import type { OpenEnum } from "./types.js";
10
10
  /** Options for `listEnumValues()` (GET `/api/v1/catalog/enum-values`). */
11
- export type ListEnumValuesOptions = {
11
+ export interface ListEnumValuesOptions {
12
12
  /**
13
13
  * A value dictionary id, from a `listAttributes()` item's `dictionaryId`.
14
14
  * Required without a `query`; with a `query`, omit it to search every
@@ -21,9 +21,9 @@ export type ListEnumValuesOptions = {
21
21
  limit?: number;
22
22
  /** `pageInfo.endCursor` from the previous page, with the same query and dictionary. */
23
23
  cursor?: string;
24
- };
24
+ }
25
25
  /** How an item was found. A distance or similarity compares only within one method. */
26
- export type EnumValueMatch = {
26
+ export interface EnumValueMatch {
27
27
  method: OpenEnum<"exact" | "alias" | "fuzzy" | "vector">;
28
28
  /** The id, label or alias that matched, or null for a match by meaning. */
29
29
  matchedText: string | null;
@@ -33,9 +33,9 @@ export type EnumValueMatch = {
33
33
  resolvedFrom?: string;
34
34
  /** Cosine similarity, 1 best. */
35
35
  similarity?: number;
36
- };
36
+ }
37
37
  /** One allowed value of a dictionary. */
38
- export type EnumValueItem = {
38
+ export interface EnumValueItem {
39
39
  /** The attributes this value can filter `listVariants()` on; empty when it cannot be filtered on. */
40
40
  attributeIds: string[];
41
41
  /** The taxonomy's definition when the value resolves to a canonical concept, otherwise null. */
@@ -46,8 +46,8 @@ export type EnumValueItem = {
46
46
  match?: EnumValueMatch;
47
47
  /** The bare term id `listVariants()` accepts for any of `attributeIds`. */
48
48
  valueId: string;
49
- };
50
- export type ListEnumValuesResult = {
49
+ }
50
+ export interface ListEnumValuesResult {
51
51
  /** The dictionary the page was read from; null when a query searched every dictionary. */
52
52
  dictionaryId: string | null;
53
53
  items: EnumValueItem[];
@@ -55,4 +55,4 @@ export type ListEnumValuesResult = {
55
55
  endCursor: string | null;
56
56
  hasNextPage: boolean;
57
57
  };
58
- };
58
+ }
@@ -5,15 +5,15 @@
5
5
  * `packages/sampling/src/sampled-together-pairs.ts`; this SDK has no runtime
6
6
  * dependency on `@materialgraph/sampling`, so the shapes are copied here.
7
7
  */
8
- export type ListSampledTogetherPairsInput = {
8
+ export interface ListSampledTogetherPairsInput {
9
9
  /** `nextCursor` from the previous page. */
10
10
  cursor?: string;
11
11
  /** Pairs per page, at most 5,000. Default 2,000. */
12
12
  limit?: number;
13
13
  /** Smallest project count a pair needs. Default 3. */
14
14
  minProjects?: number;
15
- };
16
- export type SampledTogetherPair = {
15
+ }
16
+ export interface SampledTogetherPair {
17
17
  a: string;
18
18
  b: string;
19
19
  /** Projects that sampled both. */
@@ -25,8 +25,8 @@ export type SampledTogetherPair = {
25
25
  /** Each side's own sampled project total; null when unknown. */
26
26
  aProjects: number | null;
27
27
  bProjects: number | null;
28
- };
29
- export type ListSampledTogetherPairsOutput = {
28
+ }
29
+ export interface ListSampledTogetherPairsOutput {
30
30
  window: "trailing_36mo";
31
31
  signal: "sampled";
32
32
  windowStart: string | null;
@@ -36,4 +36,4 @@ export type ListSampledTogetherPairsOutput = {
36
36
  projectTotalsWindowEnd: string | null;
37
37
  pairs: SampledTogetherPair[];
38
38
  nextCursor: string | null;
39
- };
39
+ }
@@ -9,7 +9,7 @@ import type { FilterGroups } from "./list-variants-types.js";
9
9
  * `contract-parity.test.ts` keeps them honest.
10
10
  */
11
11
  import type { SearchCatalogSubset } from "./search-catalog-subset-types.js";
12
- export type ListVariantFacetsInput = {
12
+ export interface ListVariantFacetsInput {
13
13
  /** 1–10 facetable attribute ids, or `brand`. Find attribute ids with `listAttributes()`. */
14
14
  attributeIds: string[];
15
15
  /** The same kind-grouped filter tree `listVariants()` takes. */
@@ -18,20 +18,20 @@ export type ListVariantFacetsInput = {
18
18
  filters?: FilterGroups;
19
19
  /** Top values per categorical or boolean facet, 1–50. Defaults to 10. */
20
20
  valuesPerFacet?: number;
21
- };
22
- export type VariantFacetValue = {
21
+ }
22
+ export interface VariantFacetValue {
23
23
  /** The canonical value `listVariants()`' `filters` accepts for this attribute. */
24
24
  value: string;
25
25
  label: string;
26
26
  /** Distinct eligible variants under the supplied filters carrying this value. */
27
27
  variantCount: number;
28
- };
29
- type VariantFacetBase = {
28
+ }
29
+ interface VariantFacetBase {
30
30
  attributeId: string;
31
31
  name: string;
32
32
  /** Eligible variants recording no accepted value: unknown, never false or zero. */
33
33
  missingVariantCount: number;
34
- };
34
+ }
35
35
  export type CategoricalVariantFacet = VariantFacetBase & {
36
36
  kind: "categorical";
37
37
  values: VariantFacetValue[];
@@ -51,10 +51,10 @@ export type NumericVariantFacet = VariantFacetBase & {
51
51
  unitId: string | null;
52
52
  };
53
53
  export type VariantFacet = CategoricalVariantFacet | BooleanVariantFacet | NumericVariantFacet;
54
- export type ListVariantFacetsOutput = {
54
+ export interface ListVariantFacetsOutput {
55
55
  /** Eligible variants matching every hard condition: the denominator of every count. */
56
56
  matchedVariantCount: number;
57
57
  /** One per requested attribute, in request order. */
58
58
  facets: VariantFacet[];
59
- };
59
+ }
60
60
  export {};
@@ -11,7 +11,7 @@
11
11
  */
12
12
  import type { SearchCatalogSubset } from "./search-catalog-subset-types.js";
13
13
  export type FilterOp = "in" | "not_in" | "all" | "exists" | "missing" | "eq" | "gt" | "gte" | "lt" | "lte";
14
- export type FilterTermCondition = {
14
+ export interface FilterTermCondition {
15
15
  field: string;
16
16
  op: "in" | "all" | "not_in";
17
17
  /**
@@ -26,23 +26,23 @@ export type FilterTermCondition = {
26
26
  */
27
27
  unstated?: "pass";
28
28
  values: string[];
29
- };
30
- export type FilterNumericCondition = {
29
+ }
30
+ export interface FilterNumericCondition {
31
31
  field: string;
32
32
  op: "eq" | "gt" | "gte" | "lt" | "lte";
33
33
  value: number;
34
- };
35
- export type FilterPresenceCondition = {
34
+ }
35
+ export interface FilterPresenceCondition {
36
36
  field: string;
37
37
  op: "exists" | "missing";
38
- };
38
+ }
39
39
  /**
40
40
  * A term stated under ANY of `fields` (2–8 distinct term attributes), for a
41
41
  * concept stored under several of them. `in`: at least one of `values` under
42
42
  * at least one field. `not_in`: at least one field stated at all, and none of
43
43
  * `values` under any field.
44
44
  */
45
- export type FilterAnyFieldCondition = {
45
+ export interface FilterAnyFieldCondition {
46
46
  fields: string[];
47
47
  op: "in" | "not_in";
48
48
  /**
@@ -57,7 +57,7 @@ export type FilterAnyFieldCondition = {
57
57
  */
58
58
  unstated?: "pass";
59
59
  values: string[];
60
- };
60
+ }
61
61
  /**
62
62
  * One filter condition, whichever of the four fully-required shapes. No
63
63
  * `unit` key (a numeric value is in the attribute's own canonical unit).
@@ -70,14 +70,14 @@ export type FilterCondition = FilterTermCondition | FilterNumericCondition | Fil
70
70
  * fields. Send only the arrays you need; an omitted or empty array carries no
71
71
  * conditions.
72
72
  */
73
- export type FilterGroups = {
73
+ export interface FilterGroups {
74
74
  terms?: FilterTermCondition[];
75
75
  numbers?: FilterNumericCondition[];
76
76
  presence?: FilterPresenceCondition[];
77
77
  anyField?: FilterAnyFieldCondition[];
78
- };
78
+ }
79
79
  /** `optionalFilters`: the same kind-grouped shape as `filters` but for `unstated`, with every entry also carrying a required `weight` (1–10). Ranks matched items; never excludes. */
80
- export type OptionalFilterGroups = {
80
+ export interface OptionalFilterGroups {
81
81
  terms?: (Omit<FilterTermCondition, "unstated"> & {
82
82
  weight: number;
83
83
  })[];
@@ -90,33 +90,33 @@ export type OptionalFilterGroups = {
90
90
  anyField?: (Omit<FilterAnyFieldCondition, "unstated"> & {
91
91
  weight: number;
92
92
  })[];
93
- };
94
- export type OrderByEntry = {
93
+ }
94
+ export interface OrderByEntry {
95
95
  direction: "asc" | "desc";
96
96
  /** A numeric attribute id. */
97
97
  field: string;
98
- };
98
+ }
99
99
  export type ListVariantsInclude = "image" | "url";
100
100
  export type ListVariantsCollapse = "product" | "colorway";
101
101
  /** A region in OKLCh: lightness and chroma as bounds, hue an arc in degrees that wraps when its start is past its end, null for any hue. */
102
- export type ColorRegion = {
102
+ export interface ColorRegion {
103
103
  chroma: [number, number];
104
104
  hue: [number, number] | null;
105
105
  lightness: [number, number];
106
- };
106
+ }
107
107
  /**
108
108
  * A measured-color condition. `in` keeps a variant with a large swatch inside
109
109
  * `range`; `not_in` leaves those out and lets a variant with no measured
110
110
  * color pass. `preferred` only orders and never narrows.
111
111
  */
112
- export type ColorRangeCondition = {
112
+ export interface ColorRangeCondition {
113
113
  /** The color's own point in the region, `#rrggbb`; it orders matches, nearest first. */
114
114
  hex: string;
115
115
  intent?: "required" | "preferred";
116
116
  op: "in" | "not_in";
117
117
  range: ColorRegion;
118
- };
119
- export type ListVariantsInput = {
118
+ }
119
+ export interface ListVariantsInput {
120
120
  /** Attribute ids to project under each item's `specifications`. */
121
121
  attributes?: string[];
122
122
  /**
@@ -152,27 +152,36 @@ export type ListVariantsInput = {
152
152
  orderBy?: OrderByEntry[];
153
153
  /** Words each variant must name in its text, inside the filters. */
154
154
  words?: string[];
155
- };
155
+ }
156
156
  /**
157
157
  * `score` sums the weights of the matched `optionalFilters`; `matched` lists
158
158
  * their positions in the flattened terms-then-numbers-then-presence-then-anyField order
159
159
  * the server reads `optionalFilters` in, not the caller's own array shape.
160
+ * `looks` says how the row met each look it matched (named for it, its value
161
+ * stated, its words in the description) and by which words; `photo`, that its
162
+ * photograph looks like the look.
160
163
  */
161
- export type ListVariantsPreference = {
164
+ export interface ListVariantsPreference {
165
+ looks?: {
166
+ by: ("named" | "stated" | "described")[];
167
+ index: number;
168
+ words?: string;
169
+ }[];
162
170
  matched: number[];
171
+ photo?: true;
163
172
  score: number;
164
- };
173
+ }
165
174
  /** `{ [blockId]: { [attributeId]: value } }`. Null means the value is unknown. */
166
175
  export type ListVariantsSpecifications = Record<string, Record<string, unknown>>;
167
176
  /** Material Bank's printed sample size. Any field may be absent; absent is unknown, never 0. */
168
- export type SampleSizeObservation = {
177
+ export interface SampleSizeObservation {
169
178
  /** The sample size as the channel printed it, verbatim. */
170
179
  wording?: string;
171
180
  /** The shorter side in millimeters. */
172
181
  width_mm?: number;
173
182
  /** The longer side in millimeters. */
174
183
  length_mm?: number;
175
- };
184
+ }
176
185
  /**
177
186
  * `{ [channel]: { [attributeId]: value } }`: the latest observation of each
178
187
  * selected attribute for each channel (`no_channel` when none is named). An
@@ -181,10 +190,10 @@ export type SampleSizeObservation = {
181
190
  export type VariantObservations = Record<string, {
182
191
  sample_size?: SampleSizeObservation;
183
192
  } & Record<string, unknown>>;
184
- export type ListVariantsNotApplicable = {
193
+ export interface ListVariantsNotApplicable {
185
194
  attributes?: string[];
186
195
  blocks?: string[];
187
- };
196
+ }
188
197
  /** What a sample represents, independently of its specification type. */
189
198
  export type SampleSubject = "material" | "paint_color_sample" | "unknown" | "conflict";
190
199
  /**
@@ -192,7 +201,7 @@ export type SampleSubject = "material" | "paint_color_sample" | "unknown" | "con
192
201
  * and brand page only when requested (`include`) and selected attributes
193
202
  * under `specifications`. Leaner than `get_variant`'s item on purpose.
194
203
  */
195
- export type ListVariantsItem = {
204
+ export interface ListVariantsItem {
196
205
  category: {
197
206
  id: string;
198
207
  name: string;
@@ -244,7 +253,7 @@ export type ListVariantsItem = {
244
253
  */
245
254
  variantCount?: number;
246
255
  variantId: string;
247
- };
256
+ }
248
257
  /**
249
258
  * The variant card both `listVariants` rows and `findVariantsByVector` rows
250
259
  * satisfy. The only difference between the two is the Material Bank SKU:
@@ -254,7 +263,7 @@ export type VariantCard = Omit<ListVariantsItem, "materialBankId"> & {
254
263
  /** The variant's Material Bank SKU. Absent or null means none is recorded. */
255
264
  materialBankId?: string | null;
256
265
  };
257
- export type ListVariantsOutput = {
266
+ export interface ListVariantsOutput {
258
267
  /** Explicit `{field: "variant", op: "in"}` ids that name a real variant outside the materials catalog. Present only when at least one did. */
259
268
  excludedBySearchCatalogSubset?: string[];
260
269
  items: ListVariantsItem[];
@@ -273,11 +282,11 @@ export type ListVariantsOutput = {
273
282
  unavailableVariantIds?: string[];
274
283
  /** Explicit `{field: "variant", op: "in"}` ids anywhere in `filters.terms` that name no variant at all. */
275
284
  unresolvedVariantIds?: string[];
276
- /** Filtered attributes no variant in scope states at all. Present only on an empty first page, so its absence means the empty page is a genuine no-match. */
285
+ /** Filter fields no variant in scope states at all. Present only on an empty first page, so its absence means the empty page is a genuine no-match. */
277
286
  unstated?: string[];
278
287
  /** Each requested word and whether any variant in scope names it. */
279
288
  words?: {
280
289
  matched: boolean;
281
290
  word: string;
282
291
  }[];
283
- };
292
+ }
@@ -23,10 +23,10 @@ export type VariantImagePresentation = OpenEnum<"edge_to_edge" | "packshot" | "c
23
23
  /** What a photo shows of its material, so an app can place it at real size. */
24
24
  export type VariantImageShows = OpenEnum<"sample" | "crop" | "laid_field" | "room" | "detail">;
25
25
  /** The size of the surface in an image's frame, in millimeters. */
26
- export type VariantImageSurfaceMm = {
26
+ export interface VariantImageSurfaceMm {
27
27
  width_mm: number;
28
28
  height_mm: number;
29
- };
29
+ }
30
30
  /** What a document is for; a document can carry more than one purpose. */
31
31
  export type VariantDocumentType = OpenEnum<"technical_data_sheet" | "product_sheet" | "technical_bulletin" | "sustainability_report" | "specification" | "installation_guide" | "care_maintenance_guide" | "operation_manual" | "warranty" | "parts_list" | "technical_drawing" | "test_report" | "certificate" | "declaration_of_performance" | "environmental_product_declaration" | "health_product_declaration" | "ingredient_disclosure" | "safety_data_sheet" | "brochure" | "catalog" | "color_finish_chart" | "other" | "unknown">;
32
32
  /** Every asset kind the registry knows. */
@@ -36,7 +36,7 @@ export type VariantAssetKind = OpenEnum<"image" | "document" | "cad" | "bim" | "
36
36
  * appear on their kind, and an absent value is unknown. `url` is absent when
37
37
  * `availability` is `unavailable`; `appliesTo` appears only as `product`.
38
38
  */
39
- export type VariantAssetItem = {
39
+ export interface VariantAssetItem {
40
40
  /** Only `product`: filed against the whole product. Absent: this variant's own. */
41
41
  appliesTo?: "product";
42
42
  assetId: string;
@@ -63,16 +63,16 @@ export type VariantAssetItem = {
63
63
  url?: string;
64
64
  /** Images only; absent when unknown. */
65
65
  width?: number;
66
- };
66
+ }
67
67
  /** Whether the brand's document source was read for this variant. Absent when documents are filtered out. */
68
68
  export type VariantDocumentCoverageState = OpenEnum<"available" | "none_declared" | "not_ingested" | "unavailable_source" | "dead_link" | "failed_ingest">;
69
- export type VariantAssetPageInfo = {
69
+ export interface VariantAssetPageInfo {
70
70
  nextCursor: string | null;
71
71
  returnedCount: number;
72
72
  totalMatches: number;
73
- };
73
+ }
74
74
  /** Request filters and paging for `listVariantAssets`. Each list is OR within itself, AND across lists. */
75
- export type ListVariantAssetsOptions = {
75
+ export interface ListVariantAssetsOptions {
76
76
  kinds?: VariantAssetKind[];
77
77
  imageRoles?: VariantImageRole[];
78
78
  documentTypes?: VariantDocumentType[];
@@ -80,28 +80,28 @@ export type ListVariantAssetsOptions = {
80
80
  limit?: number;
81
81
  /** `pageInfo.nextCursor` from the previous page, with the same variantId and filters. */
82
82
  cursor?: string;
83
- };
83
+ }
84
84
  /** One page. An unknown variant is a 404, never a page. */
85
- export type VariantAssetPage = {
85
+ export interface VariantAssetPage {
86
86
  documentCoverage?: VariantDocumentCoverageState;
87
87
  items: VariantAssetItem[];
88
88
  pageInfo: VariantAssetPageInfo;
89
89
  /** The variant's primary image. Absent when it has none. */
90
90
  primaryAssetId?: string;
91
- };
91
+ }
92
92
  export type MaterialDocumentStatus = OpenEnum<"downloaded" | "linked_not_downloaded" | "unavailable_source" | "dead_link" | "failed_ingest">;
93
93
  export type MaterialDocumentCoverageState = OpenEnum<"available" | "none_declared" | "not_ingested" | "unavailable_source" | "dead_link" | "failed_ingest">;
94
- export type MaterialDocumentScope = {
94
+ export interface MaterialDocumentScope {
95
95
  kind: "product" | "variant";
96
96
  id: string;
97
- };
98
- export type MaterialDocumentSource = {
97
+ }
98
+ export interface MaterialDocumentSource {
99
99
  /** Opaque, public identifier for one source collection; never a PIM/DAM path. */
100
100
  id: string;
101
101
  authority: string;
102
102
  revision: string;
103
- };
104
- export type MaterialDocumentProjectionItem = {
103
+ }
104
+ export interface MaterialDocumentProjectionItem {
105
105
  id: string;
106
106
  scope: MaterialDocumentScope & {
107
107
  inherited: boolean;
@@ -126,34 +126,34 @@ export type MaterialDocumentProjectionItem = {
126
126
  contentType: string | null;
127
127
  fileExtension: string | null;
128
128
  source: MaterialDocumentSource;
129
- };
130
- export type MaterialDocumentCoverageSource = {
129
+ }
130
+ export interface MaterialDocumentCoverageSource {
131
131
  scope: MaterialDocumentScope;
132
132
  state: MaterialDocumentCoverageState;
133
133
  exact: boolean;
134
134
  declaredCount: number | null;
135
135
  readableCount: number;
136
136
  source: MaterialDocumentSource;
137
- };
138
- export type MaterialDocumentCoverage = {
137
+ }
138
+ export interface MaterialDocumentCoverage {
139
139
  productUnion: MaterialDocumentCoverageSummary;
140
140
  requestedVariant: MaterialDocumentCoverageSummary;
141
141
  sources: MaterialDocumentCoverageSource[];
142
- };
143
- export type MaterialDocumentCoverageSummary = {
142
+ }
143
+ export interface MaterialDocumentCoverageSummary {
144
144
  state: MaterialDocumentCoverageState;
145
145
  exact: boolean;
146
146
  declaredCount: number | null;
147
147
  readableCount: number;
148
- };
149
- export type MaterialDocumentPageOptions = {
148
+ }
149
+ export interface MaterialDocumentPageOptions {
150
150
  cursor?: string;
151
151
  limit?: number;
152
- };
153
- export type MaterialDocumentPage = {
152
+ }
153
+ export interface MaterialDocumentPage {
154
154
  variantId: VariantId;
155
155
  documents: MaterialDocumentProjectionItem[];
156
156
  coverage: MaterialDocumentCoverage;
157
157
  totalDocuments: number;
158
158
  nextCursor: string | null;
159
- };
159
+ }
@@ -51,7 +51,7 @@ export type MaterialBlockFieldValue = string | number | boolean | unknown[] | Re
51
51
  * `status: "complete"` is a real negative you may publish; the same `false`
52
52
  * under `missing` is a placeholder for an unanswered question.
53
53
  */
54
- export type MaterialBlockProjectionField = {
54
+ export interface MaterialBlockProjectionField {
55
55
  /** Canonical vocabulary, not an opaque id - the same token `listVariants` filters accept. */
56
56
  attributeId: string;
57
57
  label: string;
@@ -64,21 +64,21 @@ export type MaterialBlockProjectionField = {
64
64
  valueSource?: string;
65
65
  /** Claim confidence supplied by the graph; absence means no confidence was emitted. */
66
66
  confidence?: number;
67
- };
68
- export type MaterialBlockProjectionItem = {
67
+ }
68
+ export interface MaterialBlockProjectionItem {
69
69
  canonicalBlockId: string;
70
70
  canonicalBlockName: string;
71
71
  status: MaterialBlockStatus;
72
72
  fields: MaterialBlockProjectionField[];
73
73
  /** The work queue: attributes with `status: "missing"`. UNKNOWN, never "none". */
74
74
  missingAttributeIds: string[];
75
- };
75
+ }
76
76
  /**
77
77
  * Every canonical block for one material, each field carrying whether it is
78
78
  * determined. The whole surface, not a page — there is no cursor here.
79
79
  */
80
- export type MaterialBlockProjection = {
80
+ export interface MaterialBlockProjection {
81
81
  /** Opaque — echoed from the request. */
82
82
  variantId: VariantId;
83
83
  blocks: MaterialBlockProjectionItem[];
84
- };
84
+ }
@@ -34,7 +34,7 @@ export type MaterialAvailability = OpenEnum<"available" | "discontinued" | "supe
34
34
  * The grid-card projection of a material. Tiles carry `availability` but not a
35
35
  * successor record.
36
36
  */
37
- export type MaterialTile = {
37
+ export interface MaterialTile {
38
38
  /** Accepted sampleability fact. Absent means unknown, never false. */
39
39
  sampleable?: boolean;
40
40
  /** Opaque — round-trip verbatim into every other material read. */
@@ -57,9 +57,9 @@ export type MaterialTile = {
57
57
  * the attribute is absent — never render a missing key as "unnamed".
58
58
  */
59
59
  colorName?: string;
60
- };
60
+ }
61
61
  /** A retained product-type proposal. It is review evidence, never a category. */
62
- type ProposedProductType = {
62
+ interface ProposedProductType {
63
63
  id: string;
64
64
  displayName: string;
65
65
  confidence: number | null;
@@ -67,10 +67,10 @@ type ProposedProductType = {
67
67
  sourceUrl: string | null;
68
68
  isPrimary: boolean;
69
69
  scope: "variant" | "product";
70
- };
70
+ }
71
71
  /** Accepted display categories remain separate from this review-state receipt. */
72
- export type ProductTypeReceipt = {
72
+ export interface ProductTypeReceipt {
73
73
  state: "accepted" | "proposed" | "unknown";
74
74
  proposedProductTypes: ProposedProductType[];
75
- };
75
+ }
76
76
  export {};
@@ -1,10 +1,10 @@
1
1
  import type { SearchCatalogSubset } from "./search-catalog-subset-types.js";
2
- export type NearestPaintsParams = {
2
+ export interface NearestPaintsParams {
3
3
  hexes: string[];
4
4
  limit?: number;
5
5
  searchCatalogSubset?: SearchCatalogSubset;
6
- };
7
- export type NearestPaintCard = {
6
+ }
7
+ export interface NearestPaintCard {
8
8
  variantId: string;
9
9
  name: string;
10
10
  brand: {
@@ -25,11 +25,11 @@ export type NearestPaintCard = {
25
25
  lrv: number | null;
26
26
  deltaE: number;
27
27
  closeness: "very-near" | "very-close" | "close" | "related" | "unrelated";
28
- };
29
- export type NearestPaintsHexResult = {
28
+ }
29
+ export interface NearestPaintsHexResult {
30
30
  hex: string;
31
31
  paints: NearestPaintCard[];
32
- };
33
- export type NearestPaintsOutput = {
32
+ }
33
+ export interface NearestPaintsOutput {
34
34
  results: NearestPaintsHexResult[];
35
- };
35
+ }
@@ -20,7 +20,7 @@ import type { SchemaResourceResponse } from "./schema-resource-types.js";
20
20
  import type { SearchVariantsOutput } from "./search-variants-types.js";
21
21
  import type { SourceMaterialBatchReceipt } from "./source-material-types.js";
22
22
  import type { ExtractPaletteResponse, ListAttributesResult, PairingsResponse, ResolveColorResponse, WhoamiResponse } from "./types.js";
23
- export type OperationResponses = {
23
+ export interface OperationResponses {
24
24
  get_discovery_reference: DiscoveryReference;
25
25
  interpret_discovery_terms: DiscoveryTerms;
26
26
  find_colorless_variants: ColorlessVariantsResult;
@@ -56,5 +56,5 @@ export type OperationResponses = {
56
56
  search_variants: SearchVariantsOutput;
57
57
  upload_source_material: SourceMaterialBatchReceipt;
58
58
  whoami: WhoamiResponse;
59
- };
59
+ }
60
60
  export type JsonOperationId = keyof OperationResponses;
package/operations.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type SdkOperation, type SdkOperationId } from "./operations.generated.js";
1
+ import type { SdkOperation, SdkOperationId } from "./operations.generated.js";
2
2
  export { MATERIALGRAPH_API_VERSION, SDK_OPERATIONS, } from "./operations.generated.js";
3
3
  export type { SdkOperation, SdkOperationId } from "./operations.generated.js";
4
4
  /** Look up a registered operation by its OpenAPI `operationId`. */