@cimplify/cli 0.6.14 → 0.6.15
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/dist/{add-6SPMUMSJ.mjs → add-6KEKFXOW.mjs} +1 -1
- package/dist/chunk-DEWCHGWU.mjs +5707 -0
- package/dist/{chunk-CNIFXKZV.mjs → chunk-JLSDFVML.mjs} +1 -1
- package/dist/{chunk-RGF2RSSR.mjs → chunk-OSS47KZP.mjs} +2 -2
- package/dist/dispatcher.mjs +9 -9
- package/dist/{doctor-726TVOXT.mjs → doctor-WL25JRS3.mjs} +2 -2
- package/dist/{explain-6BWR5MCK.mjs → explain-NY5A533M.mjs} +2 -2
- package/dist/{introspect-4LD27NVX.mjs → introspect-J7GVKQK7.mjs} +2 -2
- package/dist/{list-2YRVKBXY.mjs → list-FXOFYX4H.mjs} +1 -1
- package/dist/{update-J65Z6Q7E.mjs → update-WNZKECFJ.mjs} +1 -1
- package/package.json +2 -2
- package/templates/storefront-auto/app/products/[slug]/page.tsx +8 -3
- package/templates/storefront-auto/bun.lock +10 -681
- package/templates/storefront-auto/package.json +1 -1
- package/templates/storefront-bakery/bun.lock +10 -681
- package/templates/storefront-bakery/package.json +1 -1
- package/templates/storefront-fashion/app/products/[slug]/page.tsx +8 -3
- package/templates/storefront-fashion/bun.lock +12 -683
- package/templates/storefront-fashion/package.json +1 -1
- package/templates/storefront-grocery/bun.lock +10 -681
- package/templates/storefront-grocery/package.json +1 -1
- package/templates/storefront-pharmacy/app/products/[slug]/page.tsx +8 -3
- package/templates/storefront-pharmacy/bun.lock +10 -681
- package/templates/storefront-pharmacy/package.json +1 -1
- package/templates/storefront-restaurant/bun.lock +10 -681
- package/templates/storefront-restaurant/package.json +1 -1
- package/templates/storefront-retail/app/products/[slug]/page.tsx +8 -3
- package/templates/storefront-retail/bun.lock +10 -681
- package/templates/storefront-retail/package.json +1 -1
- package/templates/storefront-services/bun.lock +10 -681
- package/templates/storefront-services/package.json +1 -1
- package/dist/chunk-RIOQDUQO.mjs +0 -5707
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { gitDetectRoot, gitCurrentBranch, gitCurrentSha, gitStatusPorcelain } from './chunk-K5464A3L.mjs';
|
|
3
3
|
import { parseEnvFile } from './chunk-DBZ3UOQ2.mjs';
|
|
4
|
-
import { package_default } from './chunk-
|
|
4
|
+
import { package_default } from './chunk-OSS47KZP.mjs';
|
|
5
5
|
import { parseArgs } from './chunk-C4M3DXKC.mjs';
|
|
6
6
|
import { readAuthOrNull, readProjectLinkOrNull, readProjectState } from './chunk-UBAI443T.mjs';
|
|
7
7
|
import { bold, dim, yellow, green, info, result, red } from './chunk-E2T2SBP5.mjs';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// package.json
|
|
3
3
|
var package_default = {
|
|
4
4
|
name: "@cimplify/cli",
|
|
5
|
-
version: "0.6.
|
|
5
|
+
version: "0.6.15",
|
|
6
6
|
description: "Cimplify CLI \u2014 deploy, manage env vars, link projects, and scaffold storefronts",
|
|
7
7
|
keywords: [
|
|
8
8
|
"cimplify",
|
|
@@ -47,7 +47,7 @@ var package_default = {
|
|
|
47
47
|
vitest: "^4.1.5"
|
|
48
48
|
},
|
|
49
49
|
dependencies: {
|
|
50
|
-
"@cimplify/sdk": "^0.49.
|
|
50
|
+
"@cimplify/sdk": "^0.49.1"
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
|
package/dist/dispatcher.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { TEMPLATES } from './chunk-
|
|
3
|
-
import { package_default } from './chunk-
|
|
2
|
+
import { TEMPLATES } from './chunk-DEWCHGWU.mjs';
|
|
3
|
+
import { package_default } from './chunk-OSS47KZP.mjs';
|
|
4
4
|
|
|
5
5
|
// src/dispatcher.ts
|
|
6
6
|
var VERSION = package_default.version ?? "unknown";
|
|
@@ -138,16 +138,16 @@ var COMMANDS = {
|
|
|
138
138
|
logs: () => import('./logs-YNN2PQ24.mjs'),
|
|
139
139
|
status: () => import('./status-JSYXM5RT.mjs'),
|
|
140
140
|
dev: () => import('./dev-ONW2S77K.mjs'),
|
|
141
|
-
introspect: () => import('./introspect-
|
|
141
|
+
introspect: () => import('./introspect-J7GVKQK7.mjs'),
|
|
142
142
|
inspect: () => import('./inspect-CGYX4DDF.mjs'),
|
|
143
|
-
doctor: () => import('./doctor-
|
|
144
|
-
explain: () => import('./explain-
|
|
143
|
+
doctor: () => import('./doctor-WL25JRS3.mjs'),
|
|
144
|
+
explain: () => import('./explain-NY5A533M.mjs'),
|
|
145
145
|
assets: () => import('./assets-74SK63TR.mjs'),
|
|
146
146
|
repo: () => import('./repo-KNQMSPVV.mjs'),
|
|
147
|
-
list: () => import('./list-
|
|
148
|
-
add: () => import('./add-
|
|
149
|
-
update: () => import('./update-
|
|
150
|
-
upgrade: () => import('./update-
|
|
147
|
+
list: () => import('./list-FXOFYX4H.mjs'),
|
|
148
|
+
add: () => import('./add-6KEKFXOW.mjs'),
|
|
149
|
+
update: () => import('./update-WNZKECFJ.mjs'),
|
|
150
|
+
upgrade: () => import('./update-WNZKECFJ.mjs'),
|
|
151
151
|
"auth-step-up": () => import('./auth-step-up-BIUYQJP6.mjs')
|
|
152
152
|
};
|
|
153
153
|
var COMMAND_PREFIXES = {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { gatherIntrospection } from './chunk-
|
|
2
|
+
import { gatherIntrospection } from './chunk-JLSDFVML.mjs';
|
|
3
3
|
import './chunk-K5464A3L.mjs';
|
|
4
4
|
import './chunk-DBZ3UOQ2.mjs';
|
|
5
|
-
import './chunk-
|
|
5
|
+
import './chunk-OSS47KZP.mjs';
|
|
6
6
|
import { parseArgs, flagBool } from './chunk-C4M3DXKC.mjs';
|
|
7
7
|
import { ApiClient } from './chunk-MAOO6ZZ5.mjs';
|
|
8
8
|
import { readAuthOrNull } from './chunk-UBAI443T.mjs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { package_default } from './chunk-
|
|
2
|
+
import { package_default } from './chunk-OSS47KZP.mjs';
|
|
3
3
|
import { parseArgs } from './chunk-C4M3DXKC.mjs';
|
|
4
4
|
import { bold, dim, info, result, CliError, CLI_ERROR_CODE } from './chunk-E2T2SBP5.mjs';
|
|
5
5
|
|
|
@@ -157,7 +157,7 @@ var TOPICS = [
|
|
|
157
157
|
"title": "Revalidation",
|
|
158
158
|
"description": "Canonical cimplify:* cache-tag vocabulary + revalidate helpers",
|
|
159
159
|
"source_url": "https://cimplify.dev/docs/sdk/revalidation",
|
|
160
|
-
"body": 'Cimplify storefronts cache catalogue reads with Next 16\'s `\'use cache\'` + `cacheTag`. When the merchant edits a product, collection, or brand asset, Cimplify POSTs to your storefront\'s `/api/revalidate` with the canonical tag set, and your handler calls `revalidateTag(tag)` for each.\n\nThis page is the canonical contract between Cimplify and your storefront. Use the typed helpers \u2014 never hand-write tag strings \u2014 so the scheme stays in one place.\n\n## Tags\n\nAll tags are namespaced under `cimplify:` so they can\'t collide with consumer tags. Build them via `tags` from `@cimplify/sdk/server`:\n\n```ts\n\n// In a cached server function:\nasync function getProducts() {\n "use cache";\n cacheTag(tags.products());\n cacheLife("hours");\n // \u2026\n}\n```\n\n### Catalogue\n\n| Helper | Tag |\n| --- | --- |\n| `tags.products()` | `cimplify:products` |\n| `tags.product(id)` | `cimplify:product:{id}` |\n| `tags.categories()` | `cimplify:categories` |\n| `tags.category(id)` | `cimplify:category:{id}` |\n| `tags.categoryProducts(id)` | `cimplify:category:{id}:products` |\n| `tags.collections()` | `cimplify:collections` |\n| `tags.collection(id)` | `cimplify:collection:{id}` |\n| `tags.collectionProducts(id)` | `cimplify:collection:{id}:products` |\n| `tags.tag(name)` | `cimplify:tag:{name}` (product tag, e.g. "vegan") |\n| `tags.addons()` | `cimplify:addons` |\n| `tags.addon(id)` | `cimplify:addon:{id}` |\n| `tags.stock()` | `cimplify:stock` |\n| `tags.stockFor(productId)` | `cimplify:stock:{productId}` |\n\n### Brand / business\n\n| Helper | Tag |\n| --- | --- |\n| `tags.business()` | `cimplify:business` |\n| `tags.brand()` | `cimplify:brand` |\n| `tags.locations()` | `cimplify:locations` |\n| `tags.location(id)` | `cimplify:location:{id}` |\n| `tags.locale()` | `cimplify:locale` |\n\n### Pricing / subscriptions\n\n| Helper | Tag |\n| --- | --- |\n| `tags.pricing()` | `cimplify:pricing` |\n| `tags.subscriptions()` | `cimplify:subscriptions` |\n| `tags.subscription(id)` | `cimplify:subscription:{id}` |\n\n### Customer-scoped (Server Actions only)\n\n| Helper | Tag |\n| --- | --- |\n| `tags.orders(customerId)` | `cimplify:orders:{customerId}` |\n| `tags.order(id)` | `cimplify:order:{id}` |\n\n## Granularity\n\nTag with **both** a broad and a precise tag on every read so either-flavour invalidation works:\n\n```ts\ncacheTag(tags.products(), tags.product(id));\n```\n\nThe broad tag (`products`) catches "I changed something product-related, invalidate everything." The precise tag (`product:{id}`) catches "I changed exactly this one product, invalidate only its entries."\n\n## Revalidating from a Server Action\n\n```ts\n\nexport async function saveProduct(id: string, data: ProductInput) {\n await client.catalogue.updateProduct(id, data);\n await revalidateProduct(id);\n}\n```\n\nHelpers:\n\n| Helper | Invalidates |\n| --- | --- |\n| `revalidateProducts()` | `products` |\n| `revalidateProduct(id)` | `product:{id}` + `products` |\n| `revalidateCategories()` | `categories` |\n| `revalidateCategory(id)` | `category:{id}` + `category:{id}:products` + `categories` |\n| `revalidateCollections()` | `collections` |\n| `revalidateCollection(id)` | `collection:{id}` + `collection:{id}:products` + `collections` |\n| `revalidateBusiness()` | `business` |\n| `revalidateBrand()` | `brand` |\n| `revalidateLocations()` | `locations` |\n| `revalidateLocation(id)` | `location:{id}` + `locations` |\n| `revalidatePricing()` | `pricing` + `products` |\n| `revalidateAddOns()` | `addons` |\n| `revalidateAddOn(id)` | `addon:{id}` + `addons` |\n| `revalidateSubscriptions()` | `subscriptions` |\n| `revalidateSubscription(id)` | `subscription:{id}` + `subscriptions` |\n| `revalidateStock(productId?)` | `stock:{productId}` + `stock` (or just `stock` if no id) |\n| `revalidateByTag(tag)` | escape hatch for a raw tag |\n\n## The Cimplify \u2192 storefront contract\n\nWhen a merchant edits something in the dashboard, Cimplify POSTs to your storefront\'s `/api/revalidate` with the matching tag set:\n\n```http\nPOST /api/revalidate\nx-cimplify-timestamp: 1716480000000\nx-cimplify-signature: sha256=<hex>\ncontent-type: application/json\n\n{ "tags": ["cimplify:products", "cimplify:product:p_abc123"] }\n```\n\nYour handler verifies the HMAC (shared secret in `CIMPLIFY_REVALIDATE_SECRET`), iterates `revalidateTag(tag)` for each, and returns 200. The route handler ships in every Cimplify storefront template \u2014 you don\'t write it.\n\nThe tags Cimplify sends use the **exact strings** from this table. If you\'ve tagged your caches with the helpers above, your storefront stays in sync automatically.\n\n## Tag taxonomy is locked\n\nThe vocabulary above is the v1 contract. Adding new tag helpers is non-breaking; removing or renaming any of them bumps the SDK major version. Agents that bake these strings into prompts can pin to v0.x of `@cimplify/sdk`.\n'
|
|
160
|
+
"body": 'Cimplify storefronts cache catalogue reads with Next 16\'s `\'use cache\'` + `cacheTag`. When the merchant edits a product, collection, or brand asset, Cimplify POSTs to your storefront\'s `/api/revalidate` with the canonical tag set, and your handler calls `revalidateTag(tag)` for each.\n\nThis page is the canonical contract between Cimplify and your storefront. Use the typed helpers \u2014 never hand-write tag strings \u2014 so the scheme stays in one place.\n\n## Tags\n\nAll tags are namespaced under `cimplify:` so they can\'t collide with consumer tags. Build them via `tags` from `@cimplify/sdk/server`:\n\n```ts\n\n// In a cached server function:\nasync function getProducts() {\n "use cache";\n cacheTag(tags.products());\n cacheLife("hours");\n // \u2026\n}\n```\n\n### Catalogue\n\n| Helper | Tag |\n| --- | --- |\n| `tags.products()` | `cimplify:products` |\n| `tags.product(id)` | `cimplify:product:{id}` |\n| `tags.categories()` | `cimplify:categories` |\n| `tags.category(id)` | `cimplify:category:{id}` |\n| `tags.categoryProducts(id)` | `cimplify:category:{id}:products` |\n| `tags.collections()` | `cimplify:collections` |\n| `tags.collection(id)` | `cimplify:collection:{id}` |\n| `tags.collectionProducts(id)` | `cimplify:collection:{id}:products` |\n| `tags.tag(name)` | `cimplify:tag:{name}` (product tag, e.g. "vegan") |\n| `tags.addons()` | `cimplify:addons` |\n| `tags.addon(id)` | `cimplify:addon:{id}` |\n| `tags.stock()` | `cimplify:stock` |\n| `tags.stockFor(productId)` | `cimplify:stock:{productId}` |\n\n### Brand / business\n\n| Helper | Tag |\n| --- | --- |\n| `tags.business()` | `cimplify:business` |\n| `tags.brand()` | `cimplify:brand` |\n| `tags.locations()` | `cimplify:locations` |\n| `tags.location(id)` | `cimplify:location:{id}` |\n| `tags.locale()` | `cimplify:locale` |\n\n### Pricing / subscriptions\n\n| Helper | Tag |\n| --- | --- |\n| `tags.pricing()` | `cimplify:pricing` |\n| `tags.subscriptions()` | `cimplify:subscriptions` |\n| `tags.subscription(id)` | `cimplify:subscription:{id}` |\n\n### Customer-scoped (Server Actions only)\n\n| Helper | Tag |\n| --- | --- |\n| `tags.orders(customerId)` | `cimplify:orders:{customerId}` |\n| `tags.order(id)` | `cimplify:order:{id}` |\n\n## Granularity\n\nTag with **both** a broad and a precise tag on every read so either-flavour invalidation works:\n\n```ts\ncacheTag(tags.products(), tags.product(id));\n```\n\nThe broad tag (`products`) catches "I changed something product-related, invalidate everything." The precise tag (`product:{id}`) catches "I changed exactly this one product, invalidate only its entries."\n\n## Revalidating from a Server Action\n\n```ts\n\nexport async function saveProduct(id: string, data: ProductInput) {\n await client.catalogue.updateProduct(id, data);\n await revalidateProduct(id);\n}\n```\n\nHelpers:\n\n| Helper | Invalidates |\n| --- | --- |\n| `revalidateProducts()` | `products` |\n| `revalidateProduct(id)` | `product:{id}` + `products` |\n| `revalidateCategories()` | `categories` |\n| `revalidateCategory(id)` | `category:{id}` + `category:{id}:products` + `categories` |\n| `revalidateCollections()` | `collections` |\n| `revalidateCollection(id)` | `collection:{id}` + `collection:{id}:products` + `collections` |\n| `revalidateBusiness()` | `business` |\n| `revalidateBrand()` | `brand` |\n| `revalidateLocations()` | `locations` |\n| `revalidateLocation(id)` | `location:{id}` + `locations` |\n| `revalidatePricing()` | `pricing` + `products` |\n| `revalidateAddOns()` | `addons` |\n| `revalidateAddOn(id)` | `addon:{id}` + `addons` |\n| `revalidateSubscriptions()` | `subscriptions` |\n| `revalidateSubscription(id)` | `subscription:{id}` + `subscriptions` |\n| `revalidateStock(productId?)` | `stock:{productId}` + `stock` (or just `stock` if no id) |\n| `revalidateByTag(tag)` | escape hatch for a raw tag |\n\n## The Cimplify \u2192 storefront contract\n\nWhen a merchant edits something in the dashboard, Cimplify POSTs to your storefront\'s `/api/revalidate` with the matching tag set:\n\n```http\nPOST /api/revalidate\nx-cimplify-timestamp: 1716480000000\nx-cimplify-signature: sha256=<hex>\ncontent-type: application/json\n\n{ "tags": ["cimplify:products", "cimplify:product:p_abc123"] }\n```\n\nYour handler verifies the HMAC (shared secret in `CIMPLIFY_REVALIDATE_SECRET`), iterates `revalidateTag(tag)` for each, and returns 200. The route handler ships in every Cimplify storefront template \u2014 you don\'t write it.\n\nThe tags Cimplify sends use the **exact strings** from this table. If you\'ve tagged your caches with the helpers above, your storefront stays in sync automatically.\n\n## Dynamic routes \u2014 tag by **ID**, never by slug\n\nCimplify dispatches revalidation tags **keyed by database ID**, not by URL slug. A `/products/[slug]` page that caches itself under `tags.product(slug)` will never be invalidated by an edit \u2014 the tag the storefront wrote doesn\'t match the tag Cimplify fires.\n\nAlways resolve the slug to a record first, then tag with `record.id`. Next 16 lets you call `cacheTag` **after** an `await`, so this is one function, not two:\n\n```ts title="app/products/[slug]/page.tsx \u2014 correct"\n\nasync function getProduct(slug: string) {\n "use cache";\n cacheLife("max");\n\n const r = await getServerClient().catalogue.getProductBySlug(slug);\n if (!r.ok) {\n // 404s tagged at the collection level so deleting + re-creating works.\n cacheTag(tags.products());\n return null;\n }\n\n // Tag with the resolved ID so revalidateProduct(id) from Cimplify hits.\n cacheTag(tags.product(r.value.id), tags.products());\n return r.value;\n}\n```\n\nThe same pattern applies to `[slug]` routes for categories, collections, addons, locations, and so on \u2014 always tag with the resolved `record.id`, never with the URL slug.\n\n### Why this matters\n\n- **Renames don\'t orphan.** The cache key is keyed on the slug (the function argument), so a renamed product gets a fresh cache entry under the new slug. The old slug-keyed entry is invalidated via the `tags.products()` collection tag and will 404 naturally.\n- **IDs are stable.** Cimplify\'s bus emits `ProductUpdated { id }` events; the slug isn\'t on the event payload, and adding it would create races with concurrent rename. Keeping the tag scheme ID-only keeps the contract simple.\n- **You get instant freshness.** With Cimplify\'s tag-cache + CDN-purge in place, a `cacheLife("max")` entry can sit cached for days and still flip fresh within ~1s of an edit \u2014 but only if the tag actually matches.\n\n## `cacheLife` \u2014 go long\n\nPair the ID-keyed tagging above with a long `cacheLife`. Cimplify invalidates both the CDN and the underlying R2 cache layer the moment a tag fires, so there\'s no benefit to short timer-based expirations. Defaults that work:\n\n| Page shape | Recommended `cacheLife` |\n| --- | --- |\n| Detail page tagged with `tags.product(id)` | `"max"` |\n| Listing tagged with `tags.products()` | `"max"` (or `"days"` if you prefer a backstop) |\n| Slug-keyed wrapper tagged only with collection (e.g. slug\u2192id lookup) | `"days"` |\n| Pages that mix cached chrome with uncached personalisation | the cached parts: `"max"`; personalised parts: no `\'use cache\'` |\n\nShort profiles (`"minutes"`, `"hours"`) are only needed when you\'re caching data **not** owned by Cimplify (a weather API, an external CMS) \u2014 anything Cimplify owns is covered by on-demand invalidation.\n\n## Tag taxonomy is locked\n\nThe vocabulary above is the v1 contract. Adding new tag helpers is non-breaking; removing or renaming any of them bumps the SDK major version. Agents that bake these strings into prompts can pin to v0.x of `@cimplify/sdk`.\n'
|
|
161
161
|
},
|
|
162
162
|
{
|
|
163
163
|
"name": "inspect-suggestions",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
export { run as default, extractMockSeed, gatherIntrospection, renderIntrospection } from './chunk-
|
|
2
|
+
export { run as default, extractMockSeed, gatherIntrospection, renderIntrospection } from './chunk-JLSDFVML.mjs';
|
|
3
3
|
import './chunk-K5464A3L.mjs';
|
|
4
4
|
import './chunk-DBZ3UOQ2.mjs';
|
|
5
|
-
import './chunk-
|
|
5
|
+
import './chunk-OSS47KZP.mjs';
|
|
6
6
|
import './chunk-C4M3DXKC.mjs';
|
|
7
7
|
import './chunk-UBAI443T.mjs';
|
|
8
8
|
import './chunk-E2T2SBP5.mjs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { REGISTRY_INDEX } from './chunk-
|
|
2
|
+
import { REGISTRY_INDEX } from './chunk-DEWCHGWU.mjs';
|
|
3
3
|
import { parseArgs, flagBool } from './chunk-C4M3DXKC.mjs';
|
|
4
4
|
import { CliError, CLI_ERROR_CODE, info, bold, dim, green, result } from './chunk-E2T2SBP5.mjs';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { package_default } from './chunk-
|
|
2
|
+
import { package_default } from './chunk-OSS47KZP.mjs';
|
|
3
3
|
import { promptYesNo } from './chunk-ITAFAORS.mjs';
|
|
4
4
|
import { parseArgs, flagBool, flagString } from './chunk-C4M3DXKC.mjs';
|
|
5
5
|
import { success, bold, info, dim, result, failure, CliError, CLI_ERROR_CODE, step, isJsonMode } from './chunk-E2T2SBP5.mjs';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cimplify/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.15",
|
|
4
4
|
"description": "Cimplify CLI — deploy, manage env vars, link projects, and scaffold storefronts",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cimplify",
|
|
@@ -45,6 +45,6 @@
|
|
|
45
45
|
"vitest": "^4.1.5"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@cimplify/sdk": "^0.49.
|
|
48
|
+
"@cimplify/sdk": "^0.49.1"
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -43,12 +43,17 @@ interface ProductData {
|
|
|
43
43
|
|
|
44
44
|
async function getProduct(slug: string): Promise<ProductData | null> {
|
|
45
45
|
"use cache";
|
|
46
|
-
|
|
47
|
-
cacheLife("hours");
|
|
46
|
+
cacheLife("max");
|
|
48
47
|
|
|
49
48
|
const client = getServerClient();
|
|
50
49
|
const r = await client.catalogue.getProductBySlug(slug);
|
|
51
|
-
if (!r.ok)
|
|
50
|
+
if (!r.ok) {
|
|
51
|
+
cacheTag(tags.products());
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
// Tag with the resolved ID — Cimplify dispatches tags.product(id), not slug.
|
|
55
|
+
// See https://cimplify.dev/docs/sdk/revalidation#dynamic-routes--tag-by-id-never-by-slug
|
|
56
|
+
cacheTag(tags.product(r.value.id), tags.products());
|
|
52
57
|
|
|
53
58
|
const related = r.value.category_id
|
|
54
59
|
? await client.catalogue
|