@viu/emporix-sdk 2.14.0 → 2.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/availability.cjs +1 -0
- package/dist/availability.cjs.map +1 -1
- package/dist/availability.d.cts +1 -0
- package/dist/availability.d.ts +1 -0
- package/dist/availability.js +1 -1
- package/dist/cart.cjs +1 -0
- package/dist/cart.cjs.map +1 -1
- package/dist/cart.d.cts +1 -0
- package/dist/cart.d.ts +1 -0
- package/dist/cart.js +1 -1
- package/dist/category.cjs +1 -0
- package/dist/category.cjs.map +1 -1
- package/dist/category.d.cts +1 -0
- package/dist/category.d.ts +1 -0
- package/dist/category.js +1 -1
- package/dist/checkout.cjs +1 -0
- package/dist/checkout.cjs.map +1 -1
- package/dist/checkout.d.cts +1 -0
- package/dist/checkout.d.ts +1 -0
- package/dist/checkout.js +1 -1
- package/dist/{chunk-LGOC5XOI.js → chunk-3BTPX7IJ.js} +3 -2
- package/dist/chunk-3BTPX7IJ.js.map +1 -0
- package/dist/{chunk-MIUVJEGR.js → chunk-5VTBLBXJ.js} +3 -2
- package/dist/chunk-5VTBLBXJ.js.map +1 -0
- package/dist/{chunk-WW3H7VJ5.js → chunk-62PCCHZ2.js} +4 -2
- package/dist/chunk-62PCCHZ2.js.map +1 -0
- package/dist/{chunk-BDFOD7W3.js → chunk-A3LYJUD4.js} +3 -2
- package/dist/chunk-A3LYJUD4.js.map +1 -0
- package/dist/{chunk-MM6JF3Z7.js → chunk-BNX3JULF.js} +3 -2
- package/dist/chunk-BNX3JULF.js.map +1 -0
- package/dist/{chunk-LGLFJL3S.js → chunk-DUVIIWFG.js} +3 -2
- package/dist/chunk-DUVIIWFG.js.map +1 -0
- package/dist/{chunk-HAEVK6IS.js → chunk-EAWGUZHS.js} +3 -2
- package/dist/chunk-EAWGUZHS.js.map +1 -0
- package/dist/{chunk-WWCCB22A.js → chunk-GIZS4BY3.js} +3 -2
- package/dist/chunk-GIZS4BY3.js.map +1 -0
- package/dist/{chunk-BPVMQFO4.js → chunk-K3VQLW3P.js} +3 -2
- package/dist/chunk-K3VQLW3P.js.map +1 -0
- package/dist/{chunk-CR2JRH7T.js → chunk-NE7MIZPR.js} +4 -2
- package/dist/chunk-NE7MIZPR.js.map +1 -0
- package/dist/{chunk-UOBOFCFU.js → chunk-NEXUWPHW.js} +3 -2
- package/dist/chunk-NEXUWPHW.js.map +1 -0
- package/dist/{chunk-FU5WQALW.js → chunk-OTG2S2L4.js} +3 -2
- package/dist/chunk-OTG2S2L4.js.map +1 -0
- package/dist/{chunk-P3UHYMDH.js → chunk-PAT4CS36.js} +3 -2
- package/dist/chunk-PAT4CS36.js.map +1 -0
- package/dist/{chunk-XG2TKFY5.js → chunk-RYQVMR26.js} +3 -2
- package/dist/chunk-RYQVMR26.js.map +1 -0
- package/dist/{chunk-EINAVCV2.js → chunk-XEJPH6UN.js} +3 -2
- package/dist/chunk-XEJPH6UN.js.map +1 -0
- package/dist/companies.cjs +1 -0
- package/dist/companies.cjs.map +1 -1
- package/dist/companies.d.cts +1 -0
- package/dist/companies.d.ts +1 -0
- package/dist/companies.js +1 -1
- package/dist/contacts.cjs +1 -0
- package/dist/contacts.cjs.map +1 -1
- package/dist/contacts.d.cts +1 -0
- package/dist/contacts.d.ts +1 -0
- package/dist/contacts.js +1 -1
- package/dist/customer-groups.cjs +1 -0
- package/dist/customer-groups.cjs.map +1 -1
- package/dist/customer-groups.d.cts +1 -0
- package/dist/customer-groups.d.ts +1 -0
- package/dist/customer-groups.js +1 -1
- package/dist/customer.cjs +1 -0
- package/dist/customer.cjs.map +1 -1
- package/dist/customer.d.cts +1 -0
- package/dist/customer.d.ts +1 -0
- package/dist/customer.js +1 -1
- package/dist/index.cjs +197 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +76 -4
- package/dist/index.d.ts +76 -4
- package/dist/index.js +210 -134
- package/dist/index.js.map +1 -1
- package/dist/locations.cjs +1 -0
- package/dist/locations.cjs.map +1 -1
- package/dist/locations.d.cts +1 -0
- package/dist/locations.d.ts +1 -0
- package/dist/locations.js +1 -1
- package/dist/media.cjs +1 -0
- package/dist/media.cjs.map +1 -1
- package/dist/media.d.cts +1 -0
- package/dist/media.d.ts +1 -0
- package/dist/media.js +1 -1
- package/dist/orders.cjs +2 -0
- package/dist/orders.cjs.map +1 -1
- package/dist/orders.d.cts +2 -0
- package/dist/orders.d.ts +2 -0
- package/dist/orders.js +1 -1
- package/dist/payment.cjs +1 -0
- package/dist/payment.cjs.map +1 -1
- package/dist/payment.d.cts +1 -0
- package/dist/payment.d.ts +1 -0
- package/dist/payment.js +1 -1
- package/dist/price.cjs +1 -0
- package/dist/price.cjs.map +1 -1
- package/dist/price.d.cts +1 -0
- package/dist/price.d.ts +1 -0
- package/dist/price.js +1 -1
- package/dist/product.cjs +1 -0
- package/dist/product.cjs.map +1 -1
- package/dist/product.d.cts +1 -0
- package/dist/product.d.ts +1 -0
- package/dist/product.js +1 -1
- package/dist/segment.cjs +2 -0
- package/dist/segment.cjs.map +1 -1
- package/dist/segment.d.cts +2 -0
- package/dist/segment.d.ts +2 -0
- package/dist/segment.js +1 -1
- package/package.json +2 -1
- package/dist/chunk-BDFOD7W3.js.map +0 -1
- package/dist/chunk-BPVMQFO4.js.map +0 -1
- package/dist/chunk-CR2JRH7T.js.map +0 -1
- package/dist/chunk-EINAVCV2.js.map +0 -1
- package/dist/chunk-FU5WQALW.js.map +0 -1
- package/dist/chunk-HAEVK6IS.js.map +0 -1
- package/dist/chunk-LGLFJL3S.js.map +0 -1
- package/dist/chunk-LGOC5XOI.js.map +0 -1
- package/dist/chunk-MIUVJEGR.js.map +0 -1
- package/dist/chunk-MM6JF3Z7.js.map +0 -1
- package/dist/chunk-P3UHYMDH.js.map +0 -1
- package/dist/chunk-UOBOFCFU.js.map +0 -1
- package/dist/chunk-WW3H7VJ5.js.map +0 -1
- package/dist/chunk-WWCCB22A.js.map +0 -1
- package/dist/chunk-XG2TKFY5.js.map +0 -1
package/dist/product.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/context.ts","../src/services/product.ts"],"names":[],"mappings":"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","file":"product.cjs","sourcesContent":["import type { HttpClient } from \"./http\";\nimport type { TokenProvider, AuthContext } from \"./auth\";\nimport type { Logger } from \"./logger\";\n\n/** Shared dependencies every service facade receives. */\nexport interface ClientContext {\n tenant: string;\n http: HttpClient;\n tokenProvider: TokenProvider;\n logger: Logger;\n}\n\n/**\n * A cursor-paged collection — `pageNumber`/`pageSize` indexing with a\n * `hasNextPage` signal driven by the source page being full. Used by all\n * paginated services and hooks across the SDK.\n */\nexport interface PaginatedItems<T> {\n items: T[];\n pageNumber: number;\n pageSize: number;\n hasNextPage: boolean;\n}\n\n/** Default `AuthContext` applied by a service when the caller passes none. */\nexport type DefaultAuth = AuthContext | undefined;\n\n/**\n * Async-iterates every item across pages of a `PaginatedItems<T>` source.\n * Stops when the source reports `hasNextPage: false`.\n *\n * @param fetchPage - given a 1-based page number, returns the page.\n * @param start - first page to fetch (default `1`).\n */\nexport async function* iterateAll<T>(\n fetchPage: (pageNumber: number) => Promise<PaginatedItems<T>>,\n start = 1,\n): AsyncIterable<T> {\n let p = start;\n for (;;) {\n const page = await fetchPage(p);\n for (const it of page.items) yield it;\n if (!page.hasNextPage) return;\n p += 1;\n }\n}\n\n","import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type {\n BasicProductWithId,\n BundleProductWithId,\n ParentVariantProductWithId,\n ProductMedia,\n} from \"../generated/product\";\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\n\n/** A product as returned by the Product service (all generated fields). */\nexport type Product = BasicProductWithId | BundleProductWithId | ParentVariantProductWithId;\n\n/** A single product media entry (generated; `ProductMedia` is the list type). */\nexport type Media = ProductMedia[number];\n\n/** Catalog reads. Default auth: anonymous; pass customer for personalized pricing. */\nexport class ProductService {\n constructor(private readonly ctx: ClientContext) {}\n\n /** Fetches one product by id. */\n async get(\n productId: string,\n _opts?: Record<string, never>,\n auth: AuthContext = ANON,\n ): Promise<Product> {\n return this.ctx.http.request<Product>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products/${productId}`,\n auth,\n });\n }\n\n /** Fetches one product by its code. */\n async getByCode(code: string, auth: AuthContext = ANON): Promise<Product> {\n const rows = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { q: `code:${code}` },\n auth,\n });\n const first = rows[0];\n if (!first) throw new Error(`No product with code \"${code}\"`);\n return first;\n }\n\n /** One page of products. */\n async list(\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /** Async-iterates every product across pages. */\n listAll(params: { pageSize?: number } = {}, auth: AuthContext = ANON): AsyncIterable<Product> {\n const pageSize = params.pageSize ?? 50;\n return iterateAll<Product>((pageNumber) => this.list({ pageNumber, pageSize }, auth));\n }\n\n /** Searches products by free-text query. */\n async search(\n query: string,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { q: query, pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /**\n * Free-text product search by name. The product `q` is a `field:value` DSL,\n * so a bare term (e.g. \"in time\") 400s with \"No value for key …\". This builds\n * a `name:(~<term>)` regex filter (regex metacharacters escaped) and delegates\n * to {@link search}.\n */\n async searchByName(\n query: string,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const escaped = query.trim().replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return this.search(`name:(~${escaped})`, params, auth);\n }\n\n /**\n * Bulk fetch by id. POSTs `/products/search` with `q=\"id:(id1,id2,…)\"`,\n * chunking when the list is larger than `options.chunkSize` (default\n * 100). An empty list short-circuits with no HTTP call. **Order is not\n * guaranteed** across chunks — re-index by `id` if order matters.\n */\n async searchByIds(\n ids: string[],\n options: { chunkSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n if (ids.length === 0) return [];\n const chunkSize = options.chunkSize ?? 100;\n const chunks: string[][] = [];\n for (let i = 0; i < ids.length; i += chunkSize) {\n chunks.push(ids.slice(i, i + chunkSize));\n }\n const pages = await Promise.all(\n chunks.map((chunk) =>\n this.ctx.http.request<Product[]>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/search`,\n query: { pageSize: chunk.length },\n auth,\n body: { q: `id:(${chunk.join(\",\")})` },\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n }),\n ),\n );\n return pages.flat();\n }\n\n /**\n * Bulk fetch by code. POSTs `/products/search` with `q=\"code:(c1,c2,…)\"`,\n * chunking when the list is larger than `options.chunkSize` (default 100).\n * Duplicate codes are de-duplicated. Codes containing query-delimiter\n * characters (`(`, `)`, `,`, whitespace, `\"`) are dropped with a logged\n * warning, because the Emporix `q` syntax uses them as delimiters and does\n * not support escaping them in a plain IN-list. An empty list — or one with\n * no safe codes — short-circuits with no HTTP call. **Order is not\n * guaranteed** across chunks — re-index by `code` if order matters.\n */\n async searchByCodes(\n codes: string[],\n options: { chunkSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n const unique = [...new Set(codes)];\n const unsafe = /[(),\"\\s]/;\n const safe = unique.filter((c) => !unsafe.test(c));\n const dropped = unique.filter((c) => unsafe.test(c));\n if (dropped.length > 0) {\n this.ctx.logger.warn(\n \"products.searchByCodes: dropped codes containing query-delimiter characters\",\n { dropped },\n );\n }\n if (safe.length === 0) return [];\n const chunkSize = options.chunkSize ?? 100;\n const chunks: string[][] = [];\n for (let i = 0; i < safe.length; i += chunkSize) {\n chunks.push(safe.slice(i, i + chunkSize));\n }\n const pages = await Promise.all(\n chunks.map((chunk) =>\n this.ctx.http.request<Product[]>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/search`,\n query: { pageSize: chunk.length },\n auth,\n body: { q: `code:(${chunk.join(\",\")})` },\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n }),\n ),\n );\n return pages.flat();\n }\n\n /**\n * Streams the VARIANT children of a PARENT_VARIANT product, page by page,\n * via the search query `productType:VARIANT parentVariantId:<id>`. Default\n * pageSize 200. The query syntax (space-separated fields = implicit AND) is\n * encapsulated here so consumers don't build it themselves.\n */\n listVariantChildrenAll(\n parentVariantId: string,\n params: { pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): AsyncIterable<Product> {\n const pageSize = params.pageSize ?? 200;\n const q = `productType:VARIANT parentVariantId:${parentVariantId}`;\n return iterateAll<Product>((pageNumber) => this.search(q, { pageNumber, pageSize }, auth));\n }\n\n /**\n * Resolves ALL VARIANT children of a PARENT_VARIANT product into a flat\n * array (loads every page). Default pageSize 200. Returns `[]` when there are\n * no children — never throws.\n */\n async listVariantChildren(\n parentVariantId: string,\n params: { pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n const out: Product[] = [];\n for await (const child of this.listVariantChildrenAll(parentVariantId, params, auth)) {\n out.push(child);\n }\n return out;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/context.ts","../src/services/product.ts"],"names":[],"mappings":"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","file":"product.cjs","sourcesContent":["import type { HttpClient } from \"./http\";\nimport type { TokenProvider, AuthContext } from \"./auth\";\nimport type { Logger } from \"./logger\";\n\n/** Shared dependencies every service facade receives. */\nexport interface ClientContext {\n tenant: string;\n http: HttpClient;\n tokenProvider: TokenProvider;\n logger: Logger;\n}\n\n/**\n * A cursor-paged collection — `pageNumber`/`pageSize` indexing with a\n * `hasNextPage` signal driven by the source page being full. Used by all\n * paginated services and hooks across the SDK.\n */\nexport interface PaginatedItems<T> {\n items: T[];\n pageNumber: number;\n pageSize: number;\n hasNextPage: boolean;\n}\n\n/** Default `AuthContext` applied by a service when the caller passes none. */\nexport type DefaultAuth = AuthContext | undefined;\n\n/**\n * Async-iterates every item across pages of a `PaginatedItems<T>` source.\n * Stops when the source reports `hasNextPage: false`.\n *\n * @param fetchPage - given a 1-based page number, returns the page.\n * @param start - first page to fetch (default `1`).\n */\nexport async function* iterateAll<T>(\n fetchPage: (pageNumber: number) => Promise<PaginatedItems<T>>,\n start = 1,\n): AsyncIterable<T> {\n let p = start;\n for (;;) {\n const page = await fetchPage(p);\n for (const it of page.items) yield it;\n if (!page.hasNextPage) return;\n p += 1;\n }\n}\n\n","import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type {\n BasicProductWithId,\n BundleProductWithId,\n ParentVariantProductWithId,\n ProductMedia,\n} from \"../generated/product\";\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\n\n/** A product as returned by the Product service (all generated fields). */\nexport type Product = BasicProductWithId | BundleProductWithId | ParentVariantProductWithId;\n\n/** A single product media entry (generated; `ProductMedia` is the list type). */\nexport type Media = ProductMedia[number];\n\n/** Catalog reads. Default auth: anonymous; pass customer for personalized pricing. */\nexport class ProductService {\n static readonly channel = \"product\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n /** Fetches one product by id. */\n async get(\n productId: string,\n _opts?: Record<string, never>,\n auth: AuthContext = ANON,\n ): Promise<Product> {\n return this.ctx.http.request<Product>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products/${productId}`,\n auth,\n });\n }\n\n /** Fetches one product by its code. */\n async getByCode(code: string, auth: AuthContext = ANON): Promise<Product> {\n const rows = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { q: `code:${code}` },\n auth,\n });\n const first = rows[0];\n if (!first) throw new Error(`No product with code \"${code}\"`);\n return first;\n }\n\n /** One page of products. */\n async list(\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /** Async-iterates every product across pages. */\n listAll(params: { pageSize?: number } = {}, auth: AuthContext = ANON): AsyncIterable<Product> {\n const pageSize = params.pageSize ?? 50;\n return iterateAll<Product>((pageNumber) => this.list({ pageNumber, pageSize }, auth));\n }\n\n /** Searches products by free-text query. */\n async search(\n query: string,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { q: query, pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /**\n * Free-text product search by name. The product `q` is a `field:value` DSL,\n * so a bare term (e.g. \"in time\") 400s with \"No value for key …\". This builds\n * a `name:(~<term>)` regex filter (regex metacharacters escaped) and delegates\n * to {@link search}.\n */\n async searchByName(\n query: string,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const escaped = query.trim().replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return this.search(`name:(~${escaped})`, params, auth);\n }\n\n /**\n * Bulk fetch by id. POSTs `/products/search` with `q=\"id:(id1,id2,…)\"`,\n * chunking when the list is larger than `options.chunkSize` (default\n * 100). An empty list short-circuits with no HTTP call. **Order is not\n * guaranteed** across chunks — re-index by `id` if order matters.\n */\n async searchByIds(\n ids: string[],\n options: { chunkSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n if (ids.length === 0) return [];\n const chunkSize = options.chunkSize ?? 100;\n const chunks: string[][] = [];\n for (let i = 0; i < ids.length; i += chunkSize) {\n chunks.push(ids.slice(i, i + chunkSize));\n }\n const pages = await Promise.all(\n chunks.map((chunk) =>\n this.ctx.http.request<Product[]>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/search`,\n query: { pageSize: chunk.length },\n auth,\n body: { q: `id:(${chunk.join(\",\")})` },\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n }),\n ),\n );\n return pages.flat();\n }\n\n /**\n * Bulk fetch by code. POSTs `/products/search` with `q=\"code:(c1,c2,…)\"`,\n * chunking when the list is larger than `options.chunkSize` (default 100).\n * Duplicate codes are de-duplicated. Codes containing query-delimiter\n * characters (`(`, `)`, `,`, whitespace, `\"`) are dropped with a logged\n * warning, because the Emporix `q` syntax uses them as delimiters and does\n * not support escaping them in a plain IN-list. An empty list — or one with\n * no safe codes — short-circuits with no HTTP call. **Order is not\n * guaranteed** across chunks — re-index by `code` if order matters.\n */\n async searchByCodes(\n codes: string[],\n options: { chunkSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n const unique = [...new Set(codes)];\n const unsafe = /[(),\"\\s]/;\n const safe = unique.filter((c) => !unsafe.test(c));\n const dropped = unique.filter((c) => unsafe.test(c));\n if (dropped.length > 0) {\n this.ctx.logger.warn(\n \"products.searchByCodes: dropped codes containing query-delimiter characters\",\n { dropped },\n );\n }\n if (safe.length === 0) return [];\n const chunkSize = options.chunkSize ?? 100;\n const chunks: string[][] = [];\n for (let i = 0; i < safe.length; i += chunkSize) {\n chunks.push(safe.slice(i, i + chunkSize));\n }\n const pages = await Promise.all(\n chunks.map((chunk) =>\n this.ctx.http.request<Product[]>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/search`,\n query: { pageSize: chunk.length },\n auth,\n body: { q: `code:(${chunk.join(\",\")})` },\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n }),\n ),\n );\n return pages.flat();\n }\n\n /**\n * Streams the VARIANT children of a PARENT_VARIANT product, page by page,\n * via the search query `productType:VARIANT parentVariantId:<id>`. Default\n * pageSize 200. The query syntax (space-separated fields = implicit AND) is\n * encapsulated here so consumers don't build it themselves.\n */\n listVariantChildrenAll(\n parentVariantId: string,\n params: { pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): AsyncIterable<Product> {\n const pageSize = params.pageSize ?? 200;\n const q = `productType:VARIANT parentVariantId:${parentVariantId}`;\n return iterateAll<Product>((pageNumber) => this.search(q, { pageNumber, pageSize }, auth));\n }\n\n /**\n * Resolves ALL VARIANT children of a PARENT_VARIANT product into a flat\n * array (loads every page). Default pageSize 200. Returns `[]` when there are\n * no children — never throws.\n */\n async listVariantChildren(\n parentVariantId: string,\n params: { pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n const out: Product[] = [];\n for await (const child of this.listVariantChildrenAll(parentVariantId, params, auth)) {\n out.push(child);\n }\n return out;\n }\n}\n"]}
|
package/dist/product.d.cts
CHANGED
|
@@ -367,6 +367,7 @@ type Media = ProductMedia[number];
|
|
|
367
367
|
/** Catalog reads. Default auth: anonymous; pass customer for personalized pricing. */
|
|
368
368
|
declare class ProductService {
|
|
369
369
|
private readonly ctx;
|
|
370
|
+
static readonly channel: "product";
|
|
370
371
|
constructor(ctx: ClientContext);
|
|
371
372
|
/** Fetches one product by id. */
|
|
372
373
|
get(productId: string, _opts?: Record<string, never>, auth?: AuthContext): Promise<Product>;
|
package/dist/product.d.ts
CHANGED
|
@@ -367,6 +367,7 @@ type Media = ProductMedia[number];
|
|
|
367
367
|
/** Catalog reads. Default auth: anonymous; pass customer for personalized pricing. */
|
|
368
368
|
declare class ProductService {
|
|
369
369
|
private readonly ctx;
|
|
370
|
+
static readonly channel: "product";
|
|
370
371
|
constructor(ctx: ClientContext);
|
|
371
372
|
/** Fetches one product by id. */
|
|
372
373
|
get(productId: string, _opts?: Record<string, never>, auth?: AuthContext): Promise<Product>;
|
package/dist/product.js
CHANGED
package/dist/segment.cjs
CHANGED
package/dist/segment.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/errors.ts","../src/core/require-customer.ts","../src/services/segment.ts"],"names":[],"mappings":"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","file":"segment.cjs","sourcesContent":["/** Keys whose values are stripped from any serialised error body. */\nconst REDACTED_BODY_KEYS = new Set([\n \"access_token\", \"refresh_token\", \"token\", \"customertoken\", \"saastoken\",\n \"secret\", \"client_secret\", \"authorization\", \"password\",\n]);\n\nfunction scrub(body: unknown): unknown {\n if (Array.isArray(body)) return body.map(scrub);\n if (body && typeof body === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(body as Record<string, unknown>)) {\n out[k] = REDACTED_BODY_KEYS.has(k.toLowerCase()) ? \"***redacted***\" : scrub(v);\n }\n return out;\n }\n return body;\n}\n\n/** Base class for every error thrown by the SDK. */\nexport class EmporixError extends Error {\n readonly status: number | undefined;\n readonly body: unknown;\n constructor(message: string, status?: number, body?: unknown) {\n super(message);\n this.name = new.target.name;\n this.status = status;\n this.body = body;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n /** Safe serialisation — token-like body fields are redacted. */\n toJSON(): Record<string, unknown> {\n return { name: this.name, message: this.message, status: this.status, body: scrub(this.body) };\n }\n}\n\n/** 401 — authentication failed or token expired. */\nexport class EmporixAuthError extends EmporixError {}\n/** 403 — authenticated but not permitted. */\nexport class EmporixForbiddenError extends EmporixError {}\n/** 404 — resource not found. */\nexport class EmporixNotFoundError extends EmporixError {}\n/** 400/422 — request validation failed. */\nexport class EmporixValidationError extends EmporixError {}\n/** 5xx — server-side failure. */\nexport class EmporixServerError extends EmporixError {}\n/** Request aborted by the configured connect/read timeout. No HTTP status. */\nexport class EmporixTimeoutError extends EmporixError {}\n/** DNS/TLS/connection-level failure before or during the exchange. No HTTP status. */\nexport class EmporixNetworkError extends EmporixError {}\n\n/**\n * 403 with a `missing scope: <name>` hint in the body's `details` array.\n * Subclasses {@link EmporixForbiddenError} so existing 403 catches still work.\n */\nexport class EmporixInsufficientScopeError extends EmporixForbiddenError {\n readonly requiredScope: string | undefined;\n constructor(message: string, status: number, body: unknown, requiredScope?: string) {\n super(message, status, body);\n this.requiredScope = requiredScope;\n }\n}\n\nconst SCOPE_HINT_RE = /missing scope[: ]+([a-z0-9._-]+)/i;\n\nfunction extractRequiredScope(body: unknown): string | undefined {\n if (body && typeof body === \"object\" && \"details\" in body) {\n const details = (body as { details?: unknown }).details;\n if (Array.isArray(details)) {\n for (const d of details) {\n if (typeof d === \"string\") {\n const m = d.match(SCOPE_HINT_RE);\n if (m) return m[1];\n }\n }\n }\n }\n return undefined;\n}\n\n/** Maps an HTTP status to the matching {@link EmporixError} subclass. */\nexport function errorFromResponse(status: number, message: string, body: unknown): EmporixError {\n if (status === 401) return new EmporixAuthError(message, status, body);\n if (status === 403) {\n const scope = extractRequiredScope(body);\n if (scope) return new EmporixInsufficientScopeError(message, status, body, scope);\n return new EmporixForbiddenError(message, status, body);\n }\n if (status === 404) return new EmporixNotFoundError(message, status, body);\n if (status === 400 || status === 422) return new EmporixValidationError(message, status, body);\n if (status >= 500) return new EmporixServerError(message, status, body);\n return new EmporixError(message, status, body);\n}\n","import type { AuthContext } from \"./auth\";\nimport { EmporixAuthError } from \"./errors\";\n\n/**\n * Enforces a caller-owned customer or raw token. Throws `EmporixAuthError`\n * for any other `AuthContext` kind (or when `auth` is missing). Shared by\n * services whose endpoints require a customer scope (`/me`, payments,\n * customer-segments…).\n */\nexport function requireCustomer(auth: AuthContext | undefined): AuthContext {\n if (auth && (auth.kind === \"customer\" || auth.kind === \"raw\")) return auth;\n throw new EmporixAuthError(\"This operation requires a customer or raw AuthContext\");\n}\n","import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { requireCustomer } from \"../core/require-customer\";\nimport type { ProductService } from \"./product\";\nimport type { CategoryService } from \"./category\";\nimport type {\n SegmentResponse,\n ItemAssignmentResponse,\n CategoryTreeResponse,\n} from \"../generated/customer-segment\";\n\n/** Generated segment types (read shapes — storefront `segment_read_own`). */\nexport type Segment = SegmentResponse;\nexport type SegmentItem = ItemAssignmentResponse;\nexport type SegmentCategoryTree = CategoryTreeResponse;\nexport type SegmentCategoryTreeNode = CategoryTreeResponse[number];\n\n/** Cross-service hydrate dependencies, injected from `EmporixClient`. */\nexport interface SegmentServiceDeps {\n products: ProductService;\n categories: CategoryService;\n}\n\nfunction setIfDefined<V>(\n q: Record<string, string | number | undefined>,\n key: string,\n value: V | undefined,\n): void {\n if (value !== undefined && value !== \"\") {\n q[key] = value as unknown as string | number;\n }\n}\n\n/**\n * Customer-segment reads. Every method requires a customer/raw\n * `AuthContext` — the `segment_read_own` scope is on the customer token.\n * The standard product/category endpoints do **not** auto-filter by\n * segment; the storefront uses these reads to discover what to fetch.\n */\nexport class SegmentService {\n constructor(\n private readonly ctx: ClientContext,\n private readonly deps: SegmentServiceDeps,\n ) {}\n\n private base(): string {\n return `/customer-segment/${this.ctx.tenant}/segments`;\n }\n\n /** Lists segments the caller belongs to (with `segment_read_own`). */\n async list(\n query: { q?: string; pageNumber?: number; pageSize?: number } = {},\n auth?: AuthContext,\n ): Promise<Segment[]> {\n const q: Record<string, string | number | undefined> = {};\n setIfDefined(q, \"q\", query.q);\n setIfDefined(q, \"pageNumber\", query.pageNumber);\n setIfDefined(q, \"pageSize\", query.pageSize);\n return this.ctx.http.request<Segment[]>({\n method: \"GET\",\n path: this.base(),\n auth: requireCustomer(auth),\n ...(Object.keys(q).length ? { query: q } : {}),\n });\n }\n\n /** Fetches a single segment by id. */\n async get(segmentId: string, auth?: AuthContext): Promise<Segment> {\n return this.ctx.http.request<Segment>({\n method: \"GET\",\n path: `${this.base()}/${segmentId}`,\n auth: requireCustomer(auth),\n });\n }\n\n /** Item assignments (PRODUCT + CATEGORY) across all the caller's active segments. */\n async listItems(\n query: {\n q?: string;\n siteCode?: string;\n legalEntityId?: string;\n onlyActive?: boolean;\n pageNumber?: number;\n pageSize?: number;\n } = {},\n auth?: AuthContext,\n ): Promise<SegmentItem[]> {\n const q: Record<string, string | number | undefined> = {};\n setIfDefined(q, \"q\", query.q);\n setIfDefined(q, \"siteCode\", query.siteCode);\n setIfDefined(q, \"legalEntityId\", query.legalEntityId);\n setIfDefined(q, \"pageNumber\", query.pageNumber);\n setIfDefined(q, \"pageSize\", query.pageSize);\n if (query.onlyActive !== undefined) q.onlyActive = String(query.onlyActive);\n return this.ctx.http.request<SegmentItem[]>({\n method: \"GET\",\n path: `${this.base()}/items`,\n auth: requireCustomer(auth),\n ...(Object.keys(q).length ? { query: q } : {}),\n });\n }\n\n /** Item assignments of one specific segment. */\n async listSegmentItems(\n segmentId: string,\n query: {\n q?: string;\n legalEntityId?: string;\n pageNumber?: number;\n pageSize?: number;\n } = {},\n auth?: AuthContext,\n ): Promise<SegmentItem[]> {\n const q: Record<string, string | number | undefined> = {};\n setIfDefined(q, \"q\", query.q);\n setIfDefined(q, \"legalEntityId\", query.legalEntityId);\n setIfDefined(q, \"pageNumber\", query.pageNumber);\n setIfDefined(q, \"pageSize\", query.pageSize);\n return this.ctx.http.request<SegmentItem[]>({\n method: \"GET\",\n path: `${this.base()}/${segmentId}/items`,\n auth: requireCustomer(auth),\n ...(Object.keys(q).length ? { query: q } : {}),\n });\n }\n\n /** Category tree built only from the caller's active segments. */\n async getCategoryTree(\n query: { siteCode?: string; legalEntityId?: string } = {},\n auth?: AuthContext,\n ): Promise<SegmentCategoryTree> {\n const q: Record<string, string | number | undefined> = {};\n setIfDefined(q, \"siteCode\", query.siteCode);\n setIfDefined(q, \"legalEntityId\", query.legalEntityId);\n return this.ctx.http.request<SegmentCategoryTree>({\n method: \"GET\",\n path: `${this.base()}/items/category-trees`,\n auth: requireCustomer(auth),\n ...(Object.keys(q).length ? { query: q } : {}),\n });\n }\n\n private async pickItemIds(\n kind: \"PRODUCT\" | \"CATEGORY\",\n query: Parameters<SegmentService[\"listItems\"]>[0],\n auth: AuthContext | undefined,\n ): Promise<string[]> {\n const rows = await this.listItems(query, auth);\n const ids: string[] = [];\n for (const r of rows) {\n const id = r.item?.id;\n if (r.type === kind && typeof id === \"string\") ids.push(id);\n }\n return ids;\n }\n\n /** Product ids assigned to the caller's active segments. */\n async listMyProductIds(\n query?: Parameters<SegmentService[\"listItems\"]>[0],\n auth?: AuthContext,\n ): Promise<string[]> {\n return this.pickItemIds(\"PRODUCT\", query ?? {}, auth);\n }\n\n /** Category ids assigned to the caller's active segments. */\n async listMyCategoryIds(\n query?: Parameters<SegmentService[\"listItems\"]>[0],\n auth?: AuthContext,\n ): Promise<string[]> {\n return this.pickItemIds(\"CATEGORY\", query ?? {}, auth);\n }\n\n /**\n * Hydrates `listMyProductIds` via `ProductService.get` in parallel.\n * Resolves in the same order as the id list. Any single failure rejects\n * the whole batch (`Promise.all`); use the id-list method + your own\n * tolerance strategy if partial success matters.\n */\n async listMyProducts(\n query?: Parameters<SegmentService[\"listItems\"]>[0],\n auth?: AuthContext,\n ): Promise<PaginatedItems<Awaited<ReturnType<ProductService[\"get\"]>>>> {\n const pageNumber = query?.pageNumber ?? 1;\n const pageSize = query?.pageSize ?? 20;\n const sourceItems = await this.listItems(\n { ...(query ?? {}), pageNumber, pageSize },\n auth,\n );\n const ids: string[] = [];\n for (const r of sourceItems) {\n if (r.type === \"PRODUCT\" && typeof r.item?.id === \"string\") ids.push(r.item.id);\n }\n const items = await this.deps.products.searchByIds(ids, undefined, auth);\n return { items, pageNumber, pageSize, hasNextPage: sourceItems.length === pageSize };\n }\n\n /**\n * Hydrates a page of the caller's segment CATEGORY assignments into\n * real categories via one bulk `categories.searchByIds` call. Same\n * `hasNextPage` semantic as `listMyProducts`.\n */\n async listMyCategories(\n query?: Parameters<SegmentService[\"listItems\"]>[0],\n auth?: AuthContext,\n ): Promise<PaginatedItems<Awaited<ReturnType<CategoryService[\"get\"]>>>> {\n const pageNumber = query?.pageNumber ?? 1;\n const pageSize = query?.pageSize ?? 20;\n const sourceItems = await this.listItems(\n { ...(query ?? {}), pageNumber, pageSize },\n auth,\n );\n const ids: string[] = [];\n for (const r of sourceItems) {\n if (r.type === \"CATEGORY\" && typeof r.item?.id === \"string\") ids.push(r.item.id);\n }\n const items = await this.deps.categories.searchByIds(ids, undefined, auth);\n return { items, pageNumber, pageSize, hasNextPage: sourceItems.length === pageSize };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/errors.ts","../src/core/require-customer.ts","../src/services/segment.ts"],"names":[],"mappings":";;;AACA,IAAM,kBAAA,uBAAyB,GAAA,CAAI;AAAA,EACjC,cAAA;AAAA,EAAgB,eAAA;AAAA,EAAiB,OAAA;AAAA,EAAS,eAAA;AAAA,EAAiB,WAAA;AAAA,EAC3D,QAAA;AAAA,EAAU,eAAA;AAAA,EAAiB,eAAA;AAAA,EAAiB;AAC9C,CAAC,CAAA;AAED,SAAS,MAAM,IAAA,EAAwB;AACrC,EAAA,IAAI,MAAM,OAAA,CAAQ,IAAI,GAAG,OAAO,IAAA,CAAK,IAAI,KAAK,CAAA;AAC9C,EAAA,IAAI,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACpC,IAAA,MAAM,MAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,IAA+B,CAAA,EAAG;AACpE,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,kBAAA,CAAmB,GAAA,CAAI,CAAA,CAAE,aAAa,CAAA,GAAI,gBAAA,GAAmB,KAAA,CAAM,CAAC,CAAA;AAAA,IAC/E;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAA;AACT;AAGO,IAAM,YAAA,GAAN,cAA2B,KAAA,CAAM;AAAA,EAC7B,MAAA;AAAA,EACA,IAAA;AAAA,EACT,WAAA,CAAY,OAAA,EAAiB,MAAA,EAAiB,IAAA,EAAgB;AAC5D,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,OAAO,GAAA,CAAA,MAAA,CAAW,IAAA;AACvB,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,MAAA,CAAO,cAAA,CAAe,IAAA,EAAM,GAAA,CAAA,MAAA,CAAW,SAAS,CAAA;AAAA,EAClD;AAAA;AAAA,EAEA,MAAA,GAAkC;AAChC,IAAA,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,SAAS,IAAA,CAAK,OAAA,EAAS,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,EAAE;AAAA,EAC/F;AACF,CAAA;AAGO,IAAM,gBAAA,GAAN,cAA+B,YAAA,CAAa;AAAC,CAAA;;;AC3B7C,SAAS,gBAAgB,IAAA,EAA4C;AAC1E,EAAA,IAAI,SAAS,IAAA,CAAK,IAAA,KAAS,cAAc,IAAA,CAAK,IAAA,KAAS,QAAQ,OAAO,IAAA;AACtE,EAAA,MAAM,IAAI,iBAAiB,uDAAuD,CAAA;AACpF;;;ACWA,SAAS,YAAA,CACP,CAAA,EACA,GAAA,EACA,KAAA,EACM;AACN,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,EAAA,EAAI;AACvC,IAAA,CAAA,CAAE,GAAG,CAAA,GAAI,KAAA;AAAA,EACX;AACF;AAQO,IAAM,iBAAN,MAAqB;AAAA,EAG1B,WAAA,CACmB,KACA,IAAA,EACjB;AAFiB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AACA,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AAAA,EAChB;AAAA,EAFgB,GAAA;AAAA,EACA,IAAA;AAAA,EAJnB,OAAgB,OAAA,GAAU,SAAA;AAAA,EAC1B,OAAgB,IAAA,GAAO,CAAC,UAAA,EAAY,YAAY,CAAA;AAAA,EAMxC,IAAA,GAAe;AACrB,IAAA,OAAO,CAAA,kBAAA,EAAqB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,SAAA,CAAA;AAAA,EAC7C;AAAA;AAAA,EAGA,MAAM,IAAA,CACJ,KAAA,GAAgE,IAChE,IAAA,EACoB;AACpB,IAAA,MAAM,IAAiD,EAAC;AACxD,IAAA,YAAA,CAAa,CAAA,EAAG,GAAA,EAAK,KAAA,CAAM,CAAC,CAAA;AAC5B,IAAA,YAAA,CAAa,CAAA,EAAG,YAAA,EAAc,KAAA,CAAM,UAAU,CAAA;AAC9C,IAAA,YAAA,CAAa,CAAA,EAAG,UAAA,EAAY,KAAA,CAAM,QAAQ,CAAA;AAC1C,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAmB;AAAA,MACtC,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,IAAA,EAAM,gBAAgB,IAAI,CAAA;AAAA,MAC1B,GAAI,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,CAAE,SAAS,EAAE,KAAA,EAAO,CAAA,EAAE,GAAI;AAAC,KAC7C,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,GAAA,CAAI,SAAA,EAAmB,IAAA,EAAsC;AACjE,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAiB;AAAA,MACpC,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,SAAS,CAAA,CAAA;AAAA,MACjC,IAAA,EAAM,gBAAgB,IAAI;AAAA,KAC3B,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,SAAA,CACJ,KAAA,GAOI,IACJ,IAAA,EACwB;AACxB,IAAA,MAAM,IAAiD,EAAC;AACxD,IAAA,YAAA,CAAa,CAAA,EAAG,GAAA,EAAK,KAAA,CAAM,CAAC,CAAA;AAC5B,IAAA,YAAA,CAAa,CAAA,EAAG,UAAA,EAAY,KAAA,CAAM,QAAQ,CAAA;AAC1C,IAAA,YAAA,CAAa,CAAA,EAAG,eAAA,EAAiB,KAAA,CAAM,aAAa,CAAA;AACpD,IAAA,YAAA,CAAa,CAAA,EAAG,YAAA,EAAc,KAAA,CAAM,UAAU,CAAA;AAC9C,IAAA,YAAA,CAAa,CAAA,EAAG,UAAA,EAAY,KAAA,CAAM,QAAQ,CAAA;AAC1C,IAAA,IAAI,MAAM,UAAA,KAAe,MAAA,IAAa,UAAA,GAAa,MAAA,CAAO,MAAM,UAAU,CAAA;AAC1E,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAuB;AAAA,MAC1C,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,CAAA,MAAA,CAAA;AAAA,MACpB,IAAA,EAAM,gBAAgB,IAAI,CAAA;AAAA,MAC1B,GAAI,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,CAAE,SAAS,EAAE,KAAA,EAAO,CAAA,EAAE,GAAI;AAAC,KAC7C,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,gBAAA,CACJ,SAAA,EACA,KAAA,GAKI,IACJ,IAAA,EACwB;AACxB,IAAA,MAAM,IAAiD,EAAC;AACxD,IAAA,YAAA,CAAa,CAAA,EAAG,GAAA,EAAK,KAAA,CAAM,CAAC,CAAA;AAC5B,IAAA,YAAA,CAAa,CAAA,EAAG,eAAA,EAAiB,KAAA,CAAM,aAAa,CAAA;AACpD,IAAA,YAAA,CAAa,CAAA,EAAG,YAAA,EAAc,KAAA,CAAM,UAAU,CAAA;AAC9C,IAAA,YAAA,CAAa,CAAA,EAAG,UAAA,EAAY,KAAA,CAAM,QAAQ,CAAA;AAC1C,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAuB;AAAA,MAC1C,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,SAAS,CAAA,MAAA,CAAA;AAAA,MACjC,IAAA,EAAM,gBAAgB,IAAI,CAAA;AAAA,MAC1B,GAAI,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,CAAE,SAAS,EAAE,KAAA,EAAO,CAAA,EAAE,GAAI;AAAC,KAC7C,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,eAAA,CACJ,KAAA,GAAuD,IACvD,IAAA,EAC8B;AAC9B,IAAA,MAAM,IAAiD,EAAC;AACxD,IAAA,YAAA,CAAa,CAAA,EAAG,UAAA,EAAY,KAAA,CAAM,QAAQ,CAAA;AAC1C,IAAA,YAAA,CAAa,CAAA,EAAG,eAAA,EAAiB,KAAA,CAAM,aAAa,CAAA;AACpD,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA6B;AAAA,MAChD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,CAAA,qBAAA,CAAA;AAAA,MACpB,IAAA,EAAM,gBAAgB,IAAI,CAAA;AAAA,MAC1B,GAAI,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,CAAE,SAAS,EAAE,KAAA,EAAO,CAAA,EAAE,GAAI;AAAC,KAC7C,CAAA;AAAA,EACH;AAAA,EAEA,MAAc,WAAA,CACZ,IAAA,EACA,KAAA,EACA,IAAA,EACmB;AACnB,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,SAAA,CAAU,OAAO,IAAI,CAAA;AAC7C,IAAA,MAAM,MAAgB,EAAC;AACvB,IAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,MAAA,MAAM,EAAA,GAAK,EAAE,IAAA,EAAM,EAAA;AACnB,MAAA,IAAI,CAAA,CAAE,SAAS,IAAA,IAAQ,OAAO,OAAO,QAAA,EAAU,GAAA,CAAI,KAAK,EAAE,CAAA;AAAA,IAC5D;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,gBAAA,CACJ,KAAA,EACA,IAAA,EACmB;AACnB,IAAA,OAAO,KAAK,WAAA,CAAY,SAAA,EAAW,KAAA,IAAS,IAAI,IAAI,CAAA;AAAA,EACtD;AAAA;AAAA,EAGA,MAAM,iBAAA,CACJ,KAAA,EACA,IAAA,EACmB;AACnB,IAAA,OAAO,KAAK,WAAA,CAAY,UAAA,EAAY,KAAA,IAAS,IAAI,IAAI,CAAA;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAAA,CACJ,KAAA,EACA,IAAA,EACqE;AACrE,IAAA,MAAM,UAAA,GAAa,OAAO,UAAA,IAAc,CAAA;AACxC,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,EAAA;AACpC,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,SAAA;AAAA,MAC7B,EAAE,GAAI,KAAA,IAAS,EAAC,EAAI,YAAY,QAAA,EAAS;AAAA,MACzC;AAAA,KACF;AACA,IAAA,MAAM,MAAgB,EAAC;AACvB,IAAA,KAAA,MAAW,KAAK,WAAA,EAAa;AAC3B,MAAA,IAAI,CAAA,CAAE,IAAA,KAAS,SAAA,IAAa,OAAO,CAAA,CAAE,IAAA,EAAM,EAAA,KAAO,QAAA,EAAU,GAAA,CAAI,IAAA,CAAK,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA;AAAA,IAChF;AACA,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,IAAA,CAAK,SAAS,WAAA,CAAY,GAAA,EAAK,QAAW,IAAI,CAAA;AACvE,IAAA,OAAO,EAAE,KAAA,EAAO,UAAA,EAAY,UAAU,WAAA,EAAa,WAAA,CAAY,WAAW,QAAA,EAAS;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,gBAAA,CACJ,KAAA,EACA,IAAA,EACsE;AACtE,IAAA,MAAM,UAAA,GAAa,OAAO,UAAA,IAAc,CAAA;AACxC,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,EAAA;AACpC,IAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,SAAA;AAAA,MAC7B,EAAE,GAAI,KAAA,IAAS,EAAC,EAAI,YAAY,QAAA,EAAS;AAAA,MACzC;AAAA,KACF;AACA,IAAA,MAAM,MAAgB,EAAC;AACvB,IAAA,KAAA,MAAW,KAAK,WAAA,EAAa;AAC3B,MAAA,IAAI,CAAA,CAAE,IAAA,KAAS,UAAA,IAAc,OAAO,CAAA,CAAE,IAAA,EAAM,EAAA,KAAO,QAAA,EAAU,GAAA,CAAI,IAAA,CAAK,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA;AAAA,IACjF;AACA,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,IAAA,CAAK,WAAW,WAAA,CAAY,GAAA,EAAK,QAAW,IAAI,CAAA;AACzE,IAAA,OAAO,EAAE,KAAA,EAAO,UAAA,EAAY,UAAU,WAAA,EAAa,WAAA,CAAY,WAAW,QAAA,EAAS;AAAA,EACrF;AACF","file":"segment.cjs","sourcesContent":["/** Keys whose values are stripped from any serialised error body. */\nconst REDACTED_BODY_KEYS = new Set([\n \"access_token\", \"refresh_token\", \"token\", \"customertoken\", \"saastoken\",\n \"secret\", \"client_secret\", \"authorization\", \"password\",\n]);\n\nfunction scrub(body: unknown): unknown {\n if (Array.isArray(body)) return body.map(scrub);\n if (body && typeof body === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(body as Record<string, unknown>)) {\n out[k] = REDACTED_BODY_KEYS.has(k.toLowerCase()) ? \"***redacted***\" : scrub(v);\n }\n return out;\n }\n return body;\n}\n\n/** Base class for every error thrown by the SDK. */\nexport class EmporixError extends Error {\n readonly status: number | undefined;\n readonly body: unknown;\n constructor(message: string, status?: number, body?: unknown) {\n super(message);\n this.name = new.target.name;\n this.status = status;\n this.body = body;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n /** Safe serialisation — token-like body fields are redacted. */\n toJSON(): Record<string, unknown> {\n return { name: this.name, message: this.message, status: this.status, body: scrub(this.body) };\n }\n}\n\n/** 401 — authentication failed or token expired. */\nexport class EmporixAuthError extends EmporixError {}\n/** 403 — authenticated but not permitted. */\nexport class EmporixForbiddenError extends EmporixError {}\n/** 404 — resource not found. */\nexport class EmporixNotFoundError extends EmporixError {}\n/** 400/422 — request validation failed. */\nexport class EmporixValidationError extends EmporixError {}\n/** 5xx — server-side failure. */\nexport class EmporixServerError extends EmporixError {}\n/** Request aborted by the configured connect/read timeout. No HTTP status. */\nexport class EmporixTimeoutError extends EmporixError {}\n/** DNS/TLS/connection-level failure before or during the exchange. No HTTP status. */\nexport class EmporixNetworkError extends EmporixError {}\n\n/**\n * 403 with a `missing scope: <name>` hint in the body's `details` array.\n * Subclasses {@link EmporixForbiddenError} so existing 403 catches still work.\n */\nexport class EmporixInsufficientScopeError extends EmporixForbiddenError {\n readonly requiredScope: string | undefined;\n constructor(message: string, status: number, body: unknown, requiredScope?: string) {\n super(message, status, body);\n this.requiredScope = requiredScope;\n }\n}\n\nconst SCOPE_HINT_RE = /missing scope[: ]+([a-z0-9._-]+)/i;\n\nfunction extractRequiredScope(body: unknown): string | undefined {\n if (body && typeof body === \"object\" && \"details\" in body) {\n const details = (body as { details?: unknown }).details;\n if (Array.isArray(details)) {\n for (const d of details) {\n if (typeof d === \"string\") {\n const m = d.match(SCOPE_HINT_RE);\n if (m) return m[1];\n }\n }\n }\n }\n return undefined;\n}\n\n/** Maps an HTTP status to the matching {@link EmporixError} subclass. */\nexport function errorFromResponse(status: number, message: string, body: unknown): EmporixError {\n if (status === 401) return new EmporixAuthError(message, status, body);\n if (status === 403) {\n const scope = extractRequiredScope(body);\n if (scope) return new EmporixInsufficientScopeError(message, status, body, scope);\n return new EmporixForbiddenError(message, status, body);\n }\n if (status === 404) return new EmporixNotFoundError(message, status, body);\n if (status === 400 || status === 422) return new EmporixValidationError(message, status, body);\n if (status >= 500) return new EmporixServerError(message, status, body);\n return new EmporixError(message, status, body);\n}\n","import type { AuthContext } from \"./auth\";\nimport { EmporixAuthError } from \"./errors\";\n\n/**\n * Enforces a caller-owned customer or raw token. Throws `EmporixAuthError`\n * for any other `AuthContext` kind (or when `auth` is missing). Shared by\n * services whose endpoints require a customer scope (`/me`, payments,\n * customer-segments…).\n */\nexport function requireCustomer(auth: AuthContext | undefined): AuthContext {\n if (auth && (auth.kind === \"customer\" || auth.kind === \"raw\")) return auth;\n throw new EmporixAuthError(\"This operation requires a customer or raw AuthContext\");\n}\n","import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { requireCustomer } from \"../core/require-customer\";\nimport type { ProductService } from \"./product\";\nimport type { CategoryService } from \"./category\";\nimport type {\n SegmentResponse,\n ItemAssignmentResponse,\n CategoryTreeResponse,\n} from \"../generated/customer-segment\";\n\n/** Generated segment types (read shapes — storefront `segment_read_own`). */\nexport type Segment = SegmentResponse;\nexport type SegmentItem = ItemAssignmentResponse;\nexport type SegmentCategoryTree = CategoryTreeResponse;\nexport type SegmentCategoryTreeNode = CategoryTreeResponse[number];\n\n/** Cross-service hydrate dependencies, injected from `EmporixClient`. */\nexport interface SegmentServiceDeps {\n products: ProductService;\n categories: CategoryService;\n}\n\nfunction setIfDefined<V>(\n q: Record<string, string | number | undefined>,\n key: string,\n value: V | undefined,\n): void {\n if (value !== undefined && value !== \"\") {\n q[key] = value as unknown as string | number;\n }\n}\n\n/**\n * Customer-segment reads. Every method requires a customer/raw\n * `AuthContext` — the `segment_read_own` scope is on the customer token.\n * The standard product/category endpoints do **not** auto-filter by\n * segment; the storefront uses these reads to discover what to fetch.\n */\nexport class SegmentService {\n static readonly channel = \"segment\" as const;\n static readonly deps = [\"products\", \"categories\"] as const;\n constructor(\n private readonly ctx: ClientContext,\n private readonly deps: SegmentServiceDeps,\n ) {}\n\n private base(): string {\n return `/customer-segment/${this.ctx.tenant}/segments`;\n }\n\n /** Lists segments the caller belongs to (with `segment_read_own`). */\n async list(\n query: { q?: string; pageNumber?: number; pageSize?: number } = {},\n auth?: AuthContext,\n ): Promise<Segment[]> {\n const q: Record<string, string | number | undefined> = {};\n setIfDefined(q, \"q\", query.q);\n setIfDefined(q, \"pageNumber\", query.pageNumber);\n setIfDefined(q, \"pageSize\", query.pageSize);\n return this.ctx.http.request<Segment[]>({\n method: \"GET\",\n path: this.base(),\n auth: requireCustomer(auth),\n ...(Object.keys(q).length ? { query: q } : {}),\n });\n }\n\n /** Fetches a single segment by id. */\n async get(segmentId: string, auth?: AuthContext): Promise<Segment> {\n return this.ctx.http.request<Segment>({\n method: \"GET\",\n path: `${this.base()}/${segmentId}`,\n auth: requireCustomer(auth),\n });\n }\n\n /** Item assignments (PRODUCT + CATEGORY) across all the caller's active segments. */\n async listItems(\n query: {\n q?: string;\n siteCode?: string;\n legalEntityId?: string;\n onlyActive?: boolean;\n pageNumber?: number;\n pageSize?: number;\n } = {},\n auth?: AuthContext,\n ): Promise<SegmentItem[]> {\n const q: Record<string, string | number | undefined> = {};\n setIfDefined(q, \"q\", query.q);\n setIfDefined(q, \"siteCode\", query.siteCode);\n setIfDefined(q, \"legalEntityId\", query.legalEntityId);\n setIfDefined(q, \"pageNumber\", query.pageNumber);\n setIfDefined(q, \"pageSize\", query.pageSize);\n if (query.onlyActive !== undefined) q.onlyActive = String(query.onlyActive);\n return this.ctx.http.request<SegmentItem[]>({\n method: \"GET\",\n path: `${this.base()}/items`,\n auth: requireCustomer(auth),\n ...(Object.keys(q).length ? { query: q } : {}),\n });\n }\n\n /** Item assignments of one specific segment. */\n async listSegmentItems(\n segmentId: string,\n query: {\n q?: string;\n legalEntityId?: string;\n pageNumber?: number;\n pageSize?: number;\n } = {},\n auth?: AuthContext,\n ): Promise<SegmentItem[]> {\n const q: Record<string, string | number | undefined> = {};\n setIfDefined(q, \"q\", query.q);\n setIfDefined(q, \"legalEntityId\", query.legalEntityId);\n setIfDefined(q, \"pageNumber\", query.pageNumber);\n setIfDefined(q, \"pageSize\", query.pageSize);\n return this.ctx.http.request<SegmentItem[]>({\n method: \"GET\",\n path: `${this.base()}/${segmentId}/items`,\n auth: requireCustomer(auth),\n ...(Object.keys(q).length ? { query: q } : {}),\n });\n }\n\n /** Category tree built only from the caller's active segments. */\n async getCategoryTree(\n query: { siteCode?: string; legalEntityId?: string } = {},\n auth?: AuthContext,\n ): Promise<SegmentCategoryTree> {\n const q: Record<string, string | number | undefined> = {};\n setIfDefined(q, \"siteCode\", query.siteCode);\n setIfDefined(q, \"legalEntityId\", query.legalEntityId);\n return this.ctx.http.request<SegmentCategoryTree>({\n method: \"GET\",\n path: `${this.base()}/items/category-trees`,\n auth: requireCustomer(auth),\n ...(Object.keys(q).length ? { query: q } : {}),\n });\n }\n\n private async pickItemIds(\n kind: \"PRODUCT\" | \"CATEGORY\",\n query: Parameters<SegmentService[\"listItems\"]>[0],\n auth: AuthContext | undefined,\n ): Promise<string[]> {\n const rows = await this.listItems(query, auth);\n const ids: string[] = [];\n for (const r of rows) {\n const id = r.item?.id;\n if (r.type === kind && typeof id === \"string\") ids.push(id);\n }\n return ids;\n }\n\n /** Product ids assigned to the caller's active segments. */\n async listMyProductIds(\n query?: Parameters<SegmentService[\"listItems\"]>[0],\n auth?: AuthContext,\n ): Promise<string[]> {\n return this.pickItemIds(\"PRODUCT\", query ?? {}, auth);\n }\n\n /** Category ids assigned to the caller's active segments. */\n async listMyCategoryIds(\n query?: Parameters<SegmentService[\"listItems\"]>[0],\n auth?: AuthContext,\n ): Promise<string[]> {\n return this.pickItemIds(\"CATEGORY\", query ?? {}, auth);\n }\n\n /**\n * Hydrates `listMyProductIds` via `ProductService.get` in parallel.\n * Resolves in the same order as the id list. Any single failure rejects\n * the whole batch (`Promise.all`); use the id-list method + your own\n * tolerance strategy if partial success matters.\n */\n async listMyProducts(\n query?: Parameters<SegmentService[\"listItems\"]>[0],\n auth?: AuthContext,\n ): Promise<PaginatedItems<Awaited<ReturnType<ProductService[\"get\"]>>>> {\n const pageNumber = query?.pageNumber ?? 1;\n const pageSize = query?.pageSize ?? 20;\n const sourceItems = await this.listItems(\n { ...(query ?? {}), pageNumber, pageSize },\n auth,\n );\n const ids: string[] = [];\n for (const r of sourceItems) {\n if (r.type === \"PRODUCT\" && typeof r.item?.id === \"string\") ids.push(r.item.id);\n }\n const items = await this.deps.products.searchByIds(ids, undefined, auth);\n return { items, pageNumber, pageSize, hasNextPage: sourceItems.length === pageSize };\n }\n\n /**\n * Hydrates a page of the caller's segment CATEGORY assignments into\n * real categories via one bulk `categories.searchByIds` call. Same\n * `hasNextPage` semantic as `listMyProducts`.\n */\n async listMyCategories(\n query?: Parameters<SegmentService[\"listItems\"]>[0],\n auth?: AuthContext,\n ): Promise<PaginatedItems<Awaited<ReturnType<CategoryService[\"get\"]>>>> {\n const pageNumber = query?.pageNumber ?? 1;\n const pageSize = query?.pageSize ?? 20;\n const sourceItems = await this.listItems(\n { ...(query ?? {}), pageNumber, pageSize },\n auth,\n );\n const ids: string[] = [];\n for (const r of sourceItems) {\n if (r.type === \"CATEGORY\" && typeof r.item?.id === \"string\") ids.push(r.item.id);\n }\n const items = await this.deps.categories.searchByIds(ids, undefined, auth);\n return { items, pageNumber, pageSize, hasNextPage: sourceItems.length === pageSize };\n }\n}\n"]}
|
package/dist/segment.d.cts
CHANGED
|
@@ -187,6 +187,8 @@ interface SegmentServiceDeps {
|
|
|
187
187
|
declare class SegmentService {
|
|
188
188
|
private readonly ctx;
|
|
189
189
|
private readonly deps;
|
|
190
|
+
static readonly channel: "segment";
|
|
191
|
+
static readonly deps: readonly ["products", "categories"];
|
|
190
192
|
constructor(ctx: ClientContext, deps: SegmentServiceDeps);
|
|
191
193
|
private base;
|
|
192
194
|
/** Lists segments the caller belongs to (with `segment_read_own`). */
|
package/dist/segment.d.ts
CHANGED
|
@@ -187,6 +187,8 @@ interface SegmentServiceDeps {
|
|
|
187
187
|
declare class SegmentService {
|
|
188
188
|
private readonly ctx;
|
|
189
189
|
private readonly deps;
|
|
190
|
+
static readonly channel: "segment";
|
|
191
|
+
static readonly deps: readonly ["products", "categories"];
|
|
190
192
|
constructor(ctx: ClientContext, deps: SegmentServiceDeps);
|
|
191
193
|
private base;
|
|
192
194
|
/** Lists segments the caller belongs to (with `segment_read_own`). */
|
package/dist/segment.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viu/emporix-sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.0",
|
|
4
4
|
"description": "TypeScript SDK for the Emporix Commerce Engine",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -140,6 +140,7 @@
|
|
|
140
140
|
"test": "vitest run --coverage",
|
|
141
141
|
"lint": "eslint src",
|
|
142
142
|
"typecheck": "tsc --noEmit",
|
|
143
|
+
"check:treeshake": "node scripts/check-treeshake.mjs",
|
|
143
144
|
"fetch:specs": "tsx scripts/fetch-specs.ts",
|
|
144
145
|
"generate": "tsx scripts/generate.ts"
|
|
145
146
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/price.ts"],"names":[],"mappings":"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","file":"chunk-BDFOD7W3.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { EmporixAuthError } from \"../core/errors\";\nimport type { Match, MatchByContext, MatchResponse } from \"../generated/price\";\n\n/** Session-context match request body (generated). */\nexport type PriceMatchByContextInput = MatchByContext;\n\n/** Explicit-context match request body (generated). */\nexport type PriceMatchInput = Match;\n\n/** Item (product or price) a price was matched for. */\nexport interface PriceMatchItemRef {\n itemType?: string;\n id?: string;\n /** Localized (or plain) product name — present on the live API, absent from the OpenAPI doc. */\n name?: Record<string, string> | string;\n}\n\n/**\n * A resolved price. Superset of the generated match-response schema: the\n * deployed API returns the matched item under `itemId` (with a localized\n * `name`), while the OpenAPI doc/codegen call it `itemRef`.\n */\nexport type PriceMatch = Omit<MatchResponse, \"itemRef\"> & {\n /** Item the price was matched for, as returned by the API. */\n itemId?: PriceMatchItemRef;\n /**\n * @deprecated The OpenAPI doc names this `itemRef`, but the deployed API\n * returns `itemId`. Mirrored from `itemId` for back-compat — prefer `itemId`.\n */\n itemRef?: PriceMatchItemRef;\n};\n\n/**\n * Normalizes a raw match row: the deployed API returns `itemId`, while the\n * codegen type calls it `itemRef`. Expose `itemId` canonically and mirror it\n * to the deprecated `itemRef` so existing consumers keep working.\n */\nfunction normalizeMatch(raw: MatchResponse): PriceMatch {\n const itemId = (raw as MatchResponse & { itemId?: PriceMatchItemRef }).itemId ?? raw.itemRef;\n const base = raw as PriceMatch;\n if (!itemId) return base;\n // Mirror only id/type into the deprecated itemRef (drop name); build without\n // explicit `undefined` for exactOptionalPropertyTypes.\n const itemRef: PriceMatchItemRef = {\n ...(itemId.itemType !== undefined ? { itemType: itemId.itemType } : {}),\n ...(itemId.id !== undefined ? { id: itemId.id } : {}),\n };\n return { ...base, itemId, itemRef };\n}\n\n/** Options for {@link PriceService.matchByContextChunked}. */\nexport interface MatchByContextChunkedOptions {\n /** Items per request. Default 50. Must be >= 1. */\n chunkSize?: number;\n /** Maximum number of requests in flight at once. Default 4. Must be >= 1. */\n concurrency?: number;\n /** Invoked once per failed chunk (default mode only — not when throwing). */\n onChunkError?: (err: unknown, chunkIndex: number) => void;\n /** When true, the first failing chunk rejects the whole call. Default false. */\n throwOnAnyChunkError?: boolean;\n}\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\nconst SERVICE: AuthContext = { kind: \"service\" };\n\nfunction requireContextAuth(auth: AuthContext | undefined): AuthContext {\n const a = auth ?? ANON;\n if (a.kind === \"anonymous\" || a.kind === \"customer\" || a.kind === \"raw\") return a;\n throw new EmporixAuthError(\n \"match-prices-by-context requires an anonymous, customer, or raw AuthContext\",\n );\n}\n\n/**\n * Price matching. The Cart service does not resolve prices — call this\n * explicitly before rendering money and again right before placing an order.\n * The SDK is stateless: it never caches or revalidates prices.\n */\nexport class PriceService {\n constructor(private readonly ctx: ClientContext) {}\n\n /**\n * Resolves prices using the session context bound to the bearer token\n * (currency/site/country were set at anonymous-login time). Default auth:\n * anonymous; pass a customer/raw context for personalized pricing.\n */\n async matchByContext(\n input: PriceMatchByContextInput,\n auth?: AuthContext,\n ): Promise<PriceMatch[]> {\n const rows = await this.ctx.http.request<MatchResponse[]>({\n method: \"POST\",\n path: `/price/${this.ctx.tenant}/match-prices-by-context`,\n auth: requireContextAuth(auth),\n body: input,\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n });\n return rows.map(normalizeMatch);\n }\n\n /**\n * Resolves prices from an explicit context. Default auth: service\n * (requires `price.price_read` / `price.price_manage`).\n */\n async match(input: PriceMatchInput, auth: AuthContext = SERVICE): Promise<PriceMatch[]> {\n const rows = await this.ctx.http.request<MatchResponse[]>({\n method: \"POST\",\n path: `/price/${this.ctx.tenant}/match-prices`,\n auth,\n body: input,\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n });\n return rows.map(normalizeMatch);\n }\n\n /**\n * Chunked variant of {@link matchByContext} for large `items` arrays. The\n * Emporix backend handles only a limited number of items per request\n * (production limit ~50), so this splits `input.items` into chunks and runs\n * `matchByContext` with bounded concurrency.\n *\n * By default a failing chunk is skipped (its items are absent from the\n * result) and `opts.onChunkError` is called once for it; pass\n * `throwOnAnyChunkError: true` to reject on the first failure instead.\n *\n * **Result order is not guaranteed** — match entries back to your items by\n * `priceId` / `itemId.id`.\n */\n async matchByContextChunked(\n input: PriceMatchByContextInput,\n opts: MatchByContextChunkedOptions = {},\n auth?: AuthContext,\n ): Promise<PriceMatch[]> {\n const chunkSize = opts.chunkSize ?? 50;\n const concurrency = opts.concurrency ?? 4;\n if (chunkSize < 1) throw new Error(\"chunkSize must be >= 1\");\n if (concurrency < 1) throw new Error(\"concurrency must be >= 1\");\n\n const items = input.items ?? [];\n if (items.length === 0) return [];\n\n const chunks: PriceMatchByContextInput[] = [];\n for (let i = 0; i < items.length; i += chunkSize) {\n chunks.push({ ...input, items: items.slice(i, i + chunkSize) });\n }\n\n const results: PriceMatch[][] = new Array(chunks.length);\n let cursor = 0;\n\n const worker = async (): Promise<void> => {\n for (;;) {\n const idx = cursor++;\n const chunk = chunks[idx];\n if (chunk === undefined) return; // past the end\n try {\n results[idx] = await this.matchByContext(chunk, auth);\n } catch (err) {\n if (opts.throwOnAnyChunkError) throw err;\n results[idx] = [];\n opts.onChunkError?.(err, idx);\n }\n }\n };\n\n const workerCount = Math.min(concurrency, chunks.length);\n await Promise.all(Array.from({ length: workerCount }, () => worker()));\n\n return results.flat();\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/availability.ts"],"names":[],"mappings":";;;AAuBA,IAAM,IAAA,GAAoB,EAAE,IAAA,EAAM,WAAA,EAAY;AAQvC,IAAM,sBAAN,MAA0B;AAAA,EAC/B,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM7B,MAAM,IACJ,SAAA,EACA,QAAA,EACA,OAAoB,IAAA,EACpB,IAAA,GAA4B,EAAC,EACN;AACvB,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAsB;AAAA,QAC/C,MAAA,EAAQ,KAAA;AAAA,QACR,IAAA,EAAM,CAAA,cAAA,EAAiB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,cAAA,EAAiB,kBAAA;AAAA,UACrD;AAAA,SACD,CAAA,CAAA,EAAI,kBAAA,CAAmB,QAAQ,CAAC,CAAA,CAAA;AAAA,QACjC;AAAA,OACD,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,GAAA,YAAe,oBAAA,IAAwB,IAAA,CAAK,0BAAA,EAA4B;AAC1E,QAAA,OAAO,EAAE,SAAA,EAAW,IAAA,EAAM,QAAA,EAAU,WAAW,IAAA,EAAK;AAAA,MACtD;AACA,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QACJ,UAAA,EACA,QAAA,EACA,OAAoB,IAAA,EACpB,IAAA,GAA4B,EAAC,EACJ;AACzB,IAAA,IAAI,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AACrC,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAwB;AAAA,MACxD,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,cAAA,EAAiB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,oBAAA,CAAA;AAAA,MACtC,IAAA;AAAA,MACA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,QAAA,EAAU,WAAW,MAAA,EAAO;AAAA,MACrD,IAAA,EAAM,UAAA;AAAA,MACN,UAAA,EAAY;AAAA;AAAA,KACb,CAAA;AACD,IAAA,MAAM,IAAA,uBAAW,GAAA,EAA0B;AAC3C,IAAA,KAAA,MAAW,CAAA,IAAK,OAAO,IAAI,CAAA,CAAE,WAAW,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,SAAA,EAAW,CAAC,CAAA;AAC/D,IAAA,OAAO,UAAA,CAAW,GAAA;AAAA,MAChB,CAAC,EAAA,KACC,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,IAAK;AAAA,QACd,SAAA,EAAW,EAAA;AAAA,QACX,IAAA,EAAM,QAAA;AAAA,QACN,SAAA,EAAW,OAAA,CAAQ,IAAA,CAAK,0BAA0B;AAAA;AACpD,KACJ;AAAA,EACF;AACF","file":"chunk-BPVMQFO4.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { EmporixNotFoundError } from \"../core/errors\";\nimport type { AvailabilityWithBundle } from \"../generated/availability\";\n\n/**\n * Site-aware product availability. Mirrors the Emporix Availability Service\n * `AvailabilityWithBundle` shape (the single-product GET and the batch search\n * both return the bundle-aware variant). There is no restock-date field.\n */\nexport type Availability = AvailabilityWithBundle;\n\n/** Shared options for {@link AvailabilityService} reads. */\nexport interface AvailabilityOptions {\n /**\n * When `true`, a product with no availability record resolves to a default\n * `{ available: true }` instead of throwing (single `get`) / being marked\n * unavailable (`getMany`). Off by default — opt in for tenants that sell\n * without stock management.\n */\n defaultAvailableOnNotFound?: boolean;\n}\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\n\n/**\n * Reads product availability per site. Default auth is anonymous (like\n * `PriceService.matchByContext`); pass a customer/raw/service context to use a\n * different token. Requires the `availability.availability_view` scope on\n * whichever token is used.\n */\nexport class AvailabilityService {\n constructor(private readonly ctx: ClientContext) {}\n\n /**\n * Single product. Resolves the availability record, or — when\n * `opts.defaultAvailableOnNotFound` is set — a default available record on 404.\n */\n async get(\n productId: string,\n siteCode: string,\n auth: AuthContext = ANON,\n opts: AvailabilityOptions = {},\n ): Promise<Availability> {\n try {\n return await this.ctx.http.request<Availability>({\n method: \"GET\",\n path: `/availability/${this.ctx.tenant}/availability/${encodeURIComponent(\n productId,\n )}/${encodeURIComponent(siteCode)}`,\n auth,\n });\n } catch (err) {\n if (err instanceof EmporixNotFoundError && opts.defaultAvailableOnNotFound) {\n return { productId, site: siteCode, available: true };\n }\n throw err;\n }\n }\n\n /**\n * Batch read via `POST .../availability/search` (one request). Products with\n * no availability record are absent from the response; each is synthesized as\n * `{ available: false }` (or `{ available: true }` when\n * `opts.defaultAvailableOnNotFound` is set). The result preserves input order\n * and length. An empty `productIds` resolves to `[]` without a request.\n */\n async getMany(\n productIds: string[],\n siteCode: string,\n auth: AuthContext = ANON,\n opts: AvailabilityOptions = {},\n ): Promise<Availability[]> {\n if (productIds.length === 0) return [];\n const found = await this.ctx.http.request<Availability[]>({\n method: \"POST\",\n path: `/availability/${this.ctx.tenant}/availability/search`,\n auth,\n query: { site: siteCode, pageSize: productIds.length },\n body: productIds,\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n });\n const byId = new Map<string, Availability>();\n for (const a of found) if (a.productId) byId.set(a.productId, a);\n return productIds.map(\n (id) =>\n byId.get(id) ?? {\n productId: id,\n site: siteCode,\n available: Boolean(opts.defaultAvailableOnNotFound),\n },\n );\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/segment.ts"],"names":[],"mappings":"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","file":"chunk-CR2JRH7T.js","sourcesContent":["import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { requireCustomer } from \"../core/require-customer\";\nimport type { ProductService } from \"./product\";\nimport type { CategoryService } from \"./category\";\nimport type {\n SegmentResponse,\n ItemAssignmentResponse,\n CategoryTreeResponse,\n} from \"../generated/customer-segment\";\n\n/** Generated segment types (read shapes — storefront `segment_read_own`). */\nexport type Segment = SegmentResponse;\nexport type SegmentItem = ItemAssignmentResponse;\nexport type SegmentCategoryTree = CategoryTreeResponse;\nexport type SegmentCategoryTreeNode = CategoryTreeResponse[number];\n\n/** Cross-service hydrate dependencies, injected from `EmporixClient`. */\nexport interface SegmentServiceDeps {\n products: ProductService;\n categories: CategoryService;\n}\n\nfunction setIfDefined<V>(\n q: Record<string, string | number | undefined>,\n key: string,\n value: V | undefined,\n): void {\n if (value !== undefined && value !== \"\") {\n q[key] = value as unknown as string | number;\n }\n}\n\n/**\n * Customer-segment reads. Every method requires a customer/raw\n * `AuthContext` — the `segment_read_own` scope is on the customer token.\n * The standard product/category endpoints do **not** auto-filter by\n * segment; the storefront uses these reads to discover what to fetch.\n */\nexport class SegmentService {\n constructor(\n private readonly ctx: ClientContext,\n private readonly deps: SegmentServiceDeps,\n ) {}\n\n private base(): string {\n return `/customer-segment/${this.ctx.tenant}/segments`;\n }\n\n /** Lists segments the caller belongs to (with `segment_read_own`). */\n async list(\n query: { q?: string; pageNumber?: number; pageSize?: number } = {},\n auth?: AuthContext,\n ): Promise<Segment[]> {\n const q: Record<string, string | number | undefined> = {};\n setIfDefined(q, \"q\", query.q);\n setIfDefined(q, \"pageNumber\", query.pageNumber);\n setIfDefined(q, \"pageSize\", query.pageSize);\n return this.ctx.http.request<Segment[]>({\n method: \"GET\",\n path: this.base(),\n auth: requireCustomer(auth),\n ...(Object.keys(q).length ? { query: q } : {}),\n });\n }\n\n /** Fetches a single segment by id. */\n async get(segmentId: string, auth?: AuthContext): Promise<Segment> {\n return this.ctx.http.request<Segment>({\n method: \"GET\",\n path: `${this.base()}/${segmentId}`,\n auth: requireCustomer(auth),\n });\n }\n\n /** Item assignments (PRODUCT + CATEGORY) across all the caller's active segments. */\n async listItems(\n query: {\n q?: string;\n siteCode?: string;\n legalEntityId?: string;\n onlyActive?: boolean;\n pageNumber?: number;\n pageSize?: number;\n } = {},\n auth?: AuthContext,\n ): Promise<SegmentItem[]> {\n const q: Record<string, string | number | undefined> = {};\n setIfDefined(q, \"q\", query.q);\n setIfDefined(q, \"siteCode\", query.siteCode);\n setIfDefined(q, \"legalEntityId\", query.legalEntityId);\n setIfDefined(q, \"pageNumber\", query.pageNumber);\n setIfDefined(q, \"pageSize\", query.pageSize);\n if (query.onlyActive !== undefined) q.onlyActive = String(query.onlyActive);\n return this.ctx.http.request<SegmentItem[]>({\n method: \"GET\",\n path: `${this.base()}/items`,\n auth: requireCustomer(auth),\n ...(Object.keys(q).length ? { query: q } : {}),\n });\n }\n\n /** Item assignments of one specific segment. */\n async listSegmentItems(\n segmentId: string,\n query: {\n q?: string;\n legalEntityId?: string;\n pageNumber?: number;\n pageSize?: number;\n } = {},\n auth?: AuthContext,\n ): Promise<SegmentItem[]> {\n const q: Record<string, string | number | undefined> = {};\n setIfDefined(q, \"q\", query.q);\n setIfDefined(q, \"legalEntityId\", query.legalEntityId);\n setIfDefined(q, \"pageNumber\", query.pageNumber);\n setIfDefined(q, \"pageSize\", query.pageSize);\n return this.ctx.http.request<SegmentItem[]>({\n method: \"GET\",\n path: `${this.base()}/${segmentId}/items`,\n auth: requireCustomer(auth),\n ...(Object.keys(q).length ? { query: q } : {}),\n });\n }\n\n /** Category tree built only from the caller's active segments. */\n async getCategoryTree(\n query: { siteCode?: string; legalEntityId?: string } = {},\n auth?: AuthContext,\n ): Promise<SegmentCategoryTree> {\n const q: Record<string, string | number | undefined> = {};\n setIfDefined(q, \"siteCode\", query.siteCode);\n setIfDefined(q, \"legalEntityId\", query.legalEntityId);\n return this.ctx.http.request<SegmentCategoryTree>({\n method: \"GET\",\n path: `${this.base()}/items/category-trees`,\n auth: requireCustomer(auth),\n ...(Object.keys(q).length ? { query: q } : {}),\n });\n }\n\n private async pickItemIds(\n kind: \"PRODUCT\" | \"CATEGORY\",\n query: Parameters<SegmentService[\"listItems\"]>[0],\n auth: AuthContext | undefined,\n ): Promise<string[]> {\n const rows = await this.listItems(query, auth);\n const ids: string[] = [];\n for (const r of rows) {\n const id = r.item?.id;\n if (r.type === kind && typeof id === \"string\") ids.push(id);\n }\n return ids;\n }\n\n /** Product ids assigned to the caller's active segments. */\n async listMyProductIds(\n query?: Parameters<SegmentService[\"listItems\"]>[0],\n auth?: AuthContext,\n ): Promise<string[]> {\n return this.pickItemIds(\"PRODUCT\", query ?? {}, auth);\n }\n\n /** Category ids assigned to the caller's active segments. */\n async listMyCategoryIds(\n query?: Parameters<SegmentService[\"listItems\"]>[0],\n auth?: AuthContext,\n ): Promise<string[]> {\n return this.pickItemIds(\"CATEGORY\", query ?? {}, auth);\n }\n\n /**\n * Hydrates `listMyProductIds` via `ProductService.get` in parallel.\n * Resolves in the same order as the id list. Any single failure rejects\n * the whole batch (`Promise.all`); use the id-list method + your own\n * tolerance strategy if partial success matters.\n */\n async listMyProducts(\n query?: Parameters<SegmentService[\"listItems\"]>[0],\n auth?: AuthContext,\n ): Promise<PaginatedItems<Awaited<ReturnType<ProductService[\"get\"]>>>> {\n const pageNumber = query?.pageNumber ?? 1;\n const pageSize = query?.pageSize ?? 20;\n const sourceItems = await this.listItems(\n { ...(query ?? {}), pageNumber, pageSize },\n auth,\n );\n const ids: string[] = [];\n for (const r of sourceItems) {\n if (r.type === \"PRODUCT\" && typeof r.item?.id === \"string\") ids.push(r.item.id);\n }\n const items = await this.deps.products.searchByIds(ids, undefined, auth);\n return { items, pageNumber, pageSize, hasNextPage: sourceItems.length === pageSize };\n }\n\n /**\n * Hydrates a page of the caller's segment CATEGORY assignments into\n * real categories via one bulk `categories.searchByIds` call. Same\n * `hasNextPage` semantic as `listMyProducts`.\n */\n async listMyCategories(\n query?: Parameters<SegmentService[\"listItems\"]>[0],\n auth?: AuthContext,\n ): Promise<PaginatedItems<Awaited<ReturnType<CategoryService[\"get\"]>>>> {\n const pageNumber = query?.pageNumber ?? 1;\n const pageSize = query?.pageSize ?? 20;\n const sourceItems = await this.listItems(\n { ...(query ?? {}), pageNumber, pageSize },\n auth,\n );\n const ids: string[] = [];\n for (const r of sourceItems) {\n if (r.type === \"CATEGORY\" && typeof r.item?.id === \"string\") ids.push(r.item.id);\n }\n const items = await this.deps.categories.searchByIds(ids, undefined, auth);\n return { items, pageNumber, pageSize, hasNextPage: sourceItems.length === pageSize };\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/payment.ts"],"names":[],"mappings":";;;AA2BO,IAAM,wBAAN,MAA4B;AAAA,EACjC,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA;AAAA,EAG7B,MAAM,iBAAiB,IAAA,EAA4C;AACjE,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAuB;AAAA,MAC1C,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,CAAA,iBAAA,EAAoB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,sBAAA,CAAA;AAAA,MACzC,IAAA,EAAM,gBAAgB,IAAI;AAAA,KAC3B,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,SAAA,CACJ,KAAA,EACA,IAAA,EACiC;AACjC,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAgC;AAAA,MACnD,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,CAAA,iBAAA,EAAoB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,2BAAA,CAAA;AAAA,MACzC,IAAA,EAAM,gBAAgB,IAAI,CAAA;AAAA,MAC1B,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACF","file":"chunk-EINAVCV2.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { EmporixAuthError } from \"../core/errors\";\nimport { requireCustomer } from \"../core/require-customer\";\nimport type {\n PaymentModeFrontendResponse,\n AuthorizePaymentRequest,\n} from \"../generated/payment\";\n\n/** A frontend payment mode (generated). */\nexport type PaymentMode = PaymentModeFrontendResponse;\n\n/** Post-checkout authorize request (generated; caller sends the exact wire shape). */\nexport type AuthorizePaymentInput = AuthorizePaymentRequest;\n\n/** Post-checkout authorize result. */\nexport interface AuthorizePaymentResult {\n successful: boolean;\n paymentTransactionId?: string;\n authorizationToken?: string;\n requiresExternalPayment?: boolean;\n externalPaymentRedirectURL?: string;\n externalPaymentHttpMethod?: string;\n [k: string]: unknown;\n}\n\n/** Payment-Gateway: list frontend payment modes, authorize deferred payments. */\nexport class PaymentGatewayService {\n constructor(private readonly ctx: ClientContext) {}\n\n /** Lists configured frontend payment modes. */\n async listPaymentModes(auth?: AuthContext): Promise<PaymentMode[]> {\n return this.ctx.http.request<PaymentMode[]>({\n method: \"GET\",\n path: `/payment-gateway/${this.ctx.tenant}/paymentmodes/frontend`,\n auth: requireCustomer(auth),\n });\n }\n\n /** Authorizes a post-checkout (deferred) payment for an existing order. */\n async authorize(\n input: AuthorizePaymentInput,\n auth?: AuthContext,\n ): Promise<AuthorizePaymentResult> {\n return this.ctx.http.request<AuthorizePaymentResult>({\n method: \"POST\",\n path: `/payment-gateway/${this.ctx.tenant}/payment/frontend/authorize`,\n auth: requireCustomer(auth),\n body: input,\n });\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/media.ts"],"names":["text"],"mappings":";;;AAuDA,IAAM,OAAA,GAAuB,EAAE,IAAA,EAAM,SAAA,EAAU;AAE/C,SAAS,YAAA,CAAa,GAAe,SAAA,EAA4B;AAC/D,EAAA,OAAO,CAAA,CAAE,IAAA,KAAS,SAAA,IAAa,CAAA,CAAE,EAAA,KAAO,SAAA;AAC1C;AAMO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAErB,IAAA,GAAe;AACrB,IAAA,OAAO,CAAA,OAAA,EAAU,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,OAAA,CAAA;AAAA,EAClC;AAAA;AAAA,EAGA,MAAM,MAAA,CACJ,KAAA,EAGA,IAAA,GAAoB,OAAA,EACK;AACzB,IAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AACzB,MAAA,MAAM,EAAA,GAAK,IAAI,QAAA,EAAS;AACxB,MAAA,EAAA,CAAG,GAAA,CAAI,MAAA,EAAQ,KAAA,CAAM,IAAI,CAAA;AACzB,MAAA,EAAA,CAAG,IAAI,MAAA,EAAQ,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,IAAI,CAAC,CAAA;AACzC,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,QAC3C,MAAA,EAAQ,MAAA;AAAA,QACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,QAChB,IAAA;AAAA,QACA,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH;AACA,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,MAC3C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,IAAA;AAAA,MACA,MAAM,KAAA,CAAM;AAAA,KACb,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,IAAA,CACJ,KAAA,GAAyB,EAAC,EAC1B,OAAoB,OAAA,EACY;AAChC,IAAA,MAAM,UAAA,GAAa,MAAM,UAAA,IAAc,CAAA;AACvC,IAAA,MAAM,QAAA,GAAW,MAAM,QAAA,IAAY,EAAA;AACnC,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,GAAA,CAAI,KAAK,OAAA,CAAiB;AAAA,MACjD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,IAAA;AAAA,MACA,KAAA,EAAO,EAAE,GAAG,KAAA,EAAO,YAAY,QAAA;AAAS,KACzC,CAAA;AACD,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,UAAA;AAAA,MACA,QAAA;AAAA,MACA,WAAA,EAAa,MAAM,MAAA,KAAW;AAAA,KAChC;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,GAAA,CAAI,OAAA,EAAiB,IAAA,GAAoB,OAAA,EAAyB;AACtE,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAe;AAAA,MAClC,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,OAAO,CAAA,CAAA;AAAA,MAC/B;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,MAAA,CACJ,OAAA,EACA,KAAA,EAGA,OAAoB,OAAA,EACJ;AAChB,IAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AACzB,MAAA,MAAM,EAAA,GAAK,IAAI,QAAA,EAAS;AACxB,MAAA,EAAA,CAAG,GAAA,CAAI,MAAA,EAAQ,KAAA,CAAM,IAAI,CAAA;AACzB,MAAA,EAAA,CAAG,IAAI,MAAA,EAAQ,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,IAAI,CAAC,CAAA;AACzC,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAe;AAAA,QAClC,MAAA,EAAQ,KAAA;AAAA,QACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,OAAO,CAAA,CAAA;AAAA,QAC/B,IAAA;AAAA,QACA,IAAA,EAAM;AAAA,OACP,CAAA;AAAA,IACH;AACA,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAe;AAAA,MAClC,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,OAAO,CAAA,CAAA;AAAA,MAC/B,IAAA;AAAA,MACA,MAAM,KAAA,CAAM;AAAA,KACb,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,MAAA,CAAO,OAAA,EAAiB,IAAA,GAAoB,OAAA,EAAwB;AACxE,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,MAChC,MAAA,EAAQ,QAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,OAAO,CAAA,CAAA;AAAA,MAC/B;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,QAAA,CACJ,OAAA,EACA,IAAA,GAAoB,OAAA,EACK;AACzB,IAAA,MAAM,OAAO,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,OAAO,CAAA,SAAA,CAAA;AACtC,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,UAAA;AAAA,MAC9B,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,IAAA,EAAK;AAAA,MAC5B,EAAE,UAAU,QAAA;AAAS,KACvB;AAGA,IAAA,IAAI,GAAA,CAAI,MAAA,IAAU,GAAA,IAAO,GAAA,CAAI,SAAS,GAAA,EAAK;AACzC,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAA;AACtC,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAM,IAAI,YAAA;AAAA,UACR,CAAA,gBAAA,EAAmB,IAAI,MAAM,CAAA,mCAAA,CAAA;AAAA,UAC7B,GAAA,CAAI;AAAA,SACN;AAAA,MACF;AACA,MAAA,OAAO,EAAE,IAAA,EAAM,UAAA,EAAY,GAAA,EAAI;AAAA,IACjC;AAGA,IAAA,IAAI,IAAI,EAAA,EAAI;AACV,MAAA,MAAM,IAAA,GAAO,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,IAAK,MAAA;AACxC,MAAA,MAAM,WAAA,GAAc,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,MAAA;AACvD,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI,WAAA,EAAa,UAAA,CAAW,YAAY,CAAA,EAAG;AAIzC,QAAA,MAAMA,KAAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,QAAA,MAAM,GAAA,GAAM,KAAKA,KAAI,CAAA;AACrB,QAAA,MAAM,GAAA,GAAM,IAAI,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA;AACrC,QAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,MAAA,EAAQ,CAAA,EAAA,EAAK,GAAA,CAAI,CAAC,CAAA,GAAI,GAAA,CAAI,UAAA,CAAW,CAAC,CAAA;AAC9D,QAAA,IAAA,GAAO,GAAA,CAAI,MAAA;AAAA,MACb,CAAA,MAAO;AACL,QAAA,IAAA,GAAO,MAAM,IAAI,WAAA,EAAY;AAAA,MAC/B;AACA,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,OAAA;AAAA,QACN,IAAA;AAAA,QACA,GAAI,IAAA,KAAS,MAAA,GAAY,EAAE,IAAA,KAAS,EAAC;AAAA,QACrC,GAAI,WAAA,KAAgB,MAAA,GAAY,EAAE,WAAA,KAAgB;AAAC,OACrD;AAAA,IACF;AAGA,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,IAAA,IAAI,MAAA,GAAkB,MAAA;AACtB,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,MAC1B,CAAA,CAAA,MAAQ;AACN,QAAA,MAAA,GAAS,IAAA;AAAA,MACX;AAAA,IACF;AACA,IAAA,MAAM,iBAAA,CAAkB,IAAI,MAAA,EAAQ,CAAA,IAAA,EAAO,IAAI,CAAA,QAAA,EAAM,GAAA,CAAI,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA;AAAA,EAC3E;AAAA;AAAA,EAGA,MAAM,UAAA,CACJ,KAAA,EAOA,IAAA,GAAoB,OAAA,EACK;AACzB,IAAA,MAAM,IAAA,GAA6B;AAAA,MACjC,IAAA,EAAM,MAAA;AAAA,MACN,MAAA,EAAQ,MAAM,MAAA,IAAU,QAAA;AAAA,MACxB,GAAI,KAAA,CAAM,SAAA,GACN,EAAE,QAAQ,CAAC,EAAE,IAAA,EAAM,SAAA,EAAW,IAAI,KAAA,CAAM,SAAA,EAAW,CAAA,KACnD,EAAC;AAAA,MACL,GAAI,KAAA,CAAM,QAAA,IAAY,KAAA,CAAM,QAAA,GACxB;AAAA,QACE,OAAA,EAAS;AAAA,UACP,GAAI,MAAM,QAAA,GAAW,EAAE,UAAU,KAAA,CAAM,QAAA,KAAa,EAAC;AAAA,UACrD,GAAI,MAAM,QAAA,GAAW,EAAE,UAAU,KAAA,CAAM,QAAA,KAAa;AAAC;AACvD,UAEF;AAAC,KACP;AACA,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,KAAA,CAAM,IAAA,EAAM,IAAA,EAAK,EAAG,IAAI,CAAA;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,WAAA,CACJ,OAAA,EACA,KAAA,EAOA,OAAoB,OAAA,EACJ;AAChB,IAAA,MAAM,IAAA,GAA6B;AAAA,MACjC,IAAA,EAAM,MAAA;AAAA,MACN,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,GAAI,KAAA,CAAM,QAAA,IAAY,KAAA,CAAM,QAAA,GACxB;AAAA,QACE,OAAA,EAAS;AAAA,UACP,GAAI,MAAM,QAAA,GAAW,EAAE,UAAU,KAAA,CAAM,QAAA,KAAa,EAAC;AAAA,UACrD,GAAI,MAAM,QAAA,GAAW,EAAE,UAAU,KAAA,CAAM,QAAA,KAAa;AAAC;AACvD,UAEF,EAAC;AAAA,MACL,GAAI,KAAA,CAAM,OAAA,KAAY,MAAA,GAClB,EAAE,QAAA,EAAU,EAAE,OAAA,EAAS,KAAA,CAAM,OAAA,EAAQ,EAAE,GACvC;AAAC,KACP;AACA,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,KAAA,CAAM,IAAA,EAAM,IAAA,EAAK,EAAG,IAAI,CAAA;AAAA,EAC5E;AAAA;AAAA,EAGA,MAAM,IAAA,CACJ,KAAA,EACA,IAAA,GAAoB,OAAA,EACK;AACzB,IAAA,MAAM,IAAA,GAA6B;AAAA,MACjC,IAAA,EAAM,MAAA;AAAA,MACN,MAAA,EAAQ,MAAM,MAAA,IAAU,QAAA;AAAA,MACxB,KAAK,KAAA,CAAM,GAAA;AAAA,MACX,GAAI,KAAA,CAAM,SAAA,GACN,EAAE,QAAQ,CAAC,EAAE,IAAA,EAAM,SAAA,EAAW,IAAI,KAAA,CAAM,SAAA,EAAW,CAAA,KACnD;AAAC,KACP;AACA,IAAA,OAAO,KAAK,MAAA,CAAO,EAAE,MAAM,MAAA,EAAQ,IAAA,IAAQ,IAAI,CAAA;AAAA,EACjD;AAAA;AAAA,EAGA,MAAM,eAAA,CACJ,OAAA,EACA,SAAA,EACA,OAAoB,OAAA,EACJ;AAChB,IAAA,MAAM,CAAA,GAAI,MAAM,IAAA,CAAK,GAAA,CAAI,SAAS,IAAI,CAAA;AACtC,IAAA,MAAM,MAAA,GAAuB,CAAA,CAAE,MAAA,IAAU,EAAC;AAC1C,IAAA,IAAI,MAAA,CAAO,KAAK,CAAC,CAAA,KAAM,aAAa,CAAA,EAAG,SAAS,CAAC,CAAA,EAAG,OAAO,CAAA;AAC3D,IAAA,MAAM,IAAA,GAAqB,CAAC,GAAG,MAAA,EAAQ,EAAE,IAAA,EAAM,SAAA,EAAW,EAAA,EAAI,SAAA,EAAW,CAAA;AAGzE,IAAA,MAAM,QAAQ,EAAE,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,QAAQ,IAAA,EAAK;AAC3C,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,EAAS,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAM,EAAG,IAAI,CAAA;AAAA,EACjE;AAAA;AAAA,EAGA,MAAM,iBAAA,CACJ,OAAA,EACA,SAAA,EACA,OAAoB,OAAA,EACJ;AAChB,IAAA,MAAM,CAAA,GAAI,MAAM,IAAA,CAAK,GAAA,CAAI,SAAS,IAAI,CAAA;AACtC,IAAA,MAAM,MAAA,GAAuB,CAAA,CAAE,MAAA,IAAU,EAAC;AAC1C,IAAA,MAAM,IAAA,GAAO,OAAO,MAAA,CAAO,CAAC,MAAM,CAAC,YAAA,CAAa,CAAA,EAAG,SAAS,CAAC,CAAA;AAC7D,IAAA,IAAI,IAAA,CAAK,MAAA,KAAW,MAAA,CAAO,MAAA,EAAQ,OAAO,CAAA;AAC1C,IAAA,MAAM,QAAQ,EAAE,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,QAAQ,IAAA,EAAK;AAC3C,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,EAAS,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAM,EAAG,IAAI,CAAA;AAAA,EACjE;AAAA;AAAA,EAGA,MAAM,cAAA,CACJ,SAAA,EACA,IAAA,GAAoB,OAAA,EACY;AAChC,IAAA,OAAO,KAAK,IAAA,CAAK,EAAE,WAAA,EAAa,SAAA,IAAa,IAAI,CAAA;AAAA,EACnD;AACF;AAIO,IAAM,cAAA,GAAiB,EAAE,YAAA","file":"chunk-FU5WQALW.js","sourcesContent":["import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { EmporixError, errorFromResponse } from \"../core/errors\";\nimport type {\n AssetCreateBlob,\n AssetCreateLink,\n AssetUpdateBlob,\n AssetUpdateLink,\n GetAsset,\n RefId,\n} from \"../generated/media\";\n\n/** Generated media types (caller sends the exact wire shape). */\nexport type AssetCreateBlobInput = AssetCreateBlob;\nexport type AssetCreateLinkInput = AssetCreateLink;\nexport type AssetUpdateBlobInput = AssetUpdateBlob;\nexport type AssetUpdateLinkInput = AssetUpdateLink;\nexport type AssetUpdateInput = AssetUpdateBlob | AssetUpdateLink;\nexport type Asset = GetAsset;\nexport type AssetRefId = RefId;\n\n/**\n * Filter / pagination options for {@link MediaService.list}. The explicit\n * fields are typed for autocomplete; the index signature stays open so\n * Emporix `q`-syntax filters like `\"refIds.id\"` can be passed verbatim.\n */\nexport interface ListAssetsQuery {\n pageNumber?: number;\n pageSize?: number;\n /** Emporix sort syntax, e.g. `\"name,metadata.createdAt:desc\"`. */\n sort?: string;\n /** Emporix `q`-syntax filter, e.g. `\"name:hero\"`. */\n q?: string;\n [key: string]: string | number | undefined;\n}\n\n/**\n * Result of {@link MediaService.download}. The endpoint's behaviour depends\n * on the asset's `access`:\n * - `PUBLIC` assets respond with a 30x redirect whose `Location` header\n * carries the externally-cacheable storage URL — useful when the\n * storefront wants to send the user there directly.\n * - `PRIVATE` assets respond with the raw bytes (plus an `ETag` header\n * for caching). The asset is delivered through Cloudinary behind the\n * server-side service token, never publicly addressable.\n */\nexport type DownloadResult =\n | { kind: \"redirect\"; url: string }\n | {\n kind: \"bytes\";\n data: ArrayBuffer;\n etag?: string;\n contentType?: string;\n };\n\nconst SERVICE: AuthContext = { kind: \"service\" };\n\nfunction isProductRef(r: AssetRefId, productId: string): boolean {\n return r.type === \"PRODUCT\" && r.id === productId;\n}\n\n/**\n * Media assets (BLOB/LINK). All endpoints require a backend-only scope\n * (`media.asset_manage` / `media.asset_read`) — default auth: service.\n */\nexport class MediaService {\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/media/${this.ctx.tenant}/assets`;\n }\n\n /** Create an asset. BLOB uploads via multipart; LINK via JSON. */\n async create(\n input:\n | { kind: \"blob\"; file: Blob; body: AssetCreateBlobInput }\n | { kind: \"link\"; body: AssetCreateLinkInput },\n auth: AuthContext = SERVICE,\n ): Promise<{ id: string }> {\n if (input.kind === \"blob\") {\n const fd = new FormData();\n fd.set(\"file\", input.file);\n fd.set(\"body\", JSON.stringify(input.body));\n return this.ctx.http.request<{ id: string }>({\n method: \"POST\",\n path: this.base(),\n auth,\n body: fd,\n });\n }\n return this.ctx.http.request<{ id: string }>({\n method: \"POST\",\n path: this.base(),\n auth,\n body: input.body,\n });\n }\n\n /**\n * List assets, wrapped in the shared {@link PaginatedItems} envelope so\n * callers can iterate over pages consistently with the rest of the SDK.\n * `hasNextPage` is the standard SDK heuristic: `true` when the returned\n * page is full (`items.length === requested pageSize`). Pagination\n * defaults match Emporix's server defaults (`pageNumber: 1`,\n * `pageSize: 60`) so an empty `query` produces stable expectations.\n */\n async list(\n query: ListAssetsQuery = {},\n auth: AuthContext = SERVICE,\n ): Promise<PaginatedItems<Asset>> {\n const pageNumber = query.pageNumber ?? 1;\n const pageSize = query.pageSize ?? 60;\n const items = await this.ctx.http.request<Asset[]>({\n method: \"GET\",\n path: this.base(),\n auth,\n query: { ...query, pageNumber, pageSize },\n });\n return {\n items,\n pageNumber,\n pageSize,\n hasNextPage: items.length === pageSize,\n };\n }\n\n /** Fetch an asset by id. */\n async get(assetId: string, auth: AuthContext = SERVICE): Promise<Asset> {\n return this.ctx.http.request<Asset>({\n method: \"GET\",\n path: `${this.base()}/${assetId}`,\n auth,\n });\n }\n\n /**\n * Update an asset. The input is a discriminated union mirroring\n * {@link create}:\n * - `{ kind: \"json\", body }` — metadata-only patch (BLOB or LINK).\n * Sends `application/json`. Used for `refIds`, `details`, `metadata`,\n * or `url` changes.\n * - `{ kind: \"blob\", file, body }` — replaces the BLOB file content\n * (max 10MB) AND patches metadata in the same request. Sends\n * `multipart/form-data`.\n *\n * `type` and `access` are immutable per Emporix — they must match the\n * existing asset's values. Optimistic-locking is via `body.metadata.version`;\n * the server returns 409 Conflict on a stale version.\n */\n async update(\n assetId: string,\n input:\n | { kind: \"json\"; body: AssetUpdateInput }\n | { kind: \"blob\"; file: Blob; body: AssetUpdateBlobInput },\n auth: AuthContext = SERVICE,\n ): Promise<Asset> {\n if (input.kind === \"blob\") {\n const fd = new FormData();\n fd.set(\"file\", input.file);\n fd.set(\"body\", JSON.stringify(input.body));\n return this.ctx.http.request<Asset>({\n method: \"PUT\",\n path: `${this.base()}/${assetId}`,\n auth,\n body: fd,\n });\n }\n return this.ctx.http.request<Asset>({\n method: \"PUT\",\n path: `${this.base()}/${assetId}`,\n auth,\n body: input.body,\n });\n }\n\n /** Remove an asset. */\n async remove(assetId: string, auth: AuthContext = SERVICE): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `${this.base()}/${assetId}`,\n auth,\n });\n }\n\n /**\n * Download an asset by id. Returns a discriminated union:\n * - `{ kind: \"redirect\", url }` for `PUBLIC` assets (server-side 30x with\n * the storage URL in `Location`).\n * - `{ kind: \"bytes\", data }` for `PRIVATE` assets (server-side 200 with\n * the asset bytes; `etag` + `contentType` headers are exposed for\n * caching). When the server reports `text/plain` Content-Type (the\n * OpenAPI-documented format), the SDK decodes the base64 stream into\n * an `ArrayBuffer` transparently; binary Content-Types are passed\n * through verbatim.\n *\n * Implementation note: uses `redirect: \"manual\"` so the redirect-location\n * is observable. In Node.js this works; in a browser the redirect Location\n * is intentionally hidden by fetch — there, `PUBLIC` downloads will\n * surface as an opaque-redirect and the SDK throws. Browser code should\n * use the asset's `url` field from `get()` for `LINK` assets, or the\n * direct storage URL for `PUBLIC` `BLOB` assets (typically delivered via\n * an `<img>` tag rather than `download()`).\n */\n async download(\n assetId: string,\n auth: AuthContext = SERVICE,\n ): Promise<DownloadResult> {\n const path = `${this.base()}/${assetId}/download`;\n const res = await this.ctx.http.requestRaw(\n { method: \"GET\", path, auth },\n { redirect: \"manual\" },\n );\n\n // PUBLIC: server-side redirect — capture Location.\n if (res.status >= 300 && res.status < 400) {\n const url = res.headers.get(\"location\");\n if (!url) {\n throw new EmporixError(\n `media.download: ${res.status} response without a Location header`,\n res.status,\n );\n }\n return { kind: \"redirect\", url };\n }\n\n // PRIVATE: bytes.\n if (res.ok) {\n const etag = res.headers.get(\"etag\") ?? undefined;\n const contentType = res.headers.get(\"content-type\") ?? undefined;\n let data: ArrayBuffer;\n if (contentType?.startsWith(\"text/plain\")) {\n // Per OpenAPI spec the server returns the byte stream as a\n // base64-encoded text/plain body. Decode once into raw bytes\n // so callers always see an ArrayBuffer.\n const text = await res.text();\n const bin = atob(text);\n const arr = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) arr[i] = bin.charCodeAt(i);\n data = arr.buffer;\n } else {\n data = await res.arrayBuffer();\n }\n return {\n kind: \"bytes\",\n data,\n ...(etag !== undefined ? { etag } : {}),\n ...(contentType !== undefined ? { contentType } : {}),\n };\n }\n\n // Error: surface via the standard EmporixError hierarchy.\n const text = await res.text();\n let parsed: unknown = undefined;\n if (text) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n throw errorFromResponse(res.status, `GET ${path} → ${res.status}`, parsed);\n }\n\n /** Multipart upload sugar: builds `AssetCreateBlob` from input. */\n async uploadFile(\n input: {\n file: Blob;\n productId?: string;\n filename?: string;\n mimeType?: string;\n access?: \"PUBLIC\" | \"PRIVATE\";\n },\n auth: AuthContext = SERVICE,\n ): Promise<{ id: string }> {\n const body: AssetCreateBlobInput = {\n type: \"BLOB\",\n access: input.access ?? \"PUBLIC\",\n ...(input.productId\n ? { refIds: [{ type: \"PRODUCT\", id: input.productId }] }\n : {}),\n ...(input.filename || input.mimeType\n ? {\n details: {\n ...(input.filename ? { filename: input.filename } : {}),\n ...(input.mimeType ? { mimeType: input.mimeType } : {}),\n },\n }\n : {}),\n };\n return this.create({ kind: \"blob\", file: input.file, body }, auth);\n }\n\n /**\n * Replace the file content of an existing BLOB asset. Sugar over\n * {@link update} with `kind: \"blob\"`. `access` is required because the\n * field is immutable and the server validates that the patch matches.\n * Pass `version` from `asset.metadata.version` if you want optimistic\n * locking (recommended when concurrent writers are possible).\n */\n async replaceFile(\n assetId: string,\n input: {\n file: Blob;\n access: \"PUBLIC\" | \"PRIVATE\";\n filename?: string;\n mimeType?: string;\n version?: number;\n },\n auth: AuthContext = SERVICE,\n ): Promise<Asset> {\n const body: AssetUpdateBlobInput = {\n type: \"BLOB\",\n access: input.access,\n ...(input.filename || input.mimeType\n ? {\n details: {\n ...(input.filename ? { filename: input.filename } : {}),\n ...(input.mimeType ? { mimeType: input.mimeType } : {}),\n },\n }\n : {}),\n ...(input.version !== undefined\n ? { metadata: { version: input.version } }\n : {}),\n };\n return this.update(assetId, { kind: \"blob\", file: input.file, body }, auth);\n }\n\n /** External-URL sugar: builds `AssetCreateLink`. */\n async link(\n input: { url: string; productId?: string; access?: \"PUBLIC\" | \"PRIVATE\" },\n auth: AuthContext = SERVICE,\n ): Promise<{ id: string }> {\n const body: AssetCreateLinkInput = {\n type: \"LINK\",\n access: input.access ?? \"PUBLIC\",\n url: input.url,\n ...(input.productId\n ? { refIds: [{ type: \"PRODUCT\", id: input.productId }] }\n : {}),\n };\n return this.create({ kind: \"link\", body }, auth);\n }\n\n /** Idempotently add a PRODUCT refId to an asset. */\n async attachToProduct(\n assetId: string,\n productId: string,\n auth: AuthContext = SERVICE,\n ): Promise<Asset> {\n const a = await this.get(assetId, auth);\n const refIds: AssetRefId[] = a.refIds ?? [];\n if (refIds.some((r) => isProductRef(r, productId))) return a;\n const next: AssetRefId[] = [...refIds, { type: \"PRODUCT\", id: productId }];\n // Preserve the asset's type discriminator so the update body satisfies\n // the AssetUpdateBlob | AssetUpdateLink union.\n const patch = { type: a.type, refIds: next } as unknown as AssetUpdateInput;\n return this.update(assetId, { kind: \"json\", body: patch }, auth);\n }\n\n /** Remove a PRODUCT refId from an asset (no-op if absent). */\n async detachFromProduct(\n assetId: string,\n productId: string,\n auth: AuthContext = SERVICE,\n ): Promise<Asset> {\n const a = await this.get(assetId, auth);\n const refIds: AssetRefId[] = a.refIds ?? [];\n const next = refIds.filter((r) => !isProductRef(r, productId));\n if (next.length === refIds.length) return a;\n const patch = { type: a.type, refIds: next } as unknown as AssetUpdateInput;\n return this.update(assetId, { kind: \"json\", body: patch }, auth);\n }\n\n /** Convenience: list assets attached to a product (server-side filter). */\n async listForProduct(\n productId: string,\n auth: AuthContext = SERVICE,\n ): Promise<PaginatedItems<Asset>> {\n return this.list({ \"refIds.id\": productId }, auth);\n }\n}\n\n// Re-export so consumers can `import { isProductRef } from \"@viu/emporix-sdk/media\"`?\n// Internal helper — kept module-private; convenience methods in Task 4 use it.\nexport const _internalMedia = { isProductRef };\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/contacts.ts"],"names":[],"mappings":";AAeO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAErB,IAAA,GAAe;AACrB,IAAA,OAAO,CAAA,qBAAA,EAAwB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,oBAAA,CAAA;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,cAAA,CAAe,aAAA,EAAuB,IAAA,EAAiD;AAC3F,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA6B;AAAA,MAChD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,KAAA,EAAO,EAAE,aAAA,EAAc;AAAA,MACvB;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,MAAA,CAAO,KAAA,EAAgC,IAAA,EAA4C;AACvF,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,MAC3C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAA,CACJ,mBAAA,EACA,KAAA,EACA,IAAA,EAC4B;AAC5B,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA2B;AAAA,MAC9C,MAAA,EAAQ,OAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,mBAAmB,CAAA,CAAA;AAAA,MAC3C,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,QAAA,CAAS,mBAAA,EAA6B,IAAA,EAAkC;AAC5E,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,MAChC,MAAA,EAAQ,QAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,mBAAmB,CAAA,CAAA;AAAA,MAC3C;AAAA,KACD,CAAA;AAAA,EACH;AACF","file":"chunk-HAEVK6IS.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type {\n ContactAssignment,\n ContactAssignmentCreate,\n ContactAssignmentUpdate,\n} from \"../generated/customer-management\";\n\n/**\n * Manages contact assignments linking customers to legal entities.\n *\n * `listForCompany` requires `customermanagement.contactassignment_read`;\n * `assign`/`update`/`unassign` require `_manage`. The query param\n * `legalEntityId` scopes the list to one company.\n */\nexport class ContactsService {\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/customer-management/${this.ctx.tenant}/contact-assignments`;\n }\n\n /** Lists contact assignments for one legal entity. */\n async listForCompany(legalEntityId: string, auth: AuthContext): Promise<ContactAssignment[]> {\n return this.ctx.http.request<ContactAssignment[]>({\n method: \"GET\",\n path: this.base(),\n query: { legalEntityId },\n auth,\n });\n }\n\n /** Creates a contact assignment. */\n async assign(input: ContactAssignmentCreate, auth: AuthContext): Promise<{ id: string }> {\n return this.ctx.http.request<{ id: string }>({\n method: \"POST\",\n path: this.base(),\n auth,\n body: input,\n });\n }\n\n /**\n * Patches a contact assignment. PATCH endpoint, so the body is a partial of\n * the generated `ContactAssignmentUpdate` shape.\n */\n async update(\n contactAssignmentId: string,\n patch: Partial<ContactAssignmentUpdate>,\n auth: AuthContext,\n ): Promise<ContactAssignment> {\n return this.ctx.http.request<ContactAssignment>({\n method: \"PATCH\",\n path: `${this.base()}/${contactAssignmentId}`,\n auth,\n body: patch,\n });\n }\n\n /** Deletes a contact assignment. */\n async unassign(contactAssignmentId: string, auth: AuthContext): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `${this.base()}/${contactAssignmentId}`,\n auth,\n });\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/locations.ts"],"names":[],"mappings":";AAeO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAErB,IAAA,GAAe;AACrB,IAAA,OAAO,CAAA,qBAAA,EAAwB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,UAAA,CAAA;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,cAAA,CAAe,aAAA,EAAuB,IAAA,EAAwC;AAClF,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAoB;AAAA,MACvC,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,KAAA,EAAO,EAAE,aAAA,EAAc;AAAA,MACvB;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,GAAA,CAAI,UAAA,EAAoB,IAAA,EAAsC;AAClE,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAkB;AAAA,MACrC,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,UAAU,CAAA,CAAA;AAAA,MAClC;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,MAAA,CAAO,KAAA,EAAuB,IAAA,EAA4C;AAC9E,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,MAC3C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAA,CACJ,UAAA,EACA,KAAA,EACA,IAAA,EACmB;AACnB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAkB;AAAA,MACrC,MAAA,EAAQ,OAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,UAAU,CAAA,CAAA;AAAA,MAClC,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,MAAA,CAAO,UAAA,EAAoB,IAAA,EAAkC;AACjE,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,MAChC,MAAA,EAAQ,QAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,UAAU,CAAA,CAAA;AAAA,MAClC;AAAA,KACD,CAAA;AAAA,EACH;AACF","file":"chunk-LGLFJL3S.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type {\n Location,\n LocationCreate,\n LocationUpdate,\n} from \"../generated/customer-management\";\n\n/**\n * Manages locations owned by a legal entity. Three types are supported:\n * HEADQUARTER, WAREHOUSE, OFFICE.\n *\n * Reads require `customermanagement.location_read`; mutations require\n * `_manage`.\n */\nexport class LocationsService {\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/customer-management/${this.ctx.tenant}/locations`;\n }\n\n /** Lists locations owned by one legal entity. */\n async listForCompany(legalEntityId: string, auth: AuthContext): Promise<Location[]> {\n return this.ctx.http.request<Location[]>({\n method: \"GET\",\n path: this.base(),\n query: { legalEntityId },\n auth,\n });\n }\n\n /** Fetches one location by id. */\n async get(locationId: string, auth: AuthContext): Promise<Location> {\n return this.ctx.http.request<Location>({\n method: \"GET\",\n path: `${this.base()}/${locationId}`,\n auth,\n });\n }\n\n /** Creates a location for a legal entity. */\n async create(input: LocationCreate, auth: AuthContext): Promise<{ id: string }> {\n return this.ctx.http.request<{ id: string }>({\n method: \"POST\",\n path: this.base(),\n auth,\n body: input,\n });\n }\n\n /**\n * Patches a location. PATCH endpoint, so the body is a partial of the\n * generated `LocationUpdate` shape.\n */\n async update(\n locationId: string,\n patch: Partial<LocationUpdate>,\n auth: AuthContext,\n ): Promise<Location> {\n return this.ctx.http.request<Location>({\n method: \"PATCH\",\n path: `${this.base()}/${locationId}`,\n auth,\n body: patch,\n });\n }\n\n /** Deletes a location. */\n async delete(locationId: string, auth: AuthContext): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `${this.base()}/${locationId}`,\n auth,\n });\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/customer-groups.ts"],"names":[],"mappings":";AAeO,IAAM,wBAAN,MAA4B;AAAA,EACjC,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAErB,IAAA,GAAe;AACrB,IAAA,OAAO,CAAA,KAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,OAAA,CAAA;AAAA,EAChC;AAAA;AAAA,EAGA,MAAM,cAAA,CAAe,aAAA,EAAuB,IAAA,EAAmD;AAC7F,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAA+B;AAAA,MAClD,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,KAAA,EAAO,EAAE,mBAAA,EAAqB,aAAA,EAAc;AAAA,MAC5C;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,SAAA,CACJ,OAAA,EACA,MAAA,EACA,IAAA,EACyB;AACzB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,MAC3C,MAAA,EAAQ,MAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,OAAO,CAAA,MAAA,CAAA;AAAA,MAC/B,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,YAAA,CAAa,OAAA,EAAiB,MAAA,EAAgB,IAAA,EAAkC;AACpF,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,MAChC,MAAA,EAAQ,QAAA;AAAA,MACR,IAAA,EAAM,GAAG,IAAA,CAAK,IAAA,EAAM,CAAA,CAAA,EAAI,OAAO,UAAU,MAAM,CAAA,CAAA;AAAA,MAC/C;AAAA,KACD,CAAA;AAAA,EACH;AACF","file":"chunk-LGOC5XOI.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type {\n GroupsQueryDocument,\n AssignmentCreateRequest,\n} from \"../generated/iam\";\n\n/**\n * Access to IAM customer groups for a legal entity.\n *\n * `listForCompany` requires `iam.group_read`; the member mutations\n * (`addMember`/`removeMember`) require `iam.group_manage` — typically only\n * granted to Admin-group customers; a 403 surfaces as\n * `EmporixInsufficientScopeError`.\n */\nexport class CustomerGroupsService {\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/iam/${this.ctx.tenant}/groups`;\n }\n\n /** Lists customer groups belonging to one legal entity. */\n async listForCompany(legalEntityId: string, auth: AuthContext): Promise<GroupsQueryDocument[]> {\n return this.ctx.http.request<GroupsQueryDocument[]>({\n method: \"GET\",\n path: this.base(),\n query: { \"b2b.legalEntityId\": legalEntityId },\n auth,\n });\n }\n\n /** Adds a user (customer or employee) to a group. */\n async addMember(\n groupId: string,\n member: AssignmentCreateRequest,\n auth: AuthContext,\n ): Promise<{ id: string }> {\n return this.ctx.http.request<{ id: string }>({\n method: \"POST\",\n path: `${this.base()}/${groupId}/users`,\n auth,\n body: member,\n });\n }\n\n /** Removes a user from a group. */\n async removeMember(groupId: string, userId: string, auth: AuthContext): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `${this.base()}/${groupId}/users/${userId}`,\n auth,\n });\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/product.ts"],"names":[],"mappings":"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","file":"chunk-MIUVJEGR.js","sourcesContent":["import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport { iterateAll } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type {\n BasicProductWithId,\n BundleProductWithId,\n ParentVariantProductWithId,\n ProductMedia,\n} from \"../generated/product\";\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\n\n/** A product as returned by the Product service (all generated fields). */\nexport type Product = BasicProductWithId | BundleProductWithId | ParentVariantProductWithId;\n\n/** A single product media entry (generated; `ProductMedia` is the list type). */\nexport type Media = ProductMedia[number];\n\n/** Catalog reads. Default auth: anonymous; pass customer for personalized pricing. */\nexport class ProductService {\n constructor(private readonly ctx: ClientContext) {}\n\n /** Fetches one product by id. */\n async get(\n productId: string,\n _opts?: Record<string, never>,\n auth: AuthContext = ANON,\n ): Promise<Product> {\n return this.ctx.http.request<Product>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products/${productId}`,\n auth,\n });\n }\n\n /** Fetches one product by its code. */\n async getByCode(code: string, auth: AuthContext = ANON): Promise<Product> {\n const rows = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { q: `code:${code}` },\n auth,\n });\n const first = rows[0];\n if (!first) throw new Error(`No product with code \"${code}\"`);\n return first;\n }\n\n /** One page of products. */\n async list(\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /** Async-iterates every product across pages. */\n listAll(params: { pageSize?: number } = {}, auth: AuthContext = ANON): AsyncIterable<Product> {\n const pageSize = params.pageSize ?? 50;\n return iterateAll<Product>((pageNumber) => this.list({ pageNumber, pageSize }, auth));\n }\n\n /** Searches products by free-text query. */\n async search(\n query: string,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Product[]>({\n method: \"GET\",\n path: `/product/${this.ctx.tenant}/products`,\n query: { q: query, pageNumber, pageSize },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /**\n * Free-text product search by name. The product `q` is a `field:value` DSL,\n * so a bare term (e.g. \"in time\") 400s with \"No value for key …\". This builds\n * a `name:(~<term>)` regex filter (regex metacharacters escaped) and delegates\n * to {@link search}.\n */\n async searchByName(\n query: string,\n params: { pageNumber?: number; pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Product>> {\n const escaped = query.trim().replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return this.search(`name:(~${escaped})`, params, auth);\n }\n\n /**\n * Bulk fetch by id. POSTs `/products/search` with `q=\"id:(id1,id2,…)\"`,\n * chunking when the list is larger than `options.chunkSize` (default\n * 100). An empty list short-circuits with no HTTP call. **Order is not\n * guaranteed** across chunks — re-index by `id` if order matters.\n */\n async searchByIds(\n ids: string[],\n options: { chunkSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n if (ids.length === 0) return [];\n const chunkSize = options.chunkSize ?? 100;\n const chunks: string[][] = [];\n for (let i = 0; i < ids.length; i += chunkSize) {\n chunks.push(ids.slice(i, i + chunkSize));\n }\n const pages = await Promise.all(\n chunks.map((chunk) =>\n this.ctx.http.request<Product[]>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/search`,\n query: { pageSize: chunk.length },\n auth,\n body: { q: `id:(${chunk.join(\",\")})` },\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n }),\n ),\n );\n return pages.flat();\n }\n\n /**\n * Bulk fetch by code. POSTs `/products/search` with `q=\"code:(c1,c2,…)\"`,\n * chunking when the list is larger than `options.chunkSize` (default 100).\n * Duplicate codes are de-duplicated. Codes containing query-delimiter\n * characters (`(`, `)`, `,`, whitespace, `\"`) are dropped with a logged\n * warning, because the Emporix `q` syntax uses them as delimiters and does\n * not support escaping them in a plain IN-list. An empty list — or one with\n * no safe codes — short-circuits with no HTTP call. **Order is not\n * guaranteed** across chunks — re-index by `code` if order matters.\n */\n async searchByCodes(\n codes: string[],\n options: { chunkSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n const unique = [...new Set(codes)];\n const unsafe = /[(),\"\\s]/;\n const safe = unique.filter((c) => !unsafe.test(c));\n const dropped = unique.filter((c) => unsafe.test(c));\n if (dropped.length > 0) {\n this.ctx.logger.warn(\n \"products.searchByCodes: dropped codes containing query-delimiter characters\",\n { dropped },\n );\n }\n if (safe.length === 0) return [];\n const chunkSize = options.chunkSize ?? 100;\n const chunks: string[][] = [];\n for (let i = 0; i < safe.length; i += chunkSize) {\n chunks.push(safe.slice(i, i + chunkSize));\n }\n const pages = await Promise.all(\n chunks.map((chunk) =>\n this.ctx.http.request<Product[]>({\n method: \"POST\",\n path: `/product/${this.ctx.tenant}/products/search`,\n query: { pageSize: chunk.length },\n auth,\n body: { q: `code:(${chunk.join(\",\")})` },\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n }),\n ),\n );\n return pages.flat();\n }\n\n /**\n * Streams the VARIANT children of a PARENT_VARIANT product, page by page,\n * via the search query `productType:VARIANT parentVariantId:<id>`. Default\n * pageSize 200. The query syntax (space-separated fields = implicit AND) is\n * encapsulated here so consumers don't build it themselves.\n */\n listVariantChildrenAll(\n parentVariantId: string,\n params: { pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): AsyncIterable<Product> {\n const pageSize = params.pageSize ?? 200;\n const q = `productType:VARIANT parentVariantId:${parentVariantId}`;\n return iterateAll<Product>((pageNumber) => this.search(q, { pageNumber, pageSize }, auth));\n }\n\n /**\n * Resolves ALL VARIANT children of a PARENT_VARIANT product into a flat\n * array (loads every page). Default pageSize 200. Returns `[]` when there are\n * no children — never throws.\n */\n async listVariantChildren(\n parentVariantId: string,\n params: { pageSize?: number } = {},\n auth: AuthContext = ANON,\n ): Promise<Product[]> {\n const out: Product[] = [];\n for await (const child of this.listVariantChildrenAll(parentVariantId, params, auth)) {\n out.push(child);\n }\n return out;\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/companies.ts"],"names":[],"mappings":";AAgBO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,GAAA,EAAoB;AAApB,IAAA,IAAA,CAAA,GAAA,GAAA,GAAA;AAAA,EAAqB;AAAA,EAArB,GAAA;AAAA,EAErB,IAAA,GAAe;AACrB,IAAA,OAAO,CAAA,qBAAA,EAAwB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA,eAAA,CAAA;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,SAAS,IAAA,EAA2C;AACxD,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAuB;AAAA,MAC1C,MAAA,EAAQ,KAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,GAAA,CAAI,aAAA,EAAuB,IAAA,EAAyC;AACxE,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAqB;AAAA,MACxC,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,aAAa,CAAA,CAAA;AAAA,MACrC;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,MAAA,CAAO,KAAA,EAA0B,IAAA,EAA4C;AACjF,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAwB;AAAA,MAC3C,MAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAM,KAAK,IAAA,EAAK;AAAA,MAChB,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAA,CACJ,aAAA,EACA,KAAA,EACA,IAAA,EACsB;AACtB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAqB;AAAA,MACxC,MAAA,EAAQ,OAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,aAAa,CAAA,CAAA;AAAA,MACrC,IAAA;AAAA,MACA,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,MAAA,CAAO,aAAA,EAAuB,IAAA,EAAkC;AACpE,IAAA,MAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,OAAA,CAAc;AAAA,MAChC,MAAA,EAAQ,QAAA;AAAA,MACR,MAAM,CAAA,EAAG,IAAA,CAAK,IAAA,EAAM,IAAI,aAAa,CAAA,CAAA;AAAA,MACrC;AAAA,KACD,CAAA;AAAA,EACH;AACF","file":"chunk-MM6JF3Z7.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type {\n LegalEntity,\n LegalEntityCreate,\n LegalEntityUpdate,\n} from \"../generated/customer-management\";\n\n/**\n * Storefront-customer access to Legal Entities.\n *\n * `listMine`/`get` require `customermanagement.legalentity_read_own` on the\n * customer token. `create`/`update`/`delete` require the corresponding\n * `_manage` scopes — typically only granted to Admin-group customers; a 403\n * surfaces as `EmporixInsufficientScopeError`.\n */\nexport class CompaniesService {\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/customer-management/${this.ctx.tenant}/legal-entities`;\n }\n\n /** Lists the legal entities the calling customer is assigned to. */\n async listMine(auth: AuthContext): Promise<LegalEntity[]> {\n return this.ctx.http.request<LegalEntity[]>({\n method: \"GET\",\n path: this.base(),\n auth,\n });\n }\n\n /** Fetches a single legal entity by id. */\n async get(legalEntityId: string, auth: AuthContext): Promise<LegalEntity> {\n return this.ctx.http.request<LegalEntity>({\n method: \"GET\",\n path: `${this.base()}/${legalEntityId}`,\n auth,\n });\n }\n\n /** Creates a legal entity. Requires `customermanagement.legalentity_manage`. */\n async create(input: LegalEntityCreate, auth: AuthContext): Promise<{ id: string }> {\n return this.ctx.http.request<{ id: string }>({\n method: \"POST\",\n path: this.base(),\n auth,\n body: input,\n });\n }\n\n /**\n * Patches a legal entity. The endpoint is a PATCH, so the body is a partial\n * of the generated `LegalEntityUpdate` (full-replace) shape.\n */\n async update(\n legalEntityId: string,\n patch: Partial<LegalEntityUpdate>,\n auth: AuthContext,\n ): Promise<LegalEntity> {\n return this.ctx.http.request<LegalEntity>({\n method: \"PATCH\",\n path: `${this.base()}/${legalEntityId}`,\n auth,\n body: patch,\n });\n }\n\n /** Deletes a legal entity (async cascade on the server). */\n async delete(legalEntityId: string, auth: AuthContext): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `${this.base()}/${legalEntityId}`,\n auth,\n });\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/cart.ts"],"names":[],"mappings":"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","file":"chunk-P3UHYMDH.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { EmporixNotFoundError, EmporixValidationError } from \"../core/errors\";\nimport type {\n Cart as GeneratedCart,\n CreateCart,\n CreatedCart,\n CartItemRequest,\n UpdateCartItem,\n AddressRequest,\n BatchResponse as GeneratedBatchResponse,\n SingleBatchResponse as GeneratedSingleBatchResponse,\n} from \"../generated/cart\";\n\n/** A cart as returned by the Cart service (all generated fields). */\nexport type Cart = GeneratedCart;\n\n/** The cart-create response (`{ cartId, yrn }`, generated). */\nexport type CartCreated = CreatedCart;\n\n/** Generated request bodies (caller sends the exact wire shape). */\nexport type CreateCartInput = CreateCart;\nexport type CartItemInput = CartItemRequest;\nexport type CartItemUpdate = UpdateCartItem;\n\n/** Per-entry result of `addItemsBatch`. `status` is HTTP-style per entry (e.g. 201 = added, 4xx = failed). */\nexport type CartItemBatchEntry = GeneratedSingleBatchResponse;\n/** Response shape of `addItemsBatch` — one entry per input item, matching by `index`. */\nexport type CartItemsBatchResponse = GeneratedBatchResponse;\n\n/** An address payload for cart shipping/billing (generated). */\nexport type CartAddress = AddressRequest;\n\nfunction requireCartAuth(auth: AuthContext | undefined): AuthContext {\n if (auth && (auth.kind === \"customer\" || auth.kind === \"anonymous\")) return auth;\n throw new EmporixValidationError(\n \"CartService requires an explicit { kind: 'customer' } or { kind: 'anonymous' } AuthContext\",\n );\n}\n\nfunction requireCustomerAuth(auth: AuthContext | undefined): AuthContext {\n if (auth && auth.kind === \"customer\") return auth;\n throw new EmporixValidationError(\"cart.merge requires a { kind: 'customer' } AuthContext\");\n}\n\n/** Cart operations. Every method requires an explicit customer/anonymous context. */\nexport class CartService {\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/cart/${this.ctx.tenant}/carts`;\n }\n\n /** Creates a cart. */\n async create(\n input: CreateCartInput | undefined,\n auth: AuthContext,\n ): Promise<CartCreated> {\n return this.ctx.http.request<CartCreated>({\n method: \"POST\",\n path: this.base(),\n auth: requireCartAuth(auth),\n body: input ?? {},\n });\n }\n\n /** Fetches a cart by id. */\n async get(cartId: string, auth: AuthContext): Promise<Cart> {\n return this.ctx.http.request<Cart>({\n method: \"GET\",\n path: `${this.base()}/${cartId}`,\n auth: requireCartAuth(auth),\n });\n }\n\n /** Returns the current cart for the session, or null if none. */\n /**\n * Get the customer / anonymous cart matching the given criteria. Per Emporix:\n * uniqueness is defined by `siteCode` + `type` + `legalEntityId` +\n * (`customerId` derived from a customer token, or `sessionId` derived from an\n * anonymous token). With `create: true`, Emporix creates a new cart if none\n * matches.\n *\n * Returns `null` on 404 (no cart found and `create` was not set). All other\n * errors are propagated.\n */\n async getCurrent(\n auth: AuthContext,\n opts: { siteCode: string; type?: string; legalEntityId?: string; create?: boolean },\n ): Promise<Cart | null> {\n const query: Record<string, string | number> = { siteCode: opts.siteCode };\n if (opts.type !== undefined) query.type = opts.type;\n if (opts.legalEntityId !== undefined) query.legalEntityId = opts.legalEntityId;\n if (opts.create) query.create = \"true\";\n try {\n return await this.ctx.http.request<Cart>({\n method: \"GET\",\n path: this.base(),\n query,\n auth: requireCartAuth(auth),\n });\n } catch (e) {\n if (e instanceof EmporixNotFoundError) return null;\n throw e;\n }\n }\n\n /** Adds an item. */\n async addItem(\n cartId: string,\n item: CartItemInput,\n auth: AuthContext,\n ): Promise<Cart> {\n return this.ctx.http.request<Cart>({\n method: \"POST\",\n path: `${this.base()}/${cartId}/items`,\n auth: requireCartAuth(auth),\n body: item,\n });\n }\n\n /**\n * Adds multiple items in a single request via `POST /carts/{id}/itemsBatch`.\n * Server-side limit is 200 entries per call — callers handling larger sets\n * must chunk. The response carries a per-entry `status` (HTTP-style: 201\n * for added, 4xx/5xx for failed) and `index` matching the input position;\n * partial failures do **not** throw — inspect `status` per entry.\n */\n async addItemsBatch(\n cartId: string,\n items: CartItemInput[],\n auth: AuthContext,\n ): Promise<CartItemsBatchResponse> {\n return this.ctx.http.request<CartItemsBatchResponse>({\n method: \"POST\",\n path: `${this.base()}/${cartId}/itemsBatch`,\n auth: requireCartAuth(auth),\n body: items,\n });\n }\n\n /**\n * Updates an item. By default this is a **full replace** — the server expects\n * the complete item (e.g. `itemYrn` + the `price` row). Pass\n * `{ partial: true }` to send a **partial update** (`?partial=true`), e.g. a\n * quantity-only change with just `{ quantity }`.\n */\n async updateItem(\n cartId: string,\n itemId: string,\n patch: CartItemUpdate,\n auth: AuthContext,\n opts: { partial?: boolean } = {},\n ): Promise<Cart> {\n return this.ctx.http.request<Cart>({\n method: \"PUT\",\n path: `${this.base()}/${cartId}/items/${itemId}`,\n auth: requireCartAuth(auth),\n body: patch,\n ...(opts.partial ? { query: { partial: \"true\" } } : {}),\n });\n }\n\n /** Removes an item. */\n async removeItem(cartId: string, itemId: string, auth: AuthContext): Promise<Cart> {\n return this.ctx.http.request<Cart>({\n method: \"DELETE\",\n path: `${this.base()}/${cartId}/items/${itemId}`,\n auth: requireCartAuth(auth),\n });\n }\n\n /** Empties the cart. */\n async clear(cartId: string, auth: AuthContext): Promise<Cart> {\n return this.ctx.http.request<Cart>({\n method: \"DELETE\",\n path: `${this.base()}/${cartId}/items`,\n auth: requireCartAuth(auth),\n });\n }\n\n /** Applies a coupon. */\n async applyCoupon(cartId: string, code: string, auth: AuthContext): Promise<Cart> {\n return this.ctx.http.request<Cart>({\n method: \"POST\",\n path: `${this.base()}/${cartId}/coupons`,\n auth: requireCartAuth(auth),\n body: { code },\n });\n }\n\n /** Removes a coupon. */\n async removeCoupon(cartId: string, code: string, auth: AuthContext): Promise<Cart> {\n return this.ctx.http.request<Cart>({\n method: \"DELETE\",\n path: `${this.base()}/${cartId}/coupons/${code}`,\n auth: requireCartAuth(auth),\n });\n }\n\n /** Sets the shipping address. */\n async setShippingAddress(\n cartId: string,\n address: CartAddress,\n auth: AuthContext,\n ): Promise<Cart> {\n return this.ctx.http.request<Cart>({\n method: \"PUT\",\n path: `${this.base()}/${cartId}/shipping-address`,\n auth: requireCartAuth(auth),\n body: address,\n });\n }\n\n /** Sets the billing address. */\n async setBillingAddress(\n cartId: string,\n address: CartAddress,\n auth: AuthContext,\n ): Promise<Cart> {\n return this.ctx.http.request<Cart>({\n method: \"PUT\",\n path: `${this.base()}/${cartId}/billing-address`,\n auth: requireCartAuth(auth),\n body: address,\n });\n }\n\n /**\n * Merges one or more anonymous carts into the specified customer cart.\n * Per Emporix: the target cart in the path **must belong to the logged-in\n * customer**, and each id in `anonymousCartIds` must belong to an anonymous\n * customer. Anonymous carts go `CLOSED` on success.\n *\n * Requires a customer `AuthContext`.\n */\n async merge(\n customerCartId: string,\n anonymousCartIds: string[],\n auth: AuthContext,\n ): Promise<Cart> {\n return this.ctx.http.request<Cart>({\n method: \"POST\",\n path: `${this.base()}/${customerCartId}/merge`,\n auth: requireCustomerAuth(auth),\n body: { carts: anonymousCartIds },\n });\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/customer.ts"],"names":[],"mappings":"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","file":"chunk-UOBOFCFU.js","sourcesContent":["import type { ClientContext } from \"../core/context\";\nimport type { AuthContext, AnonymousSession } from \"../core/auth\";\nimport { EmporixAuthError } from \"../core/errors\";\nimport { requireCustomer } from \"../core/require-customer\";\nimport type {\n Customer as GeneratedCustomer,\n Address as GeneratedAddress,\n CustomerSignup,\n CustomerUpdateDto,\n PasswordChangeDto,\n PasswordResetRequestDto,\n PasswordUpdate,\n AddressCreateDto,\n AddressUpdateDto,\n} from \"../generated/customer\";\n\n/**\n * Caller-owned customer session. Maps the Emporix `CustomerToken` wire shape to\n * idiomatic names: `access_token` → `customerToken`, `saas_token` →\n * `saasToken`. `saasToken` is a JWT required for the checkout (`saas-token`\n * header). The wire's `*_token` (snake_case) fields are canonical; the\n * camelCase variants are deprecated in the Emporix spec.\n */\nexport interface CustomerSession {\n customerToken: string;\n /** JWT required for completing checkout (sent as the `saas-token` header). */\n saasToken: string;\n refreshToken: string;\n /** Same session as the anonymous token — preserves the cart across login. */\n sessionId: string | undefined;\n /** Customer access-token lifetime in seconds. */\n expiresIn: number | undefined;\n /** Only set by `socialLogin`: the IdP access token echoed by Emporix. */\n socialAccessToken?: string;\n /** Only set by `socialLogin`: the IdP ID token echoed by Emporix. */\n socialIdToken?: string;\n}\n\n/** Customer profile as returned by the Customer service (all generated fields). */\nexport type Customer = GeneratedCustomer;\n\n/** A customer address as returned by the Customer service (all generated fields). */\nexport type Address = GeneratedAddress;\n\n/** Generated request bodies (caller sends the exact wire shape). */\nexport type CustomerSignupInput = CustomerSignup;\nexport type CustomerUpdateInput = CustomerUpdateDto;\nexport type PasswordChangeInput = PasswordChangeDto;\nexport type PasswordResetRequestInput = PasswordResetRequestDto;\nexport type PasswordResetConfirmInput = PasswordUpdate;\nexport type AddressCreateInput = AddressCreateDto;\nexport type AddressUpdateInput = AddressUpdateDto;\n\n/** Union of the wire shapes the four session endpoints return. snake_case is\n * canonical; camelCase is the deprecated fallback (vendored spec, design §2). */\ninterface WireSession {\n access_token?: string;\n saas_token?: string;\n refresh_token?: string;\n session_id?: string;\n expires_in?: string | number;\n accessToken?: string;\n saasToken?: string;\n refreshToken?: string;\n social_access_token?: string;\n social_id_token?: string;\n}\n\n/** Wire→facade mapping shared by login/refresh/socialLogin/exchangeToken.\n * Throws instead of fabricating an empty session: `customerToken: \"\"` would\n * read as authenticated downstream and 401-loop every subsequent call. */\nfunction toSession(\n endpoint: string,\n wire: WireSession,\n opts: { carrySaasToken?: string } = {},\n): CustomerSession {\n const customerToken = wire.access_token ?? wire.accessToken;\n if (!customerToken) {\n throw new EmporixAuthError(`${endpoint}: response missing access_token`, undefined, wire);\n }\n return {\n customerToken,\n saasToken: wire.saas_token ?? wire.saasToken ?? opts.carrySaasToken ?? \"\",\n refreshToken: wire.refresh_token ?? wire.refreshToken ?? \"\",\n sessionId: wire.session_id,\n expiresIn: wire.expires_in != null ? Number(wire.expires_in) : undefined,\n ...(wire.social_access_token ? { socialAccessToken: wire.social_access_token } : {}),\n ...(wire.social_id_token ? { socialIdToken: wire.social_id_token } : {}),\n };\n}\n\n/** Customer signup, session, profile and addresses. */\nexport class CustomerService {\n constructor(private readonly ctx: ClientContext) {}\n\n /** Obtains an anonymous storefront session (accessToken + sessionId + refreshToken). */\n async anonymous(): Promise<AnonymousSession> {\n return this.ctx.tokenProvider.getAnonymousToken();\n }\n\n /** Registers a customer. Default auth: anonymous. */\n async signup(\n input: CustomerSignupInput,\n auth: AuthContext = { kind: \"anonymous\" },\n ): Promise<Customer> {\n return this.ctx.http.request<Customer>({\n method: \"POST\",\n path: `/customer/${this.ctx.tenant}/signup`,\n auth,\n body: input,\n });\n }\n\n /**\n * Logs a customer in. Threads the anonymous token so the session (and its\n * cart) survives — losing it silently creates a new session per Emporix docs.\n * Wire `accessToken` is mapped to `customerToken`.\n */\n async login(\n creds: { email: string; password: string },\n opts: { anonymousToken?: string } = {},\n auth: AuthContext = { kind: \"anonymous\" },\n ): Promise<CustomerSession> {\n const effective: AuthContext = opts.anonymousToken\n ? { kind: \"raw\", token: opts.anonymousToken }\n : auth;\n const wire = await this.ctx.http.request<WireSession>({\n method: \"POST\",\n path: `/customer/${this.ctx.tenant}/login`,\n auth: effective,\n body: creds,\n });\n return toSession(\"login\", wire);\n }\n\n /**\n * Refreshes an authenticated customer session via its refresh token,\n * preserving the same `sessionId`. Calls\n * `GET /customer/{tenant}/refreshauthtoken?refreshToken=…`, which **must be\n * authorized with an anonymous token** (default auth: anonymous) — not the\n * expired customer token. The refresh response does **not** include a\n * `saas_token`; pass the original `saasToken` to carry it forward (it has\n * its own, independent lifetime).\n */\n async refresh(\n input: { refreshToken: string; saasToken?: string; legalEntityId?: string },\n auth: AuthContext = { kind: \"anonymous\" },\n ): Promise<CustomerSession> {\n const query: Record<string, string> = { refreshToken: input.refreshToken };\n if (input.legalEntityId) query.legalEntityId = input.legalEntityId;\n const wire = await this.ctx.http.request<WireSession>({\n method: \"GET\",\n path: `/customer/${this.ctx.tenant}/refreshauthtoken`,\n query,\n auth,\n });\n // Refresh does not return a saas_token — carry the original forward.\n return toSession(\n \"refresh\",\n wire,\n input.saasToken !== undefined ? { carrySaasToken: input.saasToken } : {},\n );\n }\n\n /**\n * Logs the customer out server-side: `GET /customer/{tenant}/logout?\n * accessToken=…` authorized with the customer token. Invalidates the\n * access token (204 No Content). Requires customer/raw auth — the token is\n * sent both as the bearer and the `accessToken` query param (per Emporix).\n */\n async logout(auth?: AuthContext): Promise<void> {\n const ctx = requireCustomer(auth);\n const token = (ctx as { token: string }).token;\n await this.ctx.http.request<void>({\n method: \"GET\",\n path: `/customer/${this.ctx.tenant}/logout`,\n query: { accessToken: token },\n auth: ctx,\n });\n }\n\n /**\n * Authorization-Code SSO: exchanges the IdP `code` for an Emporix customer\n * session via `POST /customer/{tenant}/socialLogin`. The browser performs\n * the IdP redirect itself; the SDK only does this Emporix exchange.\n * Default auth: anonymous (Emporix requires an anonymous Bearer). The\n * response has no `session_id` and returns `expires_in` as a string —\n * normalized to a number here.\n */\n async socialLogin(\n input: { code: string; redirectUri: string; codeVerifier?: string; sessionId?: string },\n auth: AuthContext = { kind: \"anonymous\" },\n ): Promise<CustomerSession> {\n const query: Record<string, string> = {\n code: input.code,\n redirect_uri: input.redirectUri,\n };\n if (input.codeVerifier) query.code_verifier = input.codeVerifier;\n const wire = await this.ctx.http.request<WireSession>({\n method: \"POST\",\n path: `/customer/${this.ctx.tenant}/socialLogin`,\n query,\n auth,\n ...(input.sessionId ? { headers: { \"session-id\": input.sessionId } } : {}),\n });\n return toSession(\"socialLogin\", wire);\n }\n\n /**\n * RFC 8693 token exchange: exchanges an external IdP JWT for an Emporix\n * customer session via `POST /customer/{tenant}/exchangeauthtoken`.\n * Emporix uses a proprietary query-param wire (not the RFC form body).\n * Default auth: anonymous. `config` selects a site-specific IdP config\n * (multi-site); omit for the tenant default. Returns `session_id` and a\n * fresh `saas_token`; `expires_in` is an integer (normalized anyway).\n */\n async exchangeToken(\n input: { subjectToken: string; config?: string },\n auth: AuthContext = { kind: \"anonymous\" },\n ): Promise<CustomerSession> {\n const query: Record<string, string> = { subjectAccessToken: input.subjectToken };\n if (input.config) query.config = input.config;\n const wire = await this.ctx.http.request<WireSession>({\n method: \"POST\",\n path: `/customer/${this.ctx.tenant}/exchangeauthtoken`,\n query,\n auth,\n });\n return toSession(\"exchangeToken\", wire);\n }\n\n /** Returns the authenticated customer. Requires customer/raw auth. */\n async me(auth?: AuthContext): Promise<Customer> {\n return this.ctx.http.request<Customer>({\n method: \"GET\",\n path: `/customer/${this.ctx.tenant}/me`,\n auth: requireCustomer(auth),\n });\n }\n\n /** Updates the authenticated customer. Requires customer/raw auth. */\n async update(patch: CustomerUpdateInput, auth?: AuthContext): Promise<Customer> {\n return this.ctx.http.request<Customer>({\n method: \"PUT\",\n path: `/customer/${this.ctx.tenant}/me`,\n auth: requireCustomer(auth),\n body: patch,\n });\n }\n\n /** Changes the password. Requires customer/raw auth. */\n async changePassword(input: PasswordChangeInput, auth?: AuthContext): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"PUT\",\n path: `/customer/${this.ctx.tenant}/password`,\n auth: requireCustomer(auth),\n body: input,\n });\n }\n\n /** Requests a password reset email. Default auth: anonymous. */\n async requestPasswordReset(\n input: PasswordResetRequestInput,\n auth: AuthContext = { kind: \"anonymous\" },\n ): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"POST\",\n path: `/customer/${this.ctx.tenant}/password/reset`,\n auth,\n body: input,\n });\n }\n\n /** Confirms a password reset. Default auth: anonymous. */\n async confirmPasswordReset(\n input: PasswordResetConfirmInput,\n auth: AuthContext = { kind: \"anonymous\" },\n ): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"POST\",\n path: `/customer/${this.ctx.tenant}/password/reset/confirm`,\n auth,\n body: input,\n });\n }\n\n /** Address sub-resource. All operations require customer/raw auth. */\n readonly addresses = {\n list: async (auth?: AuthContext): Promise<Address[]> =>\n this.ctx.http.request<Address[]>({\n method: \"GET\",\n path: `/customer/${this.ctx.tenant}/me/addresses`,\n auth: requireCustomer(auth),\n }),\n add: async (address: AddressCreateInput, auth?: AuthContext): Promise<Address> =>\n this.ctx.http.request<Address>({\n method: \"POST\",\n path: `/customer/${this.ctx.tenant}/me/addresses`,\n auth: requireCustomer(auth),\n body: address,\n }),\n update: async (id: string, patch: AddressUpdateInput, auth?: AuthContext): Promise<Address> =>\n this.ctx.http.request<Address>({\n method: \"PUT\",\n path: `/customer/${this.ctx.tenant}/me/addresses/${id}`,\n auth: requireCustomer(auth),\n body: patch,\n }),\n remove: async (id: string, auth?: AuthContext): Promise<void> =>\n this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/customer/${this.ctx.tenant}/me/addresses/${id}`,\n auth: requireCustomer(auth),\n }),\n };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/services/orders.ts"],"names":[],"mappings":"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","file":"chunk-WW3H7VJ5.js","sourcesContent":["import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport type { Order, OrderStatus, OrderUpdateDto } from \"../generated/order-v2\";\n\n/**\n * Salesorder PATCH body. The generated `orderUpdateDto` models a full order\n * (it requires `entries`/`customer`), but `PATCH /salesorders/{id}` accepts a\n * subset — so the SDK exposes a partial of it.\n */\nexport type SalesOrderPatch = Partial<OrderUpdateDto>;\n\n/** Optional fields supported by the order-v2 list endpoint. */\nexport interface ListMyOrdersOptions {\n pageNumber?: number;\n pageSize?: number;\n status?: OrderStatus;\n legalEntityId?: string;\n siteCode?: string;\n saasToken?: string;\n}\n\n/** Options for single-order reads (saas-token only). */\nexport interface GetOrderOptions {\n saasToken?: string;\n}\n\n/** Options for status transitions. */\nexport interface OrderTransitionOptions {\n saasToken?: string;\n comment?: string;\n}\n\n/** Options for `salesOrders.update`. */\nexport interface UpdateSalesOrderOptions {\n /** Forwarded as `?recalculate=`. Omit to use the server default (true). */\n recalculate?: boolean;\n}\n\nfunction setIfDefined<V>(\n q: Record<string, string | number | undefined>,\n key: string,\n value: V | undefined,\n): void {\n if (value !== undefined && value !== \"\") {\n q[key] = value as unknown as string | number;\n }\n}\n\n/**\n * Storefront-customer access to Order-v2's customer endpoints.\n *\n * `listMine`/`get` require `order.order_read_own`; transitions require\n * `order.order_manage_own`. All methods accept an optional `saasToken` that\n * is passed as the `saas-token` header (mirrors `checkout.placeOrder`).\n */\nexport class OrdersService {\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/order-v2/${this.ctx.tenant}/orders`;\n }\n\n private saasHeader(saasToken: string | undefined): Record<string, string> | undefined {\n return saasToken ? { \"saas-token\": saasToken } : undefined;\n }\n\n /** Lists the calling customer's orders. */\n async listMine(\n auth: AuthContext,\n opts: ListMyOrdersOptions = {},\n ): Promise<PaginatedItems<Order>> {\n const pageNumber = opts.pageNumber ?? 1;\n const pageSize = opts.pageSize ?? 50;\n const query: Record<string, string | number | undefined> = {\n pageNumber,\n pageSize,\n };\n setIfDefined(query, \"status\", opts.status);\n setIfDefined(query, \"legalEntityId\", opts.legalEntityId);\n setIfDefined(query, \"siteCode\", opts.siteCode);\n const headers = this.saasHeader(opts.saasToken);\n // order-v2 returns a bare JSON array (the total count lives in the\n // X-Total-Count header), not a {items,...} envelope — so wrap it into the\n // shared PaginatedItems shape like every other paginated service.\n // hasNextPage is inferred from the page being full.\n const items = await this.ctx.http.request<Order[]>({\n method: \"GET\",\n path: this.base(),\n query,\n auth,\n ...(headers ? { headers } : {}),\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n /** Fetches one of the calling customer's orders by id. */\n async get(\n orderId: string,\n auth: AuthContext,\n opts: GetOrderOptions = {},\n ): Promise<Order> {\n const headers = this.saasHeader(opts.saasToken);\n return this.ctx.http.request<Order>({\n method: \"GET\",\n path: `${this.base()}/${orderId}`,\n auth,\n ...(headers ? { headers } : {}),\n });\n }\n\n /** Transitions an order to a new status. Server enforces legal transitions. */\n async transition(\n orderId: string,\n status: OrderStatus,\n auth: AuthContext,\n opts: OrderTransitionOptions = {},\n ): Promise<void> {\n const body: { status: OrderStatus; comment?: string } = { status };\n if (opts.comment !== undefined) body.comment = opts.comment;\n const headers = this.saasHeader(opts.saasToken);\n await this.ctx.http.request<void>({\n method: \"POST\",\n path: `${this.base()}/${orderId}/transitions`,\n auth,\n body,\n ...(headers ? { headers } : {}),\n });\n }\n\n /** Convenience: transitions to `DECLINED` (customer cancel). */\n async cancel(\n orderId: string,\n auth: AuthContext,\n opts: { saasToken?: string } = {},\n ): Promise<void> {\n await this.transition(orderId, \"DECLINED\", auth, opts);\n }\n}\n\n/**\n * Backend / service-account access to the merchant-facing\n * `/salesorders/{id}` resource. Requires `order.order_read` (read) /\n * `order.order_manage` (update) scopes on a service token.\n *\n * The full admin list + filter surface is deferred to a follow-up\n * sub-spec. This service ships only single-resource read + patch — the\n * common backend use case (e.g. mixin updates after fulfilment).\n */\nexport class SalesOrdersService {\n constructor(private readonly ctx: ClientContext) {}\n\n private base(): string {\n return `/order-v2/${this.ctx.tenant}/salesorders`;\n }\n\n /** Fetches a single sales-order by id. */\n async get(orderId: string, auth: AuthContext): Promise<Order> {\n return this.ctx.http.request<Order>({\n method: \"GET\",\n path: `${this.base()}/${orderId}`,\n auth,\n });\n }\n\n /** Patches an existing order (status, mixins, customAttributes, metadata). */\n async update(\n orderId: string,\n patch: SalesOrderPatch,\n auth: AuthContext,\n opts: UpdateSalesOrderOptions = {},\n ): Promise<Order> {\n const query: Record<string, string> = {};\n if (opts.recalculate === false) query.recalculate = \"false\";\n return this.ctx.http.request<Order>({\n method: \"PATCH\",\n path: `${this.base()}/${orderId}`,\n auth,\n ...(Object.keys(query).length > 0 ? { query } : {}),\n body: patch,\n });\n }\n}\n"]}
|