sinfactura-types 1.10.554 → 1.10.555
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/brands.d.ts +49 -1
- package/dist/cjs/product.js +46 -1
- package/dist/product.d.ts +119 -0
- package/dist/product.js +45 -0
- package/package.json +1 -1
package/dist/brands.d.ts
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
declare global {
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Write shape for brand create/update — carries the transient photo controls.
|
|
4
|
+
*
|
|
5
|
+
* `name` is required on a create and optional on an update (send the diff
|
|
6
|
+
* plus `brandId`). An update of an unknown `brandId` is `404
|
|
7
|
+
* BRAND_NOT_FOUND`, never an upsert. An empty `description` or `website`
|
|
8
|
+
* clears it; omitting a field leaves it unchanged.
|
|
9
|
+
*
|
|
10
|
+
* A create may carry an `Idempotency-Key` header: the same key and body
|
|
11
|
+
* answer the same `brandId`, a changed body under that key is `422
|
|
12
|
+
* IDEMPOTENCY_KEY_REUSE`.
|
|
13
|
+
*/
|
|
3
14
|
type BrandUpsertInput = Partial<Brand> & PhotoUploadControls;
|
|
4
15
|
interface Brand {
|
|
5
16
|
storeId: string;
|
|
6
17
|
brandId: string;
|
|
18
|
+
/**
|
|
19
|
+
* Display name, trimmed, 1..200 characters. Unique per store, disabled
|
|
20
|
+
* brands included, compared after Unicode NFKC, trimming, collapsing
|
|
21
|
+
* whitespace and lower-casing — accents are kept, so `Niño` and `Nino`
|
|
22
|
+
* are different brands.
|
|
23
|
+
*/
|
|
7
24
|
name: string;
|
|
8
25
|
photoURL?: string;
|
|
9
26
|
/** @deprecated Request-only upload control, never persisted or returned — use `BrandUpsertInput.photoData`. */
|
|
@@ -13,6 +30,37 @@ declare global {
|
|
|
13
30
|
isFather: boolean;
|
|
14
31
|
father?: string;
|
|
15
32
|
disabled: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* URL slug, unique per store: `^[a-z0-9]+(?:-[a-z0-9]+)*$`, at most 80
|
|
35
|
+
* characters. Minted from `name` on a create, and on an update of a row
|
|
36
|
+
* that has none only when that update carries `name`; suffixed `-2`,
|
|
37
|
+
* `-3`… on a clash; a rename never changes it. An explicit value is never
|
|
38
|
+
* suffixed.
|
|
39
|
+
*/
|
|
40
|
+
slug?: string;
|
|
41
|
+
/** At most 2000 characters. */
|
|
42
|
+
description?: string;
|
|
43
|
+
/** An absolute `https:` URL without credentials, at most 2048 characters. Never fetched by the api. */
|
|
44
|
+
website?: string;
|
|
16
45
|
}
|
|
46
|
+
/** Every code a `POST /brands` identity or lookup check can refuse with. */
|
|
47
|
+
type BrandErrorCode = 'BRAND_NOT_FOUND' | 'BRAND_NAME_TAKEN' | 'BRAND_SLUG_TAKEN' | 'INVALID_SLUG' | 'BRAND_IDENTITY_CHECK_INCOMPLETE' | 'BRAND_WRITE_CONFLICT';
|
|
48
|
+
/**
|
|
49
|
+
* The body of a refused `POST /brands`. Statuses: `BRAND_NOT_FOUND` · 404,
|
|
50
|
+
* `INVALID_SLUG` · 400, every other code · 409.
|
|
51
|
+
*
|
|
52
|
+
* - `BRAND_NAME_TAKEN` — another brand of the store, enabled or disabled,
|
|
53
|
+
* has the same name after normalization.
|
|
54
|
+
* - `BRAND_SLUG_TAKEN` — another brand holds the slug, or won the race for
|
|
55
|
+
* a minted one.
|
|
56
|
+
* - `BRAND_IDENTITY_CHECK_INCOMPLETE` — the store has more brands than one
|
|
57
|
+
* uniqueness check reads; nothing was written.
|
|
58
|
+
* - `BRAND_WRITE_CONFLICT` — the brand changed while it was being saved;
|
|
59
|
+
* nothing was written and the request is safe to retry.
|
|
60
|
+
*/
|
|
61
|
+
type BrandRefusal = {
|
|
62
|
+
message: string;
|
|
63
|
+
error: BrandErrorCode;
|
|
64
|
+
};
|
|
17
65
|
}
|
|
18
66
|
export {};
|
package/dist/cjs/product.js
CHANGED
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PRODUCT_POST_ERROR_CODES = void 0;
|
|
3
|
+
exports.PRODUCT_POST_ERROR_CODES = exports.PRODUCT_EXPORT_ERROR_CODES = exports.PRODUCT_CATALOG_EXPORT_COLUMNS = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* The CSV header of `GET /products?mode=export`, in file order.
|
|
6
|
+
*
|
|
7
|
+
* The first block uses the bulk-import row keys, so a column means the same thing
|
|
8
|
+
* in both directions: `prices` and `sellableOn` are JSON arrays, `barcode` is the
|
|
9
|
+
* primary barcode. The last block is read-only — the import ignores it:
|
|
10
|
+
* `productId`, `currentStock` (stock now, not an opening balance), `minStock` and
|
|
11
|
+
* `updatedAt` (ms epoch).
|
|
12
|
+
*/
|
|
13
|
+
exports.PRODUCT_CATALOG_EXPORT_COLUMNS = [
|
|
14
|
+
'sku',
|
|
15
|
+
'name',
|
|
16
|
+
'description',
|
|
17
|
+
'categoryId',
|
|
18
|
+
'brandId',
|
|
19
|
+
'currency',
|
|
20
|
+
'cost',
|
|
21
|
+
'ivaType',
|
|
22
|
+
'prices',
|
|
23
|
+
'barcode',
|
|
24
|
+
'limit',
|
|
25
|
+
'zone',
|
|
26
|
+
'isService',
|
|
27
|
+
'isNew',
|
|
28
|
+
'disabled',
|
|
29
|
+
'sellableOn',
|
|
30
|
+
'weightGrams',
|
|
31
|
+
'lengthMm',
|
|
32
|
+
'widthMm',
|
|
33
|
+
'heightMm',
|
|
34
|
+
'productId',
|
|
35
|
+
'currentStock',
|
|
36
|
+
'minStock',
|
|
37
|
+
'updatedAt',
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* Every refusal `GET /products?mode=export` answers, beyond the cross-cutting
|
|
41
|
+
* `GATING_ERROR_CODES` (the `importExport` entitlement among them):
|
|
42
|
+
*
|
|
43
|
+
* - `ADMIN_REQUIRED` · 403 — the caller is neither ADMIN nor MANAGER.
|
|
44
|
+
* - `ROLE_FORBIDDEN` · 403 — a print agent or an accountant.
|
|
45
|
+
* - `VALIDATION_FAILED` · 400 — a filter outside the grammar.
|
|
46
|
+
* - `INVALID_CURSOR` · 400 — a `startKey` this store did not mint.
|
|
47
|
+
*/
|
|
48
|
+
exports.PRODUCT_EXPORT_ERROR_CODES = ['ADMIN_REQUIRED', 'ROLE_FORBIDDEN', 'VALIDATION_FAILED', 'INVALID_CURSOR'];
|
|
4
49
|
/**
|
|
5
50
|
* Every refusal `POST /products` answers on a single-product create or edit —
|
|
6
51
|
* the body with no `mode`, `stacks/lambdas/products/_post.ts` behind
|
package/dist/product.d.ts
CHANGED
|
@@ -13,6 +13,54 @@ declare global {
|
|
|
13
13
|
/** Requested IDs absent, hidden, disabled or unpriceable; never unresolved reads. */
|
|
14
14
|
unavailableProductIds: string[];
|
|
15
15
|
}
|
|
16
|
+
/** Anonymous Web GET /products related read; the tenant comes from the public store context. */
|
|
17
|
+
interface PublicRelatedProductsInput {
|
|
18
|
+
mode: 'related';
|
|
19
|
+
/** Canonical id of the product page the suggestions are for. */
|
|
20
|
+
productId: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The computed associations for one product, resolved at read time against the
|
|
24
|
+
* public projection: at most 10 products, in the model's ranked order, each
|
|
25
|
+
* visible, enabled, priceable and sellable on the storefront.
|
|
26
|
+
*
|
|
27
|
+
* ⚠️ `data: []` covers both "no model computed yet" and "every suggestion is
|
|
28
|
+
* currently not offered"; the distinction and every figure stay on the
|
|
29
|
+
* operator `GET /products?mode=associations`. An anchor that is not offered
|
|
30
|
+
* answers 404 `PRODUCT_NOT_FOUND`; an incomplete read 503
|
|
31
|
+
* `PRODUCT_LOOKUP_INCOMPLETE`, never a partial list.
|
|
32
|
+
*/
|
|
33
|
+
interface PublicRelatedProductsResponse {
|
|
34
|
+
message: string;
|
|
35
|
+
/** Current public price/projection and online stock, best suggestion first. */
|
|
36
|
+
data: Partial<Product>[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Anonymous Web GET /products composed discovery; the tenant comes from the
|
|
40
|
+
* public store context. Every filter is optional and they AND-compose.
|
|
41
|
+
*/
|
|
42
|
+
interface PublicProductDiscoverInput {
|
|
43
|
+
mode: 'discover';
|
|
44
|
+
/** Free text, ≤100 chars; every token must appear in the product's search term. */
|
|
45
|
+
search?: string;
|
|
46
|
+
/** Exact primary category; descendants are not included. */
|
|
47
|
+
categoryId?: string;
|
|
48
|
+
brandId?: string;
|
|
49
|
+
/** Only products with a promo window open now. */
|
|
50
|
+
inOffer?: 'true';
|
|
51
|
+
/** Only products the online stock authority can sell now; services always pass. */
|
|
52
|
+
inStock?: 'true';
|
|
53
|
+
/** The previous response's `LastEvaluatedKey`, under the SAME filters; else 400 INVALID_CURSOR. */
|
|
54
|
+
startKey?: string;
|
|
55
|
+
}
|
|
56
|
+
/** One page of a discovery walk; `data` can be empty while `LastEvaluatedKey` is set. */
|
|
57
|
+
interface PublicProductDiscoverResponse {
|
|
58
|
+
message: string;
|
|
59
|
+
/** Public price/projection and online stock, in index order. */
|
|
60
|
+
data: Partial<Product>[];
|
|
61
|
+
/** Present while rows remain; absent means the walk is complete. */
|
|
62
|
+
LastEvaluatedKey?: string;
|
|
63
|
+
}
|
|
16
64
|
/** Write shape for product create/update — carries the transient picture-removal control. */
|
|
17
65
|
type ProductUpsertInput = Partial<Product> & {
|
|
18
66
|
/** Request-only: pictures to delete; the BE removes them from storage and from `pictures[]`. */
|
|
@@ -745,7 +793,78 @@ declare global {
|
|
|
745
793
|
/** Ranked and truncated server-side. May be shorter than the ids requested. */
|
|
746
794
|
data: ProductAssociations[];
|
|
747
795
|
}
|
|
796
|
+
/**
|
|
797
|
+
* `GET /products?mode=export` — the filters it accepts, with the operator
|
|
798
|
+
* listing's (`GET /products`) meaning: an absent `disabled` means enabled-only,
|
|
799
|
+
* `all` adds the disabled rows, `true` is only those. Any other listing parameter
|
|
800
|
+
* is refused 400 `VALIDATION_FAILED` rather than ignored. ADMIN or MANAGER,
|
|
801
|
+
* behind the `importExport` entitlement.
|
|
802
|
+
*/
|
|
803
|
+
interface ProductCatalogExportQuery {
|
|
804
|
+
mode: 'export';
|
|
805
|
+
categoryId?: string;
|
|
806
|
+
brandId?: string;
|
|
807
|
+
search?: string;
|
|
808
|
+
disabled?: 'true' | 'false' | 'all';
|
|
809
|
+
stock?: 'out' | 'low';
|
|
810
|
+
inOffer?: 'true' | 'false';
|
|
811
|
+
/** `nextStartKey` from an incomplete export, to export the rest. */
|
|
812
|
+
startKey?: string;
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* One export: a `;`-separated UTF-8 CSV (with BOM), stored privately and handed
|
|
816
|
+
* out as a short-lived download link. The header row is
|
|
817
|
+
* {@link PRODUCT_CATALOG_EXPORT_COLUMNS}; an empty cell means the field is absent,
|
|
818
|
+
* never zero. A text cell starting with `=`, `+`, `-`, `@`, tab, CR or `'` is
|
|
819
|
+
* written with one extra leading `'` so a spreadsheet opens it as text; stripping
|
|
820
|
+
* one leading `'` from such a cell restores it exactly. Numbers use `.` as the
|
|
821
|
+
* decimal separator and are never prefixed.
|
|
822
|
+
*/
|
|
823
|
+
interface ProductCatalogExport {
|
|
824
|
+
/** Presigned GET; valid until `expiresAt`. Ask for a new export after that. */
|
|
825
|
+
url: string;
|
|
826
|
+
fileName: string;
|
|
827
|
+
/** ms epoch. */
|
|
828
|
+
expiresAt: number;
|
|
829
|
+
/** ms epoch the rows were read at. */
|
|
830
|
+
generatedAt: number;
|
|
831
|
+
rowCount: number;
|
|
832
|
+
/**
|
|
833
|
+
* `false` when the read stopped before the end of the selection. The file then
|
|
834
|
+
* holds only the rows before the stop, its name ends in `-parcial`, and
|
|
835
|
+
* `nextStartKey` exports the rest.
|
|
836
|
+
*/
|
|
837
|
+
complete: boolean;
|
|
838
|
+
nextStartKey?: string;
|
|
839
|
+
columns: ProductCatalogExportColumn[];
|
|
840
|
+
}
|
|
841
|
+
interface ProductCatalogExportResponse {
|
|
842
|
+
message: string;
|
|
843
|
+
data: ProductCatalogExport;
|
|
844
|
+
}
|
|
845
|
+
type ProductCatalogExportColumn = (typeof PRODUCT_CATALOG_EXPORT_COLUMNS)[number];
|
|
748
846
|
}
|
|
847
|
+
/**
|
|
848
|
+
* The CSV header of `GET /products?mode=export`, in file order.
|
|
849
|
+
*
|
|
850
|
+
* The first block uses the bulk-import row keys, so a column means the same thing
|
|
851
|
+
* in both directions: `prices` and `sellableOn` are JSON arrays, `barcode` is the
|
|
852
|
+
* primary barcode. The last block is read-only — the import ignores it:
|
|
853
|
+
* `productId`, `currentStock` (stock now, not an opening balance), `minStock` and
|
|
854
|
+
* `updatedAt` (ms epoch).
|
|
855
|
+
*/
|
|
856
|
+
export declare const PRODUCT_CATALOG_EXPORT_COLUMNS: readonly ["sku", "name", "description", "categoryId", "brandId", "currency", "cost", "ivaType", "prices", "barcode", "limit", "zone", "isService", "isNew", "disabled", "sellableOn", "weightGrams", "lengthMm", "widthMm", "heightMm", "productId", "currentStock", "minStock", "updatedAt"];
|
|
857
|
+
/**
|
|
858
|
+
* Every refusal `GET /products?mode=export` answers, beyond the cross-cutting
|
|
859
|
+
* `GATING_ERROR_CODES` (the `importExport` entitlement among them):
|
|
860
|
+
*
|
|
861
|
+
* - `ADMIN_REQUIRED` · 403 — the caller is neither ADMIN nor MANAGER.
|
|
862
|
+
* - `ROLE_FORBIDDEN` · 403 — a print agent or an accountant.
|
|
863
|
+
* - `VALIDATION_FAILED` · 400 — a filter outside the grammar.
|
|
864
|
+
* - `INVALID_CURSOR` · 400 — a `startKey` this store did not mint.
|
|
865
|
+
*/
|
|
866
|
+
export declare const PRODUCT_EXPORT_ERROR_CODES: readonly ["ADMIN_REQUIRED", "ROLE_FORBIDDEN", "VALIDATION_FAILED", "INVALID_CURSOR"];
|
|
867
|
+
export type ProductExportErrorCode = (typeof PRODUCT_EXPORT_ERROR_CODES)[number];
|
|
749
868
|
/**
|
|
750
869
|
* Every refusal `POST /products` answers on a single-product create or edit —
|
|
751
870
|
* the body with no `mode`, `stacks/lambdas/products/_post.ts` behind
|
package/dist/product.js
CHANGED
|
@@ -1,3 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CSV header of `GET /products?mode=export`, in file order.
|
|
3
|
+
*
|
|
4
|
+
* The first block uses the bulk-import row keys, so a column means the same thing
|
|
5
|
+
* in both directions: `prices` and `sellableOn` are JSON arrays, `barcode` is the
|
|
6
|
+
* primary barcode. The last block is read-only — the import ignores it:
|
|
7
|
+
* `productId`, `currentStock` (stock now, not an opening balance), `minStock` and
|
|
8
|
+
* `updatedAt` (ms epoch).
|
|
9
|
+
*/
|
|
10
|
+
export const PRODUCT_CATALOG_EXPORT_COLUMNS = [
|
|
11
|
+
'sku',
|
|
12
|
+
'name',
|
|
13
|
+
'description',
|
|
14
|
+
'categoryId',
|
|
15
|
+
'brandId',
|
|
16
|
+
'currency',
|
|
17
|
+
'cost',
|
|
18
|
+
'ivaType',
|
|
19
|
+
'prices',
|
|
20
|
+
'barcode',
|
|
21
|
+
'limit',
|
|
22
|
+
'zone',
|
|
23
|
+
'isService',
|
|
24
|
+
'isNew',
|
|
25
|
+
'disabled',
|
|
26
|
+
'sellableOn',
|
|
27
|
+
'weightGrams',
|
|
28
|
+
'lengthMm',
|
|
29
|
+
'widthMm',
|
|
30
|
+
'heightMm',
|
|
31
|
+
'productId',
|
|
32
|
+
'currentStock',
|
|
33
|
+
'minStock',
|
|
34
|
+
'updatedAt',
|
|
35
|
+
];
|
|
36
|
+
/**
|
|
37
|
+
* Every refusal `GET /products?mode=export` answers, beyond the cross-cutting
|
|
38
|
+
* `GATING_ERROR_CODES` (the `importExport` entitlement among them):
|
|
39
|
+
*
|
|
40
|
+
* - `ADMIN_REQUIRED` · 403 — the caller is neither ADMIN nor MANAGER.
|
|
41
|
+
* - `ROLE_FORBIDDEN` · 403 — a print agent or an accountant.
|
|
42
|
+
* - `VALIDATION_FAILED` · 400 — a filter outside the grammar.
|
|
43
|
+
* - `INVALID_CURSOR` · 400 — a `startKey` this store did not mint.
|
|
44
|
+
*/
|
|
45
|
+
export const PRODUCT_EXPORT_ERROR_CODES = ['ADMIN_REQUIRED', 'ROLE_FORBIDDEN', 'VALIDATION_FAILED', 'INVALID_CURSOR'];
|
|
1
46
|
/**
|
|
2
47
|
* Every refusal `POST /products` answers on a single-product create or edit —
|
|
3
48
|
* the body with no `mode`, `stacks/lambdas/products/_post.ts` behind
|