@01.software/cli 0.10.1 → 0.10.4

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.
@@ -1,7 +1,7 @@
1
1
  // src/handler.ts
2
2
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
3
3
 
4
- // ../../packages/auth-contracts/dist/index.js
4
+ // ../../packages/auth-contracts/src/index.ts
5
5
  var MCP_RESOURCE_AUDIENCE = "https://mcp.01.software/mcp";
6
6
  var MCP_OAUTH_ISSUER = "https://01.software";
7
7
  var MCP_PROTECTED_RESOURCE_METADATA_PATH = "/.well-known/oauth-protected-resource/mcp";
@@ -91,8 +91,9 @@ function parseJsonWhere(where) {
91
91
  }
92
92
  }
93
93
 
94
- // ../../packages/contracts/src/tenant/index.ts
94
+ // ../../packages/contracts/dist/index.js
95
95
  import { z } from "zod";
96
+ import { z as z2 } from "zod";
96
97
  var tenantFieldConfigStateSchema = z.object({
97
98
  hiddenFields: z.array(z.string()),
98
99
  isHidden: z.boolean()
@@ -241,9 +242,6 @@ var collectionSchemaResponseSchema = z.object({
241
242
  fields: z.array(collectionFieldSchema)
242
243
  }).strict()
243
244
  }).strict();
244
-
245
- // ../../packages/contracts/src/ecommerce/index.ts
246
- import { z as z2 } from "zod";
247
245
  var transactionStatusSchema = z2.enum([
248
246
  "pending",
249
247
  "paid",
@@ -295,7 +293,8 @@ var restockActionSchema = z2.enum(["return_to_stock", "discard"]);
295
293
  var returnWithRefundItemSchema = z2.object({
296
294
  orderItem: z2.union([z2.string(), z2.number()]).transform(String),
297
295
  quantity: z2.number().int().positive("quantity must be a positive integer"),
298
- restockAction: restockActionSchema.default("return_to_stock")
296
+ restockAction: restockActionSchema.default("return_to_stock"),
297
+ restockingFee: z2.number().min(0, "restockingFee must be non-negative").optional().describe("Restocking fee charged for this line (ADR 0005 \xA7Gap 1)")
299
298
  }).strict();
300
299
  var returnWithRefundSchema = z2.object({
301
300
  orderNumber: z2.string().min(1, "orderNumber is required").describe("Order number (required)"),
@@ -303,13 +302,12 @@ var returnWithRefundSchema = z2.object({
303
302
  reasonDetail: z2.string().optional().describe("Detailed reason text (optional)"),
304
303
  returnItems: z2.array(returnWithRefundItemSchema).min(1, "At least one return item is required").max(100, "Too many return items").describe("Array of products to return (required)"),
305
304
  refundAmount: z2.number().min(0, "refundAmount must be non-negative").describe("Refund amount (required, min 0)"),
305
+ returnShippingFee: z2.number().min(0, "returnShippingFee must be non-negative").optional().describe("Return shipping fee charged to the customer (ADR 0005 \xA7Gap 1)"),
306
306
  pgPaymentId: z2.string().min(1, "pgPaymentId is required").describe("PG payment ID for refund (required)"),
307
307
  paymentKey: z2.string().min(1).optional().describe("Provider payment key for verified refund"),
308
308
  refundReceiptUrl: z2.string().optional().describe("Refund receipt URL (optional)")
309
309
  }).strict();
310
310
  var ReturnWithRefundSchema = returnWithRefundSchema;
311
-
312
- // ../../packages/contracts/src/mcp/index.ts
313
311
  var MCP_TOOL_CONTRACT = {
314
312
  "query-collection": {
315
313
  consoleRole: "tenant-viewer",
@@ -331,6 +329,16 @@ var MCP_TOOL_CONTRACT = {
331
329
  oauthScope: "mcp:read",
332
330
  readOnly: true
333
331
  },
332
+ "product-detail": {
333
+ consoleRole: "tenant-viewer",
334
+ oauthScope: "mcp:read",
335
+ readOnly: true
336
+ },
337
+ "product-upsert": {
338
+ consoleRole: "tenant-admin",
339
+ oauthScope: "mcp:write",
340
+ readOnly: false
341
+ },
334
342
  "validate-discount": {
335
343
  consoleRole: "tenant-viewer",
336
344
  oauthScope: "mcp:read",
@@ -530,6 +538,21 @@ var TOOL_POLICY_MANIFEST = {
530
538
  consoleSurface: "GET /api/products/{id}/stock",
531
539
  annotationPolicy: READ_ONLY_ANNOTATION
532
540
  },
541
+ "product-detail": {
542
+ category: "read-only-collection",
543
+ oauthScope: MCP_SCOPES.read,
544
+ consoleRole: "tenant-viewer",
545
+ consoleSurface: "GET /api/products/detail",
546
+ annotationPolicy: READ_ONLY_ANNOTATION
547
+ },
548
+ "product-upsert": {
549
+ category: "mutation-product",
550
+ oauthScope: MCP_SCOPES.write,
551
+ consoleRole: "tenant-admin",
552
+ consoleSurface: "POST /api/products/upsert",
553
+ annotationPolicy: DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION,
554
+ exemptionReason: REASON_IDEMPOTENT_DESTRUCTIVE_UPDATE
555
+ },
533
556
  "validate-discount": {
534
557
  category: "read-only-collection",
535
558
  oauthScope: MCP_SCOPES.read,
@@ -883,9 +906,12 @@ function signMcpServiceToken(context) {
883
906
  }
884
907
 
885
908
  // src/lib/console-api.ts
886
- var BASE_URL = process.env.SOFTWARE_API_URL || "http://localhost:3000";
909
+ var DEFAULT_API_URL = "https://api.01.software";
887
910
  var TIMEOUT_MS = 5e3;
888
911
  var MISSING_HTTP_AUTH_CONTEXT_ERROR = "MCP HTTP requests require a validated OAuth tenant context before tool execution.";
912
+ function resolveConsoleApiUrl() {
913
+ return (process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL || DEFAULT_API_URL).replace(/\/$/, "");
914
+ }
889
915
  function resolveAuthHeaderContext() {
890
916
  const oauthContext = tenantAuthContext();
891
917
  if (oauthContext) {
@@ -935,7 +961,7 @@ async function consoleGet(path, apiKey) {
935
961
  const controller = new AbortController();
936
962
  const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
937
963
  try {
938
- const res = await fetch(`${BASE_URL}${path}`, {
964
+ const res = await fetch(`${resolveConsoleApiUrl()}${path}`, {
939
965
  headers: authHeaders,
940
966
  signal: controller.signal
941
967
  });
@@ -954,7 +980,7 @@ async function consolePost(path, body, apiKey) {
954
980
  const controller = new AbortController();
955
981
  const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
956
982
  try {
957
- const res = await fetch(`${BASE_URL}${path}`, {
983
+ const res = await fetch(`${resolveConsoleApiUrl()}${path}`, {
958
984
  method: "POST",
959
985
  headers: { ...authHeaders, "Content-Type": "application/json" },
960
986
  body: JSON.stringify(body),
@@ -975,7 +1001,7 @@ async function consolePostTelemetry(path, body, apiKey) {
975
1001
  const controller = new AbortController();
976
1002
  const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
977
1003
  try {
978
- const res = await fetch(`${BASE_URL}${path}`, {
1004
+ const res = await fetch(`${resolveConsoleApiUrl()}${path}`, {
979
1005
  method: "POST",
980
1006
  headers: { ...authHeaders, "Content-Type": "application/json" },
981
1007
  body: JSON.stringify(body),
@@ -1076,7 +1102,7 @@ async function swallow(promise) {
1076
1102
  import { z as z3 } from "zod";
1077
1103
 
1078
1104
  // src/lib/client.ts
1079
- import { createServerClient } from "@01.software/sdk";
1105
+ import { createServerClient } from "@01.software/sdk/server";
1080
1106
  var MISSING_HTTP_AUTH_CONTEXT_ERROR2 = "MCP HTTP requests require a validated OAuth tenant context before tool execution.";
1081
1107
  var HTTP_OAUTH_SDK_CLIENT_ERROR = "MCP HTTP OAuth requests cannot use SDK-backed tools. Use reviewed Console service endpoints for OAuth transport.";
1082
1108
  function getClient() {
@@ -1873,6 +1899,122 @@ async function stockCheck({
1873
1899
  }
1874
1900
  }
1875
1901
 
1902
+ // src/tools/product-detail.ts
1903
+ import { z as z22 } from "zod";
1904
+ var schema22 = {
1905
+ slug: z22.string().optional().describe("Product slug (one of slug or id required)"),
1906
+ id: z22.string().optional().describe("Product id (one of slug or id required)")
1907
+ };
1908
+ var metadata22 = {
1909
+ name: "product-detail",
1910
+ description: "Fetch full product detail by slug or id. Returns one resolver-ready product with variants, option slugs, option value slugs/media, brand, categories, tags, images, videos, and listing rollup, or null if missing/unpublished/wrong tenant/feature disabled.",
1911
+ annotations: {
1912
+ title: "Get product detail",
1913
+ readOnlyHint: true,
1914
+ destructiveHint: false,
1915
+ idempotentHint: true
1916
+ }
1917
+ };
1918
+ async function productDetail({
1919
+ slug,
1920
+ id
1921
+ }) {
1922
+ try {
1923
+ if (Boolean(slug) === Boolean(id)) {
1924
+ return toolError(new Error("Provide exactly one of slug or id"));
1925
+ }
1926
+ const client = getClient();
1927
+ const params = slug ? { slug } : { id };
1928
+ const result = await client.commerce.product.detail(params);
1929
+ return toolSuccess({ data: result });
1930
+ } catch (error) {
1931
+ return toolError(error);
1932
+ }
1933
+ }
1934
+
1935
+ // src/tools/product-upsert.ts
1936
+ import { z as z23 } from "zod";
1937
+ var optionValueSchema = z23.object({
1938
+ id: z23.string().optional().describe("Stable existing option-value ID for rename-safe updates"),
1939
+ value: z23.string().describe("Display label (e.g. Black, S)"),
1940
+ slug: z23.string().optional().describe(
1941
+ "Optional compatibility value token. The server generates one from value on create when omitted; not canonical identity."
1942
+ ),
1943
+ swatchColor: z23.string().nullable().optional(),
1944
+ thumbnail: z23.string().nullable().optional(),
1945
+ images: z23.array(z23.string()).optional(),
1946
+ metadata: z23.unknown().optional()
1947
+ });
1948
+ var optionSchema = z23.object({
1949
+ id: z23.string().optional().describe("Stable existing option ID for rename-safe updates"),
1950
+ title: z23.string().describe("Option name (e.g. Color, Size)"),
1951
+ slug: z23.string().optional().describe(
1952
+ "Optional compatibility option token. The server generates one from title on create when omitted; not canonical identity."
1953
+ ),
1954
+ values: z23.array(optionValueSchema).describe("Allowed option values")
1955
+ });
1956
+ var variantOptionValueSchema = z23.object({
1957
+ valueSlug: z23.string().optional(),
1958
+ valueId: z23.string().optional(),
1959
+ value: z23.string().optional()
1960
+ });
1961
+ var variantSchema = z23.object({
1962
+ id: z23.string().optional().describe("Existing variant ID for updates"),
1963
+ optionValues: z23.union([
1964
+ z23.record(z23.string(), z23.union([z23.string(), variantOptionValueSchema])),
1965
+ z23.array(z23.string())
1966
+ ]).optional().describe(
1967
+ "Option-value selection. Prefer stable option-value IDs, either as an array or object values using { valueId }. Slug maps and exact { OptionTitle: ValueLabel } maps remain compatibility-only and fail when labels are ambiguous."
1968
+ ),
1969
+ sku: z23.string().nullable().optional(),
1970
+ title: z23.string().nullable().optional(),
1971
+ price: z23.number().nonnegative().describe("Selling price (KRW, min 0)"),
1972
+ compareAtPrice: z23.number().nonnegative().nullable().optional(),
1973
+ stock: z23.number().int().nonnegative().optional(),
1974
+ isUnlimited: z23.boolean().optional(),
1975
+ weight: z23.number().nonnegative().nullable().optional(),
1976
+ requiresShipping: z23.boolean().optional(),
1977
+ barcode: z23.string().nullable().optional(),
1978
+ externalId: z23.string().nullable().optional(),
1979
+ isActive: z23.boolean().optional(),
1980
+ thumbnail: z23.string().nullable().optional(),
1981
+ images: z23.array(z23.string()).optional(),
1982
+ metadata: z23.unknown().optional()
1983
+ });
1984
+ var schema23 = {
1985
+ product: z23.record(z23.string(), z23.unknown()).describe(
1986
+ "Product fields. Include `id` to update an existing product; omit for create (then `title` is required)."
1987
+ ),
1988
+ options: z23.array(optionSchema).optional().describe(
1989
+ "Option definitions. Include stable option/value IDs when updating or renaming existing rows. Slugs are optional compatibility metadata generated from title/value on create when omitted; omitted options on an existing product are deleted (with their values)."
1990
+ ),
1991
+ variants: z23.array(variantSchema).optional().describe(
1992
+ "Variant rows. Prefer stable option-value IDs in optionValues. Slug/title maps are compatibility inputs. Omitted variants on an existing product are deleted, unless referenced by an active cart or non-terminal order \u2014 those are soft-deactivated (isActive: false)."
1993
+ )
1994
+ };
1995
+ var metadata23 = {
1996
+ name: "product-upsert",
1997
+ description: "Atomically create or update a product together with its options, option-values, and variants in a single transaction. Mirrors Shopify productSet semantics. Any failure rolls back the entire write.",
1998
+ annotations: {
1999
+ title: "Upsert product (atomic)",
2000
+ readOnlyHint: false,
2001
+ destructiveHint: true,
2002
+ idempotentHint: true,
2003
+ openWorldHint: false
2004
+ }
2005
+ };
2006
+ async function productUpsert(params) {
2007
+ try {
2008
+ const client = getClient();
2009
+ const result = await client.commerce.product.upsert(
2010
+ params
2011
+ );
2012
+ return toolSuccess({ data: result });
2013
+ } catch (error) {
2014
+ return toolError(error);
2015
+ }
2016
+ }
2017
+
1876
2018
  // src/tools/get-collection-schema.ts
1877
2019
  import { SERVER_COLLECTIONS as SERVER_COLLECTIONS3 } from "@01.software/sdk";
1878
2020
 
@@ -1887,8 +2029,8 @@ async function getCollectionSchema(collection) {
1887
2029
  }
1888
2030
 
1889
2031
  // src/tools/get-collection-schema.ts
1890
- var schema22 = createCollectionSchemaToolInputSchema(SERVER_COLLECTIONS3).shape;
1891
- var metadata22 = {
2032
+ var schema24 = createCollectionSchemaToolInputSchema(SERVER_COLLECTIONS3).shape;
2033
+ var metadata24 = {
1892
2034
  name: "get-collection-schema",
1893
2035
  description: "Get the authoritative tenant-aware collection schema from console. Use this before create/update to understand writable fields, hidden fields, required metadata, and collection-level visibility.",
1894
2036
  annotations: {
@@ -1939,8 +2081,8 @@ async function getTenantFeatureProgress(feature, includeEvidence = false) {
1939
2081
  }
1940
2082
 
1941
2083
  // src/tools/get-tenant-context.ts
1942
- var schema23 = tenantContextToolInputSchema.shape;
1943
- var metadata23 = {
2084
+ var schema25 = tenantContextToolInputSchema.shape;
2085
+ var metadata25 = {
1944
2086
  name: "get-tenant-context",
1945
2087
  description: "Get current tenant features, active collections, and field visibility. Call this at the start of every session. Use includeCounts=true to also get per-collection document counts for setup diagnostics.",
1946
2088
  annotations: {
@@ -2017,8 +2159,8 @@ async function handler({
2017
2159
  }
2018
2160
 
2019
2161
  // src/tools/check-feature-progress.ts
2020
- var schema24 = tenantFeatureProgressInputSchema.shape;
2021
- var metadata24 = {
2162
+ var schema26 = tenantFeatureProgressInputSchema.shape;
2163
+ var metadata26 = {
2022
2164
  name: "check-feature-progress",
2023
2165
  description: "Check tenant implementation progress for a supported feature. Start with feature=ecommerce to inspect catalog, cart, checkout, payment result, webhook, and operations readiness without mutating tenant data.",
2024
2166
  annotations: {
@@ -2041,7 +2183,7 @@ async function handler2({
2041
2183
  }
2042
2184
 
2043
2185
  // src/tools/list-configurable-fields.ts
2044
- import { z as z22 } from "zod";
2186
+ import { z as z24 } from "zod";
2045
2187
 
2046
2188
  // src/lib/field-config.ts
2047
2189
  async function fetchFieldConfigs() {
@@ -2064,12 +2206,12 @@ function invalidateFieldConfigCache() {
2064
2206
  }
2065
2207
 
2066
2208
  // src/tools/list-configurable-fields.ts
2067
- var schema25 = {
2068
- collection: z22.string().optional().describe(
2209
+ var schema27 = {
2210
+ collection: z24.string().optional().describe(
2069
2211
  "Filter by collection slug (optional \u2014 returns all if omitted). Use this filter to reduce response size when you know which collection to check."
2070
2212
  )
2071
2213
  };
2072
- var metadata25 = {
2214
+ var metadata27 = {
2073
2215
  name: "list-configurable-fields",
2074
2216
  description: "List all configurable fields for tenant collections with current visibility state. Shows which fields can be shown/hidden and their current status. Returns all collections including inactive features \u2014 cross-reference with get-tenant-context for active features. Response includes ~300 fields across 47 collections \u2014 use collection filter when possible.",
2075
2217
  annotations: {
@@ -2100,17 +2242,17 @@ async function listConfigurableFields(params) {
2100
2242
  }
2101
2243
 
2102
2244
  // src/tools/update-field-config.ts
2103
- import { z as z23 } from "zod";
2104
- var schema26 = {
2105
- collection: z23.string().min(1).describe("Collection slug (required)"),
2106
- hiddenFields: z23.array(z23.string().min(1).max(200)).max(300).describe(
2245
+ import { z as z25 } from "zod";
2246
+ var schema28 = {
2247
+ collection: z25.string().min(1).describe("Collection slug (required)"),
2248
+ hiddenFields: z25.array(z25.string().min(1).max(200)).max(300).describe(
2107
2249
  "Fields to hide (required). This is a FULL REPLACE \u2014 fields NOT in this list will be shown. Pass [] to show all fields. Use list-configurable-fields first to see available field paths."
2108
2250
  ),
2109
- isHidden: z23.boolean().optional().describe(
2251
+ isHidden: z25.boolean().optional().describe(
2110
2252
  "Hide the entire collection from Admin Panel (optional). When true, individual hiddenFields are irrelevant."
2111
2253
  )
2112
2254
  };
2113
- var metadata26 = {
2255
+ var metadata28 = {
2114
2256
  name: "update-field-config",
2115
2257
  description: "Update field visibility configuration for a tenant collection. Hidden fields are removed from the Admin Panel UI. IMPORTANT: hiddenFields is a full replace, not a merge. Always call list-configurable-fields first to see current state.",
2116
2258
  annotations: {
@@ -2138,7 +2280,7 @@ async function updateFieldConfig(params) {
2138
2280
  }
2139
2281
 
2140
2282
  // src/tools/sdk-get-recipe.ts
2141
- import { z as z24 } from "zod";
2283
+ import { z as z26 } from "zod";
2142
2284
 
2143
2285
  // src/lib/sdk-recipes.ts
2144
2286
  var recipes = {
@@ -2148,14 +2290,16 @@ var recipes = {
2148
2290
  recommendedSurface: "react-query",
2149
2291
  runtime: "browser",
2150
2292
  code: `import { createClient } from '@01.software/sdk'
2293
+ import { createQueryHooks } from '@01.software/sdk/query'
2151
2294
 
2152
2295
  const client = createClient({
2153
2296
  publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!,
2154
2297
  })
2298
+ const query = createQueryHooks(client)
2155
2299
 
2156
2300
  // React Query hook \u2014 handles caching and background updates
2157
2301
  function ProductList() {
2158
- const { data, isLoading, error } = client.query.useQuery({
2302
+ const { data, isLoading, error } = query.useQuery({
2159
2303
  collection: 'products',
2160
2304
  options: {
2161
2305
  where: { status: { equals: 'published' } },
@@ -2187,7 +2331,7 @@ function ProductList() {
2187
2331
  title: "Fetch collection list (server)",
2188
2332
  recommendedSurface: "query-builder",
2189
2333
  runtime: "server",
2190
- code: `import { createServerClient } from '@01.software/sdk'
2334
+ code: `import { createServerClient } from '@01.software/sdk/server'
2191
2335
 
2192
2336
  const client = createServerClient({
2193
2337
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -2220,13 +2364,15 @@ const result = await client.collections.from('products').find({
2220
2364
  recommendedSurface: "react-query",
2221
2365
  runtime: "browser",
2222
2366
  code: `import { createClient } from '@01.software/sdk'
2367
+ import { createQueryHooks } from '@01.software/sdk/query'
2223
2368
 
2224
2369
  const client = createClient({
2225
2370
  publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!,
2226
2371
  })
2372
+ const query = createQueryHooks(client)
2227
2373
 
2228
2374
  function ProductDetail({ id }: { id: string }) {
2229
- const { data, isLoading } = client.query.useQueryById({
2375
+ const { data, isLoading } = query.useQueryById({
2230
2376
  collection: 'products',
2231
2377
  id,
2232
2378
  })
@@ -2246,7 +2392,7 @@ function ProductDetail({ id }: { id: string }) {
2246
2392
  title: "Fetch single item by ID (server)",
2247
2393
  recommendedSurface: "query-builder",
2248
2394
  runtime: "server",
2249
- code: `import { createServerClient } from '@01.software/sdk'
2395
+ code: `import { createServerClient } from '@01.software/sdk/server'
2250
2396
 
2251
2397
  const client = createServerClient({
2252
2398
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -2269,7 +2415,7 @@ console.log(product.title)`,
2269
2415
  title: "Create a new item (server only)",
2270
2416
  recommendedSurface: "server-api",
2271
2417
  runtime: "server",
2272
- code: `import { createServerClient } from '@01.software/sdk'
2418
+ code: `import { createServerClient } from '@01.software/sdk/server'
2273
2419
 
2274
2420
  const client = createServerClient({
2275
2421
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -2298,7 +2444,7 @@ const result = await client.collections.from('products').create({
2298
2444
  title: "Update an existing item (server only)",
2299
2445
  recommendedSurface: "server-api",
2300
2446
  runtime: "server",
2301
- code: `import { createServerClient } from '@01.software/sdk'
2447
+ code: `import { createServerClient } from '@01.software/sdk/server'
2302
2448
 
2303
2449
  const client = createServerClient({
2304
2450
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -2327,7 +2473,7 @@ const result = await client.collections.from('products').update('product-id', {
2327
2473
  title: "Delete an item (server only)",
2328
2474
  recommendedSurface: "server-api",
2329
2475
  runtime: "server",
2330
- code: `import { createServerClient } from '@01.software/sdk'
2476
+ code: `import { createServerClient } from '@01.software/sdk/server'
2331
2477
 
2332
2478
  const client = createServerClient({
2333
2479
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -2352,10 +2498,12 @@ console.log('Deleted:', deleted.title)`,
2352
2498
  recommendedSurface: "react-query",
2353
2499
  runtime: "browser",
2354
2500
  code: `import { createClient } from '@01.software/sdk'
2501
+ import { createQueryHooks } from '@01.software/sdk/query'
2355
2502
 
2356
2503
  const client = createClient({
2357
2504
  publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!,
2358
2505
  })
2506
+ const query = createQueryHooks(client)
2359
2507
 
2360
2508
  function InfiniteProductList() {
2361
2509
  const {
@@ -2364,7 +2512,7 @@ function InfiniteProductList() {
2364
2512
  hasNextPage,
2365
2513
  isFetchingNextPage,
2366
2514
  isLoading,
2367
- } = client.query.useInfiniteQuery({
2515
+ } = query.useInfiniteQuery({
2368
2516
  collection: 'products',
2369
2517
  options: { where: { status: { equals: 'published' } } },
2370
2518
  pageSize: 20,
@@ -2399,7 +2547,8 @@ function InfiniteProductList() {
2399
2547
  title: "SSR data prefetching (server)",
2400
2548
  recommendedSurface: "react-query",
2401
2549
  runtime: "server",
2402
- code: `import { createServerClient } from '@01.software/sdk'
2550
+ code: `import { createServerClient } from '@01.software/sdk/server'
2551
+ import { createServerQueryHooks, getQueryClient } from '@01.software/sdk/query'
2403
2552
  import { dehydrate, HydrationBoundary } from '@tanstack/react-query'
2404
2553
 
2405
2554
  // In a Next.js Server Component or getServerSideProps:
@@ -2407,27 +2556,29 @@ const client = createServerClient({
2407
2556
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
2408
2557
  secretKey: process.env.SOFTWARE_SECRET_KEY!,
2409
2558
  })
2559
+ const queryClient = getQueryClient()
2560
+ const serverQuery = createServerQueryHooks(client, queryClient)
2410
2561
 
2411
2562
  // Prefetch list \u2014 client hydrates instantly without a loading state
2412
- await client.query.prefetchQuery({
2563
+ await serverQuery.prefetchQuery({
2413
2564
  collection: 'products',
2414
2565
  options: { limit: 20 },
2415
2566
  })
2416
2567
 
2417
2568
  // Prefetch single item
2418
- await client.query.prefetchQueryById({
2569
+ await serverQuery.prefetchQueryById({
2419
2570
  collection: 'products',
2420
2571
  id: 'product-id',
2421
2572
  })
2422
2573
 
2423
2574
  // Prefetch infinite list
2424
- await client.query.prefetchInfiniteQuery({
2575
+ await serverQuery.prefetchInfiniteQuery({
2425
2576
  collection: 'products',
2426
2577
  pageSize: 20,
2427
2578
  })
2428
2579
 
2429
2580
  // Dehydrate and pass to client
2430
- const state = dehydrate(client.query.queryClient)
2581
+ const state = dehydrate(queryClient)
2431
2582
 
2432
2583
  export default function Page() {
2433
2584
  return (
@@ -2497,7 +2648,7 @@ await client.customer.resetPassword(token, 'newPassword123')`,
2497
2648
  title: "File upload pattern (server)",
2498
2649
  recommendedSurface: "server-api",
2499
2650
  runtime: "server",
2500
- code: `import { createServerClient } from '@01.software/sdk'
2651
+ code: `import { createServerClient } from '@01.software/sdk/server'
2501
2652
 
2502
2653
  const client = createServerClient({
2503
2654
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -2528,7 +2679,7 @@ const result = await client.collections.from('images').create(formData as unknow
2528
2679
  title: "Bulk update/delete (server only)",
2529
2680
  recommendedSurface: "server-api",
2530
2681
  runtime: "server",
2531
- code: `import { createServerClient } from '@01.software/sdk'
2682
+ code: `import { createServerClient } from '@01.software/sdk/server'
2532
2683
 
2533
2684
  const client = createServerClient({
2534
2685
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -2570,8 +2721,8 @@ function getRecipe(goal, runtime = "both") {
2570
2721
  }
2571
2722
 
2572
2723
  // src/tools/sdk-get-recipe.ts
2573
- var schema27 = {
2574
- goal: z24.enum([
2724
+ var schema29 = {
2725
+ goal: z26.enum([
2575
2726
  "fetch-list",
2576
2727
  "fetch-by-id",
2577
2728
  "create-item",
@@ -2583,11 +2734,11 @@ var schema27 = {
2583
2734
  "file-upload",
2584
2735
  "bulk-operations"
2585
2736
  ]).describe("What the user wants to accomplish"),
2586
- runtime: z24.enum(["browser", "server", "both"]).default("both").describe("Target runtime environment"),
2587
- collection: z24.string().optional().describe("Specific collection name if applicable"),
2588
- includeExample: z24.boolean().default(true).describe("Whether to include a full code example")
2737
+ runtime: z26.enum(["browser", "server", "both"]).default("both").describe("Target runtime environment"),
2738
+ collection: z26.string().optional().describe("Specific collection name if applicable"),
2739
+ includeExample: z26.boolean().default(true).describe("Whether to include a full code example")
2589
2740
  };
2590
- var metadata27 = {
2741
+ var metadata29 = {
2591
2742
  name: "sdk-get-recipe",
2592
2743
  description: "Get a complete SDK code recipe for a specific task. Returns recommended approach, code example, and related documentation links. Use this FIRST when the user asks how to do something with the SDK.",
2593
2744
  annotations: {
@@ -2630,7 +2781,7 @@ function handler3({
2630
2781
  }
2631
2782
 
2632
2783
  // src/tools/sdk-search-docs.ts
2633
- import { z as z25 } from "zod";
2784
+ import { z as z27 } from "zod";
2634
2785
 
2635
2786
  // src/lib/sdk-doc-index.ts
2636
2787
  var docIndex = [
@@ -2680,15 +2831,15 @@ var docIndex = [
2680
2831
  },
2681
2832
  {
2682
2833
  title: "Query Builder \u2014 Metadata Generation",
2683
- keywords: ["metadata", "findMetadata", "findMetadataById", "next.js metadata", "seo", "open graph", "query builder"],
2684
- summary: "client.collections.from(collection).findMetadata(options, config) and findMetadataById(id, config) generate Next.js Metadata objects from collection fields.",
2834
+ keywords: ["metadata", "generateMetadata", "extractSeo", "next.js metadata", "seo", "open graph", "query builder"],
2835
+ summary: "Use @01.software/sdk/metadata helpers with fetched documents to generate Metadata-shaped SEO objects without pulling Next.js into the root SDK entry.",
2685
2836
  resourceUri: "docs://sdk/query-builder"
2686
2837
  },
2687
2838
  // React Query Hooks
2688
2839
  {
2689
2840
  title: "React Query \u2014 useQuery()",
2690
2841
  keywords: ["useQuery", "react query", "hook", "list", "fetch", "collection", "cache", "react"],
2691
- summary: "client.query.useQuery({ collection, options }) \u2014 fetches a list with caching and background updates. Use inside a React component.",
2842
+ summary: "createQueryHooks(client).useQuery({ collection, options }) \u2014 fetches a list with caching and background updates. Use inside a React component.",
2692
2843
  resourceUri: "docs://sdk/react-query"
2693
2844
  },
2694
2845
  {
@@ -2700,7 +2851,7 @@ var docIndex = [
2700
2851
  {
2701
2852
  title: "React Query \u2014 useInfiniteQuery()",
2702
2853
  keywords: ["useInfiniteQuery", "useSuspenseInfiniteQuery", "infinite scroll", "load more", "pagination", "react query", "hook"],
2703
- summary: "client.query.useInfiniteQuery({ collection, options, pageSize }) \u2014 infinite scrolling. data.pages is an array of pages; flatten with flatMap for all docs.",
2854
+ summary: "createQueryHooks(client).useInfiniteQuery({ collection, options, pageSize }) \u2014 infinite scrolling. data.pages is an array of pages; flatten with flatMap for all docs.",
2704
2855
  resourceUri: "docs://sdk/react-query"
2705
2856
  },
2706
2857
  {
@@ -2719,7 +2870,7 @@ var docIndex = [
2719
2870
  {
2720
2871
  title: "Cache Invalidation and Manual Cache Management",
2721
2872
  keywords: ["invalidateQueries", "getQueryData", "setQueryData", "cache", "invalidate", "optimistic update", "react query"],
2722
- summary: "client.query.invalidateQueries(collection, type) triggers refetch. getQueryData/setQueryData allow manual optimistic updates.",
2873
+ summary: "query.invalidateQueries(collection, type) triggers refetch. getQueryData/setQueryData allow manual optimistic updates.",
2723
2874
  resourceUri: "docs://sdk/react-query"
2724
2875
  },
2725
2876
  // Filtering
@@ -2805,11 +2956,11 @@ function searchDocs(query, limit = 5) {
2805
2956
  }
2806
2957
 
2807
2958
  // src/tools/sdk-search-docs.ts
2808
- var schema28 = {
2809
- query: z25.string().min(2).describe('Search keyword or phrase (e.g. "infinite scroll", "webhook", "customer login")'),
2810
- limit: z25.number().min(1).max(10).default(5).describe("Maximum results to return (1-10, default: 5)")
2959
+ var schema30 = {
2960
+ query: z27.string().min(2).describe('Search keyword or phrase (e.g. "infinite scroll", "webhook", "customer login")'),
2961
+ limit: z27.number().min(1).max(10).default(5).describe("Maximum results to return (1-10, default: 5)")
2811
2962
  };
2812
- var metadata28 = {
2963
+ var metadata30 = {
2813
2964
  name: "sdk-search-docs",
2814
2965
  description: "Search SDK documentation by keyword. Returns matching topics with summaries and resource links. Use when looking for specific SDK features or patterns.",
2815
2966
  annotations: {
@@ -2844,9 +2995,9 @@ function handler4({
2844
2995
  }
2845
2996
 
2846
2997
  // src/tools/sdk-get-auth-setup.ts
2847
- import { z as z26 } from "zod";
2848
- var schema29 = {
2849
- scenario: z26.enum([
2998
+ import { z as z28 } from "zod";
2999
+ var schema31 = {
3000
+ scenario: z28.enum([
2850
3001
  "browser-client",
2851
3002
  "server-client",
2852
3003
  "customer-auth",
@@ -2855,7 +3006,7 @@ var schema29 = {
2855
3006
  "webhook-verification"
2856
3007
  ]).describe("Authentication scenario")
2857
3008
  };
2858
- var metadata29 = {
3009
+ var metadata31 = {
2859
3010
  name: "sdk-get-auth-setup",
2860
3011
  description: "Get the current authentication setup for a specific scenario. Returns env var names, code snippets, and security notes.",
2861
3012
  annotations: {
@@ -2870,23 +3021,25 @@ var AUTH_GUIDES = {
2870
3021
  title: "Browser Client Setup",
2871
3022
  envVars: ["NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY"],
2872
3023
  code: `import { createClient } from '@01.software/sdk'
3024
+ import { createQueryHooks } from '@01.software/sdk/query'
2873
3025
 
2874
3026
  const client = createClient({
2875
3027
  publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!
2876
3028
  })
3029
+ const query = createQueryHooks(client)
2877
3030
 
2878
3031
  // Read-only operations + React Query hooks + Customer Auth
2879
- const { data } = client.query.useQuery({ collection: 'products' })`,
3032
+ const { data } = query.useQuery({ collection: 'products' })`,
2880
3033
  notes: [
2881
3034
  "Client is read-only \u2014 no create/update/delete operations",
2882
3035
  "publishableKey is safe to expose in browser (prefixed with NEXT_PUBLIC_)",
2883
- "Includes React Query hooks (client.query) and Customer Auth (client.customer)"
3036
+ "Use createQueryHooks(client) for React Query hooks and client.customer for Customer Auth"
2884
3037
  ]
2885
3038
  },
2886
3039
  "server-client": {
2887
3040
  title: "Server Client Setup",
2888
3041
  envVars: ["SOFTWARE_PUBLISHABLE_KEY", "SOFTWARE_SECRET_KEY"],
2889
- code: `import { createServerClient } from '@01.software/sdk'
3042
+ code: `import { createServerClient } from '@01.software/sdk/server'
2890
3043
 
2891
3044
  const client = createServerClient({
2892
3045
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -2899,7 +3052,7 @@ const result = await client.collections.from('products').create({ title: 'New Pr
2899
3052
  "ServerClient has full CRUD access and must run only in trusted server code",
2900
3053
  "Store server credentials in environment variables and rotate them from the Console",
2901
3054
  "Use in API routes, server actions, or backend services only",
2902
- "React Query hooks available for reads (useQuery, prefetchQuery, etc.) + mutations (useCreate, useUpdate, useRemove)"
3055
+ "Use createServerClient in API routes, server actions, or backend services; keep React Query hooks for browser-safe reads and server prefetching"
2903
3056
  ]
2904
3057
  },
2905
3058
  "customer-auth": {
@@ -3009,14 +3162,14 @@ function handler5({
3009
3162
  }
3010
3163
 
3011
3164
  // src/tools/sdk-get-collection-pattern.ts
3012
- import { z as z27 } from "zod";
3165
+ import { z as z29 } from "zod";
3013
3166
  import { COLLECTIONS, SERVER_COLLECTIONS as SERVER_COLLECTIONS4 } from "@01.software/sdk";
3014
- var schema30 = {
3015
- collection: z27.enum(SERVER_COLLECTIONS4).describe("Collection name"),
3016
- operation: z27.enum(["read", "write", "full-crud"]).default("read").describe("What operations are needed"),
3017
- surface: z27.enum(["query-builder", "react-query", "server-api"]).default("query-builder").describe("Preferred API surface")
3167
+ var schema32 = {
3168
+ collection: z29.enum(SERVER_COLLECTIONS4).describe("Collection name"),
3169
+ operation: z29.enum(["read", "write", "full-crud"]).default("read").describe("What operations are needed"),
3170
+ surface: z29.enum(["query-builder", "react-query", "server-api"]).default("query-builder").describe("Preferred API surface")
3018
3171
  };
3019
- var metadata30 = {
3172
+ var metadata32 = {
3020
3173
  name: "sdk-get-collection-pattern",
3021
3174
  description: "Get the recommended CRUD pattern for a specific collection. Returns code examples for the chosen API surface and operation type.",
3022
3175
  annotations: {
@@ -3037,37 +3190,35 @@ function generatePattern(collection, operation, surface) {
3037
3190
  );
3038
3191
  }
3039
3192
  const parts2 = [];
3040
- if (operation === "read") {
3193
+ if (operation === "read" || operation === "full-crud") {
3041
3194
  parts2.push(
3042
3195
  `import { createClient } from '@01.software/sdk'`,
3043
- ``,
3044
- `const client = createClient({`,
3045
- ` publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!`,
3046
- `})`,
3047
- ``
3196
+ `import { createQueryHooks } from '@01.software/sdk/query'`
3048
3197
  );
3049
- } else {
3198
+ }
3199
+ if (operation === "write" || operation === "full-crud") {
3200
+ parts2.push(`import { createServerClient } from '@01.software/sdk/server'`);
3201
+ }
3202
+ parts2.push(``);
3203
+ if (operation === "read" || operation === "full-crud") {
3050
3204
  parts2.push(
3051
- `import { createServerClient } from '@01.software/sdk'`,
3052
- ``,
3053
- `// Mutation hooks require ServerClient`,
3054
- `const client = createServerClient({`,
3055
- ` publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,`,
3056
- ` secretKey: process.env.SOFTWARE_SECRET_KEY!`,
3205
+ `const client = createClient({`,
3206
+ ` publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!`,
3057
3207
  `})`,
3208
+ `const query = createQueryHooks(client)`,
3058
3209
  ``
3059
3210
  );
3060
3211
  }
3061
3212
  if (operation === "read" || operation === "full-crud") {
3062
3213
  parts2.push(
3063
3214
  `// List query`,
3064
- `const { data, isLoading } = client.query.useQuery({`,
3215
+ `const { data, isLoading } = query.useQuery({`,
3065
3216
  ` collection: '${collection}',`,
3066
3217
  ` options: { limit: 10 }`,
3067
3218
  `})`,
3068
3219
  ``,
3069
3220
  `// Single item`,
3070
- `const { data: item } = client.query.useQueryById({`,
3221
+ `const { data: item } = query.useQueryById({`,
3071
3222
  ` collection: '${collection}',`,
3072
3223
  ` id: itemId`,
3073
3224
  `})`
@@ -3076,31 +3227,28 @@ function generatePattern(collection, operation, surface) {
3076
3227
  if (operation === "write" || operation === "full-crud") {
3077
3228
  parts2.push(
3078
3229
  ``,
3079
- `// Create (auto cache invalidation)`,
3080
- `const { mutate: create } = client.query.useCreate({ collection: '${collection}' })`,
3081
- `create({ title: 'New Item' })`,
3082
- ``,
3083
- `// Update`,
3084
- `const { mutate: update } = client.query.useUpdate({ collection: '${collection}' })`,
3085
- `update({ id: itemId, data: { title: 'Updated' } })`,
3230
+ `// Writes belong in a server action or API route, not a client component.`,
3231
+ `const server = createServerClient({`,
3232
+ ` publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,`,
3233
+ ` secretKey: process.env.SOFTWARE_SECRET_KEY!`,
3234
+ `})`,
3086
3235
  ``,
3087
- `// Delete`,
3088
- `const { mutate: remove } = client.query.useRemove({ collection: '${collection}' })`,
3089
- `remove(itemId)`
3236
+ `await server.collections.from('${collection}').create({ title: 'New Item' })`,
3237
+ `await server.collections.from('${collection}').update(itemId, { title: 'Updated' })`,
3238
+ `await server.collections.from('${collection}').remove(itemId)`
3090
3239
  );
3091
3240
  }
3092
3241
  return {
3093
3242
  code: parts2.join("\n"),
3094
3243
  notes: [
3095
- "React Query hooks provide automatic caching and background updates",
3096
- "Mutation hooks auto-invalidate related query caches",
3097
- operation === "write" || operation === "full-crud" ? "Mutation hooks (useCreate, useUpdate, useRemove) require ServerClient with SOFTWARE_PUBLISHABLE_KEY + SOFTWARE_SECRET_KEY" : "Read hooks work in browser components"
3244
+ "React Query hooks provide automatic caching and background updates for browser-safe reads",
3245
+ operation === "write" || operation === "full-crud" ? "Writes require trusted server code with SOFTWARE_PUBLISHABLE_KEY + SOFTWARE_SECRET_KEY; invalidate browser caches after the server action returns" : "Read hooks work in browser components"
3098
3246
  ]
3099
3247
  };
3100
3248
  }
3101
3249
  if (surface === "server-api") {
3102
3250
  const parts2 = [
3103
- `import { createServerClient } from '@01.software/sdk'`,
3251
+ `import { createServerClient } from '@01.software/sdk/server'`,
3104
3252
  ``,
3105
3253
  `const client = createServerClient({`,
3106
3254
  ` publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,`,
@@ -3217,14 +3365,14 @@ function handler6({
3217
3365
  }
3218
3366
 
3219
3367
  // src/prompts/sdk-usage-guide.ts
3220
- import { z as z28 } from "zod";
3221
- var schema31 = {
3222
- goal: z28.string().describe('What the user wants to accomplish (e.g., "query product list", "create order")'),
3223
- runtime: z28.enum(["browser", "server"]).optional().describe("Target runtime: browser (React/Next.js client) or server (Node.js)"),
3224
- surface: z28.enum(["query-builder", "react-query", "customer-api", "server-api"]).optional().describe("Preferred API surface"),
3225
- collection: z28.string().optional().describe("Specific collection if relevant")
3368
+ import { z as z30 } from "zod";
3369
+ var schema33 = {
3370
+ goal: z30.string().describe('What the user wants to accomplish (e.g., "query product list", "create order")'),
3371
+ runtime: z30.enum(["browser", "server"]).optional().describe("Target runtime: browser (React/Next.js client) or server (Node.js)"),
3372
+ surface: z30.enum(["query-builder", "react-query", "customer-api", "server-api"]).optional().describe("Preferred API surface"),
3373
+ collection: z30.string().optional().describe("Specific collection if relevant")
3226
3374
  };
3227
- var metadata31 = {
3375
+ var metadata33 = {
3228
3376
  name: "sdk-usage-guide",
3229
3377
  title: "SDK Usage Guide",
3230
3378
  description: "Provides guidance on how to perform a specific task using the 01.software SDK",
@@ -3267,8 +3415,12 @@ const result = await client.collections.from('products').find({
3267
3415
  })
3268
3416
 
3269
3417
  // Use React hooks
3418
+ import { createQueryHooks } from '@01.software/sdk/query'
3419
+
3420
+ const query = createQueryHooks(client)
3421
+
3270
3422
  function ProductList() {
3271
- const { data, isLoading } = client.query.useQuery({
3423
+ const { data, isLoading } = query.useQuery({
3272
3424
  collection: 'products',
3273
3425
  options: { limit: 10 }
3274
3426
  })
@@ -3285,7 +3437,7 @@ function ProductList() {
3285
3437
  }
3286
3438
  \`\`\`
3287
3439
 
3288
- ### React Query Hooks (client.query)
3440
+ ### React Query Hooks (@01.software/sdk/query)
3289
3441
 
3290
3442
  | Hook | Description |
3291
3443
  |------|-------------|
@@ -3320,13 +3472,17 @@ await client.collections.from('products').remove('id')
3320
3472
  // count() returns { totalDocs }
3321
3473
  const { totalDocs } = await client.collections.from('products').count()
3322
3474
 
3323
- // Metadata - generate Next.js Metadata from collection fields
3324
- // Auto-maps per-collection fields (e.g. articles: description\u2192description, thumbnail\u2192image)
3325
- const articleMeta = await client.collections.from('articles').findMetadataById(id, { siteName: 'My Blog' })
3326
- const productMeta = await client.collections.from('products').findMetadata(
3327
- { where: { slug: { equals: 'my-product' } } },
3328
- { siteName: 'My Store' }
3329
- )
3475
+ // Metadata - generate Metadata-shaped SEO objects from fetched documents
3476
+ import { extractSeo, generateMetadata } from '@01.software/sdk/metadata'
3477
+
3478
+ const productResult = await client.collections.from('products').find({
3479
+ where: { slug: { equals: 'my-product' } },
3480
+ limit: 1,
3481
+ depth: 1,
3482
+ })
3483
+ const productMeta = productResult.docs[0]
3484
+ ? generateMetadata(extractSeo(productResult.docs[0]), { siteName: 'My Store' })
3485
+ : null
3330
3486
  \`\`\`
3331
3487
 
3332
3488
  ### Filtering (Payload Query Syntax)
@@ -3349,7 +3505,7 @@ For ecommerce collections, use \`products.listing.*\` for browse/search pricing
3349
3505
  ### Server Client (Server-side)
3350
3506
 
3351
3507
  \`\`\`typescript
3352
- import { createServerClient } from '@01.software/sdk'
3508
+ import { createServerClient } from '@01.software/sdk/server'
3353
3509
 
3354
3510
  const client = createServerClient({
3355
3511
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -3357,18 +3513,44 @@ const client = createServerClient({
3357
3513
  })
3358
3514
  \`\`\`
3359
3515
 
3360
- You can perform the "${goal}" task by following the patterns above.`;
3516
+ You can perform the "${goal}" task by following the patterns above.
3517
+
3518
+ ## Common recipes
3519
+
3520
+ ### Product detail page (slug-based)
3521
+
3522
+ \`\`\`typescript
3523
+ const product = await client.commerce.product.detail({ slug })
3524
+ if (!product) return notFound()
3525
+ // product: { product, variants, options, brand, categories, tags, images, videos, listing }
3526
+ \`\`\`
3527
+
3528
+ For React: \`const { data } = createQueryHooks(client).useProductDetailBySlug(slug)\`.
3529
+
3530
+ ### Product listing (grouped)
3531
+
3532
+ \`\`\`typescript
3533
+ const { docs } = await client.commerce.product.listingGroups({ productIds })
3534
+ \`\`\`
3535
+
3536
+ ### Stock check before adding to cart
3537
+
3538
+ \`\`\`typescript
3539
+ const { allAvailable } = await client.commerce.product.stockCheck({
3540
+ items: [{ variantId, quantity }],
3541
+ })
3542
+ \`\`\``;
3361
3543
  }
3362
3544
 
3363
3545
  // src/prompts/collection-query-help.ts
3364
- import { z as z29 } from "zod";
3546
+ import { z as z31 } from "zod";
3365
3547
  import { COLLECTIONS as COLLECTIONS2, SERVER_COLLECTIONS as SERVER_COLLECTIONS5 } from "@01.software/sdk";
3366
- var schema32 = {
3367
- collection: z29.enum(SERVER_COLLECTIONS5).describe("Collection name"),
3368
- operation: z29.enum(["find", "create", "update", "delete"]).describe("Operation to perform (find, create, update, delete)"),
3369
- filters: z29.string().optional().describe("Filter conditions (JSON string, optional)")
3548
+ var schema34 = {
3549
+ collection: z31.enum(SERVER_COLLECTIONS5).describe("Collection name"),
3550
+ operation: z31.enum(["find", "create", "update", "delete"]).describe("Operation to perform (find, create, update, delete)"),
3551
+ filters: z31.string().optional().describe("Filter conditions (JSON string, optional)")
3370
3552
  };
3371
- var metadata32 = {
3553
+ var metadata34 = {
3372
3554
  name: "collection-query-help",
3373
3555
  title: "Collection Query Help",
3374
3556
  description: "Provides guidance on how to write queries for a specific collection",
@@ -3398,7 +3580,8 @@ ${filters}
3398
3580
  ### ${operation === "find" ? "Query" : operation === "create" ? "Create" : operation === "update" ? "Update" : "Delete"} Example
3399
3581
 
3400
3582
  \`\`\`typescript
3401
- import { createClient, createServerClient } from '@01.software/sdk'
3583
+ import { createClient } from '@01.software/sdk'
3584
+ import { createServerClient } from '@01.software/sdk/server'
3402
3585
 
3403
3586
  // Client (read-only public collections)
3404
3587
  const client = createClient({
@@ -3419,14 +3602,18 @@ const result = await ${readClientName}.collections.from('${collection}').find(${
3419
3602
  // result.docs - array of items
3420
3603
  // result.totalDocs, result.page, result.totalPages, result.hasNextPage, ...
3421
3604
 
3422
- ${isPublicCollection ? `// Using React Hook
3423
- const { data, isLoading, error } = client.query.useQuery({
3605
+ ${isPublicCollection ? `// Using React Query hooks
3606
+ import { createQueryHooks } from '@01.software/sdk/query'
3607
+
3608
+ const query = createQueryHooks(client)
3609
+
3610
+ const { data, isLoading, error } = query.useQuery({
3424
3611
  collection: '${collection}',
3425
3612
  options: { limit: 10 }
3426
3613
  })
3427
3614
 
3428
3615
  // With Suspense
3429
- const { data } = client.query.useSuspenseQuery({
3616
+ const { data } = query.useSuspenseQuery({
3430
3617
  collection: '${collection}',
3431
3618
  options: { limit: 10 }
3432
3619
  })` : `// React hooks are browser/public only and do not support '${collection}'.`}` : operation === "create" ? `// Create ${collection} item (ServerClient only)
@@ -3460,16 +3647,16 @@ ${operation === "find" ? `- Use \`where\` option for filtering (Payload query sy
3460
3647
  }
3461
3648
 
3462
3649
  // src/prompts/order-flow-guide.ts
3463
- import { z as z30 } from "zod";
3464
- var schema33 = {
3465
- scenario: z30.enum([
3650
+ import { z as z32 } from "zod";
3651
+ var schema35 = {
3652
+ scenario: z32.enum([
3466
3653
  "simple-order",
3467
3654
  "cart-checkout",
3468
3655
  "return-refund",
3469
3656
  "fulfillment-tracking"
3470
3657
  ]).describe("Order flow scenario")
3471
3658
  };
3472
- var metadata33 = {
3659
+ var metadata35 = {
3473
3660
  name: "order-flow-guide",
3474
3661
  title: "Order Flow Guide",
3475
3662
  description: "Provides step-by-step guidance for ecommerce order flows including creation, checkout, returns, and fulfillment.",
@@ -3495,7 +3682,7 @@ var SCENARIOS = {
3495
3682
 
3496
3683
  ### Code Example (ServerClient)
3497
3684
  \`\`\`typescript
3498
- import { createServerClient } from '@01.software/sdk'
3685
+ import { createServerClient } from '@01.software/sdk/server'
3499
3686
 
3500
3687
  const client = createServerClient({
3501
3688
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -3654,9 +3841,9 @@ ${SCENARIOS[scenario] || "Unknown scenario."}
3654
3841
  }
3655
3842
 
3656
3843
  // src/prompts/feature-setup-guide.ts
3657
- import { z as z31 } from "zod";
3658
- var schema34 = {
3659
- feature: z31.enum([
3844
+ import { z as z33 } from "zod";
3845
+ var schema36 = {
3846
+ feature: z33.enum([
3660
3847
  "ecommerce",
3661
3848
  "customers",
3662
3849
  "articles",
@@ -3671,7 +3858,7 @@ var schema34 = {
3671
3858
  "community"
3672
3859
  ]).describe("Feature to get setup guide for")
3673
3860
  };
3674
- var metadata34 = {
3861
+ var metadata36 = {
3675
3862
  name: "feature-setup-guide",
3676
3863
  title: "Feature Setup Guide",
3677
3864
  description: "Setup checklist and remediation guide for a tenant feature. Load with check-feature-progress and get-tenant-context to diagnose setup gaps.",
@@ -3878,7 +4065,7 @@ ${FEATURES[feature] || "Unknown feature."}
3878
4065
  }
3879
4066
 
3880
4067
  // src/resources/(config)/app.ts
3881
- var metadata35 = {
4068
+ var metadata37 = {
3882
4069
  name: "app-config",
3883
4070
  title: "Application Config",
3884
4071
  description: "01.software SDK and MCP server configuration information"
@@ -3944,7 +4131,7 @@ Rate limits depend on your tenant plan:
3944
4131
 
3945
4132
  // src/resources/(collections)/schema.ts
3946
4133
  import { COLLECTIONS as COLLECTIONS3 } from "@01.software/sdk";
3947
- var metadata36 = {
4134
+ var metadata38 = {
3948
4135
  name: "collections-schema",
3949
4136
  title: "Collection Schema Info",
3950
4137
  description: "Available collections and their schema information"
@@ -3968,7 +4155,12 @@ var COLLECTIONS_BY_CATEGORY = {
3968
4155
  "fulfillments",
3969
4156
  "fulfillment-items"
3970
4157
  ],
3971
- "Shipping & Returns": ["returns", "return-items", "shipping-policies"],
4158
+ "Shipping & Returns": [
4159
+ "returns",
4160
+ "return-items",
4161
+ "shipping-policies",
4162
+ "shipping-zones"
4163
+ ],
3972
4164
  Customers: [
3973
4165
  "customers",
3974
4166
  "customer-profiles",
@@ -3976,7 +4168,7 @@ var COLLECTIONS_BY_CATEGORY = {
3976
4168
  "customer-addresses"
3977
4169
  ],
3978
4170
  Carts: ["carts", "cart-items"],
3979
- "Discounts & Promotions": ["discounts", "promotions"],
4171
+ Discounts: ["discounts"],
3980
4172
  Documents: ["documents", "document-categories", "document-types"],
3981
4173
  Articles: [
3982
4174
  "articles",
@@ -3990,9 +4182,7 @@ var COLLECTIONS_BY_CATEGORY = {
3990
4182
  "reactions",
3991
4183
  "reaction-types",
3992
4184
  "bookmarks",
3993
- "post-categories",
3994
- "reports",
3995
- "community-bans"
4185
+ "post-categories"
3996
4186
  ],
3997
4187
  Playlists: [
3998
4188
  "playlists",
@@ -4082,7 +4272,7 @@ Total available collections: ${COLLECTIONS3.length}`;
4082
4272
  }
4083
4273
 
4084
4274
  // src/resources/(docs)/getting-started.ts
4085
- var metadata37 = {
4275
+ var metadata39 = {
4086
4276
  name: "docs-getting-started",
4087
4277
  title: "Getting Started",
4088
4278
  description: "01.software SDK getting started guide"
@@ -4102,6 +4292,22 @@ yarn add @01.software/sdk
4102
4292
  pnpm add @01.software/sdk
4103
4293
  \`\`\`
4104
4294
 
4295
+ ## Optional peers
4296
+
4297
+ You do not need extra packages for the root SDK entry. Install peer
4298
+ dependencies only when you import a feature sub-path:
4299
+
4300
+ - \`@01.software/sdk/query\` -> \`@tanstack/react-query\`, \`react\`, \`react-dom\`
4301
+ - \`@01.software/sdk/realtime\` -> \`@tanstack/react-query\`
4302
+ - \`@01.software/sdk/analytics/react\` -> \`react\`, \`react-dom\`
4303
+ - \`@01.software/sdk/ui/rich-text\` -> \`@payloadcms/richtext-lexical\`
4304
+ - \`@01.software/sdk/ui/form\` -> none
4305
+ - \`@01.software/sdk/ui/code-block\` -> \`shiki\`, \`hast-util-to-jsx-runtime\`
4306
+ - \`@01.software/sdk/ui/canvas\` -> \`@tanstack/react-query\`, \`@xyflow/react\`, \`quickjs-emscripten\`, \`postcss\`, \`sucrase\`
4307
+ - \`@01.software/sdk/ui/canvas/server\` -> none
4308
+ - \`@01.software/sdk/ui/video\` -> \`@mux/mux-player-react\`
4309
+ - \`@01.software/sdk/ui/image\` -> none
4310
+
4105
4311
  ## Basic Usage
4106
4312
 
4107
4313
  \`\`\`typescript
@@ -4127,7 +4333,7 @@ const result = await client.collections.from('products').find({
4127
4333
  }
4128
4334
 
4129
4335
  // src/resources/(docs)/guides.ts
4130
- var metadata38 = {
4336
+ var metadata40 = {
4131
4337
  name: "docs-guides",
4132
4338
  title: "Guides",
4133
4339
  description: "01.software SDK usage guides"
@@ -4139,7 +4345,7 @@ Comprehensive guides to master the 01.software SDK.
4139
4345
 
4140
4346
  ## Data Fetching
4141
4347
 
4142
- Use the Query Builder or React Query hooks to fetch data efficiently.
4348
+ Use the Query Builder or opt-in React Query hooks to fetch data efficiently.
4143
4349
 
4144
4350
  ### Query Builder
4145
4351
  \`\`\`typescript
@@ -4167,7 +4373,10 @@ const { totalDocs } = await client.collections.from('products').count()
4167
4373
 
4168
4374
  ### React Query Hook
4169
4375
  \`\`\`typescript
4170
- const { data, isLoading, error } = client.query.useQuery({
4376
+ import { createQueryHooks } from '@01.software/sdk/query'
4377
+
4378
+ const query = createQueryHooks(client)
4379
+ const { data, isLoading, error } = query.useQuery({
4171
4380
  collection: 'products',
4172
4381
  options: {
4173
4382
  where: { status: { equals: 'published' } },
@@ -4178,7 +4387,7 @@ const { data, isLoading, error } = client.query.useQuery({
4178
4387
 
4179
4388
  ### Suspense Mode
4180
4389
  \`\`\`typescript
4181
- const { data } = client.query.useSuspenseQuery({
4390
+ const { data } = query.useSuspenseQuery({
4182
4391
  collection: 'products',
4183
4392
  options: { limit: 10 }
4184
4393
  })
@@ -4187,7 +4396,7 @@ const { data } = client.query.useSuspenseQuery({
4187
4396
  ### Infinite Scroll
4188
4397
  \`\`\`typescript
4189
4398
  const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
4190
- client.query.useInfiniteQuery({
4399
+ query.useInfiniteQuery({
4191
4400
  collection: 'products',
4192
4401
  pageSize: 20
4193
4402
  })
@@ -4234,19 +4443,18 @@ const result = await serverClient.from('products').removeMany(
4234
4443
  )
4235
4444
  \`\`\`
4236
4445
 
4237
- ### Mutation Hooks (React)
4446
+ ### Server Mutations
4238
4447
  \`\`\`typescript
4239
- // Create with auto cache invalidation
4240
- const { mutate: create } = client.query.useCreate({ collection: 'products' })
4241
- create({ title: 'New', status: 'draft' })
4448
+ import { createServerClient } from '@01.software/sdk/server'
4242
4449
 
4243
- // Update with auto cache invalidation
4244
- const { mutate: update } = client.query.useUpdate({ collection: 'products' })
4245
- update({ id: 'product-id', data: { title: 'Updated' } })
4450
+ const server = createServerClient({
4451
+ publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
4452
+ secretKey: process.env.SOFTWARE_SECRET_KEY!,
4453
+ })
4246
4454
 
4247
- // Remove with auto cache invalidation
4248
- const { mutate: remove } = client.query.useRemove({ collection: 'products' })
4249
- remove('product-id')
4455
+ await server.collections.from('products').create({ title: 'New', status: 'draft' })
4456
+ await server.collections.from('products').update('product-id', { title: 'Updated' })
4457
+ await server.collections.from('products').remove('product-id')
4250
4458
  \`\`\`
4251
4459
 
4252
4460
  ## Caching Strategies
@@ -4256,17 +4464,17 @@ The SDK uses React Query for caching and background updates.
4256
4464
  ### SSR Prefetching
4257
4465
  \`\`\`typescript
4258
4466
  // Prefetch in server component for instant client hydration
4259
- await client.query.prefetchQuery({
4467
+ await query.prefetchQuery({
4260
4468
  collection: 'products',
4261
4469
  options: { limit: 10 }
4262
4470
  })
4263
4471
 
4264
- await client.query.prefetchQueryById({
4472
+ await query.prefetchQueryById({
4265
4473
  collection: 'products',
4266
4474
  id: 'product-id'
4267
4475
  })
4268
4476
 
4269
- await client.query.prefetchInfiniteQuery({
4477
+ await query.prefetchInfiniteQuery({
4270
4478
  collection: 'products',
4271
4479
  pageSize: 20
4272
4480
  })
@@ -4275,19 +4483,19 @@ await client.query.prefetchInfiniteQuery({
4275
4483
  ### Cache Invalidation
4276
4484
  \`\`\`typescript
4277
4485
  // Invalidate list cache for a collection
4278
- client.query.invalidateQueries('products', 'list')
4486
+ query.invalidateQueries('products', 'list')
4279
4487
 
4280
4488
  // Invalidate all caches for a collection
4281
- client.query.invalidateQueries('products')
4489
+ query.invalidateQueries('products')
4282
4490
  \`\`\`
4283
4491
 
4284
4492
  ### Manual Cache Management
4285
4493
  \`\`\`typescript
4286
4494
  // Read cached data
4287
- const cached = client.query.getQueryData('products', 'list')
4495
+ const cached = query.getQueryData('products', 'list')
4288
4496
 
4289
4497
  // Write to cache (optimistic updates)
4290
- client.query.setQueryData('products', 'list', newData)
4498
+ query.setQueryData('products', 'list', newData)
4291
4499
  \`\`\`
4292
4500
 
4293
4501
  ## Error Handling
@@ -4338,7 +4546,7 @@ For more implementation guidance, see the [SDK Guide](/developers/sdk).`;
4338
4546
  }
4339
4547
 
4340
4548
  // src/resources/(docs)/api.ts
4341
- var metadata39 = {
4549
+ var metadata41 = {
4342
4550
  name: "docs-api",
4343
4551
  title: "API Reference",
4344
4552
  description: "01.software SDK API reference documentation"
@@ -4365,7 +4573,7 @@ const client = createClient({
4365
4573
  For server-side operations (full CRUD)
4366
4574
 
4367
4575
  \`\`\`typescript
4368
- import { createServerClient } from '@01.software/sdk'
4576
+ import { createServerClient } from '@01.software/sdk/server'
4369
4577
 
4370
4578
  const client = createServerClient({
4371
4579
  publishableKey: string,
@@ -4444,13 +4652,19 @@ const result = await client.collections.from('collection').removeMany(where)
4444
4652
  // Returns PayloadFindResponse with deleted docs
4445
4653
  \`\`\`
4446
4654
 
4447
- ## React Query Hooks (client.query)
4655
+ ## React Query Hooks (\`@01.software/sdk/query\`)
4656
+
4657
+ \`\`\`typescript
4658
+ import { createQueryHooks } from '@01.software/sdk/query'
4659
+
4660
+ const query = createQueryHooks(client)
4661
+ \`\`\`
4448
4662
 
4449
4663
  ### useQuery()
4450
4664
  Query a collection list.
4451
4665
 
4452
4666
  \`\`\`typescript
4453
- const { data, isLoading, error } = client.query.useQuery({
4667
+ const { data, isLoading, error } = query.useQuery({
4454
4668
  collection: 'products',
4455
4669
  options: { limit: 10, where: { status: { equals: 'published' } } }
4456
4670
  })
@@ -4460,7 +4674,7 @@ const { data, isLoading, error } = client.query.useQuery({
4460
4674
  Suspense mode list query.
4461
4675
 
4462
4676
  \`\`\`typescript
4463
- const { data } = client.query.useSuspenseQuery({
4677
+ const { data } = query.useSuspenseQuery({
4464
4678
  collection: 'products',
4465
4679
  options: { limit: 10 }
4466
4680
  })
@@ -4470,7 +4684,7 @@ const { data } = client.query.useSuspenseQuery({
4470
4684
  Get a single item by ID.
4471
4685
 
4472
4686
  \`\`\`typescript
4473
- const { data } = client.query.useQueryById({
4687
+ const { data } = query.useQueryById({
4474
4688
  collection: 'products',
4475
4689
  id: 'product-id'
4476
4690
  })
@@ -4480,7 +4694,7 @@ const { data } = client.query.useQueryById({
4480
4694
  Suspense mode single item query.
4481
4695
 
4482
4696
  \`\`\`typescript
4483
- const { data } = client.query.useSuspenseQueryById({
4697
+ const { data } = query.useSuspenseQueryById({
4484
4698
  collection: 'products',
4485
4699
  id: 'product-id'
4486
4700
  })
@@ -4490,7 +4704,7 @@ const { data } = client.query.useSuspenseQueryById({
4490
4704
  Infinite scroll.
4491
4705
 
4492
4706
  \`\`\`typescript
4493
- const { data, fetchNextPage, hasNextPage } = client.query.useInfiniteQuery({
4707
+ const { data, fetchNextPage, hasNextPage } = query.useInfiniteQuery({
4494
4708
  collection: 'products',
4495
4709
  options: { limit: 20 },
4496
4710
  pageSize: 20
@@ -4501,52 +4715,43 @@ const { data, fetchNextPage, hasNextPage } = client.query.useInfiniteQuery({
4501
4715
  Suspense mode infinite scroll.
4502
4716
 
4503
4717
  \`\`\`typescript
4504
- const { data, fetchNextPage } = client.query.useSuspenseInfiniteQuery({
4718
+ const { data, fetchNextPage } = query.useSuspenseInfiniteQuery({
4505
4719
  collection: 'products',
4506
4720
  pageSize: 20
4507
4721
  })
4508
4722
  \`\`\`
4509
4723
 
4510
- ## Mutation Hooks (client.query)
4724
+ ## Server Mutations
4511
4725
 
4512
- ### useCreate()
4513
- Create a document with automatic cache invalidation.
4726
+ Writes require trusted server code with \`createServerClient\`; do not run server credentials in React client components.
4514
4727
 
4515
4728
  \`\`\`typescript
4516
- const { mutate } = client.query.useCreate({ collection: 'products' })
4517
- mutate({ title: 'New Product', status: 'draft' })
4518
- \`\`\`
4729
+ import { createServerClient } from '@01.software/sdk/server'
4519
4730
 
4520
- ### useUpdate()
4521
- Update a document with automatic cache invalidation.
4522
-
4523
- \`\`\`typescript
4524
- const { mutate } = client.query.useUpdate({ collection: 'products' })
4525
- mutate({ id: 'product-id', data: { title: 'Updated' } })
4526
- \`\`\`
4527
-
4528
- ### useRemove()
4529
- Remove a document with automatic cache invalidation.
4731
+ const server = createServerClient({
4732
+ publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
4733
+ secretKey: process.env.SOFTWARE_SECRET_KEY!,
4734
+ })
4530
4735
 
4531
- \`\`\`typescript
4532
- const { mutate } = client.query.useRemove({ collection: 'products' })
4533
- mutate('product-id')
4736
+ await server.collections.from('products').create({ title: 'New Product', status: 'draft' })
4737
+ await server.collections.from('products').update('product-id', { title: 'Updated' })
4738
+ await server.collections.from('products').remove('product-id')
4534
4739
  \`\`\`
4535
4740
 
4536
4741
  ## Cache Utilities
4537
4742
 
4538
4743
  \`\`\`typescript
4539
4744
  // Invalidate cache
4540
- client.query.invalidateQueries('products', 'list')
4745
+ query.invalidateQueries('products', 'list')
4541
4746
 
4542
4747
  // SSR prefetch
4543
- await client.query.prefetchQuery({ collection: 'products', options: { limit: 10 } })
4544
- await client.query.prefetchQueryById({ collection: 'products', id: 'id' })
4545
- await client.query.prefetchInfiniteQuery({ collection: 'products', pageSize: 20 })
4748
+ await query.prefetchQuery({ collection: 'products', options: { limit: 10 } })
4749
+ await query.prefetchQueryById({ collection: 'products', id: 'id' })
4750
+ await query.prefetchInfiniteQuery({ collection: 'products', pageSize: 20 })
4546
4751
 
4547
4752
  // Get/set cached data
4548
- const cached = client.query.getQueryData('products', 'list')
4549
- client.query.setQueryData('products', 'list', newData)
4753
+ const cached = query.getQueryData('products', 'list')
4754
+ query.setQueryData('products', 'list', newData)
4550
4755
  \`\`\`
4551
4756
 
4552
4757
  For ecommerce reads, prefer \`products.listing.*\` for card/search pricing and keep authoritative sellable pricing on \`product-variants.price\`.
@@ -4624,7 +4829,7 @@ For more details, see the [API documentation](/developers/api).`;
4624
4829
  }
4625
4830
 
4626
4831
  // src/resources/(docs)/query-builder.ts
4627
- var metadata40 = {
4832
+ var metadata42 = {
4628
4833
  name: "docs-query-builder",
4629
4834
  title: "Query Builder",
4630
4835
  description: "01.software SDK Query Builder API reference (client.collections.from)"
@@ -4793,7 +4998,7 @@ const result3 = await client.collections.from('products').find({ sort: '-isFeatu
4793
4998
  ## Full Example
4794
4999
 
4795
5000
  \`\`\`typescript
4796
- import { createServerClient } from '@01.software/sdk'
5001
+ import { createServerClient } from '@01.software/sdk/server'
4797
5002
 
4798
5003
  const serverClient = createServerClient({
4799
5004
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -4818,17 +5023,25 @@ console.log(result.hasNextPage) // true
4818
5023
  }
4819
5024
 
4820
5025
  // src/resources/(docs)/react-query.ts
4821
- var metadata41 = {
5026
+ var metadata43 = {
4822
5027
  name: "docs-react-query",
4823
5028
  title: "React Query Hooks",
4824
- description: "01.software SDK React Query hooks reference (client.query)"
5029
+ description: "01.software SDK React Query hooks reference (@01.software/sdk/query)"
4825
5030
  };
4826
5031
  function handler13() {
4827
5032
  return `# React Query Hooks
4828
5033
 
4829
- React Query hooks are available on the browser-side \`Client\` via \`client.query\`. They provide automatic caching, background refetching, and cache invalidation.
5034
+ React Query hooks are opt-in through \`@01.software/sdk/query\`. They provide automatic caching, background refetching, and cache invalidation without making root \`createClient\` consumers install React Query.
5035
+
5036
+ Install \`@tanstack/react-query\` and React peers only when importing this sub-path.
5037
+
5038
+ \`\`\`typescript
5039
+ import { createClient } from '@01.software/sdk'
5040
+ import { createQueryHooks } from '@01.software/sdk/query'
4830
5041
 
4831
- > React Query hooks are available on \`Client\` (createClient) only. \`ServerClient\` does not include them.
5042
+ const client = createClient({ publishableKey })
5043
+ const query = createQueryHooks(client)
5044
+ \`\`\`
4832
5045
 
4833
5046
  ## Query Hooks
4834
5047
 
@@ -4836,7 +5049,7 @@ React Query hooks are available on the browser-side \`Client\` via \`client.quer
4836
5049
  Query a collection list with automatic caching.
4837
5050
 
4838
5051
  \`\`\`typescript
4839
- const { data, isLoading, error } = client.query.useQuery({
5052
+ const { data, isLoading, error } = query.useQuery({
4840
5053
  collection: 'products',
4841
5054
  options: {
4842
5055
  where: { status: { equals: 'published' } },
@@ -4854,7 +5067,7 @@ Suspense-mode list query. Throws a promise while loading (use with React Suspens
4854
5067
 
4855
5068
  \`\`\`typescript
4856
5069
  // Inside a Suspense boundary
4857
- const { data } = client.query.useSuspenseQuery({
5070
+ const { data } = query.useSuspenseQuery({
4858
5071
  collection: 'products',
4859
5072
  options: { limit: 10 },
4860
5073
  })
@@ -4865,7 +5078,7 @@ const { data } = client.query.useSuspenseQuery({
4865
5078
  Get a single document by ID.
4866
5079
 
4867
5080
  \`\`\`typescript
4868
- const { data, isLoading } = client.query.useQueryById({
5081
+ const { data, isLoading } = query.useQueryById({
4869
5082
  collection: 'products',
4870
5083
  id: 'product-id',
4871
5084
  })
@@ -4876,7 +5089,7 @@ const { data, isLoading } = client.query.useQueryById({
4876
5089
  Suspense-mode single document query.
4877
5090
 
4878
5091
  \`\`\`typescript
4879
- const { data } = client.query.useSuspenseQueryById({
5092
+ const { data } = query.useSuspenseQueryById({
4880
5093
  collection: 'products',
4881
5094
  id: 'product-id',
4882
5095
  })
@@ -4892,7 +5105,7 @@ const {
4892
5105
  fetchNextPage,
4893
5106
  hasNextPage,
4894
5107
  isFetchingNextPage,
4895
- } = client.query.useInfiniteQuery({
5108
+ } = query.useInfiniteQuery({
4896
5109
  collection: 'products',
4897
5110
  options: {
4898
5111
  where: { status: { equals: 'published' } },
@@ -4908,55 +5121,33 @@ const {
4908
5121
  Suspense-mode infinite scroll.
4909
5122
 
4910
5123
  \`\`\`typescript
4911
- const { data, fetchNextPage, hasNextPage } = client.query.useSuspenseInfiniteQuery({
5124
+ const { data, fetchNextPage, hasNextPage } = query.useSuspenseInfiniteQuery({
4912
5125
  collection: 'products',
4913
5126
  pageSize: 20,
4914
5127
  })
4915
5128
  \`\`\`
4916
5129
 
4917
- ## Mutation Hooks
5130
+ ## Writes
4918
5131
 
4919
- Mutation hooks automatically invalidate relevant cache keys after success.
4920
-
4921
- ### useCreate()
4922
- Create a document and invalidate list cache.
5132
+ Keep writes in trusted server code. Use a server action, API route, or backend service with \`createServerClient\`, then invalidate browser React Query caches after the action completes.
4923
5133
 
4924
5134
  \`\`\`typescript
4925
- const { mutate, mutateAsync, isPending } = client.query.useCreate({
4926
- collection: 'products',
4927
- })
4928
-
4929
- // Fire and forget
4930
- mutate({ title: 'New Product', status: 'draft' })
4931
-
4932
- // Await result
4933
- const result = await mutateAsync({ title: 'New Product', status: 'draft' })
4934
- // result.doc - created document
4935
- \`\`\`
4936
-
4937
- For ecommerce reads, price-oriented product cards should consume \`products.listing.minPrice/maxPrice\`. Authoritative sellable pricing still lives on \`product-variants.price\`.
5135
+ // app/products/actions.ts
5136
+ 'use server'
4938
5137
 
4939
- ### useUpdate()
4940
- Update a document and invalidate list + detail cache.
5138
+ import { createServerClient } from '@01.software/sdk/server'
4941
5139
 
4942
- \`\`\`typescript
4943
- const { mutate, mutateAsync } = client.query.useUpdate({
4944
- collection: 'products',
5140
+ const server = createServerClient({
5141
+ publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
5142
+ secretKey: process.env.SOFTWARE_SECRET_KEY!,
4945
5143
  })
4946
5144
 
4947
- mutate({ id: 'product-id', data: { title: 'Updated Title' } })
5145
+ export async function createProduct(data: { title: string; status: 'draft' | 'published' }) {
5146
+ return server.collections.from('products').create(data)
5147
+ }
4948
5148
  \`\`\`
4949
5149
 
4950
- ### useRemove()
4951
- Remove a document and invalidate list cache.
4952
-
4953
- \`\`\`typescript
4954
- const { mutate, mutateAsync } = client.query.useRemove({
4955
- collection: 'products',
4956
- })
4957
-
4958
- mutate('product-id')
4959
- \`\`\`
5150
+ For ecommerce reads, price-oriented product cards should consume \`products.listing.minPrice/maxPrice\`. Authoritative sellable pricing still lives on \`product-variants.price\`.
4960
5151
 
4961
5152
  ## Cache Utilities
4962
5153
 
@@ -4965,10 +5156,10 @@ Manually invalidate cached queries for a collection.
4965
5156
 
4966
5157
  \`\`\`typescript
4967
5158
  // Invalidate all list queries for a collection
4968
- client.query.invalidateQueries('products', 'list')
5159
+ query.invalidateQueries('products', 'list')
4969
5160
 
4970
5161
  // Invalidate all queries for a collection (list + detail)
4971
- client.query.invalidateQueries('products')
5162
+ query.invalidateQueries('products')
4972
5163
  \`\`\`
4973
5164
 
4974
5165
  ### getQueryData() / setQueryData()
@@ -4976,10 +5167,10 @@ Read and write the React Query cache directly.
4976
5167
 
4977
5168
  \`\`\`typescript
4978
5169
  // Read cached data
4979
- const cached = client.query.getQueryData('products', 'list')
5170
+ const cached = query.getQueryData('products', 'list')
4980
5171
 
4981
5172
  // Write to cache (useful for optimistic updates)
4982
- client.query.setQueryData('products', 'list', newData)
5173
+ query.setQueryData('products', 'list', newData)
4983
5174
  \`\`\`
4984
5175
 
4985
5176
  ## SSR Prefetching
@@ -4989,34 +5180,37 @@ Prefetch data in server components for instant hydration on the client.
4989
5180
  \`\`\`typescript
4990
5181
  // app/products/page.tsx (Next.js App Router Server Component)
4991
5182
  import { HydrationBoundary, dehydrate } from '@tanstack/react-query'
4992
- import { createServerClient } from '@01.software/sdk'
5183
+ import { createServerClient } from '@01.software/sdk/server'
5184
+ import { createServerQueryHooks, getQueryClient } from '@01.software/sdk/query'
4993
5185
 
4994
5186
  export default async function ProductsPage() {
4995
5187
  const serverClient = createServerClient({
4996
5188
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
4997
5189
  secretKey: process.env.SOFTWARE_SECRET_KEY!,
4998
5190
  })
5191
+ const queryClient = getQueryClient()
5192
+ const serverQuery = createServerQueryHooks(serverClient, queryClient)
4999
5193
 
5000
5194
  // Prefetch list
5001
- await serverClient.query.prefetchQuery({
5195
+ await serverQuery.prefetchQuery({
5002
5196
  collection: 'products',
5003
5197
  options: { limit: 20, where: { status: { equals: 'published' } } },
5004
5198
  })
5005
5199
 
5006
5200
  // Prefetch single item
5007
- await serverClient.query.prefetchQueryById({
5201
+ await serverQuery.prefetchQueryById({
5008
5202
  collection: 'products',
5009
5203
  id: 'product-id',
5010
5204
  })
5011
5205
 
5012
5206
  // Prefetch infinite query
5013
- await serverClient.query.prefetchInfiniteQuery({
5207
+ await serverQuery.prefetchInfiniteQuery({
5014
5208
  collection: 'products',
5015
5209
  pageSize: 20,
5016
5210
  })
5017
5211
 
5018
5212
  return (
5019
- <HydrationBoundary state={dehydrate(serverClient.query.queryClient)}>
5213
+ <HydrationBoundary state={dehydrate(queryClient)}>
5020
5214
  <ProductList />
5021
5215
  </HydrationBoundary>
5022
5216
  )
@@ -5029,13 +5223,15 @@ export default async function ProductsPage() {
5029
5223
  'use client'
5030
5224
 
5031
5225
  import { createClient } from '@01.software/sdk'
5226
+ import { createQueryHooks } from '@01.software/sdk/query'
5032
5227
 
5033
5228
  const client = createClient({
5034
5229
  publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!,
5035
5230
  })
5231
+ const query = createQueryHooks(client)
5036
5232
 
5037
5233
  export function ProductList() {
5038
- const { data, isLoading, error } = client.query.useQuery({
5234
+ const { data, isLoading, error } = query.useQuery({
5039
5235
  collection: 'products',
5040
5236
  options: {
5041
5237
  where: { status: { equals: 'published' } },
@@ -5044,20 +5240,13 @@ export function ProductList() {
5044
5240
  },
5045
5241
  })
5046
5242
 
5047
- const { mutate: removeProduct } = client.query.useRemove({
5048
- collection: 'products',
5049
- })
5050
-
5051
5243
  if (isLoading) return <div>Loading...</div>
5052
5244
  if (error) return <div>Error: {error.message}</div>
5053
5245
 
5054
5246
  return (
5055
5247
  <ul>
5056
5248
  {data?.docs.map((product) => (
5057
- <li key={product.id}>
5058
- {product.title}
5059
- <button onClick={() => removeProduct(product.id)}>Delete</button>
5060
- </li>
5249
+ <li key={product.id}>{product.title}</li>
5061
5250
  ))}
5062
5251
  </ul>
5063
5252
  )
@@ -5066,7 +5255,7 @@ export function ProductList() {
5066
5255
  }
5067
5256
 
5068
5257
  // src/resources/(docs)/server-api.ts
5069
- var metadata42 = {
5258
+ var metadata44 = {
5070
5259
  name: "docs-server-api",
5071
5260
  title: "Server-side API",
5072
5261
  description: "01.software SDK server-side API reference (client.commerce) for orders, fulfillments, returns, carts, and validation"
@@ -5077,7 +5266,7 @@ function handler14() {
5077
5266
  Server-side operations are available via \`client.commerce\` on \`ServerClient\`. Use \`createServerClient\` with both \`publishableKey\` and \`secretKey\`.
5078
5267
 
5079
5268
  \`\`\`typescript
5080
- import { createServerClient } from '@01.software/sdk'
5269
+ import { createServerClient } from '@01.software/sdk/server'
5081
5270
 
5082
5271
  const client = createServerClient({
5083
5272
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -5328,7 +5517,7 @@ const result = await client.commerce.shipping.calculate({
5328
5517
  }
5329
5518
 
5330
5519
  // src/resources/(docs)/customer-auth.ts
5331
- var metadata43 = {
5520
+ var metadata45 = {
5332
5521
  name: "docs-customer-auth",
5333
5522
  title: "Customer Auth API",
5334
5523
  description: "01.software SDK Customer Auth API reference (client.customer)"
@@ -5506,7 +5695,7 @@ async function loadProfile() {
5506
5695
  }
5507
5696
 
5508
5697
  // src/resources/(docs)/browser-vs-server.ts
5509
- var metadata44 = {
5698
+ var metadata46 = {
5510
5699
  name: "docs-browser-vs-server",
5511
5700
  title: "Client vs ServerClient",
5512
5701
  description: "When to use Client (createClient) vs ServerClient (createServerClient) in the 01.software SDK"
@@ -5526,9 +5715,9 @@ The SDK provides two client types for different execution environments.
5526
5715
  | Read (\`find\`, \`findById\`, \`count\`) | Yes | Yes |
5527
5716
  | Write (\`create\`, \`update\`, \`remove\`) | No | Yes |
5528
5717
  | Bulk (\`updateMany\`, \`removeMany\`) | No | Yes |
5529
- | React Query hooks (\`client.query\`) | Yes | Yes (SSR prefetch) |
5718
+ | React Query hooks (\`@01.software/sdk/query\`) | Yes | Yes (SSR prefetch) |
5530
5719
  | Customer auth (\`client.customer\`) | Yes | No |
5531
- | Server API (\`client.api\`) | No | Yes |
5720
+ | Commerce/server APIs (\`server.commerce\`, server CRUD) | No | Yes |
5532
5721
 
5533
5722
  ## Client (createClient)
5534
5723
 
@@ -5536,16 +5725,18 @@ Use in browser code, React client components, and anywhere the secret key must n
5536
5725
 
5537
5726
  \`\`\`typescript
5538
5727
  import { createClient } from '@01.software/sdk'
5728
+ import { createQueryHooks } from '@01.software/sdk/query'
5539
5729
 
5540
5730
  const client = createClient({
5541
5731
  publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!,
5542
5732
  })
5733
+ const query = createQueryHooks(client)
5543
5734
 
5544
5735
  // Read data
5545
5736
  const products = await client.collections.from('products').find({ limit: 10 })
5546
5737
 
5547
5738
  // React Query hooks
5548
- const { data } = client.query.useQuery({ collection: 'products' })
5739
+ const { data } = query.useQuery({ collection: 'products' })
5549
5740
 
5550
5741
  // Customer auth
5551
5742
  await client.customer.login({ email, password })
@@ -5558,7 +5749,7 @@ await client.customer.login({ email, password })
5558
5749
  Use in server components, API routes, server actions, and background jobs. Has full CRUD access.
5559
5750
 
5560
5751
  \`\`\`typescript
5561
- import { createServerClient } from '@01.software/sdk'
5752
+ import { createServerClient } from '@01.software/sdk/server'
5562
5753
 
5563
5754
  const client = createServerClient({
5564
5755
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -5579,11 +5770,14 @@ await client.collections.from('product-variants').create({
5579
5770
  })
5580
5771
  await client.collections.from('products').remove('product-id')
5581
5772
 
5582
- // Server API (orders, carts, etc.)
5773
+ // Commerce API (orders, carts, etc.)
5583
5774
  await client.commerce.orders.create({ ... })
5584
5775
  await client.commerce.orders.checkout({ ... })
5585
5776
  \`\`\`
5586
5777
 
5778
+ Server-only code must import \`createServerClient\` from the \`/server\`
5779
+ sub-path.
5780
+
5587
5781
  **Environment variables**:
5588
5782
  - \`SOFTWARE_PUBLISHABLE_KEY\` \u2014 publishable key (no NEXT_PUBLIC prefix, server-only)
5589
5783
  - \`SOFTWARE_SECRET_KEY\` \u2014 server credential
@@ -5613,7 +5807,7 @@ deploying again.
5613
5807
 
5614
5808
  \`\`\`typescript
5615
5809
  // lib/sdk.ts \u2014 server-only module
5616
- import { createServerClient } from '@01.software/sdk'
5810
+ import { createServerClient } from '@01.software/sdk/server'
5617
5811
 
5618
5812
  export function getServerClient() {
5619
5813
  return createServerClient({
@@ -5626,10 +5820,12 @@ export function getServerClient() {
5626
5820
  \`\`\`typescript
5627
5821
  // lib/sdk-client.ts \u2014 browser-safe module
5628
5822
  import { createClient } from '@01.software/sdk'
5823
+ import { createQueryHooks } from '@01.software/sdk/query'
5629
5824
 
5630
5825
  export const browserClient = createClient({
5631
5826
  publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!,
5632
5827
  })
5828
+ export const browserQuery = createQueryHooks(browserClient)
5633
5829
  \`\`\`
5634
5830
 
5635
5831
  \`\`\`typescript
@@ -5646,10 +5842,10 @@ export default async function ProductsPage() {
5646
5842
  \`\`\`typescript
5647
5843
  // components/product-list.tsx \u2014 Client Component
5648
5844
  'use client'
5649
- import { browserClient } from '@/lib/sdk-client'
5845
+ import { browserQuery } from '@/lib/sdk-client'
5650
5846
 
5651
5847
  export function ProductList() {
5652
- const { data } = browserClient.query.useQuery({ collection: 'products' })
5848
+ const { data } = browserQuery.useQuery({ collection: 'products' })
5653
5849
  return <ul>{data?.docs.map(p => <li key={p.id}>{p.title}</li>)}</ul>
5654
5850
  }
5655
5851
  \`\`\`
@@ -5665,7 +5861,7 @@ export function ProductList() {
5665
5861
  }
5666
5862
 
5667
5863
  // src/resources/(docs)/file-upload.ts
5668
- var metadata45 = {
5864
+ var metadata47 = {
5669
5865
  name: "docs-file-upload",
5670
5866
  title: "File Upload",
5671
5867
  description: "01.software SDK file upload patterns using the images collection"
@@ -5680,7 +5876,7 @@ Upload files using the \`images\` collection (tenant-scoped, unified image store
5680
5876
  Use \`ServerClient\` with \`FormData\` to upload images server-side.
5681
5877
 
5682
5878
  \`\`\`typescript
5683
- import { createServerClient } from '@01.software/sdk'
5879
+ import { createServerClient } from '@01.software/sdk/server'
5684
5880
 
5685
5881
  const client = createServerClient({
5686
5882
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -5703,7 +5899,7 @@ async function uploadImage(file: File) {
5703
5899
  \`\`\`typescript
5704
5900
  // app/api/upload/route.ts
5705
5901
  import { NextRequest, NextResponse } from 'next/server'
5706
- import { createServerClient } from '@01.software/sdk'
5902
+ import { createServerClient } from '@01.software/sdk/server'
5707
5903
 
5708
5904
  const client = createServerClient({
5709
5905
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -5733,7 +5929,7 @@ export async function POST(req: NextRequest) {
5733
5929
  // actions/upload.ts
5734
5930
  'use server'
5735
5931
 
5736
- import { createServerClient } from '@01.software/sdk'
5932
+ import { createServerClient } from '@01.software/sdk/server'
5737
5933
 
5738
5934
  const client = createServerClient({
5739
5935
  publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!,
@@ -5816,7 +6012,7 @@ The platform stores files in Cloudflare R2 and serves via CDN (\`cdn.01.software
5816
6012
  }
5817
6013
 
5818
6014
  // src/resources/(docs)/webhook.ts
5819
- var metadata46 = {
6015
+ var metadata48 = {
5820
6016
  name: "docs-webhook",
5821
6017
  title: "Webhooks",
5822
6018
  description: "01.software SDK webhook verification and event handling"
@@ -5929,9 +6125,100 @@ Failed webhook deliveries are queued with automatic retries. Ensure your handler
5929
6125
  Configure webhook URLs in the 01.software console under Tenant Settings > Webhooks. Multiple URLs can be registered; all receive every event.`;
5930
6126
  }
5931
6127
 
6128
+ // src/resources/(docs)/product-detail.ts
6129
+ var metadata49 = {
6130
+ name: "docs-product-detail",
6131
+ title: "Product Detail Helper",
6132
+ description: "01.software SDK commerce.product.detail helper guide"
6133
+ };
6134
+ function handler19() {
6135
+ return `# Product Detail Helper
6136
+
6137
+ ## When to use the helper vs the raw query builder
6138
+
6139
+ Use \`client.commerce.product.detail({ slug | id })\` when you need a full product detail page payload in one call. The helper folds the Payload query, access policy, and response shaping (variants, options, option value slugs/media, brand, categories, tags, images, videos, listing rollup) into a single call.
6140
+
6141
+ Use \`client.collections.from('products').find(...)\` (escape hatch) when you need bulk reads, custom filter combinations, or fields outside the helper response shape.
6142
+
6143
+ ## Single-call example
6144
+
6145
+ \`\`\`typescript
6146
+ import { createClient, resolveProductSelection } from '@01.software/sdk'
6147
+
6148
+ const client = createClient({
6149
+ publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!,
6150
+ })
6151
+
6152
+ const detail = await client.commerce.product.detail({ slug: 'my-product' })
6153
+ if (!detail) return notFound()
6154
+ const selection = resolveProductSelection(detail, {
6155
+ search: '?opt.option-color=color-black',
6156
+ })
6157
+ // selection.selectedVariant, selection.price, selection.stock, selection.media
6158
+ \`\`\`
6159
+
6160
+ ## URL round-trip
6161
+
6162
+ Use the SDK codec for canonical selection URLs. Complete selections use
6163
+ \`variant=<variantId>\`; partial selections use
6164
+ \`opt.<optionId>=<valueId>\`. Older
6165
+ \`opt.<optionSlug>=<valueSlug>\` URLs still decode during Stage 1, but slugs are
6166
+ compatibility metadata rather than canonical identity.
6167
+
6168
+ \`\`\`typescript
6169
+ import { createProductSelectionCodec } from '@01.software/sdk'
6170
+
6171
+ const codec = createProductSelectionCodec(detail)
6172
+ const selection = codec.parse('?opt.option-color=color-black')
6173
+ const selectionQuery = codec.stringify(selection)
6174
+ \`\`\`
6175
+
6176
+ Use IDs from \`detail.options[].id\` and \`detail.options[].values[].id\` when building new selection links. Slugs remain useful for display and older inbound URLs, but new outbound URLs should use the codec output.
6177
+
6178
+ Value-slug-only URLs such as \`?black\` or \`?color=black\` are rejected because option titles and values are not stable identifiers.
6179
+
6180
+ ## React Query hook variant
6181
+
6182
+ \`\`\`typescript
6183
+ import { createQueryHooks } from '@01.software/sdk/query'
6184
+
6185
+ const query = createQueryHooks(client)
6186
+ const { data: detail, isLoading } = query.useProductDetailBySlug(slug)
6187
+ \`\`\`
6188
+
6189
+ Cache invalidates automatically when any of 10 detail-relevant collections is mutated through SDK mutation hooks.
6190
+
6191
+ ## SSG / Server Component snippet
6192
+
6193
+ \`\`\`tsx
6194
+ // app/products/[slug]/page.tsx
6195
+ import { createClient } from '@01.software/sdk'
6196
+ import { notFound } from 'next/navigation'
6197
+
6198
+ export const revalidate = 60
6199
+
6200
+ export default async function ProductPage({ params }: { params: { slug: string } }) {
6201
+ const client = createClient({
6202
+ publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!,
6203
+ })
6204
+ const detail = await client.commerce.product.detail({ slug: params.slug })
6205
+ if (!detail) return notFound()
6206
+ return <ProductView detail={detail} />
6207
+ }
6208
+ \`\`\`
6209
+
6210
+ ## The \`null\` return contract
6211
+
6212
+ The endpoint returns 404 for \`not_found\`, \`not_published\`, \`tenant_mismatch\`, or \`feature_disabled\`. The SDK collapses all 404s to \`null\` so consumer UIs render one "not available" path.
6213
+
6214
+ ## Backend correlation
6215
+
6216
+ Log \`client.lastRequestId\` against backend logs \u2014 the endpoint records the exact 404 code alongside the request ID.`;
6217
+ }
6218
+
5932
6219
  // src/server.ts
5933
6220
  var REGISTERED_TOOLS_BY_SERVER = /* @__PURE__ */ new WeakMap();
5934
- function registerTool(server, schema35, meta, handler20) {
6221
+ function registerTool(server, schema37, meta, handler21) {
5935
6222
  let registered = REGISTERED_TOOLS_BY_SERVER.get(server);
5936
6223
  if (!registered) {
5937
6224
  registered = /* @__PURE__ */ new Set();
@@ -5942,7 +6229,7 @@ function registerTool(server, schema35, meta, handler20) {
5942
6229
  meta.name,
5943
6230
  {
5944
6231
  description: meta.description,
5945
- inputSchema: schema35,
6232
+ inputSchema: schema37,
5946
6233
  annotations: meta.annotations
5947
6234
  },
5948
6235
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -5971,7 +6258,7 @@ function registerTool(server, schema35, meta, handler20) {
5971
6258
  const summary = activeSummary ?? ownSummary;
5972
6259
  let result = null;
5973
6260
  try {
5974
- result = await handler20(params);
6261
+ result = await handler21(params);
5975
6262
  return { content: [{ type: "text", text: result }] };
5976
6263
  } finally {
5977
6264
  if (summary) {
@@ -5988,26 +6275,26 @@ function registerTool(server, schema35, meta, handler20) {
5988
6275
  }
5989
6276
  );
5990
6277
  }
5991
- function registerPrompt(server, schema35, meta, handler20) {
6278
+ function registerPrompt(server, schema37, meta, handler21) {
5992
6279
  server.registerPrompt(
5993
6280
  meta.name,
5994
6281
  {
5995
6282
  title: meta.title,
5996
6283
  description: meta.description,
5997
- argsSchema: schema35
6284
+ argsSchema: schema37
5998
6285
  },
5999
6286
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
6000
6287
  (params) => ({
6001
6288
  messages: [
6002
6289
  {
6003
6290
  role: meta.role ?? "assistant",
6004
- content: { type: "text", text: handler20(params) }
6291
+ content: { type: "text", text: handler21(params) }
6005
6292
  }
6006
6293
  ]
6007
6294
  })
6008
6295
  );
6009
6296
  }
6010
- function registerStaticResource(server, uri, meta, handler20) {
6297
+ function registerStaticResource(server, uri, meta, handler21) {
6011
6298
  server.registerResource(
6012
6299
  meta.name,
6013
6300
  uri,
@@ -6017,7 +6304,7 @@ function registerStaticResource(server, uri, meta, handler20) {
6017
6304
  mimeType: meta.mimeType ?? "text/plain"
6018
6305
  },
6019
6306
  async (url) => ({
6020
- contents: [{ uri: url.href, text: handler20() }]
6307
+ contents: [{ uri: url.href, text: handler21() }]
6021
6308
  })
6022
6309
  );
6023
6310
  }
@@ -6119,147 +6406,160 @@ function createServer(options = {}) {
6119
6406
  calculateShipping
6120
6407
  );
6121
6408
  registerTool(server, schema21, metadata21, stockCheck);
6409
+ registerTool(server, schema22, metadata22, productDetail);
6410
+ registerTool(
6411
+ server,
6412
+ schema23,
6413
+ metadata23,
6414
+ productUpsert
6415
+ );
6122
6416
  }
6123
- registerTool(
6124
- server,
6125
- schema22,
6126
- metadata22,
6127
- getCollectionSchemaTool
6128
- );
6129
- registerTool(
6130
- server,
6131
- schema23,
6132
- metadata23,
6133
- handler
6134
- );
6135
6417
  registerTool(
6136
6418
  server,
6137
6419
  schema24,
6138
6420
  metadata24,
6139
- handler2
6421
+ getCollectionSchemaTool
6140
6422
  );
6141
6423
  registerTool(
6142
6424
  server,
6143
6425
  schema25,
6144
6426
  metadata25,
6145
- listConfigurableFields
6427
+ handler
6146
6428
  );
6147
6429
  registerTool(
6148
6430
  server,
6149
6431
  schema26,
6150
6432
  metadata26,
6151
- updateFieldConfig
6433
+ handler2
6152
6434
  );
6153
6435
  registerTool(
6154
6436
  server,
6155
6437
  schema27,
6156
6438
  metadata27,
6157
- handler3
6439
+ listConfigurableFields
6158
6440
  );
6159
6441
  registerTool(
6160
6442
  server,
6161
6443
  schema28,
6162
6444
  metadata28,
6163
- handler4
6445
+ updateFieldConfig
6164
6446
  );
6165
6447
  registerTool(
6166
6448
  server,
6167
6449
  schema29,
6168
6450
  metadata29,
6169
- handler5
6451
+ handler3
6170
6452
  );
6171
6453
  registerTool(
6172
6454
  server,
6173
6455
  schema30,
6174
6456
  metadata30,
6175
- handler6
6457
+ handler4
6176
6458
  );
6177
- registerPrompt(
6459
+ registerTool(
6178
6460
  server,
6179
6461
  schema31,
6180
6462
  metadata31,
6181
- sdkUsageGuide
6463
+ handler5
6182
6464
  );
6183
- registerPrompt(
6465
+ registerTool(
6184
6466
  server,
6185
6467
  schema32,
6186
6468
  metadata32,
6187
- collectionQueryHelp
6469
+ handler6
6188
6470
  );
6189
6471
  registerPrompt(
6190
6472
  server,
6191
6473
  schema33,
6192
6474
  metadata33,
6193
- orderFlowGuide
6475
+ sdkUsageGuide
6194
6476
  );
6195
6477
  registerPrompt(
6196
6478
  server,
6197
6479
  schema34,
6198
6480
  metadata34,
6481
+ collectionQueryHelp
6482
+ );
6483
+ registerPrompt(
6484
+ server,
6485
+ schema35,
6486
+ metadata35,
6487
+ orderFlowGuide
6488
+ );
6489
+ registerPrompt(
6490
+ server,
6491
+ schema36,
6492
+ metadata36,
6199
6493
  featureSetupGuide
6200
6494
  );
6201
6495
  registerStaticResource(
6202
6496
  server,
6203
6497
  "config://app",
6204
- metadata35,
6498
+ metadata37,
6205
6499
  handler7
6206
6500
  );
6207
6501
  registerStaticResource(
6208
6502
  server,
6209
6503
  "collections://schema",
6210
- metadata36,
6504
+ metadata38,
6211
6505
  handler8
6212
6506
  );
6213
6507
  registerStaticResource(
6214
6508
  server,
6215
6509
  "docs://sdk/getting-started",
6216
- metadata37,
6510
+ metadata39,
6217
6511
  handler9
6218
6512
  );
6219
- registerStaticResource(server, "docs://sdk/guides", metadata38, handler10);
6220
- registerStaticResource(server, "docs://sdk/api", metadata39, handler11);
6513
+ registerStaticResource(server, "docs://sdk/guides", metadata40, handler10);
6514
+ registerStaticResource(server, "docs://sdk/api", metadata41, handler11);
6221
6515
  registerStaticResource(
6222
6516
  server,
6223
6517
  "docs://sdk/query-builder",
6224
- metadata40,
6518
+ metadata42,
6225
6519
  handler12
6226
6520
  );
6227
6521
  registerStaticResource(
6228
6522
  server,
6229
6523
  "docs://sdk/react-query",
6230
- metadata41,
6524
+ metadata43,
6231
6525
  handler13
6232
6526
  );
6233
6527
  registerStaticResource(
6234
6528
  server,
6235
6529
  "docs://sdk/server-api",
6236
- metadata42,
6530
+ metadata44,
6237
6531
  handler14
6238
6532
  );
6239
6533
  registerStaticResource(
6240
6534
  server,
6241
6535
  "docs://sdk/customer-auth",
6242
- metadata43,
6536
+ metadata45,
6243
6537
  handler15
6244
6538
  );
6245
6539
  registerStaticResource(
6246
6540
  server,
6247
6541
  "docs://sdk/browser-vs-server",
6248
- metadata44,
6542
+ metadata46,
6249
6543
  handler16
6250
6544
  );
6251
6545
  registerStaticResource(
6252
6546
  server,
6253
6547
  "docs://sdk/file-upload",
6254
- metadata45,
6548
+ metadata47,
6255
6549
  handler17
6256
6550
  );
6257
6551
  registerStaticResource(
6258
6552
  server,
6259
6553
  "docs://sdk/webhook",
6260
- metadata46,
6554
+ metadata48,
6261
6555
  handler18
6262
6556
  );
6557
+ registerStaticResource(
6558
+ server,
6559
+ "docs://sdk/product-detail",
6560
+ metadata49,
6561
+ handler19
6562
+ );
6263
6563
  return server;
6264
6564
  }
6265
6565
 
@@ -6595,7 +6895,7 @@ function acceptsEventStream(req) {
6595
6895
  (entry) => entry.trim().split(";")[0]?.toLowerCase() === "text/event-stream"
6596
6896
  );
6597
6897
  }
6598
- async function handler19(req, res) {
6898
+ async function handler20(req, res) {
6599
6899
  setCors(res);
6600
6900
  if (req.method === "OPTIONS") {
6601
6901
  res.writeHead(204);
@@ -6705,5 +7005,5 @@ function writeRequestError(res, err) {
6705
7005
  res.end(JSON.stringify({ error: "Internal server error" }));
6706
7006
  }
6707
7007
  export {
6708
- handler19 as default
7008
+ handler20 as default
6709
7009
  };