@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/http-transport.d.ts
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
import type { RateLimit } from "./errors.js";
|
|
2
|
+
import type { JsonValue } from "./json-value-types.js";
|
|
2
3
|
import type { JsonOperationId, OperationResponses } from "./operation-responses.js";
|
|
3
4
|
import type { SdkOperation } from "./operations.js";
|
|
4
5
|
type QueryValue = string | number | boolean | undefined | null | (string | number | boolean)[];
|
|
5
6
|
export type QueryParams = Record<string, QueryValue>;
|
|
6
|
-
export
|
|
7
|
+
export interface RequestOptions {
|
|
7
8
|
/** Required by state-changing operations that support safe retries. */
|
|
8
9
|
idempotencyKey?: string;
|
|
9
10
|
query?: QueryParams;
|
|
10
11
|
body?: unknown;
|
|
11
12
|
signal?: AbortSignal;
|
|
12
13
|
pathParams?: Readonly<Record<string, string>>;
|
|
13
|
-
}
|
|
14
|
+
}
|
|
14
15
|
/** A read, status-checked HTTP response with its parsed body. */
|
|
15
|
-
export
|
|
16
|
+
export interface SentResponse {
|
|
16
17
|
response: Response;
|
|
17
18
|
text: string;
|
|
18
|
-
parsed:
|
|
19
|
-
}
|
|
20
|
-
|
|
19
|
+
parsed: JsonValue | undefined;
|
|
20
|
+
}
|
|
21
|
+
interface SendInput {
|
|
21
22
|
method: string;
|
|
22
23
|
url: string;
|
|
23
24
|
headers: Record<string, string>;
|
|
24
25
|
/** The only bodies the SDK sends: a JSON string or a multipart `FormData`. */
|
|
25
26
|
body?: string | FormData;
|
|
26
27
|
signal?: AbortSignal;
|
|
27
|
-
}
|
|
28
|
-
export
|
|
28
|
+
}
|
|
29
|
+
export interface HttpTransportOptions {
|
|
29
30
|
apiKey: string;
|
|
30
31
|
baseUrl: string;
|
|
31
32
|
fetch: typeof fetch;
|
|
32
33
|
/** Deadline in milliseconds for each JSON or upload request. Not applied to streams. */
|
|
33
34
|
timeoutMs?: number;
|
|
34
|
-
}
|
|
35
|
+
}
|
|
35
36
|
export declare class HttpTransport {
|
|
36
37
|
#private;
|
|
37
38
|
readonly baseUrl: string;
|
|
@@ -40,7 +41,10 @@ export declare class HttpTransport {
|
|
|
40
41
|
constructor(options: HttpTransportOptions);
|
|
41
42
|
get lastRateLimit(): RateLimit | null;
|
|
42
43
|
/** The bearer + JSON `Accept` headers, plus any per-request additions. */
|
|
43
|
-
authHeaders(extra?: Record<string, string>):
|
|
44
|
+
authHeaders(extra?: Record<string, string>): {
|
|
45
|
+
Accept: string;
|
|
46
|
+
Authorization: string;
|
|
47
|
+
};
|
|
44
48
|
buildUrl(path: string, query?: QueryParams): string;
|
|
45
49
|
/**
|
|
46
50
|
* Send one request, capture rate limits, read the body, and map a non-2xx or
|
package/http-transport.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* failure surfaces as one {@link MaterialGraphError}.
|
|
7
7
|
*/
|
|
8
8
|
import { MaterialGraphError } from "./errors.js";
|
|
9
|
+
import { parseJson } from "./json.js";
|
|
9
10
|
import { operationPath } from "./operations.js";
|
|
10
11
|
import { parseOperationResponse } from "./parse-operation-response.js";
|
|
11
12
|
const parseNumberOrNull = (value) => {
|
|
@@ -106,11 +107,11 @@ export class HttpTransport {
|
|
|
106
107
|
signal,
|
|
107
108
|
});
|
|
108
109
|
}
|
|
109
|
-
catch (
|
|
110
|
+
catch (error) {
|
|
110
111
|
throw MaterialGraphError.fromTransport({
|
|
111
112
|
...metadata,
|
|
112
113
|
callerSignal: signal,
|
|
113
|
-
cause,
|
|
114
|
+
cause: error,
|
|
114
115
|
});
|
|
115
116
|
}
|
|
116
117
|
const rateLimit = parseRateLimit(response.headers);
|
|
@@ -119,17 +120,17 @@ export class HttpTransport {
|
|
|
119
120
|
try {
|
|
120
121
|
text = await response.text();
|
|
121
122
|
}
|
|
122
|
-
catch (
|
|
123
|
+
catch (error) {
|
|
123
124
|
throw MaterialGraphError.fromTransport({
|
|
124
125
|
...metadata,
|
|
125
126
|
callerSignal: signal,
|
|
126
|
-
cause,
|
|
127
|
+
cause: error,
|
|
127
128
|
});
|
|
128
129
|
}
|
|
129
130
|
let parsed;
|
|
130
131
|
if (text.length > 0) {
|
|
131
132
|
try {
|
|
132
|
-
parsed =
|
|
133
|
+
parsed = parseJson(text);
|
|
133
134
|
}
|
|
134
135
|
catch {
|
|
135
136
|
parsed = text;
|
|
@@ -152,15 +153,16 @@ export class HttpTransport {
|
|
|
152
153
|
async requestJson(sdkOperation, options = {}) {
|
|
153
154
|
const url = this.buildUrl(operationPath(sdkOperation, options.pathParams), options.query);
|
|
154
155
|
const hasBody = options.body !== undefined;
|
|
156
|
+
const extraHeaders = {};
|
|
157
|
+
if (hasBody) {
|
|
158
|
+
extraHeaders["Content-Type"] = "application/json";
|
|
159
|
+
}
|
|
160
|
+
if (options.idempotencyKey !== undefined && options.idempotencyKey !== "") {
|
|
161
|
+
extraHeaders["Idempotency-Key"] = options.idempotencyKey;
|
|
162
|
+
}
|
|
155
163
|
const { parsed } = await this.send({
|
|
156
164
|
body: hasBody ? JSON.stringify(options.body) : undefined,
|
|
157
|
-
headers: this.authHeaders(
|
|
158
|
-
...(hasBody ? { "Content-Type": "application/json" } : {}),
|
|
159
|
-
...(options.idempotencyKey !== undefined &&
|
|
160
|
-
options.idempotencyKey !== ""
|
|
161
|
-
? { "Idempotency-Key": options.idempotencyKey }
|
|
162
|
-
: {}),
|
|
163
|
-
}),
|
|
165
|
+
headers: this.authHeaders(extraHeaders),
|
|
164
166
|
method: sdkOperation.method,
|
|
165
167
|
signal: options.signal,
|
|
166
168
|
url,
|
|
@@ -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
|
|
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/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type { DiscoveryReference, DiscoveryTerms, InterpretDiscoveryTermsInput, ColorlessVariantsResult, VariantSibling, } from "./discovery-context-types.js";
|
|
2
2
|
export { MaterialGraphClient, DEFAULT_BASE_URL } from "./client.js";
|
|
3
3
|
export type { MaterialGraphClientOptions } from "./client.js";
|
|
4
|
-
export type { FilterOp, FilterTermCondition, FilterNumericCondition, FilterPresenceCondition, FilterAnyFieldCondition, FilterCondition, FilterGroups, OptionalFilterGroups, OrderByEntry, ListVariantsInclude, ListVariantsCollapse, ColorRegion, ColorRangeCondition, ListVariantsInput, ListVariantsPreference, ListVariantsSpecifications, ListVariantsNotApplicable, SampleSubject, ListVariantsItem, ListVariantsOutput, VariantCard, } from "./list-variants-types.js";
|
|
4
|
+
export type { FilterOp, FilterTermCondition, FilterNumericCondition, FilterPresenceCondition, FilterAnyFieldCondition, FilterCondition, FilterGroups, OptionalFilterGroups, OrderByEntry, ListVariantsInclude, ListVariantsCollapse, ColorRegion, ColorRangeCondition, ListVariantsInput, ListVariantsPreference, ListVariantsSpecifications, ListVariantsNotApplicable, SampleSizeObservation, VariantObservations, SampleSubject, ListVariantsItem, ListVariantsOutput, VariantCard, } from "./list-variants-types.js";
|
|
5
5
|
export type { ListVariantFacetsInput, VariantFacetValue, CategoricalVariantFacet, BooleanVariantFacet, NumericVariantFacet, VariantFacet, ListVariantFacetsOutput, } from "./list-variant-facets-types.js";
|
|
6
6
|
export type { SearchVariantsSelection, SearchVariantsInput, SearchVariantsUnderstood, SearchVariantsReading, SearchVariantsSuggestion, SearchVariantsChoice, SearchVariantsOutput, } from "./search-variants-types.js";
|
|
7
7
|
export type { ListEnumValuesOptions, EnumValueMatch, EnumValueItem, ListEnumValuesResult, } from "./list-enum-values-types.js";
|
|
@@ -27,7 +27,7 @@ export type { ColorsTransport } from "./colors-client.js";
|
|
|
27
27
|
export type { CategoryTier, CategoryColor, CategoryColorProfile, CategoryColorProfilesResponse, ColorProfilesParams, } from "./color-profiles-types.js";
|
|
28
28
|
export type { DeclaredProvenance, DeclaredAssociationSubject, DeclaredAssociation, DeclaredAssociationsResponse, AssociatedOptions, ApplicabilitySubject, ApplicabilityCoverageState, ApplicabilityCoverage, ApplicabilityFact, ApplicabilitySourceEntry, UnresolvedApplicabilityEndpoint, ApplicabilityResponse, ApplicabilityOptions, } from "./association-types.js";
|
|
29
29
|
export type { BrandsOptions, BrandItem, ListBrandsPage, } from "./brand-types.js";
|
|
30
|
-
export type { VariantAssetAvailability, VariantImageRole, VariantImagePresentation, VariantDocumentType, VariantAssetKind, VariantAssetItem, VariantDocumentCoverageState, VariantAssetPageInfo, ListVariantAssetsOptions, VariantAssetPage, MaterialDocumentStatus, MaterialDocumentCoverageState, MaterialDocumentScope, MaterialDocumentSource, MaterialDocumentProjectionItem, MaterialDocumentCoverageSource, MaterialDocumentCoverage, MaterialDocumentCoverageSummary, MaterialDocumentPageOptions, MaterialDocumentPage, } from "./material-asset-types.js";
|
|
30
|
+
export type { VariantAssetAvailability, VariantImageRole, VariantImagePresentation, VariantImageShows, VariantImageSurfaceMm, VariantDocumentType, VariantAssetKind, VariantAssetItem, VariantDocumentCoverageState, VariantAssetPageInfo, ListVariantAssetsOptions, VariantAssetPage, MaterialDocumentStatus, MaterialDocumentCoverageState, MaterialDocumentScope, MaterialDocumentSource, MaterialDocumentProjectionItem, MaterialDocumentCoverageSource, MaterialDocumentCoverage, MaterialDocumentCoverageSummary, MaterialDocumentPageOptions, MaterialDocumentPage, } from "./material-asset-types.js";
|
|
31
31
|
export type { MaterialCoverageStatus, MaterialBlockStatus, MaterialBlockFieldStatus, MaterialBlockFieldValue, MaterialBlockProjectionField, MaterialBlockProjectionItem, MaterialBlockProjection, VariantColorPalette, } from "./material-block-types.js";
|
|
32
32
|
export type { SchemaResource, SCHEMA_RESOURCE_OPERATION_IDS, SchemaResourceRequest, SchemaLifecycle, SchemaExternalMapping, SchemaMatchStrength, SchemaValueDictionaryTerm, SchemaValueDictionaryItem, SchemaResourceItemMap, SchemaResourceResponse, } from "./schema-resource-types.js";
|
|
33
33
|
export type { NearestPaintsParams, NearestPaintCard, NearestPaintsHexResult, NearestPaintsOutput, } from "./nearest-paints-types.js";
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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 {};
|
package/list-variants-types.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
29
|
+
}
|
|
30
|
+
export interface FilterNumericCondition {
|
|
31
31
|
field: string;
|
|
32
32
|
op: "eq" | "gt" | "gte" | "lt" | "lte";
|
|
33
33
|
value: number;
|
|
34
|
-
}
|
|
35
|
-
export
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
118
|
+
}
|
|
119
|
+
export interface ListVariantsInput {
|
|
120
120
|
/** Attribute ids to project under each item's `specifications`. */
|
|
121
121
|
attributes?: string[];
|
|
122
122
|
/**
|
|
@@ -145,27 +145,55 @@ export type ListVariantsInput = {
|
|
|
145
145
|
* ambiguous matches are all returned rather than guessed between.
|
|
146
146
|
*/
|
|
147
147
|
name?: string;
|
|
148
|
+
/** Observation attribute ids to add under each item's `observations`, e.g. `["sample_size"]`. */
|
|
149
|
+
observations?: string[];
|
|
148
150
|
/** Rank only — never excludes. */
|
|
149
151
|
optionalFilters?: OptionalFilterGroups;
|
|
150
152
|
orderBy?: OrderByEntry[];
|
|
151
153
|
/** Words each variant must name in its text, inside the filters. */
|
|
152
154
|
words?: string[];
|
|
153
|
-
}
|
|
155
|
+
}
|
|
154
156
|
/**
|
|
155
157
|
* `score` sums the weights of the matched `optionalFilters`; `matched` lists
|
|
156
158
|
* their positions in the flattened terms-then-numbers-then-presence-then-anyField order
|
|
157
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.
|
|
158
163
|
*/
|
|
159
|
-
export
|
|
164
|
+
export interface ListVariantsPreference {
|
|
165
|
+
looks?: {
|
|
166
|
+
by: ("named" | "stated" | "described")[];
|
|
167
|
+
index: number;
|
|
168
|
+
words?: string;
|
|
169
|
+
}[];
|
|
160
170
|
matched: number[];
|
|
171
|
+
photo?: true;
|
|
161
172
|
score: number;
|
|
162
|
-
}
|
|
173
|
+
}
|
|
163
174
|
/** `{ [blockId]: { [attributeId]: value } }`. Null means the value is unknown. */
|
|
164
175
|
export type ListVariantsSpecifications = Record<string, Record<string, unknown>>;
|
|
165
|
-
|
|
176
|
+
/** Material Bank's printed sample size. Any field may be absent; absent is unknown, never 0. */
|
|
177
|
+
export interface SampleSizeObservation {
|
|
178
|
+
/** The sample size as the channel printed it, verbatim. */
|
|
179
|
+
wording?: string;
|
|
180
|
+
/** The shorter side in millimeters. */
|
|
181
|
+
width_mm?: number;
|
|
182
|
+
/** The longer side in millimeters. */
|
|
183
|
+
length_mm?: number;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* `{ [channel]: { [attributeId]: value } }`: the latest observation of each
|
|
187
|
+
* selected attribute for each channel (`no_channel` when none is named). An
|
|
188
|
+
* attribute with no observation is absent.
|
|
189
|
+
*/
|
|
190
|
+
export type VariantObservations = Record<string, {
|
|
191
|
+
sample_size?: SampleSizeObservation;
|
|
192
|
+
} & Record<string, unknown>>;
|
|
193
|
+
export interface ListVariantsNotApplicable {
|
|
166
194
|
attributes?: string[];
|
|
167
195
|
blocks?: string[];
|
|
168
|
-
}
|
|
196
|
+
}
|
|
169
197
|
/** What a sample represents, independently of its specification type. */
|
|
170
198
|
export type SampleSubject = "material" | "paint_color_sample" | "unknown" | "conflict";
|
|
171
199
|
/**
|
|
@@ -173,7 +201,7 @@ export type SampleSubject = "material" | "paint_color_sample" | "unknown" | "con
|
|
|
173
201
|
* and brand page only when requested (`include`) and selected attributes
|
|
174
202
|
* under `specifications`. Leaner than `get_variant`'s item on purpose.
|
|
175
203
|
*/
|
|
176
|
-
export
|
|
204
|
+
export interface ListVariantsItem {
|
|
177
205
|
category: {
|
|
178
206
|
id: string;
|
|
179
207
|
name: string;
|
|
@@ -210,6 +238,8 @@ export type ListVariantsItem = {
|
|
|
210
238
|
/** The trimmed source variant label; null when unknown or for a paint color sample, whose own name identifies its color. Separate from surface finish, color family and derived color names. */
|
|
211
239
|
variantLabel: string | null;
|
|
212
240
|
notApplicable?: ListVariantsNotApplicable;
|
|
241
|
+
/** Present when `observations` was asked for and the variant has any. */
|
|
242
|
+
observations?: VariantObservations;
|
|
213
243
|
preference?: ListVariantsPreference;
|
|
214
244
|
product: {
|
|
215
245
|
id: string;
|
|
@@ -223,7 +253,7 @@ export type ListVariantsItem = {
|
|
|
223
253
|
*/
|
|
224
254
|
variantCount?: number;
|
|
225
255
|
variantId: string;
|
|
226
|
-
}
|
|
256
|
+
}
|
|
227
257
|
/**
|
|
228
258
|
* The variant card both `listVariants` rows and `findVariantsByVector` rows
|
|
229
259
|
* satisfy. The only difference between the two is the Material Bank SKU:
|
|
@@ -233,7 +263,7 @@ export type VariantCard = Omit<ListVariantsItem, "materialBankId"> & {
|
|
|
233
263
|
/** The variant's Material Bank SKU. Absent or null means none is recorded. */
|
|
234
264
|
materialBankId?: string | null;
|
|
235
265
|
};
|
|
236
|
-
export
|
|
266
|
+
export interface ListVariantsOutput {
|
|
237
267
|
/** Explicit `{field: "variant", op: "in"}` ids that name a real variant outside the materials catalog. Present only when at least one did. */
|
|
238
268
|
excludedBySearchCatalogSubset?: string[];
|
|
239
269
|
items: ListVariantsItem[];
|
|
@@ -252,11 +282,11 @@ export type ListVariantsOutput = {
|
|
|
252
282
|
unavailableVariantIds?: string[];
|
|
253
283
|
/** Explicit `{field: "variant", op: "in"}` ids anywhere in `filters.terms` that name no variant at all. */
|
|
254
284
|
unresolvedVariantIds?: string[];
|
|
255
|
-
/**
|
|
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. */
|
|
256
286
|
unstated?: string[];
|
|
257
287
|
/** Each requested word and whether any variant in scope names it. */
|
|
258
288
|
words?: {
|
|
259
289
|
matched: boolean;
|
|
260
290
|
word: string;
|
|
261
291
|
}[];
|
|
262
|
-
}
|
|
292
|
+
}
|