@instruments/materialgraph 0.1.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/brand-types.d.ts +25 -0
- package/brand-types.js +1 -0
- package/catalog-discovery-types.d.ts +47 -0
- package/catalog-discovery-types.js +1 -0
- package/client.d.ts +119 -0
- package/client.js +333 -0
- package/errors.d.ts +83 -0
- package/errors.js +217 -0
- package/index.d.ts +12 -0
- package/index.js +3 -0
- package/material-asset-types.d.ts +35 -0
- package/material-asset-types.js +1 -0
- package/material-block-types.d.ts +22 -0
- package/material-block-types.js +1 -0
- package/operations.d.ts +11 -0
- package/operations.js +53 -0
- package/package.json +23 -0
- package/schema-resource-types.d.ts +163 -0
- package/schema-resource-types.js +1 -0
- package/search-refinement-types.d.ts +16 -0
- package/search-refinement-types.js +1 -0
- package/types.d.ts +749 -0
- package/types.js +1 -0
package/errors.js
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/** Error and rate-limit contracts for the retry-free MaterialGraph SDK. */
|
|
2
|
+
const RETRIABLE_STATUS = new Set([502, 503, 504]);
|
|
3
|
+
const MAX_UNEXPECTED_TEXT = 768;
|
|
4
|
+
const MAX_EXTENSION_DEPTH = 8;
|
|
5
|
+
const MAX_EXTENSION_ITEMS = 100;
|
|
6
|
+
const MAX_EXTENSION_STRING = 1_024;
|
|
7
|
+
function isRecord(value) {
|
|
8
|
+
return typeof value === "object" && value !== null;
|
|
9
|
+
}
|
|
10
|
+
function redact(text, secrets) {
|
|
11
|
+
return secrets.reduce((sanitized, secret) => {
|
|
12
|
+
if (secret.length === 0)
|
|
13
|
+
return sanitized;
|
|
14
|
+
return sanitized.split(secret).join("[REDACTED]");
|
|
15
|
+
}, text);
|
|
16
|
+
}
|
|
17
|
+
function safeString(text, secrets) {
|
|
18
|
+
return redact(text, secrets).slice(0, MAX_EXTENSION_STRING);
|
|
19
|
+
}
|
|
20
|
+
function secretVariants(apiKey, queryValues) {
|
|
21
|
+
return [
|
|
22
|
+
apiKey,
|
|
23
|
+
...queryValues,
|
|
24
|
+
...queryValues.map(encodeURIComponent),
|
|
25
|
+
...queryValues.map((value) => new URLSearchParams([["value", value]]).toString().slice("value=".length)),
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
function requestMetadata(input) {
|
|
29
|
+
return { method: input.method, origin: input.origin, path: input.path };
|
|
30
|
+
}
|
|
31
|
+
function sanitizeValue(value, secrets, depth = 0) {
|
|
32
|
+
if (depth >= MAX_EXTENSION_DEPTH)
|
|
33
|
+
return undefined;
|
|
34
|
+
if (value === null || typeof value === "boolean")
|
|
35
|
+
return value;
|
|
36
|
+
if (typeof value === "number")
|
|
37
|
+
return Number.isFinite(value) ? value : undefined;
|
|
38
|
+
if (typeof value === "string") {
|
|
39
|
+
return safeString(value, secrets);
|
|
40
|
+
}
|
|
41
|
+
if (Array.isArray(value)) {
|
|
42
|
+
return value
|
|
43
|
+
.slice(0, MAX_EXTENSION_ITEMS)
|
|
44
|
+
.map((item) => sanitizeValue(item, secrets, depth + 1))
|
|
45
|
+
.filter((item) => item !== undefined);
|
|
46
|
+
}
|
|
47
|
+
if (!isRecord(value))
|
|
48
|
+
return undefined;
|
|
49
|
+
return sanitizeRecord(value, secrets, depth);
|
|
50
|
+
}
|
|
51
|
+
function sanitizeRecord(value, secrets, depth) {
|
|
52
|
+
const entries = Object.entries(value)
|
|
53
|
+
.slice(0, MAX_EXTENSION_ITEMS)
|
|
54
|
+
.flatMap(([key, item]) => {
|
|
55
|
+
const sanitized = sanitizeValue(item, secrets, depth + 1);
|
|
56
|
+
return sanitized === undefined ? [] : [[safeString(key, secrets), sanitized]];
|
|
57
|
+
});
|
|
58
|
+
return Object.fromEntries(entries);
|
|
59
|
+
}
|
|
60
|
+
function sanitizeIssues(value, secrets) {
|
|
61
|
+
if (!Array.isArray(value))
|
|
62
|
+
return undefined;
|
|
63
|
+
return value
|
|
64
|
+
.slice(0, MAX_EXTENSION_ITEMS)
|
|
65
|
+
.filter((issue) => isRecord(issue) && !Array.isArray(issue))
|
|
66
|
+
.map((issue) => sanitizeRecord(issue, secrets, 0));
|
|
67
|
+
}
|
|
68
|
+
function sanitizeSuggestions(value, secrets) {
|
|
69
|
+
if (!Array.isArray(value) || value.some((suggestion) => typeof suggestion !== "string")) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
return value.slice(0, MAX_EXTENSION_ITEMS).map((suggestion) => safeString(suggestion, secrets));
|
|
73
|
+
}
|
|
74
|
+
function normalizeProblem(body, secrets) {
|
|
75
|
+
if (!isRecord(body) ||
|
|
76
|
+
typeof body.type !== "string" ||
|
|
77
|
+
typeof body.title !== "string" ||
|
|
78
|
+
typeof body.status !== "number" ||
|
|
79
|
+
typeof body.detail !== "string" ||
|
|
80
|
+
typeof body.is_retriable !== "boolean" ||
|
|
81
|
+
typeof body.trace_id !== "string" ||
|
|
82
|
+
(body.instance !== undefined && typeof body.instance !== "string")) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
const suggestions = sanitizeSuggestions(body.suggestions, secrets);
|
|
86
|
+
const issues = sanitizeIssues(body.issues, secrets);
|
|
87
|
+
return {
|
|
88
|
+
type: safeString(body.type, secrets),
|
|
89
|
+
title: safeString(body.title, secrets),
|
|
90
|
+
status: body.status,
|
|
91
|
+
detail: safeString(body.detail, secrets),
|
|
92
|
+
...(body.instance === undefined ? {} : { instance: safeString(body.instance, secrets) }),
|
|
93
|
+
is_retriable: body.is_retriable,
|
|
94
|
+
trace_id: safeString(body.trace_id, secrets),
|
|
95
|
+
...(suggestions === undefined ? {} : { suggestions }),
|
|
96
|
+
...(typeof body.doc_uri === "string" ? { doc_uri: safeString(body.doc_uri, secrets) } : {}),
|
|
97
|
+
...(issues === undefined ? {} : { issues }),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function normalizeSimple(body, secrets) {
|
|
101
|
+
if (!isRecord(body) || typeof body.error !== "string")
|
|
102
|
+
return undefined;
|
|
103
|
+
const issues = sanitizeIssues(body.issues, secrets);
|
|
104
|
+
return {
|
|
105
|
+
error: safeString(body.error, secrets),
|
|
106
|
+
...(issues === undefined ? {} : { issues }),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function unexpectedMessage(status, responseText, secrets) {
|
|
110
|
+
const sanitized = redact(responseText, secrets).trim().slice(0, MAX_UNEXPECTED_TEXT);
|
|
111
|
+
return sanitized.length > 0
|
|
112
|
+
? `MaterialGraph request failed with HTTP ${status}: ${sanitized}`
|
|
113
|
+
: `MaterialGraph request failed with HTTP ${status}`;
|
|
114
|
+
}
|
|
115
|
+
/** The one error class thrown by all SDK transport and HTTP failures. */
|
|
116
|
+
export class MaterialGraphError extends Error {
|
|
117
|
+
kind;
|
|
118
|
+
status;
|
|
119
|
+
retriable;
|
|
120
|
+
traceId;
|
|
121
|
+
problem;
|
|
122
|
+
simple;
|
|
123
|
+
rateLimit;
|
|
124
|
+
method;
|
|
125
|
+
origin;
|
|
126
|
+
path;
|
|
127
|
+
constructor(message, init) {
|
|
128
|
+
super(message);
|
|
129
|
+
this.name = "MaterialGraphError";
|
|
130
|
+
this.kind = init.kind;
|
|
131
|
+
this.status = init.status;
|
|
132
|
+
this.retriable = init.retriable;
|
|
133
|
+
this.traceId = init.traceId;
|
|
134
|
+
this.problem = init.problem;
|
|
135
|
+
this.simple = init.simple;
|
|
136
|
+
this.rateLimit = init.rateLimit ?? null;
|
|
137
|
+
this.method = init.method;
|
|
138
|
+
this.origin = init.origin;
|
|
139
|
+
this.path = init.path;
|
|
140
|
+
}
|
|
141
|
+
/** Compatibility alias for the former SDK property. */
|
|
142
|
+
get isRetriable() {
|
|
143
|
+
return this.retriable;
|
|
144
|
+
}
|
|
145
|
+
static unexpected(message) {
|
|
146
|
+
return new MaterialGraphError(message, { kind: "unexpected", retriable: false });
|
|
147
|
+
}
|
|
148
|
+
static fromTransport(input) {
|
|
149
|
+
if (input.callerSignal?.aborted === true) {
|
|
150
|
+
return new MaterialGraphError("MaterialGraph request aborted by caller", {
|
|
151
|
+
...requestMetadata(input),
|
|
152
|
+
kind: "aborted",
|
|
153
|
+
retriable: false,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
const name = input.cause instanceof Error ? input.cause.name : "";
|
|
157
|
+
if (name === "TimeoutError") {
|
|
158
|
+
return new MaterialGraphError("MaterialGraph request timed out", {
|
|
159
|
+
...requestMetadata(input),
|
|
160
|
+
kind: "timeout",
|
|
161
|
+
retriable: false,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return new MaterialGraphError("MaterialGraph network request failed", {
|
|
165
|
+
...requestMetadata(input),
|
|
166
|
+
kind: "network",
|
|
167
|
+
retriable: true,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
static fromResponse(input) {
|
|
171
|
+
const secrets = secretVariants(input.apiKey, input.queryValues);
|
|
172
|
+
const problem = normalizeProblem(input.body, secrets);
|
|
173
|
+
const simple = problem === undefined ? normalizeSimple(input.body, secrets) : undefined;
|
|
174
|
+
const retriable = RETRIABLE_STATUS.has(input.status);
|
|
175
|
+
const metadata = requestMetadata(input);
|
|
176
|
+
if (input.status === 429) {
|
|
177
|
+
return new MaterialGraphError(problem?.detail ?? simple?.error ?? "MaterialGraph rate limit exceeded (429)", {
|
|
178
|
+
...metadata,
|
|
179
|
+
status: input.status,
|
|
180
|
+
rateLimit: input.rateLimit,
|
|
181
|
+
kind: "rate_limited",
|
|
182
|
+
retriable: false,
|
|
183
|
+
traceId: problem?.trace_id,
|
|
184
|
+
problem,
|
|
185
|
+
simple,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
if (problem !== undefined) {
|
|
189
|
+
return new MaterialGraphError(problem.detail || problem.title, {
|
|
190
|
+
...metadata,
|
|
191
|
+
status: input.status,
|
|
192
|
+
rateLimit: input.rateLimit,
|
|
193
|
+
kind: "problem",
|
|
194
|
+
retriable: retriable || problem.is_retriable,
|
|
195
|
+
traceId: problem.trace_id,
|
|
196
|
+
problem,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (simple !== undefined) {
|
|
200
|
+
return new MaterialGraphError(simple.error, {
|
|
201
|
+
...metadata,
|
|
202
|
+
status: input.status,
|
|
203
|
+
rateLimit: input.rateLimit,
|
|
204
|
+
kind: "simple",
|
|
205
|
+
retriable,
|
|
206
|
+
simple,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return new MaterialGraphError(unexpectedMessage(input.status, input.responseText, secrets), {
|
|
210
|
+
...metadata,
|
|
211
|
+
kind: "unexpected",
|
|
212
|
+
status: input.status,
|
|
213
|
+
retriable,
|
|
214
|
+
rateLimit: input.rateLimit,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { MaterialGraphClient, DEFAULT_BASE_URL, MAX_BATCH_IDS } from "./client.js";
|
|
2
|
+
export type { MaterialGraphClientOptions, BrowseNamespace } from "./client.js";
|
|
3
|
+
export { MATERIALGRAPH_API_VERSION, SDK_OPERATIONS } from "./operations.js";
|
|
4
|
+
export type { SdkOperation, SdkOperationId } from "./operations.js";
|
|
5
|
+
export { MaterialGraphError } from "./errors.js";
|
|
6
|
+
export type { MaterialGraphErrorInit, MaterialGraphErrorKind, MaterialGraphRequestMetadata, ProblemDetail, RateLimit, SanitizedErrorValue, SanitizedIssue, SimpleErrorBody, } from "./errors.js";
|
|
7
|
+
export type * from "./types.js";
|
|
8
|
+
export type * from "./brand-types.js";
|
|
9
|
+
export type * from "./material-asset-types.js";
|
|
10
|
+
export type * from "./material-block-types.js";
|
|
11
|
+
export type * from "./schema-resource-types.js";
|
|
12
|
+
export type * from "./search-refinement-types.js";
|
package/index.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { OpenEnum } from "./types.js";
|
|
2
|
+
export type MaterialAssetVisualRole = OpenEnum<"grid" | "detail" | "scene" | "swatch" | "technical" | "unknown">;
|
|
3
|
+
export type MaterialAssetStatus = OpenEnum<"downloaded" | "linked_not_downloaded" | "failed">;
|
|
4
|
+
export interface MaterialAssetProjectionImage {
|
|
5
|
+
key: string;
|
|
6
|
+
ordinal: number;
|
|
7
|
+
proxyPath: string;
|
|
8
|
+
visualRole: MaterialAssetVisualRole;
|
|
9
|
+
status: MaterialAssetStatus;
|
|
10
|
+
contentType: string | null;
|
|
11
|
+
fileExtension: string | null;
|
|
12
|
+
filename: string | null;
|
|
13
|
+
byteSize: number | null;
|
|
14
|
+
}
|
|
15
|
+
export interface MaterialAssetProjectionDownload {
|
|
16
|
+
ordinal: number;
|
|
17
|
+
url: string;
|
|
18
|
+
label: string | null;
|
|
19
|
+
assetKind: string;
|
|
20
|
+
status: string;
|
|
21
|
+
contentType: string | null;
|
|
22
|
+
fileExtension: string | null;
|
|
23
|
+
filename: string | null;
|
|
24
|
+
}
|
|
25
|
+
export interface MaterialAssetProjectionSummary {
|
|
26
|
+
imageCount: number;
|
|
27
|
+
downloadCount: number;
|
|
28
|
+
downloadedImageCount: number;
|
|
29
|
+
}
|
|
30
|
+
export interface MaterialAssetProjection {
|
|
31
|
+
variantId: string;
|
|
32
|
+
images: MaterialAssetProjectionImage[];
|
|
33
|
+
downloads: MaterialAssetProjectionDownload[];
|
|
34
|
+
summary: MaterialAssetProjectionSummary;
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { OpenEnum } from "./types.js";
|
|
2
|
+
export type MaterialBlockStatus = OpenEnum<"populated" | "partial" | "pending" | "not_applicable">;
|
|
3
|
+
export type MaterialBlockFieldStatus = OpenEnum<"verified" | "partial" | "missing" | "not_applicable">;
|
|
4
|
+
export type MaterialBlockFieldValue = string | number | boolean | unknown[] | Record<string, unknown> | null;
|
|
5
|
+
export interface MaterialBlockProjectionField {
|
|
6
|
+
attributeId: string;
|
|
7
|
+
label: string;
|
|
8
|
+
value: MaterialBlockFieldValue;
|
|
9
|
+
unit?: string;
|
|
10
|
+
status: MaterialBlockFieldStatus;
|
|
11
|
+
}
|
|
12
|
+
export interface MaterialBlockProjectionItem {
|
|
13
|
+
canonicalBlockId: string;
|
|
14
|
+
canonicalBlockName: string;
|
|
15
|
+
status: MaterialBlockStatus;
|
|
16
|
+
fields: MaterialBlockProjectionField[];
|
|
17
|
+
missingAttributeIds: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface MaterialBlockProjection {
|
|
20
|
+
variantId: string;
|
|
21
|
+
blocks: MaterialBlockProjectionItem[];
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/operations.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const MATERIALGRAPH_API_VERSION = "0.6.0";
|
|
2
|
+
declare const OPERATION_DEFINITIONS: readonly [readonly ["search", "POST", "/api/v1/search", "search_materials_post"], readonly ["searchGet", "GET", "/api/v1/search", "search_materials_get"], readonly ["match", "POST", "/api/v1/search/match", "match_material"], readonly ["byColour", "GET", "/api/v1/search/colours", "search_by_colour"], readonly ["material", "GET", "/api/v1/materials/{variantId}", "get_material"], readonly ["siblings", "GET", "/api/v1/materials/{variantId}/siblings", "get_material_siblings"], readonly ["materialBlocks", "GET", "/api/v1/materials/{variantId}/blocks", "list_material_blocks"], readonly ["materialAssets", "GET", "/api/v1/materials/{variantId}/assets", "list_material_assets"], readonly ["schema", "GET", "/api/v1/schema/blocks", "list_schema_blocks"], readonly ["schema", "GET", "/api/v1/schema/attributes", "list_schema_attributes"], readonly ["schema", "GET", "/api/v1/schema/verticals", "list_schema_verticals"], readonly ["schema", "GET", "/api/v1/schema/product-types", "list_schema_product_types"], readonly ["schema", "GET", "/api/v1/schema/units", "list_schema_units"], readonly ["schema", "GET", "/api/v1/schema/value-dictionaries", "list_schema_value_dictionaries"], readonly ["schema", "GET", "/api/v1/schema/source-requirements", "list_schema_source_requirements"], readonly ["schema", "GET", "/api/v1/schema/product-type-templates", "list_schema_product_type_templates"], readonly ["schema", "GET", "/api/v1/schema/mappings", "list_schema_mappings"], readonly ["pairings", "GET", "/api/v1/materials/{variantId}/pairings", "get_material_pairings"], readonly ["materials", "POST", "/api/v1/materials/batch", "get_materials_batch_post"], readonly ["materialsCached", "GET", "/api/v1/materials/batch", "get_materials_batch_get"], readonly ["browse", "GET", "/api/v1/search/browse", "search_browse_by_colour"], readonly ["colourFacets", "GET", "/api/v1/colours/facets", "get_colour_facets"], readonly ["resolveColour", "GET", "/api/v1/search/colours/resolve", "resolve_colour_name"], readonly ["suggestColour", "GET", "/api/v1/search/colours/suggest", "suggest_colour_names"], readonly ["resolveAttribute", "GET", "/api/v1/catalog/attributes/resolve", "catalog_resolve_attribute"], readonly ["resolveAttributeValue", "GET", "/api/v1/catalog/attributes/{attributeId}/values/resolve", "catalog_resolve_value"], readonly ["searchVocabulary", "GET", "/api/v1/catalog/vocabulary/search", "catalog_vocabulary_search"], readonly ["bySpec", "GET", "/api/v1/search/specifications", "catalog_by_spec"], readonly ["taxonomy", "GET", "/api/v1/taxonomy/categories", "get_category_taxonomy"], readonly ["whoami", "GET", "/api/v1/whoami", "whoami"], readonly ["coordinate", "POST", "/api/v1/pairings/coordinate", "coordinate_materials"], readonly ["demand", "GET", "/api/v1/demand", "get_material_demand"], readonly ["extractPalette", "POST", "/api/v1/search/palettes/extract", "extract_image_palette"], readonly ["specificationFacets", "GET", "/api/v1/catalog/specifications/facets", "list_spec_facets"], readonly ["attributeValues", "GET", "/api/v1/catalog/attributes/{attributeId}/values", "list_attribute_values"], readonly ["applicableSpecs", "GET", "/api/v1/taxonomy/categories/{key}/specs", "get_applicable_specs"], readonly ["glossary", "GET", "/api/v1/glossary/{term}", "explain_material_term"], readonly ["brands", "GET", "/api/v1/brands", "list_brands"], readonly ["brand", "GET", "/api/v1/brands/{slug}", "get_brand_profile"]];
|
|
3
|
+
export type SdkOperationId = (typeof OPERATION_DEFINITIONS)[number][3];
|
|
4
|
+
export type SdkOperation = Readonly<{
|
|
5
|
+
clientMethod: (typeof OPERATION_DEFINITIONS)[number][0];
|
|
6
|
+
method: (typeof OPERATION_DEFINITIONS)[number][1];
|
|
7
|
+
path: (typeof OPERATION_DEFINITIONS)[number][2];
|
|
8
|
+
operationId: SdkOperationId;
|
|
9
|
+
}>;
|
|
10
|
+
export declare const SDK_OPERATIONS: readonly SdkOperation[];
|
|
11
|
+
export {};
|
package/operations.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export const MATERIALGRAPH_API_VERSION = "0.6.0";
|
|
2
|
+
const OPERATION_DEFINITIONS = [
|
|
3
|
+
["search", "POST", "/api/v1/search", "search_materials_post"],
|
|
4
|
+
["searchGet", "GET", "/api/v1/search", "search_materials_get"],
|
|
5
|
+
["match", "POST", "/api/v1/search/match", "match_material"],
|
|
6
|
+
["byColour", "GET", "/api/v1/search/colours", "search_by_colour"],
|
|
7
|
+
["material", "GET", "/api/v1/materials/{variantId}", "get_material"],
|
|
8
|
+
["siblings", "GET", "/api/v1/materials/{variantId}/siblings", "get_material_siblings"],
|
|
9
|
+
["materialBlocks", "GET", "/api/v1/materials/{variantId}/blocks", "list_material_blocks"],
|
|
10
|
+
["materialAssets", "GET", "/api/v1/materials/{variantId}/assets", "list_material_assets"],
|
|
11
|
+
["schema", "GET", "/api/v1/schema/blocks", "list_schema_blocks"],
|
|
12
|
+
["schema", "GET", "/api/v1/schema/attributes", "list_schema_attributes"],
|
|
13
|
+
["schema", "GET", "/api/v1/schema/verticals", "list_schema_verticals"],
|
|
14
|
+
["schema", "GET", "/api/v1/schema/product-types", "list_schema_product_types"],
|
|
15
|
+
["schema", "GET", "/api/v1/schema/units", "list_schema_units"],
|
|
16
|
+
["schema", "GET", "/api/v1/schema/value-dictionaries", "list_schema_value_dictionaries"],
|
|
17
|
+
["schema", "GET", "/api/v1/schema/source-requirements", "list_schema_source_requirements"],
|
|
18
|
+
["schema", "GET", "/api/v1/schema/product-type-templates", "list_schema_product_type_templates"],
|
|
19
|
+
["schema", "GET", "/api/v1/schema/mappings", "list_schema_mappings"],
|
|
20
|
+
["pairings", "GET", "/api/v1/materials/{variantId}/pairings", "get_material_pairings"],
|
|
21
|
+
["materials", "POST", "/api/v1/materials/batch", "get_materials_batch_post"],
|
|
22
|
+
["materialsCached", "GET", "/api/v1/materials/batch", "get_materials_batch_get"],
|
|
23
|
+
["browse", "GET", "/api/v1/search/browse", "search_browse_by_colour"],
|
|
24
|
+
["colourFacets", "GET", "/api/v1/colours/facets", "get_colour_facets"],
|
|
25
|
+
["resolveColour", "GET", "/api/v1/search/colours/resolve", "resolve_colour_name"],
|
|
26
|
+
["suggestColour", "GET", "/api/v1/search/colours/suggest", "suggest_colour_names"],
|
|
27
|
+
["resolveAttribute", "GET", "/api/v1/catalog/attributes/resolve", "catalog_resolve_attribute"],
|
|
28
|
+
[
|
|
29
|
+
"resolveAttributeValue",
|
|
30
|
+
"GET",
|
|
31
|
+
"/api/v1/catalog/attributes/{attributeId}/values/resolve",
|
|
32
|
+
"catalog_resolve_value",
|
|
33
|
+
],
|
|
34
|
+
["searchVocabulary", "GET", "/api/v1/catalog/vocabulary/search", "catalog_vocabulary_search"],
|
|
35
|
+
["bySpec", "GET", "/api/v1/search/specifications", "catalog_by_spec"],
|
|
36
|
+
["taxonomy", "GET", "/api/v1/taxonomy/categories", "get_category_taxonomy"],
|
|
37
|
+
["whoami", "GET", "/api/v1/whoami", "whoami"],
|
|
38
|
+
["coordinate", "POST", "/api/v1/pairings/coordinate", "coordinate_materials"],
|
|
39
|
+
["demand", "GET", "/api/v1/demand", "get_material_demand"],
|
|
40
|
+
["extractPalette", "POST", "/api/v1/search/palettes/extract", "extract_image_palette"],
|
|
41
|
+
["specificationFacets", "GET", "/api/v1/catalog/specifications/facets", "list_spec_facets"],
|
|
42
|
+
[
|
|
43
|
+
"attributeValues",
|
|
44
|
+
"GET",
|
|
45
|
+
"/api/v1/catalog/attributes/{attributeId}/values",
|
|
46
|
+
"list_attribute_values",
|
|
47
|
+
],
|
|
48
|
+
["applicableSpecs", "GET", "/api/v1/taxonomy/categories/{key}/specs", "get_applicable_specs"],
|
|
49
|
+
["glossary", "GET", "/api/v1/glossary/{term}", "explain_material_term"],
|
|
50
|
+
["brands", "GET", "/api/v1/brands", "list_brands"],
|
|
51
|
+
["brand", "GET", "/api/v1/brands/{slug}", "get_brand_profile"],
|
|
52
|
+
];
|
|
53
|
+
export const SDK_OPERATIONS = Object.freeze(OPERATION_DEFINITIONS.map(([clientMethod, method, path, operationId]) => Object.freeze({ clientMethod, method, path, operationId })));
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@instruments/materialgraph",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./index.d.ts",
|
|
8
|
+
"import": "./index.js"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"license": "Proprietary",
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=24.0.0"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/materialinstruments/materialgraph.git",
|
|
21
|
+
"directory": "packages/sdk"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import type { OpenEnum } from "./types.js";
|
|
2
|
+
export type SchemaResource = "blocks" | "attributes" | "verticals" | "productTypes" | "units" | "valueDictionaries" | "sourceRequirements" | "productTypeTemplates" | "mappings";
|
|
3
|
+
export type SchemaResourceRequest = SchemaResource;
|
|
4
|
+
export interface SchemaLifecycle {
|
|
5
|
+
status: OpenEnum<"draft" | "active" | "deprecated">;
|
|
6
|
+
introducedIn: string;
|
|
7
|
+
deprecatedIn?: string;
|
|
8
|
+
supersededBy?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SchemaExternalMapping {
|
|
11
|
+
target: OpenEnum<"schema_org" | "ifc_pset" | "bsdd" | "iso_23387" | "eclass" | "gs1_gdm" | "gdsn" | "etim" | "uniclass">;
|
|
12
|
+
targetPath: string;
|
|
13
|
+
mappingType: OpenEnum<"direct" | "transform" | "derived" | "classification" | "semantic">;
|
|
14
|
+
notes?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface SchemaBlockItem {
|
|
17
|
+
id: string;
|
|
18
|
+
semanticId: string;
|
|
19
|
+
lifecycle: SchemaLifecycle;
|
|
20
|
+
name: string;
|
|
21
|
+
description: string;
|
|
22
|
+
attributeIds: string[];
|
|
23
|
+
}
|
|
24
|
+
export type KnownSchemaQuantityKind = "length" | "area" | "volume" | "mass" | "time" | "temperature" | "currency" | "ratio" | "density" | "coverage" | "emissions" | "force" | "power" | "voltage" | "current" | "frequency" | "luminous_flux" | "color_temperature" | "count" | "unitless";
|
|
25
|
+
export type SchemaQuantityKind = OpenEnum<KnownSchemaQuantityKind>;
|
|
26
|
+
export interface SchemaAttributeItem {
|
|
27
|
+
id: string;
|
|
28
|
+
semanticId: string;
|
|
29
|
+
lifecycle: SchemaLifecycle;
|
|
30
|
+
name: string;
|
|
31
|
+
description: string;
|
|
32
|
+
valueKind: OpenEnum<"string" | "text" | "integer" | "number" | "boolean" | "enum" | "object" | "reference">;
|
|
33
|
+
quantityKind: SchemaQuantityKind | null;
|
|
34
|
+
canonicalUnitId: string | null;
|
|
35
|
+
acceptedUnitIds: string[];
|
|
36
|
+
valueDictionaryId: string | null;
|
|
37
|
+
defaultSourceRequirementId: string | null;
|
|
38
|
+
externalMappings: SchemaExternalMapping[];
|
|
39
|
+
searchFacet: boolean;
|
|
40
|
+
comparable: boolean;
|
|
41
|
+
usedInBlocks: string[];
|
|
42
|
+
enumValues: string[] | null;
|
|
43
|
+
}
|
|
44
|
+
export interface SchemaVerticalItem {
|
|
45
|
+
id: string;
|
|
46
|
+
displayName: string;
|
|
47
|
+
description: string;
|
|
48
|
+
}
|
|
49
|
+
export type SchemaApplicability = OpenEnum<"required" | "recommended" | "optional" | "unusual">;
|
|
50
|
+
export interface SchemaProductTypeBlock {
|
|
51
|
+
blockId: string;
|
|
52
|
+
applicability: SchemaApplicability;
|
|
53
|
+
requiredAttributes?: string[];
|
|
54
|
+
optionalAttributes?: string[];
|
|
55
|
+
sourceRequirementId?: string;
|
|
56
|
+
completenessWeight?: number;
|
|
57
|
+
notes?: string;
|
|
58
|
+
optional?: boolean;
|
|
59
|
+
}
|
|
60
|
+
export interface SchemaProductTypeItem {
|
|
61
|
+
id: string;
|
|
62
|
+
name: string;
|
|
63
|
+
description?: string;
|
|
64
|
+
verticalId: string;
|
|
65
|
+
parentProductTypeGroupId?: string;
|
|
66
|
+
blocks: SchemaProductTypeBlock[];
|
|
67
|
+
productTypeSpecificAttributes?: string[];
|
|
68
|
+
semanticId: string;
|
|
69
|
+
lifecycle: SchemaLifecycle;
|
|
70
|
+
}
|
|
71
|
+
export interface SchemaUnitItem {
|
|
72
|
+
id: string;
|
|
73
|
+
name: string;
|
|
74
|
+
symbol: string;
|
|
75
|
+
quantityKind: SchemaQuantityKind;
|
|
76
|
+
acceptedSourceUnits?: string[];
|
|
77
|
+
conversionToCanonical?: {
|
|
78
|
+
factor: number;
|
|
79
|
+
offset?: number;
|
|
80
|
+
};
|
|
81
|
+
notes?: string;
|
|
82
|
+
semanticId: string;
|
|
83
|
+
lifecycle: SchemaLifecycle;
|
|
84
|
+
}
|
|
85
|
+
export interface SchemaValueDictionaryTerm {
|
|
86
|
+
id: string;
|
|
87
|
+
label: string;
|
|
88
|
+
aliases?: string[];
|
|
89
|
+
broaderTermId?: string;
|
|
90
|
+
externalMappings?: SchemaExternalMapping[];
|
|
91
|
+
semanticId: string;
|
|
92
|
+
lifecycle: SchemaLifecycle;
|
|
93
|
+
}
|
|
94
|
+
export interface SchemaValueDictionaryItem {
|
|
95
|
+
id: string;
|
|
96
|
+
name: string;
|
|
97
|
+
description: string;
|
|
98
|
+
terms: SchemaValueDictionaryTerm[];
|
|
99
|
+
semanticId: string;
|
|
100
|
+
lifecycle: SchemaLifecycle;
|
|
101
|
+
}
|
|
102
|
+
export type KnownSchemaSourceType = "manufacturer_page" | "technical_data_sheet" | "safety_data_sheet" | "test_report" | "certificate" | "image" | "commerce_page" | "catalog_pdf" | "derived_analysis";
|
|
103
|
+
export type SchemaSourceType = OpenEnum<KnownSchemaSourceType>;
|
|
104
|
+
export type KnownSchemaSourceMethod = "manual_review" | "agent_extract" | "pdf_extract" | "image_analysis" | "html_scrape" | "structured_feed" | "calculation";
|
|
105
|
+
export type SchemaSourceMethod = OpenEnum<KnownSchemaSourceMethod>;
|
|
106
|
+
export interface SchemaSourceRequirementItem {
|
|
107
|
+
id: string;
|
|
108
|
+
name: string;
|
|
109
|
+
description: string;
|
|
110
|
+
allowedSourceTypes: SchemaSourceType[];
|
|
111
|
+
allowedMethods: SchemaSourceMethod[];
|
|
112
|
+
minConfidence: number;
|
|
113
|
+
reviewRequired: boolean;
|
|
114
|
+
freshnessDays?: number;
|
|
115
|
+
sourceBasis?: OpenEnum<"declared" | "derived" | "tested">;
|
|
116
|
+
semanticId: string;
|
|
117
|
+
lifecycle: SchemaLifecycle;
|
|
118
|
+
}
|
|
119
|
+
export interface SchemaProductTypeTemplateBlock {
|
|
120
|
+
blockId: string;
|
|
121
|
+
applicability: SchemaApplicability;
|
|
122
|
+
requiredAttributes?: string[];
|
|
123
|
+
optionalAttributes?: string[];
|
|
124
|
+
sourceRequirementId?: string;
|
|
125
|
+
completenessWeight?: number;
|
|
126
|
+
notes?: string;
|
|
127
|
+
}
|
|
128
|
+
export interface SchemaProductTypeTemplateItem {
|
|
129
|
+
id: string;
|
|
130
|
+
name: string;
|
|
131
|
+
productTypeId: string;
|
|
132
|
+
blocks: SchemaProductTypeTemplateBlock[];
|
|
133
|
+
defaultSourceRequirementId?: string;
|
|
134
|
+
notes?: string;
|
|
135
|
+
semanticId: string;
|
|
136
|
+
lifecycle: SchemaLifecycle;
|
|
137
|
+
}
|
|
138
|
+
export interface SchemaMappingItem {
|
|
139
|
+
target: SchemaExternalMapping["target"];
|
|
140
|
+
subjectKind?: OpenEnum<"attribute" | "block" | "product_type" | "template" | "unit" | "value_dictionary" | "value_dictionary_term">;
|
|
141
|
+
subjectId?: string;
|
|
142
|
+
canonicalPath: string;
|
|
143
|
+
targetPath: string;
|
|
144
|
+
mappingType: SchemaExternalMapping["mappingType"];
|
|
145
|
+
notes?: string;
|
|
146
|
+
}
|
|
147
|
+
export interface SchemaResourceItemMap {
|
|
148
|
+
blocks: SchemaBlockItem;
|
|
149
|
+
attributes: SchemaAttributeItem;
|
|
150
|
+
verticals: SchemaVerticalItem;
|
|
151
|
+
productTypes: SchemaProductTypeItem;
|
|
152
|
+
units: SchemaUnitItem;
|
|
153
|
+
valueDictionaries: SchemaValueDictionaryItem;
|
|
154
|
+
sourceRequirements: SchemaSourceRequirementItem;
|
|
155
|
+
productTypeTemplates: SchemaProductTypeTemplateItem;
|
|
156
|
+
mappings: SchemaMappingItem;
|
|
157
|
+
}
|
|
158
|
+
export interface SchemaResourceResponse<K extends SchemaResource = SchemaResource> {
|
|
159
|
+
kind: K;
|
|
160
|
+
schemaVersion: string;
|
|
161
|
+
items: SchemaResourceItemMap[K][];
|
|
162
|
+
totalCount: number;
|
|
163
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Types for structured refinements returned by MaterialGraph search. */
|
|
2
|
+
import type { SearchInput } from "./types.js";
|
|
3
|
+
/** A hard canonical-attribute filter accepted by the search engine. */
|
|
4
|
+
export type SearchFilter = {
|
|
5
|
+
attributeId: string;
|
|
6
|
+
term: string;
|
|
7
|
+
} | {
|
|
8
|
+
attributeId: string;
|
|
9
|
+
hasValue: true;
|
|
10
|
+
};
|
|
11
|
+
/** One structured refinement returned with a search response. */
|
|
12
|
+
export interface SearchSuggestion {
|
|
13
|
+
label: string;
|
|
14
|
+
/** Complete replacement request, not a partial patch. */
|
|
15
|
+
request: SearchInput;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|