@instruments/materialgraph 0.13.0 → 0.15.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.
@@ -0,0 +1,18 @@
1
+ import type { CatalogueDocumentAccessResult, CatalogueReferenceBatchResponse } from "./catalogue-types.js";
2
+ import type { HttpTransport } from "./http-transport.js";
3
+ import type { VariantId } from "./identifiers.js";
4
+ /** Catalogue publication operations inherited by the public SDK client. */
5
+ export declare class CatalogueClient {
6
+ #private;
7
+ protected constructor(transport: HttpTransport);
8
+ /**
9
+ * Read exact, verified brand-publication page relationships for variants.
10
+ * Missing evidence stays explicit; this operation never guesses a page from
11
+ * a generic PDF.
12
+ */
13
+ catalogueReferences(input: {
14
+ variantIds: VariantId[];
15
+ }, signal?: AbortSignal): Promise<CatalogueReferenceBatchResponse>;
16
+ /** Resolve browser-safe access to one immutable catalogue document. */
17
+ catalogueDocumentAccess(documentId: string, signal?: AbortSignal): Promise<CatalogueDocumentAccessResult>;
18
+ }
@@ -0,0 +1,20 @@
1
+ import { resolveOperation } from "./operations.js";
2
+ /** Catalogue publication operations inherited by the public SDK client. */
3
+ export class CatalogueClient {
4
+ #transport;
5
+ constructor(transport) {
6
+ this.#transport = transport;
7
+ }
8
+ /**
9
+ * Read exact, verified brand-publication page relationships for variants.
10
+ * Missing evidence stays explicit; this operation never guesses a page from
11
+ * a generic PDF.
12
+ */
13
+ catalogueReferences(input, signal) {
14
+ return this.#transport.requestJson(resolveOperation("get_catalogue_references_batch"), { body: input, signal });
15
+ }
16
+ /** Resolve browser-safe access to one immutable catalogue document. */
17
+ catalogueDocumentAccess(documentId, signal) {
18
+ return this.#transport.requestJson(resolveOperation("get_catalogue_document_access"), { pathParams: { documentId }, signal });
19
+ }
20
+ }
@@ -0,0 +1,65 @@
1
+ /** A verified product location in a specific immutable brand publication. */
2
+ export interface CatalogueReference {
3
+ variantId: string;
4
+ brand: {
5
+ id: string;
6
+ name: string;
7
+ };
8
+ catalogue: {
9
+ id: string;
10
+ title: string;
11
+ };
12
+ edition: {
13
+ id: string;
14
+ label: string;
15
+ title?: string;
16
+ };
17
+ document: {
18
+ id: string;
19
+ mediaType: "application/pdf";
20
+ };
21
+ page: {
22
+ documentPage: number;
23
+ printedPageLabel?: string;
24
+ pageCount?: number;
25
+ };
26
+ source: {
27
+ brandItemCode: string;
28
+ };
29
+ status: "verified";
30
+ isPrimary: true;
31
+ }
32
+ export type CatalogueReferenceResult = {
33
+ variantId: string;
34
+ status: "verified";
35
+ reference: CatalogueReference;
36
+ } | {
37
+ variantId: string;
38
+ status: "no_verified_reference" | "unresolved_variant" | "unavailable" | "upstream_failure";
39
+ };
40
+ export interface CatalogueReferenceBatchResponse {
41
+ results: CatalogueReferenceResult[];
42
+ coverage: {
43
+ requested: number;
44
+ verified: number;
45
+ noVerifiedReference: number;
46
+ unresolvedVariant: number;
47
+ unavailable: number;
48
+ upstreamFailure: number;
49
+ };
50
+ }
51
+ export interface CatalogueDocumentAccess {
52
+ documentId: string;
53
+ contentType: "application/pdf";
54
+ readerUrl: string;
55
+ originalUrl: string;
56
+ byteRanges: "supported" | "unknown";
57
+ }
58
+ export type CatalogueDocumentAccessResult = {
59
+ documentId: string;
60
+ status: "available";
61
+ access: CatalogueDocumentAccess;
62
+ } | {
63
+ documentId: string;
64
+ status: "unresolved_document" | "unavailable" | "forbidden" | "upstream_failure";
65
+ };
@@ -0,0 +1 @@
1
+ export {};
package/client.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { CatalogueClient } from "./catalogue-client.js";
1
2
  import type { MaterialGraphClientOptions } from "./client-config.js";
2
3
  import { type RateLimit } from "./errors.js";
3
4
  export * from "./client-config.js";
@@ -8,7 +9,7 @@ export type { ExplorationNamespace } from "./client-exploration.js";
8
9
  import { type SourceMaterialCommentsNamespace } from "./client-source-material-comments.js";
9
10
  export type { SourceMaterialCommentsNamespace } from "./client-source-material-comments.js";
10
11
  import type { AssociatedOptions } from "./association-types.js";
11
- import type { BrandCatalogListPage, BrandsOptions } from "./brand-types.js";
12
+ import type { BrandsOptions } from "./brand-types.js";
12
13
  import type { ByColourParams, ByColourResponse } from "./by-colour-types.js";
13
14
  import { CodesClient } from "./codes-client.js";
14
15
  import type { CodeAdvisoryInput, CodeAdvisoryResponse } from "./codes-types.js";
@@ -26,7 +27,7 @@ import type { CapabilityManifestResponse, CreatePublicRunRequest, CreatePublicRu
26
27
  import type { FinishScheduleResponse, GetRunScheduleOptions } from "./schedule-types.js";
27
28
  import type { SchemaResource, SchemaResourceResponse } from "./schema-resource-types.js";
28
29
  import type { SlotPoolsRequest, SlotPoolsResponse } from "./slot-pool-types.js";
29
- import type { ApplicableSpecsResponse, BrandOptions, BrandProfileResponse, BySpecOptions, BySpecResponse, ColourFacetsResponse, CoordinateInput, CoordinateResponse, DemandBatchInput, DemandBatchResponse, DemandParams, DemandResponse, ExtractPaletteInput, ExtractPaletteResponse, GlossaryTermResponse, MaterialResponse, MaterialsBatchDetailResponse, MaterialsBatchGetOptions, MaterialsBatchOptions, MaterialsBatchTileResponse, PairingsOptions, PairingsResponse, ResolveAttributeOptions, ResolveAttributeResponse, ResolveAttributeValueOptions, ResolveAttributeValueResponse, ResolveColourResponse, SearchGetParams, SearchInput, SearchResponse, SiblingsResponse, SpecFacetsDistributionResponse, SpecFacetsListResponse, SuggestColourResponse, SuggestOptions, SuggestResponse, TaxonomyResponse, VocabularySearchOptions, WhoamiResponse } from "./types.js";
30
+ import type { ApplicableSpecsResponse, BrandOptions, BySpecOptions, BySpecResponse, ColourFacetsResponse, CoordinateInput, CoordinateResponse, DemandBatchInput, DemandBatchResponse, DemandParams, DemandResponse, ExtractPaletteInput, ExtractPaletteResponse, GlossaryTermResponse, MaterialResponse, MaterialsBatchDetailResponse, MaterialsBatchGetOptions, MaterialsBatchOptions, MaterialsBatchTileResponse, PairingsOptions, PairingsResponse, ResolveAttributeOptions, ResolveAttributeResponse, ResolveAttributeValueOptions, ResolveAttributeValueResponse, ResolveColourResponse, SearchGetParams, SearchInput, SearchResponse, SiblingsResponse, SpecFacetsDistributionResponse, SpecFacetsListResponse, SuggestColourResponse, SuggestOptions, SuggestResponse, TaxonomyResponse, VocabularySearchOptions, WhoamiResponse } from "./types.js";
30
31
  /**
31
32
  * The MaterialGraph client — every lens on the graph, on one object.
32
33
  *
@@ -59,11 +60,10 @@ import type { ApplicableSpecsResponse, BrandOptions, BrandProfileResponse, BySpe
59
60
  * `pairings()` returns companionship the graph INFERRED. The response shapes
60
61
  * share no field, on purpose — render them as separate sections and never
61
62
  * concatenate them.
62
- *
63
63
  * And three reading rules that apply to every lens: ids are opaque (see
64
64
  * `./identifiers.ts`), absent is not false, and a page is not a corpus.
65
65
  */
66
- export declare class MaterialGraphClient {
66
+ export declare class MaterialGraphClient extends CatalogueClient {
67
67
  #private;
68
68
  readonly baseUrl: string;
69
69
  /**
@@ -483,9 +483,9 @@ export declare class MaterialGraphClient {
483
483
  */
484
484
  glossary(term: string, signal?: AbortSignal): Promise<GlossaryTermResponse>;
485
485
  /** "Whose catalogs are in here, and how big is each?" — {@link listBrands}. */
486
- brands(options?: BrandsOptions, signal?: AbortSignal): Promise<BrandCatalogListPage>;
486
+ brands(options?: BrandsOptions, signal?: AbortSignal): Promise<import("./brand-types.js").BrandCatalogListPage>;
487
487
  /** "Who is this brand, and what do they claim?" — {@link brandProfile}. */
488
- brand(brandSlug: string, options?: BrandOptions, signal?: AbortSignal): Promise<BrandProfileResponse>;
488
+ brand(brandSlug: string, options?: BrandOptions, signal?: AbortSignal): Promise<import("./types.js").BrandProfileResponse>;
489
489
  /** "This maker's whole range, the way a fan deck reads" — {@link brandColourDeck}. */
490
490
  brandColourDeck(brandSlug: string, signal?: AbortSignal): Promise<import("./fan-deck-types.js").BrandFanDeck>;
491
491
  /**
package/client.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { CatalogueClient } from "./catalogue-client.js";
1
2
  import { DEFAULT_BASE_URL, MAX_BATCH_IDS } from "./client-config.js";
2
3
  import { MaterialGraphError } from "./errors.js";
3
4
  import { HttpTransport } from "./http-transport.js";
@@ -52,11 +53,10 @@ import { suggestQuery } from "./suggest-types.js";
52
53
  * `pairings()` returns companionship the graph INFERRED. The response shapes
53
54
  * share no field, on purpose — render them as separate sections and never
54
55
  * concatenate them.
55
- *
56
56
  * And three reading rules that apply to every lens: ids are opaque (see
57
57
  * `./identifiers.ts`), absent is not false, and a page is not a corpus.
58
58
  */
59
- export class MaterialGraphClient {
59
+ export class MaterialGraphClient extends CatalogueClient {
60
60
  baseUrl;
61
61
  /**
62
62
  * THE QUESTION: "show me everything in this category / this brand, in a plain
@@ -112,12 +112,14 @@ export class MaterialGraphClient {
112
112
  if (!options.apiKey) {
113
113
  throw MaterialGraphError.unexpected("MaterialGraphClient: `apiKey` is required.");
114
114
  }
115
- this.#transport = new HttpTransport({
115
+ const transport = new HttpTransport({
116
116
  apiKey: options.apiKey,
117
117
  baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
118
118
  fetch: options.fetch ?? globalThis.fetch,
119
119
  });
120
- this.baseUrl = this.#transport.baseUrl;
120
+ super(transport);
121
+ this.#transport = transport;
122
+ this.baseUrl = transport.baseUrl;
121
123
  this.browse = createBrowseNamespace((params, signal) => this.#get("search_browse_by_colour", browseQuery(params), signal));
122
124
  this.codes = new CodesClient({
123
125
  get: (operationId, query, signal) => this.#get(operationId, query, signal),
package/index.d.ts CHANGED
@@ -19,6 +19,7 @@ export type { MaterialGraphErrorInit, MaterialGraphErrorKind, MaterialGraphReque
19
19
  export type * from "./types.js";
20
20
  export type * from "./match-types.js";
21
21
  export type * from "./browse-types.js";
22
+ export type * from "./catalogue-types.js";
22
23
  export type * from "./by-colour-types.js";
23
24
  export { MATCH_IMAGE_TYPES, MATCH_OUTCOMES, MATCH_MATERIAL_FUNCTIONS, MATCH_STREAM_EVENT_TYPES, MATCH_SURFACE_STATUSES, MATCH_WORKFLOW_STEPS, } from "./match-stream-types.js";
24
25
  export type * from "./match-stream-types.js";
@@ -120,6 +120,16 @@ export interface MaterialDetail extends MaterialTile {
120
120
  color: string | null;
121
121
  /** Material Bank's own opaque id, when one is mapped. Null = unmapped, not absent. */
122
122
  materialBankId: string | null;
123
+ /**
124
+ * Explicit source-governed permission to save this exact source-coded variant
125
+ * to a Project. Absent means unknown/not allowed; never infer it from identity.
126
+ */
127
+ projectSaveCapability?: "allowed";
128
+ /**
129
+ * The governed source status behind Project capture. Provisional remains
130
+ * source-backed, but is not a verified catalogue claim.
131
+ */
132
+ sourceStatus?: "provisional";
123
133
  installationImageUrl: string | null;
124
134
  displayCategory: string | null;
125
135
  categoryPath: string[];
package/operations.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export declare const MATERIALGRAPH_API_VERSION = "0.7.0";
2
- declare const OPERATION_DEFINITIONS: readonly [readonly ["search", "POST", "/api/v1/search", "search_materials_post"], readonly ["planQuery", "POST", "/api/v1/search/plan", "plan_material_query"], 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 ["exploration.operators", "GET", "/api/v1/materials/{variantId}/operators", "list_material_operators"], readonly ["exploration.candidates", "POST", "/api/v1/materials/{variantId}/candidates", "read_material_candidates"], 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 ["associatedFinishes", "GET", "/api/v1/associated/finishes", "list_associated_finishes"], readonly ["associatedProducts", "GET", "/api/v1/associated/products", "list_associated_products"], 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 ["colours.profiles", "GET", "/api/v1/colours/profiles", "get_category_colour_profiles"], readonly ["colours.stats", "GET", "/api/v1/colours/stats", "get_colour_stats"], readonly ["resolveColour", "GET", "/api/v1/search/colours/resolve", "resolve_colour_name"], readonly ["suggestColour", "GET", "/api/v1/search/colours/suggest", "suggest_colour_names"], readonly ["suggest", "GET", "/api/v1/search/suggest", "search_suggest"], 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 ["resolve", "POST", "/api/v1/resolve", "resolve_phrases"], 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 ["colours.palette", "POST", "/api/v1/search/palettes", "search_by_palette"], readonly ["extractPalette", "POST", "/api/v1/search/palettes/extract", "extract_image_palette"], readonly ["colours.gradient", "POST", "/api/v1/search/gradients", "search_by_gradient"], 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/{brandSlug}", "get_brand_profile"], readonly ["brandColourDeck", "GET", "/api/v1/brands/{brandSlug}/colours", "brand_colour_deck"], readonly ["uploadSourceMaterial", "POST", "/api/v1/source-material", "upload_source_material"], readonly ["sourceMaterialBatch", "GET", "/api/v1/source-material/{batchId}", "get_source_material_batch"], readonly ["sourceMaterialComments", "GET", "/api/v1/source-material/{batchId}/sources/{sourceId}/comments", "list_source_material_comments"], readonly ["sourceMaterialComments", "POST", "/api/v1/source-material/{batchId}/sources/{sourceId}/comments", "post_source_material_comment"], readonly ["capabilities", "GET", "/api/v1/capabilities", "list_public_capabilities"], readonly ["createRun", "POST", "/api/v1/runs", "create_public_run"], readonly ["listRuns", "GET", "/api/v1/runs", "list_public_runs"], readonly ["run", "GET", "/api/v1/runs/{runId}", "get_public_run"], readonly ["runSchedule", "GET", "/api/v1/runs/{runId}/schedule", "get_run_finish_schedule"], readonly ["streamRunEvents", "GET", "/api/v1/runs/{runId}/events", "list_public_run_events"], readonly ["resumeRun", "POST", "/api/v1/runs/{runId}/resume", "resume_public_run"], readonly ["cancelRun", "POST", "/api/v1/runs/{runId}/cancel", "cancel_public_run"], readonly ["varyScheme", "POST", "/api/v1/schemes/vary", "vary_schemes"], readonly ["slotPools", "POST", "/api/v1/schemes/pools", "slot_pools"], readonly ["createProject", "POST", "/api/v1/projects", "create_box_project"], readonly ["listProjects", "GET", "/api/v1/projects", "list_box_projects"], readonly ["getProject", "GET", "/api/v1/projects/{projectId}", "get_box_project"], readonly ["appendProjectEvent", "POST", "/api/v1/projects/{projectId}/events", "append_box_project_event"], readonly ["demandBatch", "POST", "/api/v1/demand/batch", "get_demand_batch"], readonly ["codeAdvisory", "POST", "/api/v1/codes/advisory", "resolveCodeAdvisory"], readonly ["codes.context", "GET", "/api/v1/codes/context", "list_code_context"], readonly ["codes.requirements", "GET", "/api/v1/codes/requirements", "list_code_requirements"]];
2
+ declare const OPERATION_DEFINITIONS: readonly [readonly ["search", "POST", "/api/v1/search", "search_materials_post"], readonly ["planQuery", "POST", "/api/v1/search/plan", "plan_material_query"], 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 ["catalogueReferences", "POST", "/api/v1/catalogues/references", "get_catalogue_references_batch"], readonly ["catalogueDocumentAccess", "GET", "/api/v1/catalogues/documents/{documentId}", "get_catalogue_document_access"], 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 ["exploration.operators", "GET", "/api/v1/materials/{variantId}/operators", "list_material_operators"], readonly ["exploration.candidates", "POST", "/api/v1/materials/{variantId}/candidates", "read_material_candidates"], 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 ["associatedFinishes", "GET", "/api/v1/associated/finishes", "list_associated_finishes"], readonly ["associatedProducts", "GET", "/api/v1/associated/products", "list_associated_products"], 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 ["colours.profiles", "GET", "/api/v1/colours/profiles", "get_category_colour_profiles"], readonly ["colours.stats", "GET", "/api/v1/colours/stats", "get_colour_stats"], readonly ["resolveColour", "GET", "/api/v1/search/colours/resolve", "resolve_colour_name"], readonly ["suggestColour", "GET", "/api/v1/search/colours/suggest", "suggest_colour_names"], readonly ["suggest", "GET", "/api/v1/search/suggest", "search_suggest"], 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 ["resolve", "POST", "/api/v1/resolve", "resolve_phrases"], 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 ["colours.palette", "POST", "/api/v1/search/palettes", "search_by_palette"], readonly ["extractPalette", "POST", "/api/v1/search/palettes/extract", "extract_image_palette"], readonly ["colours.gradient", "POST", "/api/v1/search/gradients", "search_by_gradient"], 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/{brandSlug}", "get_brand_profile"], readonly ["brandColourDeck", "GET", "/api/v1/brands/{brandSlug}/colours", "brand_colour_deck"], readonly ["uploadSourceMaterial", "POST", "/api/v1/source-material", "upload_source_material"], readonly ["sourceMaterialBatch", "GET", "/api/v1/source-material/{batchId}", "get_source_material_batch"], readonly ["sourceMaterialComments", "GET", "/api/v1/source-material/{batchId}/sources/{sourceId}/comments", "list_source_material_comments"], readonly ["sourceMaterialComments", "POST", "/api/v1/source-material/{batchId}/sources/{sourceId}/comments", "post_source_material_comment"], readonly ["capabilities", "GET", "/api/v1/capabilities", "list_public_capabilities"], readonly ["createRun", "POST", "/api/v1/runs", "create_public_run"], readonly ["listRuns", "GET", "/api/v1/runs", "list_public_runs"], readonly ["run", "GET", "/api/v1/runs/{runId}", "get_public_run"], readonly ["runSchedule", "GET", "/api/v1/runs/{runId}/schedule", "get_run_finish_schedule"], readonly ["streamRunEvents", "GET", "/api/v1/runs/{runId}/events", "list_public_run_events"], readonly ["resumeRun", "POST", "/api/v1/runs/{runId}/resume", "resume_public_run"], readonly ["cancelRun", "POST", "/api/v1/runs/{runId}/cancel", "cancel_public_run"], readonly ["varyScheme", "POST", "/api/v1/schemes/vary", "vary_schemes"], readonly ["slotPools", "POST", "/api/v1/schemes/pools", "slot_pools"], readonly ["createProject", "POST", "/api/v1/projects", "create_box_project"], readonly ["listProjects", "GET", "/api/v1/projects", "list_box_projects"], readonly ["getProject", "GET", "/api/v1/projects/{projectId}", "get_box_project"], readonly ["appendProjectEvent", "POST", "/api/v1/projects/{projectId}/events", "append_box_project_event"], readonly ["demandBatch", "POST", "/api/v1/demand/batch", "get_demand_batch"], readonly ["codeAdvisory", "POST", "/api/v1/codes/advisory", "resolveCodeAdvisory"], readonly ["codes.context", "GET", "/api/v1/codes/context", "list_code_context"], readonly ["codes.requirements", "GET", "/api/v1/codes/requirements", "list_code_requirements"]];
3
3
  export type SdkOperationId = (typeof OPERATION_DEFINITIONS)[number][3];
4
4
  export type SdkOperation = Readonly<{
5
5
  clientMethod: (typeof OPERATION_DEFINITIONS)[number][0];
package/operations.js CHANGED
@@ -7,6 +7,18 @@ const OPERATION_DEFINITIONS = [
7
7
  ["match", "POST", "/api/v1/search/match", "match_material"],
8
8
  ["byColour", "GET", "/api/v1/search/colours", "search_by_colour"],
9
9
  ["material", "GET", "/api/v1/materials/{variantId}", "get_material"],
10
+ [
11
+ "catalogueReferences",
12
+ "POST",
13
+ "/api/v1/catalogues/references",
14
+ "get_catalogue_references_batch",
15
+ ],
16
+ [
17
+ "catalogueDocumentAccess",
18
+ "GET",
19
+ "/api/v1/catalogues/documents/{documentId}",
20
+ "get_catalogue_document_access",
21
+ ],
10
22
  [
11
23
  "siblings",
12
24
  "GET",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instruments/materialgraph",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -162,6 +162,13 @@ export function checkSearchResultItem(value, what, fail) {
162
162
  // `z.string().optional()` — absent, or a string. NOT nullable: the emit path
163
163
  // omits the key rather than sending null when no MB identity is known.
164
164
  requireOptionalString(record.materialBankId, `${what}.materialBankId`, fail);
165
+ requireOptionalString(record.manufacturerCode, `${what}.manufacturerCode`, fail);
166
+ if (record.projectSaveCapability !== undefined) {
167
+ requireEnum(record.projectSaveCapability, ["allowed"], `${what}.projectSaveCapability`, fail);
168
+ }
169
+ if (record.sourceStatus !== undefined) {
170
+ requireEnum(record.sourceStatus, ["provisional"], `${what}.sourceStatus`, fail);
171
+ }
165
172
  // Same shape as `materialBankId`: absent, or a string. The emit path omits
166
173
  // the key when no primary product type is on record rather than sending null,
167
174
  // so "we don't know what this is" and "this is a null kind of thing" cannot
package/types.d.ts CHANGED
@@ -131,19 +131,19 @@ export interface SearchResultItem {
131
131
  brandSlug: string | null;
132
132
  productId: ProductId | null;
133
133
  /**
134
- * The variant's Material Bank SKU — the ONE EXTERNAL identifier on a result,
135
- * in deliberate contrast to the opaque `variantId` above. `variantId` is ours
136
- * and means nothing anywhere else; this is the id you are expected to match
134
+ * The variant's Material Bank SKU, unlike our opaque `variantId`; this is the
135
+ * id you are expected to match
137
136
  * against Material Bank's own catalogue, so a result list can be joined to a
138
137
  * cart, an order or an analytics event without a per-result lookup.
139
- *
140
138
  * Populated on EVERY lane: `search()` (all four arms), `match()`, and
141
139
  * `matchStream()` frames.
142
- *
143
140
  * ABSENT means no MB identity is known for the variant — never that the SKU
144
141
  * cannot be ordered. Presence is the orderability tell; absence is silence.
145
142
  */
146
143
  materialBankId?: string;
144
+ manufacturerCode?: string;
145
+ projectSaveCapability?: "allowed";
146
+ sourceStatus?: "provisional";
147
147
  /**
148
148
  * What kind of material this is — the variant's primary product type, as a
149
149
  * display name (`"Wall Tile"`, `"Modular Carpet"`, `"Interior Paint"`).
@@ -286,6 +286,8 @@ export interface SearchCardItem {
286
286
  name: string;
287
287
  variantName: string | null;
288
288
  imageUrl: string | null;
289
+ projectSaveCapability?: "allowed";
290
+ sourceStatus?: "provisional";
289
291
  score: number;
290
292
  /**
291
293
  * Resolved values for the attribute ids sent in `returnAttributes`, keyed by