@kotao/storefront 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +34 -0
- package/dist/cart-documents-CwwRTvm8.d.ts +21 -0
- package/dist/cart-documents.d.ts +2 -0
- package/dist/cart-documents.js +3 -0
- package/dist/cart-documents.js.map +1 -0
- package/dist/chunk-2IWNUDSZ.js +104 -0
- package/dist/chunk-2IWNUDSZ.js.map +1 -0
- package/dist/chunk-3YQXJNR7.js +70 -0
- package/dist/chunk-3YQXJNR7.js.map +1 -0
- package/dist/chunk-5QOFKGKD.js +51 -0
- package/dist/chunk-5QOFKGKD.js.map +1 -0
- package/dist/chunk-GCQI6OKH.js +239 -0
- package/dist/chunk-GCQI6OKH.js.map +1 -0
- package/dist/chunk-ISAFEOR2.js +214 -0
- package/dist/chunk-ISAFEOR2.js.map +1 -0
- package/dist/chunk-MYDKIJRH.js +81 -0
- package/dist/chunk-MYDKIJRH.js.map +1 -0
- package/dist/chunk-OGWYTYYS.js +72 -0
- package/dist/chunk-OGWYTYYS.js.map +1 -0
- package/dist/chunk-PXZ737N3.js +439 -0
- package/dist/chunk-PXZ737N3.js.map +1 -0
- package/dist/chunk-QOEEUTHQ.js +110 -0
- package/dist/chunk-QOEEUTHQ.js.map +1 -0
- package/dist/chunk-U5677AEA.js +1690 -0
- package/dist/chunk-U5677AEA.js.map +1 -0
- package/dist/chunk-XMTWFJCZ.js +138 -0
- package/dist/chunk-XMTWFJCZ.js.map +1 -0
- package/dist/client-D9YYA2w6.d.ts +159 -0
- package/dist/customer-account-api-types.d.ts +144 -0
- package/dist/customer-account-api-types.js +3 -0
- package/dist/customer-account-api-types.js.map +1 -0
- package/dist/editor.d.ts +112 -0
- package/dist/editor.js +3 -0
- package/dist/editor.js.map +1 -0
- package/dist/image.d.ts +89 -0
- package/dist/image.js +3 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +183 -0
- package/dist/index.js +208 -0
- package/dist/index.js.map +1 -0
- package/dist/pagination-CPgH3fAa.d.ts +77 -0
- package/dist/product.d.ts +105 -0
- package/dist/product.js +4 -0
- package/dist/product.js.map +1 -0
- package/dist/react-router.d.ts +29 -0
- package/dist/react-router.js +33 -0
- package/dist/react-router.js.map +1 -0
- package/dist/react.d.ts +299 -0
- package/dist/react.js +1813 -0
- package/dist/react.js.map +1 -0
- package/dist/routing-BfUp49o8.d.ts +302 -0
- package/dist/seo.d.ts +155 -0
- package/dist/seo.js +4 -0
- package/dist/seo.js.map +1 -0
- package/dist/settings.d.ts +87 -0
- package/dist/settings.js +3 -0
- package/dist/settings.js.map +1 -0
- package/dist/shop-DkQmro-Y.d.ts +202 -0
- package/dist/store-DQK1nhob.d.ts +67 -0
- package/dist/storefront-api-types.d.ts +312 -0
- package/dist/storefront-api-types.js +3 -0
- package/dist/storefront-api-types.js.map +1 -0
- package/dist/types-BDhHWZsP.d.ts +77 -0
- package/dist/types-Df3bGbKU.d.ts +167 -0
- package/package.json +82 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { C as CartFormAction } from './types-Df3bGbKU.js';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface CartFormProps {
|
|
5
|
+
readonly action: CartFormAction;
|
|
6
|
+
}
|
|
7
|
+
interface CartFormInputResult {
|
|
8
|
+
readonly action: CartFormAction | null;
|
|
9
|
+
readonly inputs: Record<string, any>;
|
|
10
|
+
}
|
|
11
|
+
declare function getCartFormInput(formData: FormData): CartFormInputResult;
|
|
12
|
+
/**
|
|
13
|
+
* Lightweight CartForm surface marker for Hydrogen-style imports. React render integration can wrap
|
|
14
|
+
* this constant surface; the load-bearing API today is the stable ACTIONS contract used by handlers.
|
|
15
|
+
*/
|
|
16
|
+
declare const CartForm: ((_props: CartFormProps) => null) & {
|
|
17
|
+
ACTIONS: Readonly<{
|
|
18
|
+
readonly LinesAdd: "LinesAdd";
|
|
19
|
+
readonly LinesUpdate: "LinesUpdate";
|
|
20
|
+
readonly LinesRemove: "LinesRemove";
|
|
21
|
+
readonly DiscountCodesUpdate: "DiscountCodesUpdate";
|
|
22
|
+
readonly GiftCardCodesAdd: "GiftCardCodesAdd";
|
|
23
|
+
readonly GiftCardCodesRemove: "GiftCardCodesRemove";
|
|
24
|
+
readonly BuyerIdentityUpdate: "BuyerIdentityUpdate";
|
|
25
|
+
readonly NoteUpdate: "NoteUpdate";
|
|
26
|
+
readonly AttributesUpdate: "AttributesUpdate";
|
|
27
|
+
readonly MetafieldsSet: "MetafieldsSet";
|
|
28
|
+
readonly MetafieldsDelete: "MetafieldsDelete";
|
|
29
|
+
readonly DeliveryAddressesReplace: "DeliveryAddressesReplace";
|
|
30
|
+
readonly SelectedDeliveryOptionsUpdate: "SelectedDeliveryOptionsUpdate";
|
|
31
|
+
}>;
|
|
32
|
+
getFormInput: typeof getCartFormInput;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Legacy consent state. The visible Storefront consent UI is disabled until the replacement flow ships,
|
|
37
|
+
* so runtime analytics treats every bucket as effectively granted and ignores stale consent cookies.
|
|
38
|
+
*/
|
|
39
|
+
type ConsentBucket = 'analytics' | 'marketing' | 'preferences';
|
|
40
|
+
type ConsentState = Readonly<Record<ConsentBucket, boolean>>;
|
|
41
|
+
declare const CONSENT_BUCKETS: readonly ConsentBucket[];
|
|
42
|
+
declare const DENIED_CONSENT: ConsentState;
|
|
43
|
+
declare const GRANTED_CONSENT: ConsentState;
|
|
44
|
+
declare const CONSENT_COOKIE = "kotao_consent";
|
|
45
|
+
declare function isGranted(state: ConsentState, bucket: ConsentBucket): boolean;
|
|
46
|
+
declare function mergeConsent(state: ConsentState, patch: Partial<ConsentState>): ConsentState;
|
|
47
|
+
declare function serializeConsent(state: ConsentState): string;
|
|
48
|
+
declare function parseConsent(value: string | null | undefined): ConsentState;
|
|
49
|
+
/** The `document.cookie` string to persist consent (Secure, SameSite=Lax, Path=/, ~180d). */
|
|
50
|
+
declare function buildConsentCookie(state: ConsentState): string;
|
|
51
|
+
/** Read the consent cookie out of a `document.cookie`-style string. */
|
|
52
|
+
declare function readConsentCookie(cookieHeader: string | null | undefined): ConsentState;
|
|
53
|
+
|
|
54
|
+
type BoundNonceProvider = (props: {
|
|
55
|
+
readonly children?: ReactNode;
|
|
56
|
+
}) => ReactNode;
|
|
57
|
+
/** Hydrogen-compatible nonce hook. */
|
|
58
|
+
declare function useNonce(): string | undefined;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Coarse visitor geo attached to pixel events — structurally the SDK's `context.geo` (a `Geo` value is
|
|
62
|
+
* assignable here). Declared locally so the analytics surface (and its DOM/React preset) need not pull
|
|
63
|
+
* in the geo crypto module.
|
|
64
|
+
*/
|
|
65
|
+
interface AnalyticsGeo {
|
|
66
|
+
readonly country: string | null;
|
|
67
|
+
readonly city: string | null;
|
|
68
|
+
readonly colo: string | null;
|
|
69
|
+
readonly botScore: number | null;
|
|
70
|
+
readonly clientIp: string | null;
|
|
71
|
+
}
|
|
72
|
+
/** The standard storefront analytics events (Hydrogen-shaped names). */
|
|
73
|
+
declare const ANALYTICS_EVENTS: {
|
|
74
|
+
readonly pageViewed: "page_viewed";
|
|
75
|
+
readonly productViewed: "product_viewed";
|
|
76
|
+
readonly collectionViewed: "collection_viewed";
|
|
77
|
+
readonly cartViewed: "cart_viewed";
|
|
78
|
+
readonly searchViewed: "search_viewed";
|
|
79
|
+
readonly productAddedToCart: "product_added_to_cart";
|
|
80
|
+
};
|
|
81
|
+
type AnalyticsEventName = (typeof ANALYTICS_EVENTS)[keyof typeof ANALYTICS_EVENTS];
|
|
82
|
+
/** Ambient context the provider attaches to every event before it reaches the pixel. */
|
|
83
|
+
interface AnalyticsContext {
|
|
84
|
+
readonly shopId?: string;
|
|
85
|
+
readonly url?: string;
|
|
86
|
+
readonly geo?: AnalyticsGeo;
|
|
87
|
+
}
|
|
88
|
+
interface PageViewedPayload {
|
|
89
|
+
readonly title?: string;
|
|
90
|
+
}
|
|
91
|
+
interface ProductViewedPayload {
|
|
92
|
+
readonly productId: string;
|
|
93
|
+
readonly handle?: string;
|
|
94
|
+
}
|
|
95
|
+
interface CollectionViewedPayload {
|
|
96
|
+
readonly collectionId: string;
|
|
97
|
+
readonly handle?: string;
|
|
98
|
+
}
|
|
99
|
+
interface CartViewedPayload {
|
|
100
|
+
readonly cartId?: string;
|
|
101
|
+
}
|
|
102
|
+
interface SearchViewedPayload {
|
|
103
|
+
readonly query: string;
|
|
104
|
+
readonly resultCount?: number;
|
|
105
|
+
}
|
|
106
|
+
interface ProductAddedToCartPayload {
|
|
107
|
+
readonly productId: string;
|
|
108
|
+
readonly variantId: string;
|
|
109
|
+
readonly quantity: number;
|
|
110
|
+
}
|
|
111
|
+
/** Event name → payload (the typed pub/sub surface). */
|
|
112
|
+
interface AnalyticsEventMap {
|
|
113
|
+
page_viewed: PageViewedPayload;
|
|
114
|
+
product_viewed: ProductViewedPayload;
|
|
115
|
+
collection_viewed: CollectionViewedPayload;
|
|
116
|
+
cart_viewed: CartViewedPayload;
|
|
117
|
+
search_viewed: SearchViewedPayload;
|
|
118
|
+
product_added_to_cart: ProductAddedToCartPayload;
|
|
119
|
+
}
|
|
120
|
+
/** A pixel-bound event: the name, its payload, the ambient context, a timestamp, and consent state. */
|
|
121
|
+
interface PixelEvent<E extends AnalyticsEventName = AnalyticsEventName> {
|
|
122
|
+
readonly event: E;
|
|
123
|
+
readonly payload: AnalyticsEventMap[E];
|
|
124
|
+
readonly context: AnalyticsContext;
|
|
125
|
+
readonly timestamp: string;
|
|
126
|
+
/** Whether the analytics-consent bucket was granted when this event was recorded. */
|
|
127
|
+
readonly consent: boolean;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
type EventHandler<E extends AnalyticsEventName> = (payload: AnalyticsEventMap[E]) => void;
|
|
131
|
+
/** A framework-agnostic typed pub/sub bus (Hydrogen `useAnalytics` shape, minus React). */
|
|
132
|
+
interface AnalyticsEmitter {
|
|
133
|
+
subscribe<E extends AnalyticsEventName>(event: E, handler: EventHandler<E>): () => void;
|
|
134
|
+
publish<E extends AnalyticsEventName>(event: E, payload: AnalyticsEventMap[E]): void;
|
|
135
|
+
}
|
|
136
|
+
declare function createAnalyticsEmitter(): AnalyticsEmitter;
|
|
137
|
+
|
|
138
|
+
/** The actual network send. Injectable so tests don't touch the network. */
|
|
139
|
+
type PixelSend = (endpoint: string, body: string) => void;
|
|
140
|
+
interface PixelTransportOptions {
|
|
141
|
+
/** Same-origin carve-out endpoint (default '/api/storefront/pixel') — never cross-origin. */
|
|
142
|
+
readonly endpoint?: string;
|
|
143
|
+
readonly batchSize?: number;
|
|
144
|
+
/**
|
|
145
|
+
* The actual network send. Required + injected: the browser sender (`sendBeacon`/keepalive `fetch`)
|
|
146
|
+
* is DOM-specific and lives in the React layer, keeping this batching core framework-agnostic and
|
|
147
|
+
* unit-testable with a spy. The provider wires the real sender.
|
|
148
|
+
*/
|
|
149
|
+
readonly send: PixelSend;
|
|
150
|
+
}
|
|
151
|
+
interface PixelTransport {
|
|
152
|
+
record(event: PixelEvent): void;
|
|
153
|
+
flush(): void;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Batches pixel events and POSTs them to the same-origin carve-out. Flushes on `batchSize` or an
|
|
157
|
+
* explicit `flush()` (the provider flushes on page-hide). The endpoint is same-origin so themes need
|
|
158
|
+
* no CORS and no token is exposed in the browser.
|
|
159
|
+
*/
|
|
160
|
+
declare function createPixelTransport(options: PixelTransportOptions): PixelTransport;
|
|
161
|
+
|
|
162
|
+
interface AnalyticsBusOptions {
|
|
163
|
+
readonly transport: PixelTransport;
|
|
164
|
+
/** Legacy consent seam retained for API compatibility while Storefront consent UI is disabled. */
|
|
165
|
+
readonly getConsent: () => ConsentState;
|
|
166
|
+
/** Ambient context (shopId, geo, url) attached to each pixel event. */
|
|
167
|
+
readonly getContext?: () => AnalyticsContext;
|
|
168
|
+
/** Clock seam for deterministic timestamps in tests. */
|
|
169
|
+
readonly now?: () => string;
|
|
170
|
+
}
|
|
171
|
+
interface AnalyticsBus {
|
|
172
|
+
readonly emitter: AnalyticsEmitter;
|
|
173
|
+
publish<E extends AnalyticsEventName>(event: E, payload: AnalyticsEventMap[E]): void;
|
|
174
|
+
flush(): void;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Wire the emitter to the pixel. Every published event reaches theme subscribers (via the emitter) and
|
|
178
|
+
* is also recorded to the pixel. Consent gating is temporarily disabled with the UI; the consent seam
|
|
179
|
+
* remains so a proper replacement can reinstate the policy without changing theme APIs.
|
|
180
|
+
*/
|
|
181
|
+
declare function createAnalyticsBus(options: AnalyticsBusOptions): AnalyticsBus;
|
|
182
|
+
|
|
183
|
+
interface ShopAnalytics {
|
|
184
|
+
readonly acceptedLanguage?: string;
|
|
185
|
+
readonly currency?: string;
|
|
186
|
+
readonly shopId?: string;
|
|
187
|
+
readonly storefrontId?: string;
|
|
188
|
+
}
|
|
189
|
+
interface GetShopAnalyticsOptions {
|
|
190
|
+
readonly publicStorefrontId?: string;
|
|
191
|
+
readonly storefront?: {
|
|
192
|
+
readonly i18n?: {
|
|
193
|
+
readonly country?: string | null;
|
|
194
|
+
readonly currency?: string | null;
|
|
195
|
+
readonly language?: string | null;
|
|
196
|
+
readonly pathPrefix?: string | null;
|
|
197
|
+
} | null;
|
|
198
|
+
} | null;
|
|
199
|
+
}
|
|
200
|
+
declare function getShopAnalytics(options: GetShopAnalyticsOptions): ShopAnalytics;
|
|
201
|
+
|
|
202
|
+
export { ANALYTICS_EVENTS as A, type BoundNonceProvider as B, type ConsentBucket as C, DENIED_CONSENT as D, type EventHandler as E, getShopAnalytics as F, GRANTED_CONSENT as G, isGranted as H, mergeConsent as I, parseConsent as J, readConsentCookie as K, serializeConsent as L, getCartFormInput as M, useNonce as N, type PageViewedPayload as P, type SearchViewedPayload as S, type ConsentState as a, type AnalyticsBus as b, type AnalyticsBusOptions as c, type AnalyticsContext as d, type AnalyticsEmitter as e, type AnalyticsEventMap as f, type AnalyticsEventName as g, type AnalyticsGeo as h, CONSENT_BUCKETS as i, CONSENT_COOKIE as j, CartForm as k, type CartFormProps as l, type CartViewedPayload as m, type CollectionViewedPayload as n, type GetShopAnalyticsOptions as o, type PixelEvent as p, type PixelSend as q, type PixelTransport as r, type PixelTransportOptions as s, type ProductAddedToCartPayload as t, type ProductViewedPayload as u, type ShopAnalytics as v, buildConsentCookie as w, createAnalyticsBus as x, createAnalyticsEmitter as y, createPixelTransport as z };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolved (merged) settings shapes. Deliberately free of any `@kotao/storefront-contracts` import so the
|
|
3
|
+
* React layer (typechecked under the DOM lib) can consume them without pulling the contracts' Worker-crypto
|
|
4
|
+
* (`shop-context.ts`) into a DOM typecheck — the same decoupling the analytics `AnalyticsGeo` type uses.
|
|
5
|
+
* The merge engine (merge.ts), which DOES consume contracts types, lives in the Worker-core typecheck.
|
|
6
|
+
*/
|
|
7
|
+
type ResolvedSettings = Record<string, unknown>;
|
|
8
|
+
interface ResolvedBlock {
|
|
9
|
+
readonly id?: string;
|
|
10
|
+
readonly type: string;
|
|
11
|
+
readonly settings: ResolvedSettings;
|
|
12
|
+
}
|
|
13
|
+
interface ResolvedSection {
|
|
14
|
+
readonly id: string;
|
|
15
|
+
readonly type: string;
|
|
16
|
+
readonly settings: ResolvedSettings;
|
|
17
|
+
readonly blocks: readonly ResolvedBlock[];
|
|
18
|
+
}
|
|
19
|
+
interface ResolvedValuesDocument {
|
|
20
|
+
readonly shopId: string;
|
|
21
|
+
readonly sections: readonly ResolvedSection[];
|
|
22
|
+
}
|
|
23
|
+
/** The fully-merged settings a theme renders from: ordered sections + global theme tokens. */
|
|
24
|
+
interface ThemeSettingsSnapshot {
|
|
25
|
+
readonly sections: readonly ResolvedSection[];
|
|
26
|
+
readonly global: ResolvedSettings;
|
|
27
|
+
readonly templates?: Readonly<Record<string, ResolvedValuesDocument>>;
|
|
28
|
+
readonly sectionGroups?: Readonly<Record<string, ResolvedValuesDocument>>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Framework-agnostic theme-settings store (#93). Holds the merged {@link ThemeSettingsSnapshot} and lets
|
|
33
|
+
* subscribers react to live edits. In plain runtime the snapshot is the stable server-provided value and
|
|
34
|
+
* never changes; in the visual editor, postMessage-driven setting patches call `patchSection`/`patchGlobal`
|
|
35
|
+
* so the React binding (useSyncExternalStore) re-renders without a reload. `getSnapshot` returns a stable
|
|
36
|
+
* reference between patches (a new one only on change), as useSyncExternalStore requires.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
interface ThemeSettingsStore {
|
|
40
|
+
getSnapshot(): ThemeSettingsSnapshot;
|
|
41
|
+
subscribe(listener: () => void): () => void;
|
|
42
|
+
/** Replace a section instance's resolved settings (editor live-patch); no-op if the id is unknown. */
|
|
43
|
+
patchSection(instanceId: string, settings: ResolvedSettings): void;
|
|
44
|
+
/** Insert a fully-resolved section instance (editor live-add); reserved ids are ignored. */
|
|
45
|
+
insertSection(section: ResolvedSection, index?: number): void;
|
|
46
|
+
/** Remove one section instance (editor live-delete); no-op if unknown. */
|
|
47
|
+
removeSection(instanceId: string): void;
|
|
48
|
+
/** Move one section instance to a new position (editor live-reorder); no-op if unknown. */
|
|
49
|
+
moveSection(instanceId: string, index: number): void;
|
|
50
|
+
/** Replace the global theme tokens (editor live-patch). */
|
|
51
|
+
patchGlobal(settings: ResolvedSettings): void;
|
|
52
|
+
/** Replace a block instance's resolved settings; no-op if section/block is unknown. */
|
|
53
|
+
patchBlock(sectionId: string, blockId: string, settings: ResolvedSettings): void;
|
|
54
|
+
/** Insert a fully-resolved block instance into a section. */
|
|
55
|
+
insertBlock(sectionId: string, block: ResolvedBlock, index?: number): void;
|
|
56
|
+
/** Remove one block instance from a section. */
|
|
57
|
+
removeBlock(sectionId: string, blockId: string): void;
|
|
58
|
+
/** Move one block instance to a new position inside a section. */
|
|
59
|
+
moveBlock(sectionId: string, blockId: string, index: number): void;
|
|
60
|
+
/** Replace all preview sections from a template values document. */
|
|
61
|
+
replaceSections(sections: readonly ResolvedSection[]): void;
|
|
62
|
+
/** Replace one layout section group document, such as header or footer. */
|
|
63
|
+
replaceSectionGroup(handle: string, document: ResolvedValuesDocument): void;
|
|
64
|
+
}
|
|
65
|
+
declare function createThemeSettingsStore(initial: ThemeSettingsSnapshot): ThemeSettingsStore;
|
|
66
|
+
|
|
67
|
+
export { type ResolvedBlock as R, type ThemeSettingsSnapshot as T, type ResolvedSection as a, type ResolvedSettings as b, type ThemeSettingsStore as c, createThemeSettingsStore as d };
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
type Maybe<T> = T | null;
|
|
2
|
+
type InputMaybe<T> = Maybe<T>;
|
|
3
|
+
type Exact<T extends Record<string, unknown>> = {
|
|
4
|
+
[K in keyof T]: T[K];
|
|
5
|
+
};
|
|
6
|
+
interface Scalars {
|
|
7
|
+
readonly ID: {
|
|
8
|
+
readonly input: string;
|
|
9
|
+
readonly output: string;
|
|
10
|
+
};
|
|
11
|
+
readonly String: {
|
|
12
|
+
readonly input: string;
|
|
13
|
+
readonly output: string;
|
|
14
|
+
};
|
|
15
|
+
readonly Boolean: {
|
|
16
|
+
readonly input: boolean;
|
|
17
|
+
readonly output: boolean;
|
|
18
|
+
};
|
|
19
|
+
readonly Int: {
|
|
20
|
+
readonly input: number;
|
|
21
|
+
readonly output: number;
|
|
22
|
+
};
|
|
23
|
+
readonly Float: {
|
|
24
|
+
readonly input: number;
|
|
25
|
+
readonly output: number;
|
|
26
|
+
};
|
|
27
|
+
readonly Decimal: {
|
|
28
|
+
readonly input: string;
|
|
29
|
+
readonly output: string;
|
|
30
|
+
};
|
|
31
|
+
readonly DateTime: {
|
|
32
|
+
readonly input: string;
|
|
33
|
+
readonly output: string;
|
|
34
|
+
};
|
|
35
|
+
readonly HTML: {
|
|
36
|
+
readonly input: string;
|
|
37
|
+
readonly output: string;
|
|
38
|
+
};
|
|
39
|
+
readonly URL: {
|
|
40
|
+
readonly input: string;
|
|
41
|
+
readonly output: string;
|
|
42
|
+
};
|
|
43
|
+
readonly [key: string]: {
|
|
44
|
+
readonly input: any;
|
|
45
|
+
readonly output: any;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
interface LooseObject {
|
|
49
|
+
[key: string]: any;
|
|
50
|
+
}
|
|
51
|
+
type CountryCode = string;
|
|
52
|
+
type CurrencyCode = string;
|
|
53
|
+
type LanguageCode = string;
|
|
54
|
+
type ProductCollectionSortKeys = string;
|
|
55
|
+
type ProductSortKeys = string;
|
|
56
|
+
interface Seo extends LooseObject {
|
|
57
|
+
readonly description: string | null;
|
|
58
|
+
readonly title?: string | null;
|
|
59
|
+
}
|
|
60
|
+
interface Image extends LooseObject {
|
|
61
|
+
readonly altText?: string | null;
|
|
62
|
+
readonly height?: number | null;
|
|
63
|
+
readonly id?: string;
|
|
64
|
+
readonly url: string;
|
|
65
|
+
readonly width?: number | null;
|
|
66
|
+
}
|
|
67
|
+
interface MoneyV2 extends LooseObject {
|
|
68
|
+
readonly amount: string;
|
|
69
|
+
readonly currencyCode: CurrencyCode;
|
|
70
|
+
}
|
|
71
|
+
interface Domain extends LooseObject {
|
|
72
|
+
readonly url: string;
|
|
73
|
+
}
|
|
74
|
+
interface Metafield extends LooseObject {
|
|
75
|
+
readonly key: string;
|
|
76
|
+
readonly namespace: string;
|
|
77
|
+
readonly value: string;
|
|
78
|
+
}
|
|
79
|
+
interface ArticleAuthor extends LooseObject {
|
|
80
|
+
readonly name?: string | null;
|
|
81
|
+
}
|
|
82
|
+
interface Article extends LooseObject {
|
|
83
|
+
readonly author?: ArticleAuthor | null;
|
|
84
|
+
readonly contentHtml?: string;
|
|
85
|
+
readonly excerpt?: string | null;
|
|
86
|
+
readonly handle: string;
|
|
87
|
+
readonly id: string;
|
|
88
|
+
readonly image?: Image | null;
|
|
89
|
+
readonly publishedAt: string;
|
|
90
|
+
readonly seo?: Seo | null;
|
|
91
|
+
readonly title: string;
|
|
92
|
+
}
|
|
93
|
+
interface Blog extends LooseObject {
|
|
94
|
+
readonly handle: string;
|
|
95
|
+
readonly id: string;
|
|
96
|
+
readonly seo?: Seo | null;
|
|
97
|
+
readonly title: string;
|
|
98
|
+
}
|
|
99
|
+
interface Collection extends LooseObject {
|
|
100
|
+
readonly description: string;
|
|
101
|
+
readonly descriptionHtml?: string | null;
|
|
102
|
+
readonly handle: string;
|
|
103
|
+
readonly id: string;
|
|
104
|
+
readonly image?: Image | null;
|
|
105
|
+
readonly seo?: Seo | null;
|
|
106
|
+
readonly title: string;
|
|
107
|
+
readonly updatedAt?: string | null;
|
|
108
|
+
}
|
|
109
|
+
interface Page extends LooseObject {
|
|
110
|
+
readonly body?: string | null;
|
|
111
|
+
readonly bodySummary?: string | null;
|
|
112
|
+
readonly handle: string;
|
|
113
|
+
readonly id: string;
|
|
114
|
+
readonly seo?: Seo | null;
|
|
115
|
+
readonly title: string;
|
|
116
|
+
}
|
|
117
|
+
interface ExternalVideo extends LooseObject {
|
|
118
|
+
readonly alt?: string | null;
|
|
119
|
+
readonly embedUrl: string;
|
|
120
|
+
readonly host: string;
|
|
121
|
+
readonly id: string;
|
|
122
|
+
readonly mediaContentType: string;
|
|
123
|
+
readonly previewImage?: Image | null;
|
|
124
|
+
}
|
|
125
|
+
interface MediaImage extends LooseObject {
|
|
126
|
+
readonly alt?: string | null;
|
|
127
|
+
readonly id: string;
|
|
128
|
+
readonly image?: Image | null;
|
|
129
|
+
readonly mediaContentType: string;
|
|
130
|
+
readonly previewImage?: Image | null;
|
|
131
|
+
}
|
|
132
|
+
interface Model3dSource extends LooseObject {
|
|
133
|
+
readonly mimeType: string;
|
|
134
|
+
readonly url: string;
|
|
135
|
+
}
|
|
136
|
+
interface Model3d extends LooseObject {
|
|
137
|
+
readonly alt?: string | null;
|
|
138
|
+
readonly id: string;
|
|
139
|
+
readonly mediaContentType: string;
|
|
140
|
+
readonly previewImage?: Image | null;
|
|
141
|
+
readonly sources: readonly Model3dSource[];
|
|
142
|
+
}
|
|
143
|
+
interface VideoSource extends LooseObject {
|
|
144
|
+
readonly mimeType: string;
|
|
145
|
+
readonly url: string;
|
|
146
|
+
}
|
|
147
|
+
interface Video extends LooseObject {
|
|
148
|
+
readonly alt?: string | null;
|
|
149
|
+
readonly id: string;
|
|
150
|
+
readonly mediaContentType: string;
|
|
151
|
+
readonly previewImage?: Image | null;
|
|
152
|
+
readonly sources: readonly VideoSource[];
|
|
153
|
+
}
|
|
154
|
+
type Media = ExternalVideo | MediaImage | Model3d | Video;
|
|
155
|
+
interface MenuItem extends LooseObject {
|
|
156
|
+
readonly id: string;
|
|
157
|
+
readonly items?: readonly MenuItem[];
|
|
158
|
+
readonly resourceId?: string | null;
|
|
159
|
+
readonly tags?: readonly string[];
|
|
160
|
+
readonly title: string;
|
|
161
|
+
readonly type?: string;
|
|
162
|
+
readonly url?: string | null;
|
|
163
|
+
}
|
|
164
|
+
interface Menu extends LooseObject {
|
|
165
|
+
readonly id: string;
|
|
166
|
+
readonly items: readonly MenuItem[];
|
|
167
|
+
}
|
|
168
|
+
interface PageInfo extends LooseObject {
|
|
169
|
+
readonly endCursor?: string | null;
|
|
170
|
+
readonly hasNextPage: boolean;
|
|
171
|
+
readonly hasPreviousPage: boolean;
|
|
172
|
+
readonly startCursor?: string | null;
|
|
173
|
+
}
|
|
174
|
+
interface ProductOptionValueSwatch extends LooseObject {
|
|
175
|
+
readonly color?: string | null;
|
|
176
|
+
readonly image?: Image | null;
|
|
177
|
+
}
|
|
178
|
+
interface ProductOptionValue extends LooseObject {
|
|
179
|
+
readonly available?: boolean;
|
|
180
|
+
readonly firstSelectableVariant?: ProductVariant | null;
|
|
181
|
+
readonly isActive?: boolean;
|
|
182
|
+
readonly name?: string;
|
|
183
|
+
readonly swatch?: ProductOptionValueSwatch | null;
|
|
184
|
+
}
|
|
185
|
+
interface ProductOption extends LooseObject {
|
|
186
|
+
readonly name: string;
|
|
187
|
+
readonly optionValues?: ProductOptionValue[];
|
|
188
|
+
readonly values?: string[];
|
|
189
|
+
}
|
|
190
|
+
interface SelectedOption extends LooseObject {
|
|
191
|
+
readonly name: string;
|
|
192
|
+
readonly value: string;
|
|
193
|
+
}
|
|
194
|
+
interface SelectedOptionInput extends LooseObject {
|
|
195
|
+
readonly name: string;
|
|
196
|
+
readonly value: string;
|
|
197
|
+
}
|
|
198
|
+
interface ProductVariant extends LooseObject {
|
|
199
|
+
readonly availableForSale?: boolean | null;
|
|
200
|
+
readonly compareAtPrice?: MoneyV2 | null;
|
|
201
|
+
readonly id: string;
|
|
202
|
+
readonly image?: Image | null;
|
|
203
|
+
readonly price: MoneyV2;
|
|
204
|
+
readonly product: Pick<Product, 'id' | 'handle' | 'title'>;
|
|
205
|
+
readonly selectedOptions: SelectedOption[];
|
|
206
|
+
readonly sku?: string | null;
|
|
207
|
+
readonly title?: string;
|
|
208
|
+
}
|
|
209
|
+
interface Product extends LooseObject {
|
|
210
|
+
readonly availableForSale?: boolean;
|
|
211
|
+
readonly description: string;
|
|
212
|
+
readonly descriptionHtml?: string;
|
|
213
|
+
readonly featuredImage?: Image | null;
|
|
214
|
+
readonly handle: string;
|
|
215
|
+
readonly id: string;
|
|
216
|
+
readonly media?: {
|
|
217
|
+
readonly nodes?: Media[];
|
|
218
|
+
};
|
|
219
|
+
readonly options?: ProductOption[];
|
|
220
|
+
readonly publishedAt: string;
|
|
221
|
+
readonly priceRange?: {
|
|
222
|
+
readonly maxVariantPrice?: MoneyV2;
|
|
223
|
+
readonly minVariantPrice: MoneyV2;
|
|
224
|
+
};
|
|
225
|
+
readonly seo?: Seo | null;
|
|
226
|
+
readonly title: string;
|
|
227
|
+
readonly variants: {
|
|
228
|
+
readonly nodes: ProductVariant[];
|
|
229
|
+
};
|
|
230
|
+
readonly vendor: string;
|
|
231
|
+
}
|
|
232
|
+
interface FilterValue extends LooseObject {
|
|
233
|
+
readonly count?: number;
|
|
234
|
+
readonly id: string;
|
|
235
|
+
readonly input?: string;
|
|
236
|
+
readonly label: string;
|
|
237
|
+
}
|
|
238
|
+
interface Filter extends LooseObject {
|
|
239
|
+
readonly id: string;
|
|
240
|
+
readonly label: string;
|
|
241
|
+
readonly type?: string;
|
|
242
|
+
readonly values: readonly FilterValue[];
|
|
243
|
+
}
|
|
244
|
+
type ProductFilter = LooseObject;
|
|
245
|
+
interface ShopPolicy extends LooseObject {
|
|
246
|
+
readonly body: string;
|
|
247
|
+
readonly handle: string;
|
|
248
|
+
readonly id: string;
|
|
249
|
+
readonly title: string;
|
|
250
|
+
readonly url?: string;
|
|
251
|
+
}
|
|
252
|
+
interface ShopPolicyWithDefault extends ShopPolicy {
|
|
253
|
+
readonly default?: boolean;
|
|
254
|
+
}
|
|
255
|
+
interface Shop extends LooseObject {
|
|
256
|
+
readonly brand?: LooseObject | null;
|
|
257
|
+
readonly description?: string | null;
|
|
258
|
+
readonly id: string;
|
|
259
|
+
readonly name: string;
|
|
260
|
+
readonly primaryDomain?: Domain;
|
|
261
|
+
}
|
|
262
|
+
interface OrderLineItem extends LooseObject {
|
|
263
|
+
readonly title: string;
|
|
264
|
+
}
|
|
265
|
+
interface Order extends LooseObject {
|
|
266
|
+
readonly financialStatus?: string | null;
|
|
267
|
+
readonly fulfillmentStatus?: string | null;
|
|
268
|
+
readonly id: string;
|
|
269
|
+
readonly orderNumber?: number;
|
|
270
|
+
readonly processedAt: string;
|
|
271
|
+
}
|
|
272
|
+
interface CartCost extends LooseObject {
|
|
273
|
+
readonly subtotalAmount?: MoneyV2;
|
|
274
|
+
readonly totalAmount?: MoneyV2;
|
|
275
|
+
readonly totalTaxAmount?: MoneyV2 | null;
|
|
276
|
+
}
|
|
277
|
+
interface CartLine extends LooseObject {
|
|
278
|
+
readonly id: string;
|
|
279
|
+
readonly merchandise?: ProductVariant;
|
|
280
|
+
readonly quantity: number;
|
|
281
|
+
}
|
|
282
|
+
interface CartLineUpdateInput extends LooseObject {
|
|
283
|
+
readonly id: string;
|
|
284
|
+
readonly merchandiseId?: string | null;
|
|
285
|
+
readonly quantity?: number | null;
|
|
286
|
+
}
|
|
287
|
+
interface CartBuyerIdentityInput extends LooseObject {
|
|
288
|
+
readonly countryCode?: CountryCode | null;
|
|
289
|
+
readonly customerAccessToken?: string | null;
|
|
290
|
+
readonly email?: string | null;
|
|
291
|
+
readonly phone?: string | null;
|
|
292
|
+
}
|
|
293
|
+
interface CartDiscountCode extends LooseObject {
|
|
294
|
+
readonly applicable?: boolean;
|
|
295
|
+
readonly code: string;
|
|
296
|
+
}
|
|
297
|
+
interface CartLineConnection extends LooseObject {
|
|
298
|
+
readonly edges?: {
|
|
299
|
+
readonly node: CartLine;
|
|
300
|
+
}[];
|
|
301
|
+
readonly nodes?: CartLine[];
|
|
302
|
+
}
|
|
303
|
+
interface Cart extends LooseObject {
|
|
304
|
+
readonly checkoutUrl: string;
|
|
305
|
+
readonly cost: CartCost;
|
|
306
|
+
readonly discountCodes?: readonly CartDiscountCode[];
|
|
307
|
+
readonly id: string;
|
|
308
|
+
readonly lines?: CartLineConnection;
|
|
309
|
+
readonly totalQuantity: number;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export type { Article, ArticleAuthor, Blog, Cart, CartBuyerIdentityInput, CartCost, CartDiscountCode, CartLine, CartLineConnection, CartLineUpdateInput, Collection, CountryCode, CurrencyCode, Domain, Exact, ExternalVideo, Filter, FilterValue, Image, InputMaybe, LanguageCode, Maybe, Media, MediaImage, Menu, MenuItem, Metafield, Model3d, Model3dSource, MoneyV2, Order, OrderLineItem, Page, PageInfo, Product, ProductCollectionSortKeys, ProductFilter, ProductOption, ProductOptionValue, ProductOptionValueSwatch, ProductSortKeys, ProductVariant, Scalars, SelectedOption, SelectedOptionInput, Seo, Shop, ShopPolicy, ShopPolicyWithDefault, Video, VideoSource };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"storefront-api-types.js"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEO surface types for `@kotao/storefront` (ADR-0003 §SDK), Hydrogen-shaped. Framework-agnostic:
|
|
3
|
+
* `getSeoMeta` emits a flat descriptor list a theme can return from a React Router 7 `meta` export or
|
|
4
|
+
* feed to the `<Seo/>` component.
|
|
5
|
+
*/
|
|
6
|
+
interface OpenGraphImage {
|
|
7
|
+
readonly url: string;
|
|
8
|
+
readonly width?: number;
|
|
9
|
+
readonly height?: number;
|
|
10
|
+
readonly alt?: string;
|
|
11
|
+
}
|
|
12
|
+
interface OpenGraph {
|
|
13
|
+
readonly title?: string;
|
|
14
|
+
readonly description?: string;
|
|
15
|
+
/** og:type, e.g. 'website' | 'article' | 'product'. Defaults to 'website' when OG tags are emitted. */
|
|
16
|
+
readonly type?: string;
|
|
17
|
+
readonly url?: string;
|
|
18
|
+
readonly siteName?: string;
|
|
19
|
+
readonly locale?: string;
|
|
20
|
+
readonly images?: readonly OpenGraphImage[];
|
|
21
|
+
}
|
|
22
|
+
interface TwitterCard {
|
|
23
|
+
readonly card?: 'summary' | 'summary_large_image' | 'app' | 'player';
|
|
24
|
+
readonly site?: string;
|
|
25
|
+
readonly creator?: string;
|
|
26
|
+
readonly title?: string;
|
|
27
|
+
readonly description?: string;
|
|
28
|
+
readonly image?: string;
|
|
29
|
+
}
|
|
30
|
+
/** An hreflang alternate. Design-only hook (no multi-language data ships) — emitted only when supplied. */
|
|
31
|
+
interface Alternate {
|
|
32
|
+
readonly hreflang: string;
|
|
33
|
+
readonly href: string;
|
|
34
|
+
}
|
|
35
|
+
/** A schema.org JSON-LD object (produced by the json-ld builders, or hand-authored). */
|
|
36
|
+
type JsonLd = any;
|
|
37
|
+
interface RobotsOptions {
|
|
38
|
+
readonly noIndex?: boolean;
|
|
39
|
+
readonly noFollow?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/** SEO config merged across levels (root → route → leaf); deeper/later wins per field. */
|
|
42
|
+
interface SeoConfig {
|
|
43
|
+
readonly [key: string]: unknown;
|
|
44
|
+
readonly title?: string | null;
|
|
45
|
+
/** Applied to the resolved title as `titleTemplate.replace('%s', title)`. Last level wins. */
|
|
46
|
+
readonly titleTemplate?: string;
|
|
47
|
+
readonly description?: string | null;
|
|
48
|
+
/** Absolute canonical URL. */
|
|
49
|
+
readonly canonical?: string | null;
|
|
50
|
+
readonly url?: string | null;
|
|
51
|
+
/** Robots directive, e.g. 'index,follow' or 'noindex,nofollow'. */
|
|
52
|
+
readonly robots?: string | RobotsOptions;
|
|
53
|
+
readonly openGraph?: OpenGraph;
|
|
54
|
+
readonly twitter?: TwitterCard;
|
|
55
|
+
readonly alternates?: readonly Alternate[];
|
|
56
|
+
/** schema.org JSON-LD object(s); accumulated (not overridden) across levels. */
|
|
57
|
+
readonly jsonLd?: JsonLd | readonly JsonLd[];
|
|
58
|
+
}
|
|
59
|
+
/** A head descriptor, shaped to be React Router 7 `meta`-export compatible. */
|
|
60
|
+
type SeoDescriptor = {
|
|
61
|
+
readonly title: string;
|
|
62
|
+
} | {
|
|
63
|
+
readonly name: string;
|
|
64
|
+
readonly content: string;
|
|
65
|
+
} | {
|
|
66
|
+
readonly property: string;
|
|
67
|
+
readonly content: string;
|
|
68
|
+
} | {
|
|
69
|
+
readonly tagName: 'link';
|
|
70
|
+
readonly rel: string;
|
|
71
|
+
readonly href: string;
|
|
72
|
+
readonly hrefLang?: string;
|
|
73
|
+
} | {
|
|
74
|
+
readonly 'script:ld+json': JsonLd;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export type { Alternate as A, JsonLd as J, OpenGraph as O, SeoConfig as S, TwitterCard as T, OpenGraphImage as a, SeoDescriptor as b };
|