@01.software/sdk 0.1.8 → 0.1.9

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,
package/dist/index.cjs CHANGED
@@ -704,6 +704,37 @@ var ProductApi = class {
704
704
  }
705
705
  };
706
706
 
707
+ // src/utils/types.ts
708
+ var resolveRelation = (ref) => {
709
+ if (typeof ref === "number" || ref === null || ref === void 0) return null;
710
+ return ref;
711
+ };
712
+ var objectFor = resolveRelation;
713
+
714
+ // src/core/metadata/index.ts
715
+ function generateMetadata(doc, options) {
716
+ var _a, _b, _c, _d;
717
+ const meta = doc == null ? void 0 : doc.meta;
718
+ const title = (_b = (_a = meta == null ? void 0 : meta.title) != null ? _a : options == null ? void 0 : options.title) != null ? _b : void 0;
719
+ const description = (_d = (_c = meta == null ? void 0 : meta.description) != null ? _c : options == null ? void 0 : options.description) != null ? _d : void 0;
720
+ const image = resolveMetaImage(meta == null ? void 0 : meta.image);
721
+ return {
722
+ title,
723
+ description,
724
+ openGraph: __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, title && { title }), description && { description }), (options == null ? void 0 : options.siteName) && { siteName: options.siteName }), image && { images: [image] }),
725
+ twitter: __spreadValues(__spreadValues(__spreadValues({
726
+ card: image ? "summary_large_image" : "summary"
727
+ }, title && { title }), description && { description }), image && { images: [image.url] })
728
+ };
729
+ }
730
+ function resolveMetaImage(ref) {
731
+ const media = resolveRelation(ref);
732
+ if (!(media == null ? void 0 : media.url)) return null;
733
+ return __spreadValues(__spreadValues(__spreadValues({
734
+ url: media.url
735
+ }, media.width && { width: media.width }), media.height && { height: media.height }), media.alt && { alt: media.alt });
736
+ }
737
+
707
738
  // src/core/collection/query-builder.ts
708
739
  var CollectionQueryBuilder = class {
709
740
  constructor(api, collection) {
@@ -775,6 +806,36 @@ var CollectionQueryBuilder = class {
775
806
  );
776
807
  });
777
808
  }
809
+ /**
810
+ * Find first matching document and return its Next.js Metadata.
811
+ * Applies depth: 1 (image populate) and limit: 1 automatically.
812
+ * @returns Metadata or null if no document matches
813
+ */
814
+ findMetadata(options, metadataOptions) {
815
+ return __async(this, null, function* () {
816
+ const { docs } = yield this.find(__spreadProps(__spreadValues({}, options), { limit: 1, depth: 1 }));
817
+ const doc = docs[0];
818
+ if (!doc) return null;
819
+ return generateMetadata(
820
+ doc,
821
+ metadataOptions
822
+ );
823
+ });
824
+ }
825
+ /**
826
+ * Find document by ID and return its Next.js Metadata.
827
+ * Applies depth: 1 (image populate) automatically.
828
+ * @returns Metadata (throws on 404)
829
+ */
830
+ findMetadataById(id, metadataOptions) {
831
+ return __async(this, null, function* () {
832
+ const doc = yield this.findById(id, { depth: 1 });
833
+ return generateMetadata(
834
+ doc,
835
+ metadataOptions
836
+ );
837
+ });
838
+ }
778
839
  /**
779
840
  * Update multiple documents (bulk update)
780
841
  * PATCH /api/{collection}
@@ -1777,11 +1838,6 @@ function handleWebhook(request, handler, options) {
1777
1838
  return __async(this, null, function* () {
1778
1839
  try {
1779
1840
  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
1841
  if (options == null ? void 0 : options.secret) {
1786
1842
  const signature = request.headers.get("x-webhook-signature") || "";
1787
1843
  const valid = yield verifySignature(rawBody, options.secret, signature);
@@ -1791,6 +1847,10 @@ function handleWebhook(request, handler, options) {
1791
1847
  { status: 401, headers: { "Content-Type": "application/json" } }
1792
1848
  );
1793
1849
  }
1850
+ } else {
1851
+ console.warn(
1852
+ "[@01.software/sdk] Webhook signature verification is disabled. Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification."
1853
+ );
1794
1854
  }
1795
1855
  const body = JSON.parse(rawBody);
1796
1856
  if (!isValidWebhookEvent(body)) {
@@ -1834,13 +1894,6 @@ var generateOrderNumber = () => {
1834
1894
  return `${year}${month}${day}${random}`;
1835
1895
  };
1836
1896
 
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
1897
  // src/utils/order/formatOrderName.ts
1845
1898
  var formatOrderName = (options) => {
1846
1899
  var _a, _b;