@01.software/sdk 0.1.8 → 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/README.md CHANGED
@@ -108,7 +108,7 @@ const client = createBrowserClient({
108
108
 
109
109
  Access collections via `client.from(collection)` method.
110
110
 
111
- > **Note:** `BrowserClient.from()` returns a `ReadOnlyQueryBuilder` (only `find`, `findById`, `count`). Write operations (`create`, `update`, `remove`, `updateMany`, `removeMany`) are only available on `ServerClient.from()`.
111
+ > **Note:** `BrowserClient.from()` returns a `ReadOnlyQueryBuilder` (only `find`, `findById`, `count`, `findMetadata`, `findMetadataById`). Write operations (`create`, `update`, `remove`, `updateMany`, `removeMany`) are only available on `ServerClient.from()`.
112
112
 
113
113
  ```typescript
114
114
  // List query - returns PayloadFindResponse
@@ -136,6 +136,16 @@ const deletedDoc = await client.from('products').remove('id')
136
136
  // Count
137
137
  const { totalDocs } = await client.from('products').count()
138
138
 
139
+ // SEO Metadata (fetch + generate in one call, depth: 1 auto-applied)
140
+ const metadata = await client.from('products').findMetadata(
141
+ { where: { slug: { equals: 'my-product' } } },
142
+ { siteName: 'My Store' },
143
+ )
144
+
145
+ const metadataById = await client.from('products').findMetadataById('id', {
146
+ siteName: 'My Store',
147
+ })
148
+
139
149
  // Bulk operations (server only)
140
150
  await client.from('products').updateMany(where, data)
141
151
  await client.from('products').removeMany(where)
@@ -178,6 +188,8 @@ interface PayloadMutationResponse<T> {
178
188
  | `update()` | `PayloadMutationResponse<T>` - `{ doc, message }` |
179
189
  | `remove()` | `T` - deleted document object directly |
180
190
  | `count()` | `{ totalDocs: number }` |
191
+ | `findMetadata()` | `Metadata \| null` - Next.js Metadata (null if no match) |
192
+ | `findMetadataById()` | `Metadata` - Next.js Metadata (throws on 404) |
181
193
 
182
194
  ### React Query Hooks
183
195
 
@@ -334,7 +346,7 @@ export async function POST(request: Request) {
334
346
  })
335
347
  }
336
348
 
337
- // With signature verification
349
+ // With HMAC-SHA256 signature verification (recommended)
338
350
  export async function POST(request: Request) {
339
351
  return handleWebhook(request, handler, {
340
352
  secret: process.env.WEBHOOK_SECRET,
@@ -359,7 +371,7 @@ const handler = createTypedWebhookHandler('orders', async (event) => {
359
371
  | Carts | `carts`, `cart-items` |
360
372
  | Commerce | `discounts`, `shipping-policies` |
361
373
  | Content | `posts`, `post-categories`, `post-tags`, `post-images`, `documents`, `document-categories`, `document-images` |
362
- | Media | `playlists`, `playlist-images`, `musics`, `galleries`, `gallery-images`, `media` |
374
+ | Media | `playlists`, `playlist-images`, `musics`, `media` |
363
375
  | Forms | `forms`, `form-submissions` |
364
376
 
365
377
  ## Utilities
@@ -1,5 +1,5 @@
1
1
  import { Sort, Where } from 'payload';
2
- import './payload-types-DcOQUD4x.js';
2
+ import './payload-types-BWJZhklJ.js';
3
3
 
4
4
  declare class SDKError extends Error {
5
5
  readonly code: string;
@@ -1,5 +1,5 @@
1
1
  import { Sort, Where } from 'payload';
2
- import './payload-types-DcOQUD4x.cjs';
2
+ import './payload-types-BWJZhklJ.cjs';
3
3
 
4
4
  declare class SDKError extends Error {
5
5
  readonly code: string;
package/dist/auth.d.cts CHANGED
@@ -1,3 +1,3 @@
1
- export { J as JwtPayload, q as createApiKey, o as createServerToken, p as decodeServerToken, r as parseApiKey, v as verifyServerToken } from './auth-BnCTXZG0.cjs';
1
+ export { J as JwtPayload, q as createApiKey, o as createServerToken, p as decodeServerToken, r as parseApiKey, v as verifyServerToken } from './auth-BE80zCjC.cjs';
2
2
  import 'payload';
3
- import './payload-types-DcOQUD4x.cjs';
3
+ import './payload-types-BWJZhklJ.cjs';
package/dist/auth.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { J as JwtPayload, q as createApiKey, o as createServerToken, p as decodeServerToken, r as parseApiKey, v as verifyServerToken } from './auth-Cxfq94pG.js';
1
+ export { J as JwtPayload, q as createApiKey, o as createServerToken, p as decodeServerToken, r as parseApiKey, v as verifyServerToken } from './auth-BC0CWHt_.js';
2
2
  import 'payload';
3
- import './payload-types-DcOQUD4x.js';
3
+ import './payload-types-BWJZhklJ.js';
package/dist/index.cjs CHANGED
@@ -88,6 +88,7 @@ __export(src_exports, {
88
88
  CollectionQueryBuilder: () => CollectionQueryBuilder,
89
89
  ConfigError: () => ConfigError,
90
90
  CustomerAuth: () => CustomerAuth,
91
+ IMAGE_SIZES: () => IMAGE_SIZES,
91
92
  NetworkError: () => NetworkError,
92
93
  OrderApi: () => OrderApi,
93
94
  ProductApi: () => ProductApi,
@@ -107,6 +108,8 @@ __export(src_exports, {
107
108
  decodeServerToken: () => decodeServerToken,
108
109
  formatOrderName: () => formatOrderName,
109
110
  generateOrderNumber: () => generateOrderNumber,
111
+ getImageSrcSet: () => getImageSrcSet,
112
+ getImageUrl: () => getImageUrl,
110
113
  getQueryClient: () => getQueryClient,
111
114
  handleWebhook: () => handleWebhook,
112
115
  isApiError: () => isApiError,
@@ -704,6 +707,37 @@ var ProductApi = class {
704
707
  }
705
708
  };
706
709
 
710
+ // src/utils/types.ts
711
+ var resolveRelation = (ref) => {
712
+ if (typeof ref === "number" || ref === null || ref === void 0) return null;
713
+ return ref;
714
+ };
715
+ var objectFor = resolveRelation;
716
+
717
+ // src/core/metadata/index.ts
718
+ function generateMetadata(doc, options) {
719
+ var _a, _b, _c, _d;
720
+ const meta = doc == null ? void 0 : doc.meta;
721
+ const title = (_b = (_a = meta == null ? void 0 : meta.title) != null ? _a : options == null ? void 0 : options.title) != null ? _b : void 0;
722
+ const description = (_d = (_c = meta == null ? void 0 : meta.description) != null ? _c : options == null ? void 0 : options.description) != null ? _d : void 0;
723
+ const image = resolveMetaImage(meta == null ? void 0 : meta.image);
724
+ return {
725
+ title,
726
+ description,
727
+ openGraph: __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, title && { title }), description && { description }), (options == null ? void 0 : options.siteName) && { siteName: options.siteName }), image && { images: [image] }),
728
+ twitter: __spreadValues(__spreadValues(__spreadValues({
729
+ card: image ? "summary_large_image" : "summary"
730
+ }, title && { title }), description && { description }), image && { images: [image.url] })
731
+ };
732
+ }
733
+ function resolveMetaImage(ref) {
734
+ const media = resolveRelation(ref);
735
+ if (!(media == null ? void 0 : media.url)) return null;
736
+ return __spreadValues(__spreadValues(__spreadValues({
737
+ url: media.url
738
+ }, media.width && { width: media.width }), media.height && { height: media.height }), media.alt && { alt: media.alt });
739
+ }
740
+
707
741
  // src/core/collection/query-builder.ts
708
742
  var CollectionQueryBuilder = class {
709
743
  constructor(api, collection) {
@@ -775,6 +809,36 @@ var CollectionQueryBuilder = class {
775
809
  );
776
810
  });
777
811
  }
812
+ /**
813
+ * Find first matching document and return its Next.js Metadata.
814
+ * Applies depth: 1 (image populate) and limit: 1 automatically.
815
+ * @returns Metadata or null if no document matches
816
+ */
817
+ findMetadata(options, metadataOptions) {
818
+ return __async(this, null, function* () {
819
+ const { docs } = yield this.find(__spreadProps(__spreadValues({}, options), { limit: 1, depth: 1 }));
820
+ const doc = docs[0];
821
+ if (!doc) return null;
822
+ return generateMetadata(
823
+ doc,
824
+ metadataOptions
825
+ );
826
+ });
827
+ }
828
+ /**
829
+ * Find document by ID and return its Next.js Metadata.
830
+ * Applies depth: 1 (image populate) automatically.
831
+ * @returns Metadata (throws on 404)
832
+ */
833
+ findMetadataById(id, metadataOptions) {
834
+ return __async(this, null, function* () {
835
+ const doc = yield this.findById(id, { depth: 1 });
836
+ return generateMetadata(
837
+ doc,
838
+ metadataOptions
839
+ );
840
+ });
841
+ }
778
842
  /**
779
843
  * Update multiple documents (bulk update)
780
844
  * PATCH /api/{collection}
@@ -1050,6 +1114,7 @@ var COLLECTIONS = [
1050
1114
  "product-categories",
1051
1115
  "product-tags",
1052
1116
  "product-images",
1117
+ "product-collections",
1053
1118
  "brands",
1054
1119
  "brand-logos",
1055
1120
  "orders",
@@ -1079,8 +1144,6 @@ var COLLECTIONS = [
1079
1144
  "playlists",
1080
1145
  "playlist-images",
1081
1146
  "musics",
1082
- "galleries",
1083
- "gallery-images",
1084
1147
  "forms",
1085
1148
  "form-submissions",
1086
1149
  "media"
@@ -1777,11 +1840,6 @@ function handleWebhook(request, handler, options) {
1777
1840
  return __async(this, null, function* () {
1778
1841
  try {
1779
1842
  const rawBody = yield request.text();
1780
- if (!(options == null ? void 0 : options.secret)) {
1781
- console.warn(
1782
- "[@01.software/sdk] Webhook signature verification is skipped because no secret was provided. Pass { secret } to handleWebhook() to enable signature verification."
1783
- );
1784
- }
1785
1843
  if (options == null ? void 0 : options.secret) {
1786
1844
  const signature = request.headers.get("x-webhook-signature") || "";
1787
1845
  const valid = yield verifySignature(rawBody, options.secret, signature);
@@ -1791,6 +1849,10 @@ function handleWebhook(request, handler, options) {
1791
1849
  { status: 401, headers: { "Content-Type": "application/json" } }
1792
1850
  );
1793
1851
  }
1852
+ } else {
1853
+ console.warn(
1854
+ "[@01.software/sdk] Webhook signature verification is disabled. Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification."
1855
+ );
1794
1856
  }
1795
1857
  const body = JSON.parse(rawBody);
1796
1858
  if (!isValidWebhookEvent(body)) {
@@ -1822,6 +1884,39 @@ function createTypedWebhookHandler(collection, handler) {
1822
1884
  });
1823
1885
  }
1824
1886
 
1887
+ // src/utils/image.ts
1888
+ var IMAGE_SIZES = [384, 768, 1536];
1889
+ function getImageUrl(image, displayWidth, dpr = 1) {
1890
+ var _a;
1891
+ const target = displayWidth * dpr;
1892
+ const sizes = image.sizes;
1893
+ if (sizes) {
1894
+ for (const size of IMAGE_SIZES) {
1895
+ if (size >= target) {
1896
+ const entry = sizes[String(size)];
1897
+ if (entry == null ? void 0 : entry.url) return entry.url;
1898
+ }
1899
+ }
1900
+ }
1901
+ return (_a = image.url) != null ? _a : "";
1902
+ }
1903
+ function getImageSrcSet(image) {
1904
+ const parts = [];
1905
+ const sizes = image.sizes;
1906
+ if (sizes) {
1907
+ for (const size of IMAGE_SIZES) {
1908
+ const entry = sizes[String(size)];
1909
+ if ((entry == null ? void 0 : entry.url) && entry.width) {
1910
+ parts.push(`${entry.url} ${entry.width}w`);
1911
+ }
1912
+ }
1913
+ }
1914
+ if (image.url && image.width) {
1915
+ parts.push(`${image.url} ${image.width}w`);
1916
+ }
1917
+ return parts.join(", ");
1918
+ }
1919
+
1825
1920
  // src/utils/order/generateOrderNumber.ts
1826
1921
  var generateOrderNumber = () => {
1827
1922
  var _a;
@@ -1834,13 +1929,6 @@ var generateOrderNumber = () => {
1834
1929
  return `${year}${month}${day}${random}`;
1835
1930
  };
1836
1931
 
1837
- // src/utils/types.ts
1838
- var resolveRelation = (ref) => {
1839
- if (typeof ref === "number" || ref === null || ref === void 0) return null;
1840
- return ref;
1841
- };
1842
- var objectFor = resolveRelation;
1843
-
1844
1932
  // src/utils/order/formatOrderName.ts
1845
1933
  var formatOrderName = (options) => {
1846
1934
  var _a, _b;