@doswiftly/storefront-sdk 22.8.0 → 22.9.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/CHANGELOG.md CHANGED
@@ -1,5 +1,63 @@
1
1
  # Changelog
2
2
 
3
+ ## 22.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 36c28ff: Add `customerNote` to the storefront `Order` type — the note a buyer left at checkout (delivery instructions, gift message, etc.). It is selected by the order fragment, so it is available on every order query, and is `null` when the buyer left no note.
8
+
9
+ ```tsx
10
+ // Order confirmation / detail page
11
+ const note = order.customerNote;
12
+ if (note) {
13
+ return <p className="order-note">{note}</p>;
14
+ }
15
+ ```
16
+
17
+ - a399d36: Image loader now produces clean image URLs (no internal storage prefix) on custom domains.
18
+
19
+ **Why**: when your storefront is served from its own image domain, the built `<Image>` URLs no longer carry the `/s/{shopId}` storage prefix (`https://img.yourshop.com/_next/static/media/hero.webp?width=256` instead of `.../s/{shopId}/_next/...`). The stored object is unchanged — the platform restores the prefix toward storage — so this is purely a nicer public URL. Branding-friendly, and one fewer internal detail in the markup.
20
+
21
+ **This is automatic — no code change.** The common `createImageLoader()` setup reads the flag from the platform-injected env var, so clean URLs simply turn on when your storefront is served from a custom domain configured for them:
22
+
23
+ ```ts
24
+ // lib/image-loader.ts — unchanged; clean URLs turn on automatically.
25
+ import { createImageLoader } from "@doswiftly/storefront-sdk/next";
26
+ export default createImageLoader();
27
+ ```
28
+
29
+ **Additive (backward-compatible)**:
30
+ 1. `ImageLoaderConfig` gains an optional `cleanUrl?: boolean` (defaults to `false`).
31
+ 2. `createImageLoader()` reads it automatically from `NEXT_PUBLIC_ASSET_CLEAN_URL`.
32
+
33
+ When `cleanUrl` is off (the default), URLs keep the `/s/{shopId}` prefix exactly as before — existing storefronts are unaffected. The boolean is also accepted by the low-level `buildImageLoaderUrl` for non-`<Image>` usage (e.g. CSS backgrounds) or tests:
34
+
35
+ ```ts
36
+ import { buildImageLoaderUrl } from "@doswiftly/storefront-sdk";
37
+ buildImageLoaderUrl(
38
+ { shopId, version, cleanUrl: true, cdnBase: "https://img.yourshop.com" },
39
+ { src: "/hero.webp", width: 256 },
40
+ );
41
+ // → https://img.yourshop.com/public/hero.webp?width=256&v=<version>
42
+ ```
43
+
44
+ **Migration checklist for existing storefronts**:
45
+ - [ ] None required — the default behavior is unchanged. Re-deploy to pick up clean URLs once your custom domain is configured.
46
+
47
+ ## 22.8.1
48
+
49
+ ### Patch Changes
50
+
51
+ - 61a2841: Fix: images imported in code are optimized again when your build serves static assets from a CDN domain.
52
+
53
+ An image you import in code (`import hero from './hero.webp'`) becomes a content-hashed file under `/_next/static/media/`. When your build serves static assets from a CDN domain (`assetPrefix` / `getAssetPrefix()`), Next.js rewrites the `<Image>` `src` to an absolute CDN URL before the loader runs. The loader did not recognize that form, so every `srcset` entry pointed at the full-size original — no resizing or format negotiation.
54
+
55
+ The loader now recognizes code-imported images in that absolute form and routes them through the image CDN, so each `srcset` width is resized again — the same behavior as a build without `assetPrefix`. Product images and `public/` images were never affected.
56
+
57
+ No API changes — update the package and redeploy.
58
+
59
+ (`@doswiftly/storefront-operations` is version-synced with the SDK; no operation changes.)
60
+
3
61
  ## 22.8.0
4
62
 
5
63
  ### Minor Changes
package/README.md CHANGED
@@ -777,13 +777,16 @@ The loader is global and handles each `<Image src>` by category:
777
777
  | Image imported in code (`import hero from './hero.webp'`) | Routed through the CDN — the framework bundles it under `/_next/static/media/`, the loader resizes it per `srcset` (no code change needed) |
778
778
  | Other build asset (`/_next/*` JS/CSS, `/_nuxt/`, `/_astro/`, `/_app/`), absolute external URL, `data:` URI, SVG | Returned unchanged |
779
779
 
780
- The loader reads `NEXT_PUBLIC_SHOP_ID`, `NEXT_PUBLIC_DEPLOYMENT_COMMIT`, and
781
- `NEXT_PUBLIC_IMGPROXY_BASE` — all injected by the platform at build/deploy time. When
782
- they are absent (e.g. local `doswiftly dev`, where `public/` images are served by the
783
- dev server) the loader leaves local `public/` images untouched; product images, being
784
- absolute CDN URLs, are unaffected. `<Image quality>` is a no-op — quality is applied
785
- server-side (the format is still auto-negotiated AVIF/WebP). Pass explicit overrides only for non-standard setups:
786
- `createImageLoader({ shopId, version, cdnBase })`.
780
+ The loader reads `NEXT_PUBLIC_SHOP_ID`, `NEXT_PUBLIC_DEPLOYMENT_COMMIT`,
781
+ `NEXT_PUBLIC_IMGPROXY_BASE`, and `NEXT_PUBLIC_ASSET_CLEAN_URL` — all injected by the platform
782
+ at build/deploy time. When they are absent (e.g. local `doswiftly dev`, where `public/` images
783
+ are served by the dev server) the loader leaves local `public/` images untouched; product
784
+ images, being absolute CDN URLs, are unaffected. `NEXT_PUBLIC_ASSET_CLEAN_URL` is set to `true`
785
+ only when your storefront is served from a custom domain configured for clean URLs — then the
786
+ built URLs omit the internal storage prefix (`{host}/_next/static/media/...` instead of
787
+ `{host}/s/{shopId}/_next/...`); the stored object is unchanged. `<Image quality>` is a no-op —
788
+ quality is applied server-side (the format is still auto-negotiated AVIF/WebP). Pass explicit
789
+ overrides only for non-standard setups: `createImageLoader({ shopId, version, cdnBase, cleanUrl })`.
787
790
 
788
791
  For non-`<Image>` usage (CSS backgrounds, raw `<img>`), build CDN URLs yourself
789
792
  with the pure helper `buildImageLoaderUrl` from `@doswiftly/storefront-sdk`.
@@ -2439,6 +2439,8 @@ export type Order = Node & {
2439
2439
  cancelledAt?: Maybe<Scalars['DateTime']['output']>;
2440
2440
  /** When the order was confirmed (e.g. payment authorised / approved). Null until confirmation. */
2441
2441
  confirmedAt?: Maybe<Scalars['DateTime']['output']>;
2442
+ /** The note the buyer left at checkout (delivery instructions, gift message, etc.). Null when no note was provided. */
2443
+ customerNote?: Maybe<Scalars['String']['output']>;
2442
2444
  /** Per-code discount allocations on the order (parity with `Cart.discountAllocations`). One entry per code that reduced the price; empty when no discount applied. The sum of `amount` equals the order-level discount. */
2443
2445
  discountAllocations: Array<OrderDiscountAllocation>;
2444
2446
  /** When the order expired (e.g. pending payment timed out). Null when not expired. */
@@ -4182,7 +4184,7 @@ export type CartCompleteMutationVariables = Exact<{
4182
4184
  }>;
4183
4185
  export type CartCompleteMutation = {
4184
4186
  cartComplete: {
4185
- order?: Maybe<(Pick<Order, 'id' | 'orderNumber' | 'accessToken' | 'status' | 'paymentStatus' | 'fulfillmentStatus' | 'processedAt' | 'confirmedAt' | 'cancelledAt' | 'expiredAt' | 'itemCount' | 'canCreatePayment' | 'paymentMethodType'> & {
4187
+ order?: Maybe<(Pick<Order, 'id' | 'orderNumber' | 'accessToken' | 'status' | 'paymentStatus' | 'fulfillmentStatus' | 'processedAt' | 'confirmedAt' | 'cancelledAt' | 'expiredAt' | 'itemCount' | 'customerNote' | 'canCreatePayment' | 'paymentMethodType'> & {
4186
4188
  totals: {
4187
4189
  total: Pick<Money, 'amount' | 'currencyCode'>;
4188
4190
  subtotal: Pick<Money, 'amount' | 'currencyCode'>;
@@ -5307,7 +5309,7 @@ export type OrderByTokenQueryVariables = Exact<{
5307
5309
  email?: InputMaybe<Scalars['String']['input']>;
5308
5310
  }>;
5309
5311
  export type OrderByTokenQuery = {
5310
- orderByToken?: Maybe<(Pick<Order, 'id' | 'orderNumber' | 'accessToken' | 'status' | 'paymentStatus' | 'fulfillmentStatus' | 'processedAt' | 'confirmedAt' | 'cancelledAt' | 'expiredAt' | 'itemCount' | 'canCreatePayment' | 'paymentMethodType'> & {
5312
+ orderByToken?: Maybe<(Pick<Order, 'id' | 'orderNumber' | 'accessToken' | 'status' | 'paymentStatus' | 'fulfillmentStatus' | 'processedAt' | 'confirmedAt' | 'cancelledAt' | 'expiredAt' | 'itemCount' | 'customerNote' | 'canCreatePayment' | 'paymentMethodType'> & {
5311
5313
  totals: {
5312
5314
  total: Pick<Money, 'amount' | 'currencyCode'>;
5313
5315
  subtotal: Pick<Money, 'amount' | 'currencyCode'>;
@@ -5568,7 +5570,7 @@ export type FreeShippingProgressFragment = (Pick<FreeShippingProgress, 'qualifie
5568
5570
  threshold?: Maybe<Pick<Money, 'amount' | 'currencyCode'>>;
5569
5571
  remaining?: Maybe<Pick<Money, 'amount' | 'currencyCode'>>;
5570
5572
  });
5571
- export type OrderFragment = (Pick<Order, 'id' | 'orderNumber' | 'accessToken' | 'status' | 'paymentStatus' | 'fulfillmentStatus' | 'processedAt' | 'confirmedAt' | 'cancelledAt' | 'expiredAt' | 'itemCount' | 'canCreatePayment' | 'paymentMethodType'> & {
5573
+ export type OrderFragment = (Pick<Order, 'id' | 'orderNumber' | 'accessToken' | 'status' | 'paymentStatus' | 'fulfillmentStatus' | 'processedAt' | 'confirmedAt' | 'cancelledAt' | 'expiredAt' | 'itemCount' | 'customerNote' | 'canCreatePayment' | 'paymentMethodType'> & {
5572
5574
  totals: {
5573
5575
  total: Pick<Money, 'amount' | 'currencyCode'>;
5574
5576
  subtotal: Pick<Money, 'amount' | 'currencyCode'>;