@instruments/materialgraph 3.0.2 → 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.
- package/association-types.d.ts +20 -20
- package/brand-types.d.ts +6 -6
- package/by-spec-types.d.ts +6 -6
- package/catalog-discovery-types.d.ts +4 -4
- package/categories-client.d.ts +3 -3
- package/category-types.d.ts +18 -18
- package/client-config.d.ts +2 -2
- package/client-response-schema.d.ts +2 -2
- package/client-response-schema.js +4 -4
- package/client-vocabulary.js +1 -1
- package/client.d.ts +1 -1
- package/client.js +14 -10
- package/color-profiles-types.d.ts +8 -8
- package/color-wire-types.d.ts +6 -6
- package/colors-client.d.ts +3 -3
- package/discovery-context-types.d.ts +8 -8
- package/errors.d.ts +12 -13
- package/errors.js +84 -74
- package/find-sampled-together-types.d.ts +6 -6
- package/find-variants-by-color-types.d.ts +30 -30
- package/find-variants-by-vector-types.d.ts +13 -13
- package/get-variant-types.d.ts +11 -7
- package/http-transport.d.ts +14 -10
- package/http-transport.js +14 -12
- package/image-reference-types.d.ts +2 -2
- package/index.d.ts +2 -2
- package/json.d.ts +18 -0
- package/json.js +36 -0
- package/list-enum-values-types.d.ts +8 -8
- package/list-sampled-together-pairs-types.d.ts +6 -6
- package/list-variant-facets-types.d.ts +8 -8
- package/list-variants-types.d.ts +59 -29
- package/material-asset-types.d.ts +37 -24
- package/material-block-types.d.ts +6 -6
- package/material-types.d.ts +6 -6
- package/nearest-paints-types.d.ts +8 -8
- package/operation-responses.d.ts +2 -2
- package/operations.d.ts +1 -1
- package/operations.js +1 -1
- package/package.json +1 -1
- package/parse-operation-response.d.ts +4 -3
- package/parse-operation-response.js +112 -135
- package/resolve-color-types.d.ts +6 -6
- package/resolve-variant-types.d.ts +10 -10
- package/response-schema-catalog.d.ts +8 -0
- package/response-schema-catalog.js +82 -0
- package/response-schemas.d.ts +32 -3
- package/response-schemas.generated.js +26 -25
- package/response-schemas.js +5 -77
- package/schema-resource-types.d.ts +12 -12
- package/search-catalog-subset-types.d.ts +2 -2
- package/search-variants-types.d.ts +12 -12
- package/source-material-types.d.ts +6 -6
- package/source-material.js +2 -32
- package/types.d.ts +38 -38
- package/webmcp.d.ts +10 -4
- package/webmcp.generated.js +5 -4
package/association-types.d.ts
CHANGED
|
@@ -22,24 +22,24 @@ import type { SearchCatalogSubset } from "./search-catalog-subset-types.js";
|
|
|
22
22
|
* score or used to rank. Declared associations carry no ranking at all: that is
|
|
23
23
|
* the point of them.
|
|
24
24
|
*/
|
|
25
|
-
export
|
|
25
|
+
export interface DeclaredProvenance {
|
|
26
26
|
/** The stored convention value (0.9 today). Never a per-edge measurement. */
|
|
27
27
|
confidence: number;
|
|
28
28
|
/** The brand enumerated this association in its own catalog data. */
|
|
29
29
|
basis: "manufacturer_declared";
|
|
30
30
|
/** The provenance recorded on the edge - the brand catalog feed. */
|
|
31
31
|
source: "warehouse";
|
|
32
|
-
}
|
|
32
|
+
}
|
|
33
33
|
/** The material the question was asked about, resolved to its identity. */
|
|
34
|
-
export
|
|
34
|
+
export interface DeclaredAssociationSubject {
|
|
35
35
|
variantId: VariantId;
|
|
36
36
|
brand: string;
|
|
37
37
|
product: string;
|
|
38
38
|
/** The variant's own name; null when it is unnamed. */
|
|
39
39
|
variantName: string | null;
|
|
40
|
-
}
|
|
40
|
+
}
|
|
41
41
|
/** One declared association, plus why it is believed. */
|
|
42
|
-
export
|
|
42
|
+
export interface DeclaredAssociation {
|
|
43
43
|
variantId: VariantId;
|
|
44
44
|
brand: string;
|
|
45
45
|
product: string;
|
|
@@ -65,7 +65,7 @@ export type DeclaredAssociation = {
|
|
|
65
65
|
* pages. Absent when the product has no eligible variant.
|
|
66
66
|
*/
|
|
67
67
|
colorwayCount?: number;
|
|
68
|
-
}
|
|
68
|
+
}
|
|
69
69
|
/**
|
|
70
70
|
* One page of declared associations.
|
|
71
71
|
*
|
|
@@ -74,7 +74,7 @@ export type DeclaredAssociation = {
|
|
|
74
74
|
* is the whole set for this subject, direction and corpus scope. A page is not a
|
|
75
75
|
* corpus — walk `nextCursor` before making any claim about the full set.
|
|
76
76
|
*/
|
|
77
|
-
export
|
|
77
|
+
export interface DeclaredAssociationsResponse {
|
|
78
78
|
subject: DeclaredAssociationSubject;
|
|
79
79
|
/**
|
|
80
80
|
* Constant discriminator. Its presence is how a caller tells a declared fact
|
|
@@ -88,9 +88,9 @@ export type DeclaredAssociationsResponse = {
|
|
|
88
88
|
returnedCount: number;
|
|
89
89
|
/** Present only when another page exists; pass back verbatim as `cursor`. */
|
|
90
90
|
nextCursor?: Cursor;
|
|
91
|
-
}
|
|
91
|
+
}
|
|
92
92
|
/** Options for a declared-association read. */
|
|
93
|
-
export
|
|
93
|
+
export interface AssociatedOptions {
|
|
94
94
|
/**
|
|
95
95
|
* Page size, 1–48 inclusive (default 24). The server rejects (400), not
|
|
96
96
|
* clamps, values outside this range.
|
|
@@ -111,7 +111,7 @@ export type AssociatedOptions = {
|
|
|
111
111
|
* different one is a 400, never a silently different page.
|
|
112
112
|
*/
|
|
113
113
|
cursor?: Cursor;
|
|
114
|
-
}
|
|
114
|
+
}
|
|
115
115
|
export type ApplicabilitySubject = {
|
|
116
116
|
kind: "product";
|
|
117
117
|
id: string;
|
|
@@ -120,15 +120,15 @@ export type ApplicabilitySubject = {
|
|
|
120
120
|
id: VariantId;
|
|
121
121
|
};
|
|
122
122
|
export type ApplicabilityCoverageState = "available" | "partial" | "none_declared" | "not_ingested" | "source_not_applicable" | "unavailable";
|
|
123
|
-
export
|
|
123
|
+
export interface ApplicabilityCoverage {
|
|
124
124
|
state: ApplicabilityCoverageState;
|
|
125
125
|
countKind: "exact" | "partial";
|
|
126
126
|
declaredCount: number | null;
|
|
127
127
|
sourceAuthority: string;
|
|
128
128
|
sourceLocator: string;
|
|
129
129
|
sourceRevision: string;
|
|
130
|
-
}
|
|
131
|
-
export
|
|
130
|
+
}
|
|
131
|
+
export interface ApplicabilityFact {
|
|
132
132
|
id: string;
|
|
133
133
|
subject: ApplicabilitySubject;
|
|
134
134
|
finish: {
|
|
@@ -144,8 +144,8 @@ export type ApplicabilityFact = {
|
|
|
144
144
|
revision: string;
|
|
145
145
|
};
|
|
146
146
|
lifecycle: "active";
|
|
147
|
-
}
|
|
148
|
-
export
|
|
147
|
+
}
|
|
148
|
+
export interface ApplicabilitySourceEntry {
|
|
149
149
|
scope: {
|
|
150
150
|
sourceAuthority: string;
|
|
151
151
|
sourceLocator: string;
|
|
@@ -158,8 +158,8 @@ export type ApplicabilitySourceEntry = {
|
|
|
158
158
|
facts: ApplicabilityFact[];
|
|
159
159
|
/** Source endpoints that could not be resolved during reconciliation. */
|
|
160
160
|
unresolved: UnresolvedApplicabilityEndpoint[];
|
|
161
|
-
}
|
|
162
|
-
export
|
|
161
|
+
}
|
|
162
|
+
export interface UnresolvedApplicabilityEndpoint {
|
|
163
163
|
subjectLocator: string;
|
|
164
164
|
subjectKind: "product" | "variant" | "unknown";
|
|
165
165
|
finishLocator: string;
|
|
@@ -171,14 +171,14 @@ export type UnresolvedApplicabilityEndpoint = {
|
|
|
171
171
|
locator: string;
|
|
172
172
|
revision: string;
|
|
173
173
|
};
|
|
174
|
-
}
|
|
174
|
+
}
|
|
175
175
|
/** Source-grained response; sources are never merged or given hidden precedence. */
|
|
176
|
-
export
|
|
176
|
+
export interface ApplicabilityResponse {
|
|
177
177
|
kind: "manufacturer_declared_applicability";
|
|
178
178
|
requestedSubject: ApplicabilitySubject;
|
|
179
179
|
direction: "forward" | "reverse";
|
|
180
180
|
sources: ApplicabilitySourceEntry[];
|
|
181
|
-
}
|
|
181
|
+
}
|
|
182
182
|
export type ApplicabilityOptions = {
|
|
183
183
|
subjectKind: "product";
|
|
184
184
|
subjectId: string;
|
package/brand-types.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* `list_brands` tool and the `mg brand list` command take.
|
|
5
5
|
*/
|
|
6
6
|
import type { SearchCatalogSubset } from "./search-catalog-subset-types.js";
|
|
7
|
-
export
|
|
7
|
+
export interface BrandsOptions {
|
|
8
8
|
/**
|
|
9
9
|
* A brand name, alias or misspelling, e.g. `"Kvadrat"`. Omit to browse the
|
|
10
10
|
* list by name. Every brand the text matches comes back, so an ambiguous name
|
|
@@ -26,8 +26,8 @@ export type BrandsOptions = {
|
|
|
26
26
|
limit?: number;
|
|
27
27
|
/** The previous page's `pageInfo.endCursor`, with the same `query`, `categoryId` and `searchCatalogSubset`. */
|
|
28
28
|
cursor?: string;
|
|
29
|
-
}
|
|
30
|
-
export
|
|
29
|
+
}
|
|
30
|
+
export interface BrandItem {
|
|
31
31
|
/**
|
|
32
32
|
* The brand's slug: the value `listVariants()`' `brand` filter and
|
|
33
33
|
* `resolveVariant()`' `brandId` take. Never a display name.
|
|
@@ -36,8 +36,8 @@ export type BrandItem = {
|
|
|
36
36
|
name: string;
|
|
37
37
|
/** The brand's homepage, or null when none is on record. */
|
|
38
38
|
website: string | null;
|
|
39
|
-
}
|
|
40
|
-
export
|
|
39
|
+
}
|
|
40
|
+
export interface ListBrandsPage {
|
|
41
41
|
/** THIS PAGE. Follow `pageInfo.endCursor` for the rest; a page is not a total. */
|
|
42
42
|
items: BrandItem[];
|
|
43
43
|
pageInfo: {
|
|
@@ -45,4 +45,4 @@ export type ListBrandsPage = {
|
|
|
45
45
|
endCursor: string | null;
|
|
46
46
|
hasNextPage: boolean;
|
|
47
47
|
};
|
|
48
|
-
}
|
|
48
|
+
}
|
package/by-spec-types.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export type BySpecVerdictState = "matched" | "deviated" | "failed" | "unverified
|
|
|
22
22
|
* Hand-mirrors the `AttributeVerdict` contract from `@materialgraph/contracts`;
|
|
23
23
|
* the OpenAPI `CatalogBySpecResponse` schema is the source of truth on the wire.
|
|
24
24
|
*/
|
|
25
|
-
export
|
|
25
|
+
export interface BySpecVerdictCell {
|
|
26
26
|
attributeId: string;
|
|
27
27
|
state: BySpecVerdictState;
|
|
28
28
|
strength: "required" | "preferred";
|
|
@@ -57,7 +57,7 @@ export type BySpecVerdictCell = {
|
|
|
57
57
|
* - `basis_unmet` — the value's source is weaker than the criterion demanded.
|
|
58
58
|
*/
|
|
59
59
|
trustGap: "below_confidence" | "basis_unmet" | null;
|
|
60
|
-
}
|
|
60
|
+
}
|
|
61
61
|
/**
|
|
62
62
|
* A match's full report card: every cell, the rolled-up grade, weakest confidence.
|
|
63
63
|
*
|
|
@@ -70,11 +70,11 @@ export type BySpecVerdictCell = {
|
|
|
70
70
|
* `minConfidence` is the WEAKEST cell's confidence — the honest ceiling on the
|
|
71
71
|
* whole card, not an average. Quote it alongside the grade.
|
|
72
72
|
*/
|
|
73
|
-
export
|
|
73
|
+
export interface BySpecVerdict {
|
|
74
74
|
cells: BySpecVerdictCell[];
|
|
75
75
|
grade: "meets_all" | "close" | "hard_no";
|
|
76
76
|
minConfidence: number | null;
|
|
77
|
-
}
|
|
77
|
+
}
|
|
78
78
|
/**
|
|
79
79
|
* The verdict a materials-search hit carries (MG-625). It IS the shared
|
|
80
80
|
* {@link BySpecVerdict} shape — the single CandidateVerdict mirror — aliased here
|
|
@@ -99,7 +99,7 @@ export type MaterialVerdict = BySpecVerdict;
|
|
|
99
99
|
* EVERY miss is reported, not just the first, so one round trip is enough to fix
|
|
100
100
|
* a whole spec.
|
|
101
101
|
*/
|
|
102
|
-
export
|
|
102
|
+
export interface BySpecUnresolvedCriterion {
|
|
103
103
|
/** The parsed attribute id, after the route's surrounding-whitespace trim. */
|
|
104
104
|
attributeId: string;
|
|
105
105
|
/** The parsed value — never overwritten by the attribute id when that id is unknown. */
|
|
@@ -108,4 +108,4 @@ export type BySpecUnresolvedCriterion = {
|
|
|
108
108
|
reason?: "unknown_attribute_or_term" | "not_a_specification";
|
|
109
109
|
/** Ranked candidates for whichever half failed. See {@link ValueResolution}. */
|
|
110
110
|
resolution: ValueResolution;
|
|
111
|
-
}
|
|
111
|
+
}
|
|
@@ -11,7 +11,7 @@ import type { OpenEnum } from "./types.js";
|
|
|
11
11
|
* first: `exact_id` > `exact_alias` > `lexical` > `semantic`. A `semantic` hit
|
|
12
12
|
* is a guess worth confirming, not an equivalence.
|
|
13
13
|
*/
|
|
14
|
-
export
|
|
14
|
+
export interface ResolveValueCandidate {
|
|
15
15
|
id: string;
|
|
16
16
|
label: string;
|
|
17
17
|
dictionaryId?: string;
|
|
@@ -19,7 +19,7 @@ export type ResolveValueCandidate = {
|
|
|
19
19
|
tier: OpenEnum<"exact_id" | "exact_alias" | "lexical" | "semantic">;
|
|
20
20
|
/** Present only for a color_family candidate resolved via the colorscope fallback. */
|
|
21
21
|
via?: OpenEnum<"colorscope">;
|
|
22
|
-
}
|
|
22
|
+
}
|
|
23
23
|
/**
|
|
24
24
|
* The resolver's verdict on ONE free-text token — the single shape every
|
|
25
25
|
* resolving surface speaks, so a caller learns to read it once. Carried per bad
|
|
@@ -40,10 +40,10 @@ export type ResolveValueCandidate = {
|
|
|
40
40
|
* `query` is the trimmed token that was actually resolved, which is how you tell
|
|
41
41
|
* WHICH half of a failed `attribute:value` pair was the problem.
|
|
42
42
|
*/
|
|
43
|
-
export
|
|
43
|
+
export interface ValueResolution {
|
|
44
44
|
status: OpenEnum<"resolved" | "ambiguous" | "unresolved">;
|
|
45
45
|
query: string;
|
|
46
46
|
best: ResolveValueCandidate | null;
|
|
47
47
|
candidates: ResolveValueCandidate[];
|
|
48
48
|
recommendedAction: OpenEnum<"use_best" | "choose_from_candidates" | "ask_user" | "none_found">;
|
|
49
|
-
}
|
|
49
|
+
}
|
package/categories-client.d.ts
CHANGED
|
@@ -19,9 +19,9 @@ import type { CategoriesGetResult, CategoriesListInput, CategoriesListResult } f
|
|
|
19
19
|
import type { QueryParams } from "./http-transport.js";
|
|
20
20
|
import type { JsonOperationId, OperationResponses } from "./operation-responses.js";
|
|
21
21
|
/** The client's own request primitive, handed down so this file owns no transport. */
|
|
22
|
-
export
|
|
23
|
-
get<K extends JsonOperationId>(operationId: K, query?: QueryParams, signal?: AbortSignal, pathParams?: Readonly<Record<string, string>>)
|
|
24
|
-
}
|
|
22
|
+
export interface CategoriesTransport {
|
|
23
|
+
get: <K extends JsonOperationId>(operationId: K, query?: QueryParams, signal?: AbortSignal, pathParams?: Readonly<Record<string, string>>) => Promise<OperationResponses[K]>;
|
|
24
|
+
}
|
|
25
25
|
export declare class CategoriesClient {
|
|
26
26
|
#private;
|
|
27
27
|
constructor(transport: CategoriesTransport);
|
package/category-types.d.ts
CHANGED
|
@@ -12,22 +12,22 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import type { OpenEnum } from "./types.js";
|
|
14
14
|
/** A category named by id, as in `ancestors` and `children`. */
|
|
15
|
-
export
|
|
15
|
+
export interface CategoryRef {
|
|
16
16
|
id: string;
|
|
17
17
|
name: string;
|
|
18
|
-
}
|
|
18
|
+
}
|
|
19
19
|
export type CategoryKind = OpenEnum<"category">;
|
|
20
20
|
/** How a query matched source category names or exact paths through the lexical matcher. */
|
|
21
|
-
export
|
|
21
|
+
export interface CategoryMatch {
|
|
22
22
|
/** The name or source path that matched. */
|
|
23
23
|
matchedText: string | null;
|
|
24
24
|
method: OpenEnum<"exact" | "alias" | "fuzzy">;
|
|
25
|
-
}
|
|
25
|
+
}
|
|
26
26
|
/**
|
|
27
27
|
* One item on a `categories.list` page: what picks the next call. `get(id)`
|
|
28
28
|
* has the source path, depth, ancestors and children.
|
|
29
29
|
*/
|
|
30
|
-
export
|
|
30
|
+
export interface CategoryItem {
|
|
31
31
|
/** Whether `categories.list({ parentId: this.id })` lists anything. */
|
|
32
32
|
hasChildren: boolean;
|
|
33
33
|
/** A source category identity, also used in product_category memberships. */
|
|
@@ -39,14 +39,14 @@ export type CategoryItem = {
|
|
|
39
39
|
parentId: string | null;
|
|
40
40
|
path: string;
|
|
41
41
|
depth: number;
|
|
42
|
-
}
|
|
43
|
-
export
|
|
42
|
+
}
|
|
43
|
+
export interface CategoriesPageInfo {
|
|
44
44
|
/** Pass back as `cursor` with the same `query` and `parentId` for the next page. */
|
|
45
45
|
nextCursor: string | null;
|
|
46
46
|
returnedCount: number;
|
|
47
47
|
totalMatches: number;
|
|
48
|
-
}
|
|
49
|
-
export
|
|
48
|
+
}
|
|
49
|
+
export interface CategoriesListInput {
|
|
50
50
|
/** `pageInfo.nextCursor` from the previous page, with the same `query` and `parentId`. */
|
|
51
51
|
cursor?: string;
|
|
52
52
|
/** Items per page, 1 to 50. Default 20. */
|
|
@@ -55,21 +55,21 @@ export type CategoriesListInput = {
|
|
|
55
55
|
parentId?: string;
|
|
56
56
|
/** A category name or description, e.g. `"wallpaper"` or `"beds"`. */
|
|
57
57
|
query?: string;
|
|
58
|
-
}
|
|
59
|
-
export
|
|
58
|
+
}
|
|
59
|
+
export interface CategoriesListResult {
|
|
60
60
|
items: CategoryItem[];
|
|
61
61
|
/** Present only when the query is refused as a category, and says why. */
|
|
62
62
|
notice?: string;
|
|
63
63
|
pageInfo: CategoriesPageInfo;
|
|
64
|
-
}
|
|
64
|
+
}
|
|
65
65
|
/** Independent semantic mapping metadata; it does not assert source category membership. */
|
|
66
|
-
export
|
|
66
|
+
export interface CategoryConcept {
|
|
67
67
|
label: string;
|
|
68
68
|
match?: OpenEnum<"exact" | "close" | "broad" | "narrow">;
|
|
69
69
|
termId: string;
|
|
70
70
|
uri: string;
|
|
71
|
-
}
|
|
72
|
-
export
|
|
71
|
+
}
|
|
72
|
+
export interface CategoryProductCategory {
|
|
73
73
|
concepts: CategoryConcept[];
|
|
74
74
|
/** Legacy semantic mapping value, separate from source product_category enum[] values. */
|
|
75
75
|
recordValue: string | null;
|
|
@@ -79,8 +79,8 @@ export type CategoryProductCategory = {
|
|
|
79
79
|
* fits yet.
|
|
80
80
|
*/
|
|
81
81
|
status: OpenEnum<"mapped" | "conditional" | "unmapped">;
|
|
82
|
-
}
|
|
83
|
-
export
|
|
82
|
+
}
|
|
83
|
+
export interface CategoriesGetResult {
|
|
84
84
|
/** Phrases that name this category in a `query`. */
|
|
85
85
|
aliases: string[];
|
|
86
86
|
/** The categories above this one, root first. Empty for a top-level category. */
|
|
@@ -98,4 +98,4 @@ export type CategoriesGetResult = {
|
|
|
98
98
|
path: string;
|
|
99
99
|
/** Zero-based depth in the source hierarchy. */
|
|
100
100
|
depth: number;
|
|
101
|
-
}
|
|
101
|
+
}
|
package/client-config.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
/** The hosted API origin the client talks to unless `baseUrl` overrides it. */
|
|
7
7
|
export declare const DEFAULT_BASE_URL = "https://beta.materialgraph.com";
|
|
8
|
-
export
|
|
8
|
+
export interface MaterialGraphClientOptions {
|
|
9
9
|
/** A `mg_read_*` API key, presented as `Authorization: Bearer <key>`. */
|
|
10
10
|
apiKey: string;
|
|
11
11
|
/** Override the API origin. Defaults to {@link DEFAULT_BASE_URL}. */
|
|
@@ -19,4 +19,4 @@ export type MaterialGraphClientOptions = {
|
|
|
19
19
|
* they end or the caller aborts. Absent means no deadline.
|
|
20
20
|
*/
|
|
21
21
|
timeoutMs?: number;
|
|
22
|
-
}
|
|
22
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { JsonObject } from "./json.js";
|
|
2
2
|
/** Adapt a fresh producer schema to the SDK's existing open string enums. */
|
|
3
|
-
export declare const openClientResponseEnums: (schema:
|
|
3
|
+
export declare const openClientResponseEnums: (schema: JsonObject) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { isJsonObject } from "./json.js";
|
|
2
2
|
// Only the fields declared as OpenEnum in the SDK are open here. Union
|
|
3
3
|
// discriminants stay closed so their associated object shapes remain true.
|
|
4
4
|
const openStrings = new Set([
|
|
@@ -47,19 +47,19 @@ const openStrings = new Set([
|
|
|
47
47
|
/** Adapt a fresh producer schema to the SDK's existing open string enums. */
|
|
48
48
|
export const openClientResponseEnums = (schema) => {
|
|
49
49
|
const visit = (node, path) => {
|
|
50
|
-
if (!
|
|
50
|
+
if (!isJsonObject(node)) {
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
if (node.type === "string" && openStrings.has(path)) {
|
|
54
54
|
delete node.enum;
|
|
55
55
|
delete node.const;
|
|
56
56
|
}
|
|
57
|
-
if (
|
|
57
|
+
if (isJsonObject(node.$defs)) {
|
|
58
58
|
for (const [name, definition] of Object.entries(node.$defs)) {
|
|
59
59
|
visit(definition, name);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
-
if (
|
|
62
|
+
if (isJsonObject(node.properties)) {
|
|
63
63
|
for (const [name, property] of Object.entries(node.properties)) {
|
|
64
64
|
visit(property, `${path}.${name}`);
|
|
65
65
|
}
|
package/client-vocabulary.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolveOperation } from "./operations.js";
|
|
2
2
|
export const resolveColor = async (transport, name, signal, options) => await transport.requestJson(resolveOperation("resolve_color_name"), {
|
|
3
|
-
query: { searchCatalogSubset: options?.searchCatalogSubset
|
|
3
|
+
query: { name, searchCatalogSubset: options?.searchCatalogSubset },
|
|
4
4
|
signal,
|
|
5
5
|
});
|
|
6
6
|
/**
|
package/client.d.ts
CHANGED
|
@@ -177,7 +177,7 @@ export declare class MaterialGraphClient {
|
|
|
177
177
|
* materials catalog, never silently dropped from the page.
|
|
178
178
|
*
|
|
179
179
|
* `filters`/`optionalFilters`/`orderBy`/`colors` are sent as URL-encoded
|
|
180
|
-
* JSON; `attributes`/`include`/`words` as comma-separated lists — the server
|
|
180
|
+
* JSON; `attributes`/`observations`/`include`/`words` as comma-separated lists — the server
|
|
181
181
|
* validates, this method does not duplicate that check.
|
|
182
182
|
*/
|
|
183
183
|
listVariants(input: ListVariantsInput, signal?: AbortSignal): Promise<ListVariantsOutput>;
|
package/client.js
CHANGED
|
@@ -86,9 +86,7 @@ export class MaterialGraphClient {
|
|
|
86
86
|
apiKey: options.apiKey,
|
|
87
87
|
baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
|
|
88
88
|
fetch: options.fetch ?? globalThis.fetch,
|
|
89
|
-
|
|
90
|
-
? {}
|
|
91
|
-
: { timeoutMs: options.timeoutMs }),
|
|
89
|
+
timeoutMs: options.timeoutMs,
|
|
92
90
|
});
|
|
93
91
|
this.#transport = transport;
|
|
94
92
|
this.baseUrl = transport.baseUrl;
|
|
@@ -182,6 +180,9 @@ export class MaterialGraphClient {
|
|
|
182
180
|
? options.blocks.join(",")
|
|
183
181
|
: undefined,
|
|
184
182
|
ifc: options?.ifc === true ? "true" : undefined,
|
|
183
|
+
observations: options?.observations !== undefined && options.observations.length > 0
|
|
184
|
+
? options.observations.join(",")
|
|
185
|
+
: undefined,
|
|
185
186
|
}, signal, { variantId });
|
|
186
187
|
}
|
|
187
188
|
async materialBlocks(variantId, signal) {
|
|
@@ -249,7 +250,7 @@ export class MaterialGraphClient {
|
|
|
249
250
|
* materials catalog, never silently dropped from the page.
|
|
250
251
|
*
|
|
251
252
|
* `filters`/`optionalFilters`/`orderBy`/`colors` are sent as URL-encoded
|
|
252
|
-
* JSON; `attributes`/`include`/`words` as comma-separated lists — the server
|
|
253
|
+
* JSON; `attributes`/`observations`/`include`/`words` as comma-separated lists — the server
|
|
253
254
|
* validates, this method does not duplicate that check.
|
|
254
255
|
*/
|
|
255
256
|
async listVariants(input, signal) {
|
|
@@ -261,7 +262,6 @@ export class MaterialGraphClient {
|
|
|
261
262
|
colors: input.colors !== undefined && input.colors.length > 0
|
|
262
263
|
? JSON.stringify(input.colors)
|
|
263
264
|
: undefined,
|
|
264
|
-
searchCatalogSubset: input.searchCatalogSubset,
|
|
265
265
|
cursor: input.cursor,
|
|
266
266
|
filters: input.filters ? JSON.stringify(input.filters) : undefined,
|
|
267
267
|
include: input.include !== undefined && input.include.length > 0
|
|
@@ -269,12 +269,16 @@ export class MaterialGraphClient {
|
|
|
269
269
|
: undefined,
|
|
270
270
|
limit: input.limit,
|
|
271
271
|
name: input.name,
|
|
272
|
+
observations: input.observations !== undefined && input.observations.length > 0
|
|
273
|
+
? input.observations.join(",")
|
|
274
|
+
: undefined,
|
|
272
275
|
optionalFilters: input.optionalFilters
|
|
273
276
|
? JSON.stringify(input.optionalFilters)
|
|
274
277
|
: undefined,
|
|
275
278
|
orderBy: input.orderBy !== undefined && input.orderBy.length > 0
|
|
276
279
|
? JSON.stringify(input.orderBy)
|
|
277
280
|
: undefined,
|
|
281
|
+
searchCatalogSubset: input.searchCatalogSubset,
|
|
278
282
|
words: input.words !== undefined && input.words.length > 0
|
|
279
283
|
? input.words.join(",")
|
|
280
284
|
: undefined,
|
|
@@ -357,11 +361,11 @@ export class MaterialGraphClient {
|
|
|
357
361
|
*/
|
|
358
362
|
async listSampledTogetherPairs(input = {}, signal) {
|
|
359
363
|
return await this.#get("list_sampled_together_pairs", {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
?
|
|
364
|
-
:
|
|
364
|
+
cursor: input.cursor,
|
|
365
|
+
limit: input.limit === undefined ? undefined : String(input.limit),
|
|
366
|
+
minProjects: input.minProjects === undefined
|
|
367
|
+
? undefined
|
|
368
|
+
: String(input.minProjects),
|
|
365
369
|
}, signal);
|
|
366
370
|
}
|
|
367
371
|
/**
|
|
@@ -14,7 +14,7 @@ import type { OpenEnum } from "./types.js";
|
|
|
14
14
|
*/
|
|
15
15
|
export type CategoryTier = OpenEnum<"group" | "type" | "merged">;
|
|
16
16
|
/** One representative color bucket of a category. */
|
|
17
|
-
export
|
|
17
|
+
export interface CategoryColor {
|
|
18
18
|
hex: string;
|
|
19
19
|
oklab: {
|
|
20
20
|
l: number;
|
|
@@ -24,8 +24,8 @@ export type CategoryColor = {
|
|
|
24
24
|
variantCount: number;
|
|
25
25
|
/** This bucket's share of the selection's colored variants, 0 to 1. */
|
|
26
26
|
proportion: number;
|
|
27
|
-
}
|
|
28
|
-
export
|
|
27
|
+
}
|
|
28
|
+
export interface CategoryColorProfile {
|
|
29
29
|
categoryKey: string;
|
|
30
30
|
level: CategoryTier;
|
|
31
31
|
name: string;
|
|
@@ -39,12 +39,12 @@ export type CategoryColorProfile = {
|
|
|
39
39
|
avgLightness: number;
|
|
40
40
|
avgChroma: number;
|
|
41
41
|
colors: CategoryColor[];
|
|
42
|
-
}
|
|
43
|
-
export
|
|
42
|
+
}
|
|
43
|
+
export interface CategoryColorProfilesResponse {
|
|
44
44
|
profiles: CategoryColorProfile[];
|
|
45
|
-
}
|
|
45
|
+
}
|
|
46
46
|
/** Request parameters for `colors.profiles()`. */
|
|
47
|
-
export
|
|
47
|
+
export interface ColorProfilesParams {
|
|
48
48
|
/** 1 to 8 category keys, at the tier named by `groupBy`. */
|
|
49
49
|
productTypeIds: readonly string[];
|
|
50
50
|
/**
|
|
@@ -57,4 +57,4 @@ export type ColorProfilesParams = {
|
|
|
57
57
|
topN?: number;
|
|
58
58
|
/** `"diverse"` maximizes visual distinctness instead of frequency. */
|
|
59
59
|
select?: "frequency" | "diverse";
|
|
60
|
-
}
|
|
60
|
+
}
|
package/color-wire-types.d.ts
CHANGED
|
@@ -5,28 +5,28 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { OpenEnum } from "./types.js";
|
|
7
7
|
/** A color in OKLab: lightness 0 to 1, and the green-red and blue-yellow axes. */
|
|
8
|
-
export
|
|
8
|
+
export interface OKLab {
|
|
9
9
|
L: number;
|
|
10
10
|
a: number;
|
|
11
11
|
b: number;
|
|
12
|
-
}
|
|
12
|
+
}
|
|
13
13
|
/** A region of color: chroma, hue (null for neutrals) and lightness bounds. */
|
|
14
|
-
export
|
|
14
|
+
export interface ColorRegion {
|
|
15
15
|
chroma: [number, number];
|
|
16
16
|
hue: [number, number] | null;
|
|
17
17
|
lightness: [number, number];
|
|
18
|
-
}
|
|
18
|
+
}
|
|
19
19
|
/** One of ColorScope's fifteen color families. */
|
|
20
20
|
export type ColorFamilyId = OpenEnum<"beige" | "black" | "blue" | "brown" | "cream" | "gray" | "green" | "orange" | "pink" | "purple" | "red" | "taupe" | "teal" | "white" | "yellow">;
|
|
21
21
|
/** A named color a resolution lands on, and how close the input is to it. */
|
|
22
|
-
export
|
|
22
|
+
export interface ColorResolutionMatch {
|
|
23
23
|
band: OpenEnum<"inside" | "near" | "far">;
|
|
24
24
|
family: ColorFamilyId;
|
|
25
25
|
hex: string;
|
|
26
26
|
id: string;
|
|
27
27
|
name: string;
|
|
28
28
|
range: ColorRegion;
|
|
29
|
-
}
|
|
29
|
+
}
|
|
30
30
|
/** What ColorScope makes of a color name: resolved to a color, or why not. */
|
|
31
31
|
export type ColorResolution = {
|
|
32
32
|
kind: "resolved";
|
package/colors-client.d.ts
CHANGED
|
@@ -29,9 +29,9 @@ import type { JsonOperationId, OperationResponses } from "./operation-responses.
|
|
|
29
29
|
* likeness, never a stated color specification.
|
|
30
30
|
*/
|
|
31
31
|
/** The client's own request primitives, handed down so this file owns no transport. */
|
|
32
|
-
export
|
|
33
|
-
get<K extends JsonOperationId>(operationId: K, query?: QueryParams, signal?: AbortSignal)
|
|
34
|
-
}
|
|
32
|
+
export interface ColorsTransport {
|
|
33
|
+
get: <K extends JsonOperationId>(operationId: K, query?: QueryParams, signal?: AbortSignal) => Promise<OperationResponses[K]>;
|
|
34
|
+
}
|
|
35
35
|
export declare class ColorsClient {
|
|
36
36
|
#private;
|
|
37
37
|
constructor(transport: ColorsTransport);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { MaterialTile } from "./material-types.js";
|
|
2
2
|
/** Static registry definitions and MG-owned discovery policy, without product counts. */
|
|
3
|
-
export
|
|
3
|
+
export interface DiscoveryReference {
|
|
4
4
|
attributes: {
|
|
5
5
|
id: string;
|
|
6
6
|
name: string;
|
|
@@ -23,21 +23,21 @@ export type DiscoveryReference = {
|
|
|
23
23
|
description: string;
|
|
24
24
|
}[];
|
|
25
25
|
admittedBrandIds: string[];
|
|
26
|
-
}
|
|
27
|
-
export
|
|
26
|
+
}
|
|
27
|
+
export interface InterpretDiscoveryTermsInput {
|
|
28
28
|
text: string;
|
|
29
29
|
categoryIds: readonly string[];
|
|
30
|
-
}
|
|
31
|
-
export
|
|
30
|
+
}
|
|
31
|
+
export interface DiscoveryTerms {
|
|
32
32
|
categories: {
|
|
33
33
|
categoryIds: string[];
|
|
34
34
|
words: string[];
|
|
35
35
|
} | null;
|
|
36
36
|
colorWordHexes: string[];
|
|
37
|
-
}
|
|
38
|
-
export
|
|
37
|
+
}
|
|
38
|
+
export interface ColorlessVariantsResult {
|
|
39
39
|
variantIds: string[];
|
|
40
|
-
}
|
|
40
|
+
}
|
|
41
41
|
/** A sibling uses the same tile contract as the catalog's material cards. */
|
|
42
42
|
export type VariantSibling = MaterialTile & {
|
|
43
43
|
distinction?: string;
|