@instruments/materialgraph 0.29.0 → 0.31.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/brands-client.d.ts +1 -1
- package/by-colour-types.d.ts +4 -4
- package/catalogue-client.d.ts +3 -3
- package/catalogue-client.js +3 -3
- package/catalogue-types.d.ts +1 -1
- package/client-vocabulary.d.ts +3 -5
- package/client-vocabulary.js +9 -6
- package/client.d.ts +85 -174
- package/client.js +98 -211
- package/colour-region-types.d.ts +18 -0
- package/colours-client.d.ts +10 -83
- package/colours-client.js +1 -85
- package/errors.d.ts +1 -1
- package/errors.js +1 -0
- package/find-companions-types.d.ts +70 -0
- package/find-companions-types.js +12 -0
- package/find-variants-by-colour-types.d.ts +197 -0
- package/find-variants-by-vector-types.d.ts +67 -0
- package/find-variants-by-vector-types.js +5 -0
- package/get-variant-types.d.ts +50 -0
- package/get-variant-types.js +10 -0
- package/http-transport.d.ts +1 -1
- package/identifiers.d.ts +1 -1
- package/identifiers.js +1 -1
- package/image-reference-types.d.ts +18 -0
- package/index.d.ts +9 -7
- package/index.js +1 -1
- package/list-enum-values-types.d.ts +58 -0
- package/list-variants-types.d.ts +6 -2
- package/material-asset-types.d.ts +2 -2
- package/material-types.d.ts +13 -151
- package/operations.d.ts +1 -1
- package/operations.js +27 -88
- package/package.json +1 -1
- package/palette-search-types.d.ts +3 -49
- package/resolve-colour-types.d.ts +5 -5
- package/resolve-variant-types.d.ts +75 -0
- package/{identify-types.js → resolve-variant-types.js} +2 -2
- package/response-schemas.generated.d.ts +1 -1
- package/response-schemas.generated.js +46 -84
- package/run-types.d.ts +23 -216
- package/runs.d.ts +10 -58
- package/runs.js +19 -106
- package/schema-resource-types.d.ts +2 -139
- package/schema-resource-types.js +0 -8
- package/search-card-types.d.ts +1 -1
- package/search-index-plan-types.d.ts +6 -2
- package/search-request-types.d.ts +10 -2
- package/spec-types.d.ts +4 -4
- package/spec-types.js +2 -2
- package/specifications.d.ts +1 -9
- package/specifications.js +0 -12
- package/sse.d.ts +2 -2
- package/sse.js +2 -2
- package/types.d.ts +4 -38
- package/validation.d.ts +0 -74
- package/validation.js +2 -116
- package/webmcp.generated.js +9 -9
- package/workflows-client.d.ts +54 -0
- package/workflows-client.js +41 -0
- package/client-source-material-comments.d.ts +0 -51
- package/client-source-material-comments.js +0 -6
- package/codes-client.d.ts +0 -118
- package/codes-client.js +0 -99
- package/codes-types.d.ts +0 -325
- package/colour-aggregate-types.d.ts +0 -163
- package/coordinate-client.d.ts +0 -23
- package/coordinate-client.js +0 -13
- package/demand-batch-types.d.ts +0 -118
- package/demand-types.d.ts +0 -154
- package/identify-types.d.ts +0 -82
- package/material-composition-client.d.ts +0 -21
- package/material-composition-client.js +0 -13
- package/material-composition-types.d.ts +0 -403
- package/material-composition-types.js +0 -1
- package/source-material-validation.d.ts +0 -7
- package/source-material-validation.js +0 -214
- package/spec-facet-types.d.ts +0 -48
- package/spec-facet-types.js +0 -7
- package/substitute-types.d.ts +0 -102
- package/substitute-types.js +0 -1
- package/suggest-types.d.ts +0 -67
- package/suggest-types.js +0 -28
- package/taxonomy-coverage-types.d.ts +0 -34
- package/taxonomy-coverage-types.js +0 -1
- /package/{codes-types.js → colour-region-types.js} +0 -0
- /package/{colour-aggregate-types.js → find-variants-by-colour-types.js} +0 -0
- /package/{demand-batch-types.js → image-reference-types.js} +0 -0
- /package/{demand-types.js → list-enum-values-types.js} +0 -0
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wire types for the colour AGGREGATE surface — `GET /api/v1/colours/profiles`
|
|
3
|
-
* and `GET /api/v1/colours/stats`.
|
|
4
|
-
*
|
|
5
|
-
* Kept out of `types.ts` for the same reason `material-types.ts` and
|
|
6
|
-
* `codes-types.ts` are: the shared mirror is at its source-size budget. Same
|
|
7
|
-
* tolerant-parsing contract as the rest of the mirror — response enums are
|
|
8
|
-
* widened so a new server value still type-checks.
|
|
9
|
-
*/
|
|
10
|
-
import type { OpenEnum } from "./types.js";
|
|
11
|
-
/**
|
|
12
|
-
* Which taxonomy tier a colour profile's `categoryKey` names — or `"merged"`,
|
|
13
|
-
* where the key is a composite over a caller-defined key set rather than a
|
|
14
|
-
* taxonomy node.
|
|
15
|
-
*/
|
|
16
|
-
export type CategoryTier = OpenEnum<"group" | "type" | "merged">;
|
|
17
|
-
/** How the endpoint picks which colours to keep. */
|
|
18
|
-
export type ColourProfileSelect = OpenEnum<"frequency" | "diverse">;
|
|
19
|
-
/** One representative colour bucket of a category. */
|
|
20
|
-
export type CategoryColour = {
|
|
21
|
-
hex: string;
|
|
22
|
-
oklab: {
|
|
23
|
-
l: number;
|
|
24
|
-
a: number;
|
|
25
|
-
b: number;
|
|
26
|
-
};
|
|
27
|
-
variantCount: number;
|
|
28
|
-
/** This bucket's share of the category's coloured variants, 0–1. */
|
|
29
|
-
proportion: number;
|
|
30
|
-
};
|
|
31
|
-
export type CategoryColourProfile = {
|
|
32
|
-
categoryKey: string;
|
|
33
|
-
level: CategoryTier;
|
|
34
|
-
name: string;
|
|
35
|
-
path: string;
|
|
36
|
-
/**
|
|
37
|
-
* Under `groupBy: "merged"`, the requested keys in composite-key order, so
|
|
38
|
-
* `categoryKey` never has to be split. Absent on a single-category profile.
|
|
39
|
-
*/
|
|
40
|
-
members?: string[];
|
|
41
|
-
variantCount: number;
|
|
42
|
-
avgLightness: number;
|
|
43
|
-
avgChroma: number;
|
|
44
|
-
colours: CategoryColour[];
|
|
45
|
-
};
|
|
46
|
-
/**
|
|
47
|
-
* The snapshot a profile response was computed from. Compare `variantCount`
|
|
48
|
-
* against `colours/stats`' `corpus.withColour` to see how complete the
|
|
49
|
-
* underlying materialized view currently is, and `refreshedAt` for its age.
|
|
50
|
-
*/
|
|
51
|
-
export type CategoryColourProfilesBasis = {
|
|
52
|
-
variantCount: number;
|
|
53
|
-
refreshedAt: string | null;
|
|
54
|
-
};
|
|
55
|
-
export type CategoryColourProfilesResponse = {
|
|
56
|
-
profiles: CategoryColourProfile[];
|
|
57
|
-
basis: CategoryColourProfilesBasis;
|
|
58
|
-
};
|
|
59
|
-
/** Request parameters for `colours.profiles()`. */
|
|
60
|
-
export type ColourProfilesParams = {
|
|
61
|
-
/** 1–8 category keys, at the tier named by `groupBy`. */
|
|
62
|
-
productTypeIds: readonly string[];
|
|
63
|
-
/**
|
|
64
|
-
* `"group"` merges each group's leaf product types into one palette;
|
|
65
|
-
* `"merged"` merges EVERY key's leaves into a single combined palette.
|
|
66
|
-
*/
|
|
67
|
-
groupBy?: "group" | "type" | "merged";
|
|
68
|
-
/** Representative colours per category, 1–64. */
|
|
69
|
-
topN?: number;
|
|
70
|
-
/** `"diverse"` maximises visual distinctness instead of frequency. */
|
|
71
|
-
select?: "frequency" | "diverse";
|
|
72
|
-
};
|
|
73
|
-
export type ColourStatsCorpus = {
|
|
74
|
-
variants: number;
|
|
75
|
-
withColour: number;
|
|
76
|
-
/** `withColour / variants`, 0–1. */
|
|
77
|
-
coverage: number;
|
|
78
|
-
};
|
|
79
|
-
export type ColourStatsFamily = {
|
|
80
|
-
id: string;
|
|
81
|
-
label: string;
|
|
82
|
-
variants: number;
|
|
83
|
-
brands: number;
|
|
84
|
-
};
|
|
85
|
-
export type ColourStatsGroup = {
|
|
86
|
-
key: string;
|
|
87
|
-
name: string;
|
|
88
|
-
productTypes: number;
|
|
89
|
-
variants: number;
|
|
90
|
-
};
|
|
91
|
-
/**
|
|
92
|
-
* One cell of the brand x category x colour-family matrix — the shape that
|
|
93
|
-
* answers questions no single dimension can, such as "how many whites does
|
|
94
|
-
* Benjamin Moore offer in paint".
|
|
95
|
-
*/
|
|
96
|
-
export type ColourStatsRow = {
|
|
97
|
-
/** Opaque brand id — the join key for brand reads. Never parse it. */
|
|
98
|
-
brandId: string;
|
|
99
|
-
brandSlug: string;
|
|
100
|
-
brandName: string;
|
|
101
|
-
/**
|
|
102
|
-
* Product-type key. NULL means these variants carry NO accepted primary
|
|
103
|
-
* product type — a real population, kept so the matrix sums to the corpus,
|
|
104
|
-
* not an error and not a residual bucket.
|
|
105
|
-
*/
|
|
106
|
-
categoryKey: string | null;
|
|
107
|
-
family: string;
|
|
108
|
-
/**
|
|
109
|
-
* Distinct variants at this (brand, category, family) carrying an ACCEPTED
|
|
110
|
-
* `colour_family`. Not every variant of the brand.
|
|
111
|
-
*/
|
|
112
|
-
variants: number;
|
|
113
|
-
};
|
|
114
|
-
/** How to narrow the matrix. Passing ANY of these asks for `rows`. */
|
|
115
|
-
export type ColourStatsParams = {
|
|
116
|
-
/** `"brand,category"` — ask for the whole matrix, unscoped. */
|
|
117
|
-
groupBy?: string;
|
|
118
|
-
brandId?: string;
|
|
119
|
-
brandSlug?: string;
|
|
120
|
-
/**
|
|
121
|
-
* A product-type key, or the literal `"null"` for the unclassified
|
|
122
|
-
* population. Omitting it means every category — a different question.
|
|
123
|
-
*/
|
|
124
|
-
categoryKey?: string;
|
|
125
|
-
family?: string;
|
|
126
|
-
limit?: number;
|
|
127
|
-
};
|
|
128
|
-
/** Where each section came from, how fresh it is, and what it does NOT answer. */
|
|
129
|
-
export type ColourStatsBasis = {
|
|
130
|
-
corpus: string;
|
|
131
|
-
families: string;
|
|
132
|
-
groups: string;
|
|
133
|
-
groupsRefreshedAt: string | null;
|
|
134
|
-
groupsVariantCount: number;
|
|
135
|
-
/**
|
|
136
|
-
* Where `rows` came from, its freshness, and what it EXCLUDES — present only
|
|
137
|
-
* when `rows` is. Read it: the matrix deliberately omits Samplize, which is a
|
|
138
|
-
* sampling channel printing other manufacturers' colours rather than a maker.
|
|
139
|
-
*/
|
|
140
|
-
rows?: string;
|
|
141
|
-
omissions: string[];
|
|
142
|
-
};
|
|
143
|
-
export type ColourStatsResponse = {
|
|
144
|
-
corpus: ColourStatsCorpus;
|
|
145
|
-
families: ColourStatsFamily[];
|
|
146
|
-
groups: ColourStatsGroup[];
|
|
147
|
-
/**
|
|
148
|
-
* The brand x category x colour-family matrix. Present ONLY when you asked
|
|
149
|
-
* for it; ABSENT means nobody asked, never that the matrix is empty.
|
|
150
|
-
*
|
|
151
|
-
* `families` above is NOT scoped by the same parameters and stays
|
|
152
|
-
* platform-wide under all of them. Scoped counts live here.
|
|
153
|
-
*/
|
|
154
|
-
rows?: ColourStatsRow[];
|
|
155
|
-
/**
|
|
156
|
-
* Rows matching your query BEFORE the response cap — the honest total.
|
|
157
|
-
* A shortfall against `rows.length` means `rows` is a prefix.
|
|
158
|
-
*/
|
|
159
|
-
rowsMatched?: number;
|
|
160
|
-
/** TRUE when the matrix exceeded the cap and `rows` is a prefix. */
|
|
161
|
-
rowsTruncated?: boolean;
|
|
162
|
-
basis: ColourStatsBasis;
|
|
163
|
-
};
|
package/coordinate-client.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The COORDINATION lens: given several materials already chosen, what completes
|
|
3
|
-
* them. A thin wrapper over the shared {@link HttpTransport};
|
|
4
|
-
* `MaterialGraphClient.coordinate` delegates here.
|
|
5
|
-
*
|
|
6
|
-
* Extracted from `client.ts`, which sits above the repository's source-size
|
|
7
|
-
* limit, in the same per-lens shape as `brands-client` / `codes-client` /
|
|
8
|
-
* `colours-client`. Behaviour is unchanged.
|
|
9
|
-
*/
|
|
10
|
-
import type { HttpTransport } from "./http-transport.js";
|
|
11
|
-
import type { CoordinateInput, CoordinateResponse } from "./types.js";
|
|
12
|
-
/**
|
|
13
|
-
* THE QUESTION: "here is my whole scheme so far — what completes it?" The
|
|
14
|
-
* multi-seed form of `pairings`: lift is SUMMED across seeds, so a companion
|
|
15
|
-
* suiting one pick ranks below one suiting several. Returns demand-lift-ranked
|
|
16
|
-
* companions with colour swatches and an annotate-only `colourFit` that never
|
|
17
|
-
* reorders in v1.
|
|
18
|
-
*
|
|
19
|
-
* Instead use `pairings` for a single material, and `colours.palette()` when the
|
|
20
|
-
* scheme is COLOURS rather than materials. Check `unresolved` before presenting:
|
|
21
|
-
* a reference that resolved to nothing is named there, not dropped.
|
|
22
|
-
*/
|
|
23
|
-
export declare const coordinate: (transport: HttpTransport, input: CoordinateInput, signal?: AbortSignal) => Promise<CoordinateResponse>;
|
package/coordinate-client.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { resolveOperation } from "./operations.js";
|
|
2
|
-
/**
|
|
3
|
-
* THE QUESTION: "here is my whole scheme so far — what completes it?" The
|
|
4
|
-
* multi-seed form of `pairings`: lift is SUMMED across seeds, so a companion
|
|
5
|
-
* suiting one pick ranks below one suiting several. Returns demand-lift-ranked
|
|
6
|
-
* companions with colour swatches and an annotate-only `colourFit` that never
|
|
7
|
-
* reorders in v1.
|
|
8
|
-
*
|
|
9
|
-
* Instead use `pairings` for a single material, and `colours.palette()` when the
|
|
10
|
-
* scheme is COLOURS rather than materials. Check `unresolved` before presenting:
|
|
11
|
-
* a reference that resolved to nothing is named there, not dropped.
|
|
12
|
-
*/
|
|
13
|
-
export const coordinate = async (transport, input, signal) => await transport.requestJson(resolveOperation("coordinate_materials"), { body: input, signal });
|
package/demand-batch-types.d.ts
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wire types for BATCH candidate demand enrichment — `POST /api/v1/demand/batch`.
|
|
3
|
-
*
|
|
4
|
-
* Split out of `types.ts` for the repository's source-file size budget, the same
|
|
5
|
-
* reason `material-types.ts` and `catalog-discovery-types.ts` sit beside it;
|
|
6
|
-
* re-exported from `types.ts`, so importers see no difference.
|
|
7
|
-
*
|
|
8
|
-
* THE LENS: this answers "how much is each of these already-chosen materials
|
|
9
|
-
* actually specified?" — enrichment over a bounded id list you already hold. It
|
|
10
|
-
* never resolves, ranks, reorders or discovers. Use
|
|
11
|
-
* {@link MaterialGraphClient.demand} for one material named in free text,
|
|
12
|
-
* {@link MaterialGraphClient.pairings} for what goes WITH a material, and
|
|
13
|
-
* {@link MaterialGraphClient.search} to find candidates in the first place.
|
|
14
|
-
*/
|
|
15
|
-
import type { VariantId } from "./identifiers.js";
|
|
16
|
-
import type { DemandMomentum, DemandQuarter, DemandSignal, OpenEnum } from "./types.js";
|
|
17
|
-
/**
|
|
18
|
-
* Body for `POST /api/v1/demand/batch` — enrich 1–48 already-selected candidate
|
|
19
|
-
* ids with their real specification demand, in input order and cardinality.
|
|
20
|
-
*/
|
|
21
|
-
export type DemandBatchInput = {
|
|
22
|
-
/** 1–48 canonical variant ids. Order AND cardinality are preserved — duplicates are echoed, never collapsed. */
|
|
23
|
-
variantIds: VariantId[];
|
|
24
|
-
/** The behavioural signal to read demand from. Defaults to `sampled` (order co-occurrence) server-side. */
|
|
25
|
-
signal?: DemandSignal;
|
|
26
|
-
/** Optional declared context (e.g. `{ projectType: "hospitality" }`) — echoed for provenance, never used to rank or filter. */
|
|
27
|
-
context?: Record<string, string>;
|
|
28
|
-
};
|
|
29
|
-
/** Headline population behind the metric — this variant's own counts. */
|
|
30
|
-
export type DemandBatchPopulation = {
|
|
31
|
-
specCount: number;
|
|
32
|
-
projectCount: number;
|
|
33
|
-
customerCount: number;
|
|
34
|
-
};
|
|
35
|
-
/** The consideration→specification funnel (project-grain; `exclusionRate` is annotate-only). */
|
|
36
|
-
export type DemandBatchFunnel = {
|
|
37
|
-
consideredProjects: number;
|
|
38
|
-
specifiedProjects: number;
|
|
39
|
-
excludedCount: number;
|
|
40
|
-
exclusionRate: number;
|
|
41
|
-
};
|
|
42
|
-
/** Per-result guardrail status — present on `internal` (`mg:admin`) results only. */
|
|
43
|
-
export type DemandBatchEvidence = {
|
|
44
|
-
belowPrivacyFloor: boolean;
|
|
45
|
-
belowQualityFloor: boolean;
|
|
46
|
-
suppressedForPublic: boolean;
|
|
47
|
-
};
|
|
48
|
-
/** A variant that carries a usable demand signal. */
|
|
49
|
-
export type DemandBatchAvailableResult = {
|
|
50
|
-
variantId: VariantId;
|
|
51
|
-
state: "available";
|
|
52
|
-
population: DemandBatchPopulation;
|
|
53
|
-
/** Exact per-quarter counts (sparse — zero-spec quarters are absent). */
|
|
54
|
-
intervals: DemandQuarter[];
|
|
55
|
-
momentum: DemandMomentum;
|
|
56
|
-
/** The funnel; null when the signal is not `sampled` or no `considered` row/session exists. */
|
|
57
|
-
funnel: DemandBatchFunnel | null;
|
|
58
|
-
/** Exact guardrail evidence for `internal` callers; null for public. */
|
|
59
|
-
evidence: DemandBatchEvidence | null;
|
|
60
|
-
};
|
|
61
|
-
/**
|
|
62
|
-
* A variant with a stats row that is below the public quality floor. We HAVE a
|
|
63
|
-
* reading and are declining to publish it — not a claim that nobody specifies it.
|
|
64
|
-
*/
|
|
65
|
-
export type DemandBatchInsufficientResult = {
|
|
66
|
-
variantId: VariantId;
|
|
67
|
-
state: "insufficient_data";
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
* A variant with no stats — indistinguishable from a privacy-suppressed one for
|
|
71
|
-
* public callers, and therefore never reportable as "nobody specifies this".
|
|
72
|
-
*/
|
|
73
|
-
export type DemandBatchNoSignalResult = {
|
|
74
|
-
variantId: VariantId;
|
|
75
|
-
state: "no_signal";
|
|
76
|
-
};
|
|
77
|
-
/** A requested id that resolves to no real variant. */
|
|
78
|
-
export type DemandBatchUnknownResult = {
|
|
79
|
-
variantId: VariantId;
|
|
80
|
-
state: "unknown_variant";
|
|
81
|
-
};
|
|
82
|
-
/**
|
|
83
|
-
* One discriminated result per input id, in input order and cardinality.
|
|
84
|
-
*
|
|
85
|
-
* ABSENT IS NOT ZERO: only `available` carries numbers. The other three states
|
|
86
|
-
* each mean "no number to report", for three different reasons, and none of them
|
|
87
|
-
* licenses "this material is not specified" — see each member.
|
|
88
|
-
*/
|
|
89
|
-
export type DemandBatchResult = DemandBatchAvailableResult | DemandBatchInsufficientResult | DemandBatchNoSignalResult | DemandBatchUnknownResult;
|
|
90
|
-
/** The `POST /api/v1/demand/batch` envelope. */
|
|
91
|
-
export type DemandBatchResponse = {
|
|
92
|
-
/** The completed ingestion-session id these counts were mined in (the dataset generation). */
|
|
93
|
-
generationId: string;
|
|
94
|
-
metric: "specification_demand";
|
|
95
|
-
/** The metric universe — the window and signal the counts are scoped to. */
|
|
96
|
-
universe: {
|
|
97
|
-
window: "trailing_36mo";
|
|
98
|
-
signal: DemandSignal;
|
|
99
|
-
description: string;
|
|
100
|
-
};
|
|
101
|
-
/** The guardrail status under which `results` were projected. */
|
|
102
|
-
guardrail: {
|
|
103
|
-
audience: OpenEnum<"public" | "internal">;
|
|
104
|
-
minProjectCount: number;
|
|
105
|
-
minCustomerCount: number;
|
|
106
|
-
};
|
|
107
|
-
/** Outcome tallies over `results` — never a denominator for the metric. */
|
|
108
|
-
coverage: {
|
|
109
|
-
requested: number;
|
|
110
|
-
available: number;
|
|
111
|
-
insufficientData: number;
|
|
112
|
-
noSignal: number;
|
|
113
|
-
unknownVariant: number;
|
|
114
|
-
};
|
|
115
|
-
/** The echoed declared context, or null when none was supplied. */
|
|
116
|
-
context: Record<string, string> | null;
|
|
117
|
-
results: DemandBatchResult[];
|
|
118
|
-
};
|
package/demand-types.d.ts
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wire types for the SINGLE-SEED demand reads — `GET /api/v1/demand` and
|
|
3
|
-
* `POST /api/v1/pairings/coordinate`.
|
|
4
|
-
*
|
|
5
|
-
* Split out of `types.ts` for the repository's source-file size budget, the same
|
|
6
|
-
* reason `material-types.ts` and `demand-batch-types.ts` sit beside it; both are
|
|
7
|
-
* re-exported from `types.ts`, so importers see no difference.
|
|
8
|
-
*
|
|
9
|
-
* THE LENS: demand answers "how much is this specified, and what travels with
|
|
10
|
-
* it?" from real order behaviour. It is not a search and not a recommendation
|
|
11
|
-
* engine — every number is bounded by the `trailing_36mo` window and by the
|
|
12
|
-
* {@link DemandSignal} it was read under, and a missing number means UNREAD, not
|
|
13
|
-
* zero.
|
|
14
|
-
*/
|
|
15
|
-
import type { ProductId, VariantId } from "./identifiers.js";
|
|
16
|
-
import type { CompanionDemand, DemandMomentum, DemandQuarter, OpenEnum } from "./types.js";
|
|
17
|
-
/** A resolved seed material (identity block shared by the demand reads). */
|
|
18
|
-
export type DemandSeed = {
|
|
19
|
-
/** Opaque — round-trip verbatim. */
|
|
20
|
-
variantId: VariantId;
|
|
21
|
-
brand: string;
|
|
22
|
-
product: string;
|
|
23
|
-
color: string | null;
|
|
24
|
-
variantName: string | null;
|
|
25
|
-
imageUrl: string | null;
|
|
26
|
-
brandSlug: string;
|
|
27
|
-
productId: ProductId;
|
|
28
|
-
};
|
|
29
|
-
/** Headline demand stats for a seed: counts, quarterly series, momentum. */
|
|
30
|
-
export type MaterialDemandStats = {
|
|
31
|
-
specCount: number;
|
|
32
|
-
projectCount: number;
|
|
33
|
-
customerCount: number;
|
|
34
|
-
/** Sparse — a quarter with no activity is ABSENT, not a zero row. */
|
|
35
|
-
byQuarter: DemandQuarter[];
|
|
36
|
-
momentum: DemandMomentum;
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* `getMaterialDemand` result, passed through verbatim by the `/demand` route.
|
|
40
|
-
*
|
|
41
|
-
* `demand: null` means NO READING — the seed did not resolve, or nothing cleared
|
|
42
|
-
* the publication floor. It is never a reading of zero, and never licenses
|
|
43
|
-
* "nobody specifies this".
|
|
44
|
-
*/
|
|
45
|
-
export type MaterialDemandResult = {
|
|
46
|
-
found: boolean;
|
|
47
|
-
query: string;
|
|
48
|
-
seed: DemandSeed | null;
|
|
49
|
-
/** The only window v1 serves. Activity outside it is unread, not absent. */
|
|
50
|
-
window: "trailing_36mo";
|
|
51
|
-
demand: MaterialDemandStats | null;
|
|
52
|
-
};
|
|
53
|
-
/**
|
|
54
|
-
* `getCoSpecifiedMaterials` result, passed through verbatim. The `companions`
|
|
55
|
-
* list (materials specified alongside the seed) is included but left loosely
|
|
56
|
-
* typed — there is no captured fixture to pin its full shape.
|
|
57
|
-
*
|
|
58
|
-
* `resolution` is the honest report on the free-text seed: `ambiguous` means the
|
|
59
|
-
* phrase matched several materials and `seedAlternatives` holds them — pick one
|
|
60
|
-
* and re-ask by `variantId` rather than treating the first as the answer.
|
|
61
|
-
*/
|
|
62
|
-
export type CoSpecifiedResult = {
|
|
63
|
-
found: boolean;
|
|
64
|
-
resolution: OpenEnum<"resolved" | "ambiguous" | "not_found">;
|
|
65
|
-
query: string;
|
|
66
|
-
seed: DemandSeed | null;
|
|
67
|
-
seedCategory: string | null;
|
|
68
|
-
seedAlternatives: DemandSeed[];
|
|
69
|
-
companions?: unknown[];
|
|
70
|
-
};
|
|
71
|
-
/** The `/api/v1/demand` envelope — both domain reads side by side, verbatim. */
|
|
72
|
-
export type DemandResponse = {
|
|
73
|
-
query: string;
|
|
74
|
-
demand: MaterialDemandResult;
|
|
75
|
-
cospec: CoSpecifiedResult;
|
|
76
|
-
};
|
|
77
|
-
/** Seed a demand read by EXACTLY ONE of `variantId` or `material`. */
|
|
78
|
-
export type DemandParams = {
|
|
79
|
-
/** An exact variant id. Opaque — pass through verbatim. */
|
|
80
|
-
variantId?: VariantId;
|
|
81
|
-
/** Free text ("Brand Product Colour"), resolved server-side. May be ambiguous. */
|
|
82
|
-
material?: string;
|
|
83
|
-
};
|
|
84
|
-
export type CoordinateSeed = {
|
|
85
|
-
/** The input reference this seed resolved from. */
|
|
86
|
-
resolvedFrom: string;
|
|
87
|
-
} & DemandSeed;
|
|
88
|
-
export type CoordinateCompanion = {
|
|
89
|
-
/** Opaque — round-trip verbatim. */
|
|
90
|
-
variantId: VariantId;
|
|
91
|
-
brand: string;
|
|
92
|
-
product: string;
|
|
93
|
-
color: string | null;
|
|
94
|
-
variantName: string | null;
|
|
95
|
-
imageUrl: string | null;
|
|
96
|
-
brandSlug: string;
|
|
97
|
-
productId: ProductId;
|
|
98
|
-
/**
|
|
99
|
-
* How this companion relates to the SEED SET — the closest relation that
|
|
100
|
-
* applies to any seed.
|
|
101
|
-
*
|
|
102
|
-
* `companion` is foreign to every seed: a maker the caller did not pick.
|
|
103
|
-
* `brand_sibling` shares a brand with some seed. `colourway` is a seed's own
|
|
104
|
-
* product restyled, and completes nothing.
|
|
105
|
-
*
|
|
106
|
-
* READ IT BEFORE CLAIMING BREADTH. Measured across the live edges (MG-1007),
|
|
107
|
-
* 70.6% are same-brand and 24.3% are the seed's own product in another
|
|
108
|
-
* colourway; on a two-seed rail, 27 of 40 companions came from the seeds' own
|
|
109
|
-
* two brands. A surface headed "makers you haven't picked" that does not
|
|
110
|
-
* filter on this is making a claim the evidence does not support — the
|
|
111
|
-
* measured case showed two distinct makers under a heading promising seven.
|
|
112
|
-
*
|
|
113
|
-
* The server has always sent this field; it was absent from this interface
|
|
114
|
-
* until 2026-08-23, so consumers could not see it and hand-rolled the same
|
|
115
|
-
* comparison against `brandSlug` themselves.
|
|
116
|
-
*/
|
|
117
|
-
relation: "companion" | "brand_sibling" | "colourway";
|
|
118
|
-
totalLift: number;
|
|
119
|
-
liftLabel: string;
|
|
120
|
-
seedMatchCount: number;
|
|
121
|
-
seedContributions: {
|
|
122
|
-
seedVariantId: VariantId;
|
|
123
|
-
lift: number;
|
|
124
|
-
}[];
|
|
125
|
-
demand: CompanionDemand | null;
|
|
126
|
-
swatches: {
|
|
127
|
-
hex: string;
|
|
128
|
-
proportion: number;
|
|
129
|
-
}[];
|
|
130
|
-
/** Annotate-only appearance similarity — never reorders companions in v1. */
|
|
131
|
-
colourFit: number | null;
|
|
132
|
-
};
|
|
133
|
-
/**
|
|
134
|
-
* The `POST /api/v1/pairings/coordinate` envelope. `unresolved` lists the input
|
|
135
|
-
* references that matched nothing — read it before presenting `companions` as
|
|
136
|
-
* "what goes with your palette", because a companion set derived from two of
|
|
137
|
-
* four seeds is a different claim.
|
|
138
|
-
*/
|
|
139
|
-
export type CoordinateResponse = {
|
|
140
|
-
seeds: CoordinateSeed[];
|
|
141
|
-
/** Input references that resolved to no material. Never silently dropped. */
|
|
142
|
-
unresolved: string[];
|
|
143
|
-
window: "trailing_36mo";
|
|
144
|
-
companions: CoordinateCompanion[];
|
|
145
|
-
};
|
|
146
|
-
/** Body for `POST /api/v1/pairings/coordinate`. */
|
|
147
|
-
export type CoordinateInput = {
|
|
148
|
-
/** Free-text material references, resolved server-side; misses land in `unresolved`. */
|
|
149
|
-
materials?: string[];
|
|
150
|
-
/** Exact variant ids. Opaque — pass through verbatim. */
|
|
151
|
-
variantIds?: VariantId[];
|
|
152
|
-
projectType?: string;
|
|
153
|
-
limit?: number;
|
|
154
|
-
};
|
package/identify-types.d.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Public wire types for `POST /api/v1/identify` (MG-1672's `resolve_variant`
|
|
3
|
-
* contract).
|
|
4
|
-
*
|
|
5
|
-
* These intentionally mirror the domain-owned Zod contract
|
|
6
|
-
* (`@materialgraph/products/identify-contract`) rather than importing it: the
|
|
7
|
-
* published SDK must carry no workspace package dependency.
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* What `mg.identify()` accepts. Give `url` alone, or `code` with `brandId`
|
|
11
|
-
* (from `mg.brands()`) when there is no page to read. `labels` are product
|
|
12
|
-
* names visible on the page, sent only to tell several URL candidates apart -
|
|
13
|
-
* they never widen a search or invent an identity on their own.
|
|
14
|
-
*/
|
|
15
|
-
export type IdentifyVariantInput = {
|
|
16
|
-
url?: string;
|
|
17
|
-
code?: string;
|
|
18
|
-
brandId?: string;
|
|
19
|
-
labels?: string[];
|
|
20
|
-
};
|
|
21
|
-
/** One identified, placed or bounded-candidate subject. */
|
|
22
|
-
export type IdentifySubject = {
|
|
23
|
-
kind: "variant" | "brand";
|
|
24
|
-
id: string;
|
|
25
|
-
name: string;
|
|
26
|
-
code?: string;
|
|
27
|
-
brand?: {
|
|
28
|
-
id: string;
|
|
29
|
-
name: string;
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
/** What stood behind an outcome. Exact and scoreless: never a similarity guess. */
|
|
33
|
-
export type IdentifyEvidence = {
|
|
34
|
-
kind: "manufacturer-url" | "brand-homepage" | "manufacturer-code" | "visible-label";
|
|
35
|
-
url?: string;
|
|
36
|
-
detail: string;
|
|
37
|
-
};
|
|
38
|
-
/** The submitted URL, normalised, and the steps that normalisation took. Absent for a code-only call. */
|
|
39
|
-
export type IdentifyReceipt = {
|
|
40
|
-
submittedUrl: string;
|
|
41
|
-
normalizedUrl: string;
|
|
42
|
-
normalizationSteps: string[];
|
|
43
|
-
};
|
|
44
|
-
type IdentifyResultBase = {
|
|
45
|
-
evidence: IdentifyEvidence[];
|
|
46
|
-
receipt?: IdentifyReceipt;
|
|
47
|
-
};
|
|
48
|
-
/**
|
|
49
|
-
* Why nothing was identified. Absent and empty differ: this names what was
|
|
50
|
-
* looked for and not found, never a similarity guess.
|
|
51
|
-
*/
|
|
52
|
-
export type IdentifyUnresolvedReason = "no-stored-url" | "no-code-match";
|
|
53
|
-
/** Exact identities only - no rung carries a similarity score. */
|
|
54
|
-
export type IdentifyResult = (IdentifyResultBase & {
|
|
55
|
-
outcome: "identified";
|
|
56
|
-
subject: IdentifySubject & {
|
|
57
|
-
kind: "variant";
|
|
58
|
-
};
|
|
59
|
-
}) | (IdentifyResultBase & {
|
|
60
|
-
outcome: "placed";
|
|
61
|
-
subject: IdentifySubject & {
|
|
62
|
-
kind: "brand";
|
|
63
|
-
};
|
|
64
|
-
}) | (IdentifyResultBase & {
|
|
65
|
-
outcome: "ambiguous";
|
|
66
|
-
candidates: IdentifySubject[];
|
|
67
|
-
truncated: boolean;
|
|
68
|
-
}) | (IdentifyResultBase & {
|
|
69
|
-
outcome: "unresolved";
|
|
70
|
-
reason: IdentifyUnresolvedReason;
|
|
71
|
-
});
|
|
72
|
-
/** The canonical callable-operation envelope returned by `identify()`. */
|
|
73
|
-
export type IdentifyResponse = {
|
|
74
|
-
data: IdentifyResult;
|
|
75
|
-
meta: {
|
|
76
|
-
operationId: "retrieval.identify";
|
|
77
|
-
requestId: string;
|
|
78
|
-
};
|
|
79
|
-
links: Record<string, never>;
|
|
80
|
-
warnings: [];
|
|
81
|
-
};
|
|
82
|
-
export {};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The MATERIAL COMPOSITION lens: what a product is made of, and how far the
|
|
3
|
-
* corpus that answers that question has got (MG-1969).
|
|
4
|
-
*
|
|
5
|
-
* Not `./composition-client.ts`, which wraps the slot pools a scheme composer
|
|
6
|
-
* outside MaterialGraph reads.
|
|
7
|
-
*/
|
|
8
|
-
import type { HttpTransport } from "./http-transport.js";
|
|
9
|
-
import type { CompositionCorpusSummary } from "./material-composition-types.js";
|
|
10
|
-
/**
|
|
11
|
-
* THE QUESTION: "which product types can we answer that question for yet?"
|
|
12
|
-
*
|
|
13
|
-
* Coverage per product type, counted in Live SKUs as well as in tuples. Read
|
|
14
|
-
* the SKU figure: one tuple can carry a hundred thousand SKUs or one, so a
|
|
15
|
-
* corpus that resolved every rare tuple and none of the common ones reads as
|
|
16
|
-
* good coverage counted by tuple.
|
|
17
|
-
*
|
|
18
|
-
* A type in `completeness.authoringQueue` has no bar set, which is never the
|
|
19
|
-
* same as a bar it missed. Requires the `mg:read` scope.
|
|
20
|
-
*/
|
|
21
|
-
export declare const compositionReport: (transport: HttpTransport, signal?: AbortSignal) => Promise<CompositionCorpusSummary>;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { resolveOperation } from "./operations.js";
|
|
2
|
-
/**
|
|
3
|
-
* THE QUESTION: "which product types can we answer that question for yet?"
|
|
4
|
-
*
|
|
5
|
-
* Coverage per product type, counted in Live SKUs as well as in tuples. Read
|
|
6
|
-
* the SKU figure: one tuple can carry a hundred thousand SKUs or one, so a
|
|
7
|
-
* corpus that resolved every rare tuple and none of the common ones reads as
|
|
8
|
-
* good coverage counted by tuple.
|
|
9
|
-
*
|
|
10
|
-
* A type in `completeness.authoringQueue` has no bar set, which is never the
|
|
11
|
-
* same as a bar it missed. Requires the `mg:read` scope.
|
|
12
|
-
*/
|
|
13
|
-
export const compositionReport = async (transport, signal) => await transport.requestJson(resolveOperation("get_composition_report"), { signal });
|