=============== LIBRARY RULES =============== From library maintainers: - Prefer SDK and CLI public contracts over private monorepo implementation details. - Do not expose internal infrastructure, security runbooks, credentials, or private package internals. - Treat docs in this mirror as external developer documentation. ### Install SDK with npm Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Install the SDK using npm. This is the standard way to add the package to your project. ```bash npm install @01.software/sdk ``` -------------------------------- ### Install SDK with pnpm Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Install the SDK using pnpm. This is an alternative package manager. ```bash pnpm add @01.software/sdk ``` -------------------------------- ### Client Usage Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Example of how to initialize the client and query data on the client-side. ```APIDOC ## Client Initialization and Data Querying ### Description Initialize the client with a publishable key and query data from collections. ### Method `createClient` for initialization, `collections.from().find()` for querying. ### Parameters #### Client Initialization - `publishableKey` (string) - Required - Your publishable API key. #### Query Parameters - `limit` (number) - Optional - Maximum number of documents to return. - `select` (object) - Optional - Fields to include in the response. ### Request Example ```typescript import { createClient } from '@01.software/sdk' const client = createClient({ publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY, }) const { docs } = await client.collections.from('products').find({ limit: 10, select: { title: true, slug: true }, }) ``` ### Response #### Success Response - `docs` (array) - An array of documents matching the query. ``` -------------------------------- ### Server Client Usage Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Examples of initializing the server client, creating orders, and prefetching data for SSR. ```APIDOC ## Server Client Initialization and Operations ### Description Initialize the server client with publishable and secret keys for server-side operations like order creation and data prefetching. ### Method `createServerClient` for initialization, `createServerQueryHooks` for query hooks, `server.commerce.orders.create` for order creation, `serverQuery.prefetchQuery` for SSR prefetching. ### Parameters #### Server Client Initialization - `publishableKey` (string) - Required - Your publishable API key. - `secretKey` (string) - Required - Your secret API key. #### Order Creation Parameters - `orderNumber` (string) - Required - Unique identifier for the order. - `customerSnapshot` (object) - Required - Snapshot of customer information. - `email` (string) - Required - Customer's email address. - `shippingAddress` (object) - Required - Shipping address details. - `recipientName` (string) - Required. - `phone` (string) - Required. - `postalCode` (string) - Required. - `address` (string) - Required. - `detailAddress` (string) - Required. - `items` (array) - Required - Array of items in the order. - `product` (string) - Required - Product ID. - `variant` (string) - Required - Variant ID. - `option` (string) - Required - Option ID. - `quantity` (number) - Required. - `totalAmount` (number) - Required - Total amount of the order. - `pgProvider` (string) - Required - Payment gateway provider (e.g., 'portone'). - `pgPaymentId` (string) - Required - Payment gateway payment ID. - `discountCode` (string) - Optional - Discount code to apply. #### SSR Prefetch Parameters - `collection` (string) - Required - The collection to query. - `options` (object) - Optional - Query options like `limit`. ### Request Example (Order Creation) ```typescript import { createServerClient } from '@01.software/sdk/server' import { createServerQueryHooks } from '@01.software/sdk/query' const server = createServerClient({ publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY, secretKey: process.env.SOFTWARE_SECRET_KEY, }) const serverQuery = createServerQueryHooks(server) const order = await server.commerce.orders.create({ orderNumber: generateOrderNumber(), customerSnapshot: { email: 'user@example.com' }, shippingAddress: { recipientName: 'John', phone: '010-1234-5678', postalCode: '12345', address: 'Seoul', detailAddress: 'Apt 101', }, items: [ { product: productId, variant: variantId, option: optionId, quantity: 1 }, ], totalAmount: 10000, pgProvider: 'portone', pgPaymentId: 'provider-payment-id', discountCode: 'WELCOME10', }) ``` ### Request Example (SSR Prefetch) ```typescript await serverQuery.prefetchQuery({ collection: 'products', options: { limit: 10 }, }) ``` ### Response (Order Creation) - `order` (object) - The created order object. ``` -------------------------------- ### Build Product Hrefs for Listing Cards Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use `buildProductListingGroupsByOption` or the listing-groups endpoint to get listing groups. Pass these to `buildProductHref` for generating links to product pages, which emit partial slug-compat hints by default. ```typescript buildProductHref(product, group, { detail }) ``` -------------------------------- ### Get Product Catalog and Live Stock Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Fetches product catalog data and then retrieves live stock information for its variants, merging them for an up-to-date view. This is recommended for PDPs served behind edge CDNs to avoid stale inventory data. ```APIDOC ## Get Product Catalog and Live Stock ### Description Fetches product catalog data and then retrieves live stock information for its variants, merging them for an up-to-date view. This is recommended for PDPs served behind edge CDNs to avoid stale inventory data. ### Method `client.commerce.product.detailCatalog(params: { slug: string })` followed by `client.commerce.product.stockSnapshot(params: { variantIds: string[] })` and `mergeProductDetailWithStock(catalogProduct, snapshot)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript import { createClient, mergeProductDetailWithStock } from '@01.software/sdk' const client = createClient({ publishableKey: '' }) const catalog = await client.commerce.product.detailCatalog({ slug: 'every-peach-tee', }) if (!catalog.found) return notFound() const variantIds = catalog.product.variants.map((v) => v.id) const snapshot = await client.commerce.product.stockSnapshot({ variantIds }) const { product, stockMergeStatus } = mergeProductDetailWithStock( catalog.product, snapshot, ) ``` ### Response #### Success Response `catalog`: `{ found: true, product: ProductDetail } | { found: false, reason: string }` `snapshot`: `StockSnapshot` (contains stock levels for variant IDs) `merged product`: The `catalog.product` object with updated stock information. `stockMergeStatus`: `'complete' | 'partial'` #### Response Example ```json { "product": { "product": { ... }, "variants": [ { "id": "variant-id-1", "stock": 10 // Merged stock information } ], // ... other product details }, "stockMergeStatus": "complete" } ``` ### Error Handling Errors during catalog fetch will return `{ found: false, reason: string }`. Errors during stock snapshot fetch may result in a 'partial' `stockMergeStatus` if some variant IDs are missing. ``` -------------------------------- ### Next.js SSG/Server Component Usage Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Example of creating an SDK client within a Next.js server component for fetching product details. It demonstrates setting ISR revalidation and handling not found cases. ```typescript import { createClient } from '@01.software/sdk' export const revalidate = 60 // ISR — adjust per page freshness need export default async function ProductPage({ params }) { const client = createClient({ publishableKey: '', }) const result = await client.commerce.product.detail({ slug: params.slug }) if (!result.found) return notFound() const { product } = result // ... } ``` -------------------------------- ### Agent CLI Error Output Example Source: https://github.com/01-office/01-software-docs/blob/main/docs/cli/agent-cli-contract.md Illustrates the standard JSON format for error messages output to stdout by the Agent CLI. This format includes an error code and a descriptive message. ```json { "error": { "code": "INVALID_INPUT", "message": "Unknown collection \"prodcts\". Did you mean: products?" } } ``` -------------------------------- ### Agent CLI Get Command Source: https://github.com/01-office/01-software-docs/blob/main/docs/cli/agent-cli-contract.md Retrieves a specific item from a collection by its ID. Supports field selection and pretty-printed output. ```bash 01 agent get [--select ] [--pretty] ``` -------------------------------- ### Get Product Detail Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Fetches the detailed information for a single product using its slug. It returns a discriminated union indicating if the product was found or not, along with the product data or a reason for not being found. ```APIDOC ## Get Product Detail ### Description Fetches the detailed information for a single product using its slug. It returns a discriminated union indicating if the product was found or not, along with the product data or a reason for not being found. ### Method `client.commerce.product.detail(params: { slug: string })` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript import { createClient } from '@01.software/sdk' const client = createClient({ publishableKey: '', }) const result = await client.commerce.product.detail({ slug: 'every-peach-tee', }) ``` ### Response #### Success Response `ProductDetailResult`: `{ found: true, product: ProductDetail } | { found: false, reason: 'not_found' | 'not_published' | 'feature_disabled' }` #### Response Example ```json { "found": true, "product": { "product": { ... }, "variants": [ ... ], "options": [ ... ], "brand": { ... }, "categories": [ ... ], "tags": [ ... ], "images": [ ... ], "videos": [ ... ], "featuredImage": { ... }, "priceRange": { ... }, "compareAtPriceRange": { ... }, "availableForSale": true, "selectedOrFirstAvailableVariant": { ... } } } ``` ### Error Handling Permission/auth errors throw typed `SDKError` subclasses. ``` -------------------------------- ### Agent CLI Get Document Output Source: https://github.com/01-office/01-software-docs/blob/main/docs/cli/agent-cli-contract.md The output format for the 'agent get ' command, which returns the bare document details. This includes all fields of the specified document. ```json { "id": "ord_123", "orderNumber": "ORD-123", "financialStatus": "paid", "displayFinancialStatus": "paid", "displayFulfillmentStatus": "in_progress", "returnStatus": "no_return", "primaryDisplayStatus": "preparing", "fulfillmentOrders": { "docs": [{ "status": "in_progress" }], "hasNextPage": false, "totalDocs": 1 }, "fulfillments": { "docs": [], "hasNextPage": false, "totalDocs": 0 } } ``` -------------------------------- ### React Query Hooks for Data Fetching Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Utilize these hooks for browser-safe reads and customer authentication. Ensure `@tanstack/react-query` is installed when importing from `@01.software/sdk/query`. Use `createQueryHooks(client)` for browser components and `createServerClient` for server-side operations. ```typescript import { createQueryHooks } from '@01.software/sdk/query' const query = createQueryHooks(client) // List query const { data, isLoading } = query.useQuery({ collection: 'products', options: { limit: 10 }, }) // Suspense mode const { data } = query.useSuspenseQuery({ collection: 'products', options: { limit: 10 }, }) // Query by ID const { data } = query.useQueryById({ collection: 'products', id: 'product_id', }) // Infinite scroll const { data, fetchNextPage, hasNextPage } = query.useInfiniteQuery({ collection: 'products', options: { limit: 20 }, }) // SSR Prefetch await query.prefetchQuery({ collection: 'products', options: { limit: 10 }, }) await query.prefetchQueryById({ collection: 'products', id: 'product_id', }) await query.prefetchInfiniteQuery({ collection: 'products', pageSize: 20, }) // Cache utilities query.invalidateQueries('products') query.getQueryData('products', 'list', options) query.setQueryData('products', 'detail', id, data) // Customer auth hooks (Client only) const { data: profile } = query.useCustomerMe() const { mutate: login } = query.useCustomerLogin() const { mutate: register } = query.useCustomerRegister() const { mutate: logout } = query.useCustomerLogout() login({ email: 'user@example.com', password: 'password' }) // Other customer mutations query.useCustomerForgotPassword() query.useCustomerResetPassword() query.useCustomerChangePassword() // Customer cache utilities query.invalidateCustomerQueries() query.getCustomerData() query.setCustomerData(profile) ``` -------------------------------- ### Client Initialization Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Demonstrates how to create SDK clients for browser and server environments with configuration options. ```APIDOC ## Client Configuration ### `createClient` (Browser/Server Components) ```typescript const client = createClient({ publishableKey: string, // Required apiUrl?: string, // Optional API origin override }) ``` ### `createServerClient` (Server-side only) ```typescript const server = createServerClient({ publishableKey: string, secretKey: string, // sk01_... or pat01_... apiUrl?: string, // Optional API origin override }) ``` ### Options | Option | Type | Description | | ---------------- | -------- | ------------------------------------------------------------- | | `publishableKey` | `string` | API publishable key | | `secretKey` | `string` | API secret key or PAT (server only) | | `apiUrl` | `string` | Optional API origin override for staging, preview, or proxies | Use `apiUrl: string` when an SDK instance should target a non-default API origin. API URL resolution order: 1. Explicit `apiUrl` passed to `createClient()` or `createServerClient()` 2. `SOFTWARE_API_URL` (server) or `NEXT_PUBLIC_SOFTWARE_API_URL` (browser) 3. Build-time default: `DEFAULT_API_URL` when injected at build time; otherwise dev-tagged SDK builds (`-dev.` versions) use `https://api.stg.01.software`, and regular releases use `https://api.01.software` ``` -------------------------------- ### Client Creation with Configuration Options Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Demonstrates how to create SDK clients for both browser and server environments, including optional API origin overrides. ```typescript const client = createClient({ publishableKey: string, // Required apiUrl?: string, // Optional API origin override }) ``` ```typescript const server = createServerClient({ publishableKey: string, secretKey: string, // sk01_... or pat01_... apiUrl?: string, // Optional API origin override }) ``` -------------------------------- ### Count Documents Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Get the total number of documents in a collection. ```typescript const { totalDocs } = await client.collections.from('products').count() ``` -------------------------------- ### Initialize Client SDK Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Create a client instance for making requests from your frontend application. Ensure your publishable key is set as an environment variable. ```typescript import { createClient } from '@01.software/sdk' const client = createClient({ publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY, }) // Query data (returns Payload native response) const { docs } = await client.collections.from('products').find({ limit: 10, select: { title: true, slug: true }, }) ``` -------------------------------- ### Initialize Server SDK Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Set up a server-side client for secure operations. This requires both publishable and secret keys. Use this for direct order creation or server-side data fetching. ```typescript import { createServerClient } from '@01.software/sdk/server' import { createServerQueryHooks } from '@01.software/sdk/query' const server = createServerClient({ publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY, secretKey: process.env.SOFTWARE_SECRET_KEY, // sk01_... opaque API key from Console }) const serverQuery = createServerQueryHooks(server) // Direct order creation (server-only compatibility path) const order = await server.commerce.orders.create({ orderNumber: generateOrderNumber(), customerSnapshot: { email: 'user@example.com' }, shippingAddress: { recipientName: 'John', phone: '010-1234-5678', postalCode: '12345', address: 'Seoul', detailAddress: 'Apt 101', }, items: [ { product: productId, variant: variantId, option: optionId, quantity: 1 }, ], totalAmount: 10000, pgProvider: 'portone', // required with pgPaymentId pgPaymentId: 'provider-payment-id', // omit both fields for free orders discountCode: 'WELCOME10', // optional }) // SSR prefetch (server) await serverQuery.prefetchQuery({ collection: 'products', options: { limit: 10 }, }) ``` -------------------------------- ### Get Commerce Cart Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Retrieves the customer-facing cart DTO for a given cart ID. Use server collection helpers for raw operational documents. ```typescript // Other cart operations return sanitized customer-facing cart DTOs. await client.commerce.cart.get(cartId) ``` -------------------------------- ### Configure SDK with Environment Variables Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Shows the environment variables required for SDK configuration, distinguishing between client-side and server-side keys. Publishable keys are for client-side use, while secret keys are strictly for server environments. ```bash NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY=your_publishable_key SOFTWARE_PUBLISHABLE_KEY=your_publishable_key SOFTWARE_SECRET_KEY=sk01_... # Server only — opaque API key from Console ``` -------------------------------- ### Server-Auth Product Listing with Extended Joins Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use createServerClient() and spread PRODUCT_PLP_FIND_OPTIONS for server code needing raw 'products' collection reads with raised join limits. This bypasses browser-public read constraints. ```typescript import { PRODUCT_PLP_FIND_OPTIONS, projectProductToListingShape, } from '@01.software/sdk' import { createServerClient } from '@01.software/sdk/server' const server = createServerClient({ publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!, apiUrl: process.env.SOFTWARE_API_URL!, secretKey: process.env.SOFTWARE_SECRET_KEY!, }) const now = new Date().toISOString() const { docs } = await server.collections.from('products').find({ ...PRODUCT_PLP_FIND_OPTIONS, where: { and: [ { status: { equals: 'published' } }, { or: [ { publishedAt: { less_than_equal: now } }, { publishedAt: { exists: false } }, { publishedAt: { equals: null } }, ], }, ], }, limit: 24, }) const listingProducts = docs.map(projectProductToListingShape) ``` -------------------------------- ### Fetch Storefront Links and Gallery Items Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use `client.content.links.list` to fetch links with filtering and sorting, and `client.content.galleryItems.list` to retrieve gallery items. Both require a publishable key and return shaped DTOs suitable for storefront display. ```typescript import { createClient } from '@01.software/sdk' const client = createClient({ publishableKey: '' }) const links = await client.content.links.list({ limit: 10, categorySlug: 'social', tagSlug: 'footer', featured: true, sort: 'title', }) const gallery = await client.content.galleryItems.list({ gallerySlug: 'spring-lookbook', limit: 24, }) ``` -------------------------------- ### Server Preview Detail Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md How to fetch preview details for unpublished content using a preview token. ```APIDOC ## Server Preview Detail ### Description Fetch details of unpublished or draft content using a short-lived preview token. ### Method `server.preview.detail()` or `server.commerce.product.previewDetail()`. ### Parameters #### `server.preview.detail()` - `params` (object) - Required - Parameters for the preview. - `collection` (string) - Required - The collection name. - `id` (string) - Required - The ID of the item. - `options` (object) - Required - Options for the preview. - `previewToken` (string) - Required - The short-lived preview token. #### `server.commerce.product.previewDetail()` - `params` (object) - Required - Parameters for the preview. - `id` (string) - Required - The product ID. - `options` (object) - Required - Options for the preview. - `previewToken` (string) - Required - The short-lived preview token. ### Request Example ```typescript const preview = await server.preview.detail( { collection: 'products', id: previewId }, { previewToken }, ) // For product-specific previews: const productPreview = await server.commerce.product.previewDetail({ id: productId }, { previewToken }) ``` ### Response #### Success Response (`server.preview.detail()`) - `found` (boolean) - Indicates if the item was found. - `product` (object) - The product detail payload if found. - `reason` (string) - Reason for not finding the item, if applicable. #### Success Response (`server.commerce.product.previewDetail()`) - The raw product detail payload for the saved draft/unpublished record. ``` -------------------------------- ### Build and Resolve Product Selection Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Utilize product selection helpers to build an option matrix, resolve a specific product selection from a matrix, and generate a product href. This aligns selection media with storefront display. ```typescript import { buildProductHref, buildProductOptionMatrixFromDetail, getProductSelectionImages, resolveProductSelectionFromMatrix, } from '@01.software/sdk' const matrix = buildProductOptionMatrixFromDetail(product) const selection = resolveProductSelectionFromMatrix( matrix, { search: '?opt.color=black&opt.size=s' }, undefined, { detail: product }, ) const images = getProductSelectionImages(selection) // object media only, deduped const href = buildProductHref(product, { optionSlug: 'color', optionValueSlug: 'black', }) ``` -------------------------------- ### Basic Event Tracking (Browser) Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use `createAnalytics` to initialize the SDK for basic pageview and custom event tracking in the browser. Auto-tracks pageviews, but manual tracking is also supported. ```typescript import { createAnalytics } from '@01.software/sdk/analytics' const analytics = createAnalytics({ publishableKey: 'pk_xxx' }) // auto-tracks pageviews; call analytics.pageview('/custom-path') manually if needed analytics.track('signup', { plan: 'pro', trial: false }) ``` -------------------------------- ### Browser Client and Commerce Helpers Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Import the main entry for browser clients, query builders, commerce helpers, and utilities. ```typescript // Main entry - browser client, query builder, commerce helpers, utilities import { createClient } from '@01.software/sdk' ``` -------------------------------- ### Agent CLI Plan Create Command Source: https://github.com/01-office/01-software-docs/blob/main/docs/cli/agent-cli-contract.md Creates a new plan within a collection. Input data must be provided via standard input (`--data-stdin`) or a file (`--data-file`). ```bash 01 agent plan create (--data-stdin | --data-file ) [--pretty] ``` -------------------------------- ### Agent CLI Query Command Source: https://github.com/01-office/01-software-docs/blob/main/docs/cli/agent-cli-contract.md Queries a collection with various filtering, pagination, sorting, and selection options. The `--pretty` flag enables formatted output. ```bash 01 agent query [--where ] [--limit ] [--page ] [--sort ] [--select ] [--pretty] ``` -------------------------------- ### Server Action for Collection Writes Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use `createServerClient` for server-side operations like updating collections. Ensure your environment variables for publishable and secret keys are set. ```typescript import { createServerClient } from '@01.software/sdk/server' const server = createServerClient({ publishableKey: process.env.SOFTWARE_PUBLISHABLE_KEY!, secretKey: process.env.SOFTWARE_SECRET_KEY!, }) await server.collections.from('articles').update('article_id', { title: 'Updated article', }) ``` -------------------------------- ### Realtime Client Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Import the realtime client for real-time data functionalities. ```typescript // Realtime only import { createRealtimeClient } from '@01.software/sdk/realtime' ``` -------------------------------- ### Fetch Server-Side Preview Data Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Retrieve draft or unpublished content using a preview token for server-side rendering. Use `server.preview.detail` for general content or `server.commerce.product.previewDetail` for product-specific data. ```typescript const preview = await server.preview.detail( { collection: 'products', id: previewId }, { previewToken }, ) ``` -------------------------------- ### Fetch Catalog and Live Stock Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md For storefronts using edge caching, fetch product catalog details separately and then merge with live stock information using `mergeProductDetailWithStock`. This ensures up-to-date inventory data. ```typescript import { createClient, mergeProductDetailWithStock } from '@01.software/sdk' const client = createClient({ publishableKey: '' }) const catalog = await client.commerce.product.detailCatalog({ slug: 'every-peach-tee', }) if (!catalog.found) return notFound() const variantIds = catalog.product.variants.map((v) => v.id) const snapshot = await client.commerce.product.stockSnapshot({ variantIds }) const { product, stockMergeStatus } = mergeProductDetailWithStock( catalog.product, snapshot, ) // stockMergeStatus: 'complete' | 'partial' — partial when a variant id is missing from snapshot ``` -------------------------------- ### Create Document (Server Only) Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Create a new document in a collection. Requires server credentials. Returns the created document and a message. ```typescript const { doc, message } = await server.collections .from('articles') .create({ title: 'Article' }) ``` -------------------------------- ### Format Order Name Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Formats a list of products into a single string. Displays the first product's title or a combined string if multiple products exist. ```typescript import { formatOrderName } from '@01.software/sdk' formatOrderName([{ product: { title: 'Product A' } }]) // "Product A" formatOrderName([ { product: { title: 'Product A' } }, { product: { title: 'Product B' } }, ]) // "Product A 외 1건" ``` -------------------------------- ### Handle Customer Authentication Webhooks Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Implement createCustomerAuthWebhookHandler to manage customer authentication events, such as password resets. Ensure your environment variables are correctly configured. ```typescript // Customer auth helper import { createCustomerAuthWebhookHandler } from '@01.software/sdk/webhook' async function sendPasswordResetEmail( email: string, resetPasswordToken: string, ): Promise { console.log('Send password reset email', email, resetPasswordToken) } const customerAuthHandler = createCustomerAuthWebhookHandler({ passwordReset: async ({ email, resetPasswordToken }) => { await sendPasswordResetEmail(email, resetPasswordToken) }, }) ``` -------------------------------- ### Configure Storefront React Query Client Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use `getStorefrontQueryClient` for client-only storefronts to manage query caching with a default staleTime of approximately 1 minute. This ensures fresher data compared to the default SSR behavior. ```typescript import { createClient, createQueryHooks, getStorefrontQueryClient, } from '@01.software/sdk/query' const client = createClient({ publishableKey: '...' }) const query = createQueryHooks(client, getStorefrontQueryClient()) ``` -------------------------------- ### Agent CLI Manifest Command Source: https://github.com/01-office/01-software-docs/blob/main/docs/cli/agent-cli-contract.md Retrieves the protocol version for the agent CLI. The `--pretty` flag can be used for formatted output. ```bash 01 agent manifest [--pretty] ``` -------------------------------- ### Advance Product Selection with selectNext Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use `selectNext` to transition to the next option selection, maintaining compatible prior selections and re-defaulting incompatible ones. It internally handles filling missing options. ```typescript import { resolveProductSelection, selectNext } from '@01.software/sdk' const nextSelection = selectNext(product, currentSelection, 'color', 'ivory') const resolution = resolveProductSelection(product, nextSelection) ``` -------------------------------- ### Upsert Product with Options and Variants Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use this to create or update a product with its associated options and variants. Ensure correct product ID and graph revision are used for updates. ```typescript const result = await server.commerce.product.upsert({ product: { title: 'Every Peach Tee', slug: 'every-peach-tee', status: 'published', }, options: [ { title: 'Color', slug: 'color', values: [ { value: 'Black', slug: 'black', swatch: { type: 'color', color: '#111111' }, }, { value: 'White', slug: 'white', swatch: { type: 'color', color: '#ffffff' }, }, ], }, { title: 'Size', slug: 'size', values: [ { value: 'Small', slug: 's' }, { value: 'Medium', slug: 'm' }, ], }, ], variants: [ { optionValues: { color: { valueSlug: 'black' }, size: { valueSlug: 's' } }, sku: 'TEE-BLK-S', price: 29000, stock: 10, isActive: true, }, { optionValues: { color: { valueSlug: 'white' }, size: { valueSlug: 'm' } }, sku: 'TEE-WHT-M', price: 29000, stock: 8, isActive: true, }, ], }) if (!result.ok) { throw new Error(result.message) } ``` -------------------------------- ### Storefront Cache Resources Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Import storefront cache resource names for Server-Side Generation (SSG) and Incremental Static Regeneration (ISR) adapters. ```typescript // Storefront cache resource names for SSG/ISR adapters import { storefrontCacheResources } from '@01.software/sdk/storefront-cache' ``` -------------------------------- ### Create Order Return Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Initiates a return process for an order, specifying items to be returned and refund details. ```typescript // Returns await server.commerce.orders.createReturn({ orderNumber, returnItems: [{ orderItem, quantity, restockingFee? }], refundAmount, returnShippingFee?, initialShippingRefundAmount?, initialShippingRefundOverrideNote?, reason?, }) ``` -------------------------------- ### Fetch Product Listing Groups by IDs Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use commerce.product.listingGroupsCatalog() when product IDs are already known, such as for curated rails or recommendations. ```typescript const response = await client.commerce.product.listingGroupsCatalog({ productIds: ['product-1', 'product-2'], }) ``` -------------------------------- ### Handle SDK Errors with TypeScript Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Demonstrates how to catch and differentiate between network, API, and validation errors thrown by the SDK using TypeScript. Ensure you import the necessary error checking functions. ```typescript import { isNetworkError, isApiError, isValidationError } from '@01.software/sdk' try { const { docs } = await client.collections.from('products').find() } catch (error) { if (isNetworkError(error)) { console.error('Network issue:', error.message) } else if (isApiError(error)) { console.error('API error:', error.status, error.message) } } ``` -------------------------------- ### Customer Authentication Client-Side Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Manage customer authentication flows on the client using `client.customer.auth.*`. This includes registration, login, profile management, and password resets. Ensure the client is created with `customer: { persist: true }` for persistent sessions. ```typescript const client = createClient({ publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY, customer: { persist: true }, }) // Register & login const { customer } = await client.customer.auth.register({ name: 'John', email: 'john@example.com', password: 'secure123', }) const { token, customer } = await client.customer.auth.login({ email: 'john@example.com', password: 'secure123', }) // Profile & token management const profile = await client.customer.auth.me() client.customer.auth.isAuthenticated() client.customer.auth.logout() // Authenticated customer's own orders (Client-only) const orders = await client.commerce.orders.listMine({ page: 1, limit: 10, displayFinancialStatus: 'paid', }) // Password await client.customer.auth.forgotPassword('john@example.com') await client.customer.auth.resetPassword(token, newPassword) await client.customer.auth.changePassword(currentPassword, newPassword) ``` -------------------------------- ### Create Document with File Upload (Server Only) Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Create a new document that includes a file upload. Uses multipart/form-data encoding. ```typescript const { doc } = await server.collections .from('images') .create({ alt: 'Hero image' }, { file: imageFile, filename: 'hero.jpg' }) ``` -------------------------------- ### Agent CLI Confirm Command Source: https://github.com/01-office/01-software-docs/blob/main/docs/cli/agent-cli-contract.md Confirms a plan using its token and hash. Supports pretty-printed output. ```bash 01 agent confirm --hash [--pretty] ``` -------------------------------- ### Find Products with Join Fields Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Query products, populating join fields like variants and options with specific controls for limit and sort order. This also includes populating normal relationships up to depth 2. ```typescript // Canonical product detail query — variants/options are join fields on Products await server.collections.from('products').find({ where: { slug: { equals } }, joins: { variants: { limit: 50, sort: '_order' }, options: {}, }, depth: 2, // also populate normal relationships (category, brand, etc.) }) ``` -------------------------------- ### Fetch Product Listing Page Data Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use commerce.product.listingPage() for greenfield storefront PLPs. It wraps the cacheable listing-groups query endpoint and includes cards built with buildProductListingCard(). ```typescript const response = await client.commerce.product.listingPage({ search: 'shirt', limit: 24, filters: { categoryIds: ['category-1'], price: { min: 10000, max: 50000 }, availableForSale: true, }, basePath: '/shop', }) const cards = response.cards ``` -------------------------------- ### Build Product Listing Cards from API Response Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Transforms items from a commerce API response into ProductListingCard objects. The basePath option can be used to set a custom shop path. ```typescript import { buildProductListingCard, type ProductListingCard, } from '@01.software/sdk' const cards: ProductListingCard[] = response.docs.map((item) => buildProductListingCard(item, { basePath: '/shop' }), ) ``` -------------------------------- ### Image Component Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Import the Image component for displaying images. ```typescript import { Image } from '@01.software/sdk/ui/image' ``` -------------------------------- ### Returns Management Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Methods for creating and managing returns for orders. ```APIDOC ## createReturn ### Description Creates a return for an order. ### Method `server.commerce.orders.createReturn({ orderNumber, returnItems, refundAmount, returnShippingFee?, initialShippingRefundAmount?, initialShippingRefundOverrideNote?, reason? }) ### Parameters - `orderNumber` (string) - Required - The number of the order to return. - `returnItems` (array) - Required - An array of items to be returned. Each item should include `orderItem`, `quantity`, and optionally `restockingFee`. - `refundAmount` (number) - Required - The total refund amount. - `returnShippingFee` (number) - Optional - The shipping fee for the return. - `initialShippingRefundAmount` (number) - Optional - The amount to refund for the initial shipping. - `initialShippingRefundOverrideNote` (string) - Optional - A note overriding the initial shipping refund. - `reason` (string) - Optional - The reason for the return. ``` ```APIDOC ## updateReturn ### Description Updates the status of an existing return. ### Method `server.commerce.orders.updateReturn({ returnId, status }) ### Parameters - `returnId` (string) - Required - The ID of the return to update. - `status` (string) - Required - The new status for the return. ``` ```APIDOC ## returnWithRefund ### Description Processes a return and applies a refund. ### Method `server.commerce.orders.returnWithRefund({ orderNumber, returnItems, refundAmount, returnShippingFee?, initialShippingRefundAmount?, initialShippingRefundOverrideNote?, pgPaymentId }) ### Parameters - `orderNumber` (string) - Required - The number of the order to return. - `returnItems` (array) - Required - An array of items to be returned. Each item should include `orderItem`, `quantity`, and optionally `restockingFee`. - `refundAmount` (number) - Required - The total refund amount. - `returnShippingFee` (number) - Optional - The shipping fee for the return. - `initialShippingRefundAmount` (number) - Optional - The amount to refund for the initial shipping. - `initialShippingRefundOverrideNote` (string) - Optional - A note overriding the initial shipping refund. - `pgPaymentId` (string) - Optional - The payment ID from the payment gateway to associate with the refund. ``` -------------------------------- ### Fetch Single Product Detail Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use the `detail` helper to fetch a single product's information. It returns a discriminated union indicating if the product was found or not, along with a reason if it wasn't. ```typescript import { createClient } from '@01.software/sdk' const client = createClient({ publishableKey: '', }) const result = await client.commerce.product.detail({ slug: 'every-peach-tee', }) if (!result.found) { return notFound() } const { product } = result // product: { product, variants, options, brand, categories, tags, images, videos, // featuredImage, priceRange, compareAtPriceRange, availableForSale, selectedOrFirstAvailableVariant } ``` -------------------------------- ### Find Products with Populated Relationships Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Perform a find operation on products, populating normal relationships like categories and images with specific fields, and setting a depth of 2. This query is intended for server-side execution. ```typescript await server.collections.from('products').find({ depth: 2, populate: { categories: { title: true, slug: true }, images: { url: true, alt: true }, }, }) ``` -------------------------------- ### List Query with Pagination and Selection Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use this to fetch a paginated list of documents with specific fields selected. Supports sorting and depth control. ```typescript const { docs, totalDocs, hasNextPage } = await client.collections .from('products') .find({ limit: 20, page: 1, sort: '-createdAt', depth: 0, select: { title: true, slug: true }, }) ``` -------------------------------- ### Checkout Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Methods for initiating and managing the checkout process. ```APIDOC ## checkout ### Description Starts a checkout process and returns a `PublicCheckout` object with lifecycle status. This does not create a durable `Order` before placement. ### Method `server.commerce.orders.checkout({ cartId, customerSnapshot, discountCode? }) ### Parameters - `cartId` (string) - Required - The ID of the shopping cart. - `customerSnapshot` (object) - Required - A snapshot of the customer's information. - `discountCode` (string) - Optional - A discount code to apply to the checkout. ``` -------------------------------- ### Create and Update Orders Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use these methods to create new orders or update existing ones with specific parameters. ```typescript await server.commerce.orders.create(params) await server.commerce.orders.update({ orderNumber, status: 'confirmed' }) ``` -------------------------------- ### Discounts and Shipping Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Methods for validating discounts and calculating shipping costs. ```APIDOC ## validate ### Description Validates a discount code against the current order amount. ### Method `client.commerce.discounts.validate({ code, orderAmount }) ### Parameters - `code` (string) - Required - The discount code to validate. - `orderAmount` (number) - Required - The current total amount of the order. ``` ```APIDOC ## calculate ### Description Calculates the shipping cost for an order based on provided details. ### Method `client.commerce.shipping.calculate({ shippingPolicyId?, orderAmount, postalCode? }) ### Parameters - `shippingPolicyId` (string) - Optional - The ID of the shipping policy to use. - `orderAmount` (number) - Required - The total amount of the order. - `postalCode` (string) - Optional - The postal code for shipping calculation. ### Response #### Success Response (200) - `shippingAmount` (number) - The calculated shipping amount. - `baseShippingAmount` (number) - The base shipping amount. - `extraShippingAmount` (number) - Any additional shipping charges. - `freeShipping` (boolean) - Indicates if free shipping is applicable. - `freeShippingMinAmount` (number) - The minimum order amount for free shipping. - `isJeju` (boolean) - Indicates if the destination is Jeju island. - `isRemoteIsland` (boolean) - Indicates if the destination is a remote island. ``` -------------------------------- ### Create React Query Hooks Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Use `createQueryHooks` to integrate with React Query for data fetching. Mutations on related collections automatically invalidate the product detail cache. ```typescript import { createQueryHooks } from '@01.software/sdk/query' const query = createQueryHooks(client) const { data: product, isLoading } = query.useProductDetailBySlug(slug) ``` -------------------------------- ### Agent CLI Plan Output Source: https://github.com/01-office/01-software-docs/blob/main/docs/cli/agent-cli-contract.md The metadata returned by the 'agent plan' command, which performs validation and discovery without mutating remote documents. It includes a plan token, hash, ID, expiration, and confirmation command. ```json { "planToken": "eyJwbGFuSWQiOiIuLi4ifQ", "planHash": "a1b2…", "planId": "6f1d8f2a-…", "expiresAt": "2026-05-31T12:15:00.000Z", "operation": "create", "collection": "articles", "confirmCommand": "01 agent confirm eyJwbGFuSWQiOiIuLi4ifQ --hash a1b2…" } ``` -------------------------------- ### Batch Stock Check for Product Variants Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Perform a point-in-time stock check for product items. This does not reserve stock. Handle statuses like 'not_published' or 'archived' appropriately. ```typescript // Batch stock check (point-in-time read, NOT a reservation) const { results, allAvailable } = await client.commerce.product.stockCheck({ items: [{ variantId: '...', quantity: 2 }], }) for (const item of results) { if (item.status === 'available' && item.isUnlimited) { // Unlimited stock is explicit; availableStock is a numeric count, not a sentinel. continue } if (item.status === 'not_published' || item.status === 'archived') { // Variant still exists, but its parent product is not currently sellable. continue } } ``` -------------------------------- ### Product Selection URL Contract Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Utilize `createProductSelectionCodec` to manage option selections in URLs. It handles parsing and stringifying selections, supporting both canonical IDs and slug-compatible parameters. ```typescript import { createProductSelectionCodec, resolveProductSelection, } from '@01.software/sdk' const codec = createProductSelectionCodec(product) const normalizedSelection = codec.parse('?opt.color=ivory') const selection = resolveProductSelection(product, normalizedSelection) const selectionQuery = codec.stringify(normalizedSelection) ``` -------------------------------- ### client.commerce.cart.addItem Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Adds an item to the shopping cart. ```APIDOC ## client.commerce.cart.addItem ### Description Adds an item to the shopping cart. ### Method POST (implied by add operation) ### Endpoint `/api/cart/items` (implied) ### Parameters #### Request Body - **cartId** (string) - Required - The ID of the cart. - **product** (object) - Required - The product to add. - **variant** (object) - Required - The variant of the product. - **option** (object) - Optional - The selected option for the product. - **quantity** (number) - Required - The quantity of the item to add. ``` -------------------------------- ### Update Document with File Replacement (Server Only) Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Update an existing document and replace an associated file. Requires server credentials. ```typescript await server.collections .from('images') .update('id', { alt: 'New alt' }, { file: newFile }) ``` -------------------------------- ### Webhook Handlers Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Import webhook handlers for processing incoming webhooks. ```typescript // Webhook only - webhook handlers import { handleWebhook, createTypedWebhookHandler, } from '@01.software/sdk/webhook' ``` -------------------------------- ### Server Client for Collection Writes Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Provides a server-side client for performing collection write operations like updates. ```APIDOC ## Server Client for Collection Writes Use `createServerClient` for server actions or API routes to perform collection writes. ### `createServerClient(config)` **Description**: Initializes the server client. **Parameters**: - `config` (object): Configuration object. - `publishableKey` (string): Your publishable key. - `secretKey` (string): Your secret key. ### `server.collections.from(collectionName).update(id, data)` **Description**: Updates a document within a collection. **Parameters**: - `collectionName` (string): The name of the collection. - `id` (string): The ID of the document to update. - `data` (object): The data to update the document with. ``` -------------------------------- ### Rich Text Component Source: https://github.com/01-office/01-software-docs/blob/main/docs/sdk/README.md Import the RichTextContent component for rendering rich text content. ```typescript import { RichTextContent } from '@01.software/sdk/ui/rich-text' ```