@sixtyninecommerce/admin 0.8.0 → 0.10.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/README.md +2739 -17
- package/dist/api-tokens/index.d.ts +15 -5
- package/dist/api-tokens/index.js +1 -0
- package/dist/apps/event-subscription.d.ts +59 -0
- package/dist/apps/event-subscription.js +32 -0
- package/dist/apps/hook-secret.d.ts +22 -0
- package/dist/apps/hook-secret.js +36 -0
- package/dist/apps/index.d.ts +54 -3
- package/dist/apps/index.js +17 -0
- package/dist/audit/index.d.ts +7 -0
- package/dist/auth/queries.d.ts +5 -1
- package/dist/auth/queries.js +6 -0
- package/dist/bulk/index.d.ts +323 -0
- package/dist/bulk/index.js +162 -0
- package/dist/catalog/assets.d.ts +147 -0
- package/dist/catalog/assets.js +164 -0
- package/dist/catalog/collections.d.ts +109 -0
- package/dist/catalog/collections.js +91 -0
- package/dist/catalog/facets.d.ts +103 -0
- package/dist/catalog/facets.js +100 -0
- package/dist/catalog/index.d.ts +115 -0
- package/dist/catalog/index.js +21 -0
- package/dist/catalog/options.d.ts +89 -0
- package/dist/catalog/options.js +88 -0
- package/dist/catalog/products-bulk.d.ts +21 -0
- package/dist/catalog/products-bulk.js +58 -0
- package/dist/catalog/products.d.ts +650 -0
- package/dist/catalog/products.js +458 -0
- package/dist/catalog/properties.d.ts +234 -0
- package/dist/catalog/properties.js +158 -0
- package/dist/catalog/types.d.ts +174 -0
- package/dist/catalog/types.js +141 -0
- package/dist/catalog/variants.d.ts +324 -0
- package/dist/catalog/variants.js +288 -0
- package/dist/catalog/visibility.d.ts +57 -0
- package/dist/catalog/visibility.js +59 -0
- package/dist/client.d.ts +192 -3
- package/dist/client.js +87 -12
- package/dist/compliance/index.d.ts +88 -0
- package/dist/compliance/index.js +88 -0
- package/dist/customer-data-redaction.d.ts +14 -0
- package/dist/customer-data-redaction.js +22 -0
- package/dist/customers/index.d.ts +428 -17
- package/dist/customers/index.js +322 -15
- package/dist/documents/index.d.ts +513 -16
- package/dist/documents/index.js +229 -3
- package/dist/events/index.d.ts +259 -0
- package/dist/events/index.js +147 -0
- package/dist/feeds/ai.d.ts +46 -0
- package/dist/feeds/ai.js +43 -0
- package/dist/feeds/categories.d.ts +50 -0
- package/dist/feeds/categories.js +56 -0
- package/dist/feeds/configs.d.ts +54 -0
- package/dist/feeds/configs.js +85 -0
- package/dist/feeds/identifier-fields.d.ts +25 -0
- package/dist/feeds/identifier-fields.js +29 -0
- package/dist/feeds/index.d.ts +54 -0
- package/dist/feeds/index.js +46 -0
- package/dist/feeds/preserve.d.ts +38 -0
- package/dist/feeds/preserve.js +74 -0
- package/dist/feeds/rules.d.ts +42 -0
- package/dist/feeds/rules.js +56 -0
- package/dist/feeds/types.d.ts +654 -0
- package/dist/feeds/types.js +135 -0
- package/dist/fulfillments/index.d.ts +437 -0
- package/dist/fulfillments/index.js +534 -0
- package/dist/heads/index.d.ts +60 -0
- package/dist/heads/index.js +45 -0
- package/dist/hooks/assignments.d.ts +90 -0
- package/dist/hooks/assignments.js +53 -0
- package/dist/hooks/index.d.ts +97 -0
- package/dist/hooks/index.js +76 -0
- package/dist/index.d.ts +95 -9
- package/dist/index.js +21 -1
- package/dist/integrations/index.d.ts +14 -0
- package/dist/integrations/index.js +9 -0
- package/dist/integrations/pipelines.d.ts +113 -0
- package/dist/integrations/pipelines.js +62 -0
- package/dist/integrations/types.d.ts +176 -0
- package/dist/integrations/types.js +8 -0
- package/dist/jobs/bulk-action-run.d.ts +74 -0
- package/dist/jobs/bulk-action-run.js +69 -0
- package/dist/locations/index.d.ts +6 -2
- package/dist/meta/index.d.ts +32 -0
- package/dist/orders/bulk.d.ts +75 -0
- package/dist/orders/bulk.js +150 -0
- package/dist/orders/commit-edit.d.ts +123 -0
- package/dist/orders/commit-edit.js +142 -0
- package/dist/orders/deposit-policy.d.ts +103 -0
- package/dist/orders/deposit-policy.js +202 -0
- package/dist/orders/get.d.ts +722 -0
- package/dist/orders/get.js +530 -0
- package/dist/orders/index.d.ts +186 -21
- package/dist/orders/index.js +57 -0
- package/dist/orders/line-price-preview.d.ts +297 -0
- package/dist/orders/line-price-preview.js +50 -0
- package/dist/orders/manual-discounts.d.ts +141 -0
- package/dist/orders/manual-discounts.js +97 -0
- package/dist/orders/manual-pricing.d.ts +192 -0
- package/dist/orders/manual-pricing.js +72 -0
- package/dist/orders/order-entry.d.ts +566 -0
- package/dist/orders/order-entry.js +129 -0
- package/dist/orders/parcel-charge.d.ts +45 -0
- package/dist/orders/parcel-charge.js +55 -0
- package/dist/orders/plan-edit.d.ts +489 -0
- package/dist/orders/plan-edit.js +93 -0
- package/dist/orders/status.d.ts +235 -0
- package/dist/orders/status.js +96 -0
- package/dist/orders/surcharges.d.ts +75 -2
- package/dist/orders/surcharges.js +110 -4
- package/dist/payments/account-credit.d.ts +171 -0
- package/dist/payments/account-credit.js +107 -0
- package/dist/payments/index.d.ts +241 -9
- package/dist/payments/index.js +92 -0
- package/dist/payments/methods.d.ts +37 -0
- package/dist/payments/methods.js +33 -0
- package/dist/platform/catalog.d.ts +148 -0
- package/dist/platform/catalog.js +74 -0
- package/dist/platform/entitlements.d.ts +111 -0
- package/dist/platform/entitlements.js +86 -0
- package/dist/platform/legal-entities.d.ts +139 -0
- package/dist/platform/legal-entities.js +126 -0
- package/dist/platform/legal-entity-numbering.d.ts +103 -0
- package/dist/platform/legal-entity-numbering.js +101 -0
- package/dist/platform/organization-membership.d.ts +80 -0
- package/dist/platform/organization-membership.js +71 -0
- package/dist/platform/organization-settings.d.ts +33 -0
- package/dist/platform/organization-settings.js +42 -0
- package/dist/platform/organization-sharing.d.ts +172 -0
- package/dist/platform/organization-sharing.js +120 -0
- package/dist/platform/organizations.d.ts +205 -0
- package/dist/platform/organizations.js +180 -0
- package/dist/platform/provision-store.d.ts +88 -8
- package/dist/platform/provision-store.js +12 -0
- package/dist/platform/reports.d.ts +46 -0
- package/dist/platform/reports.js +31 -0
- package/dist/platform/server-metrics.d.ts +58 -0
- package/dist/platform/server-metrics.js +11 -0
- package/dist/pos/index.d.ts +567 -0
- package/dist/pos/index.js +205 -0
- package/dist/pricing/index.d.ts +408 -0
- package/dist/pricing/index.js +353 -0
- package/dist/pricing/vouchers.d.ts +103 -0
- package/dist/pricing/vouchers.js +69 -0
- package/dist/provenance/index.d.ts +93 -0
- package/dist/provenance/index.js +53 -0
- package/dist/reports/index.d.ts +199 -0
- package/dist/reports/index.js +154 -0
- package/dist/returns/index.d.ts +225 -0
- package/dist/returns/index.js +160 -0
- package/dist/search/index.d.ts +99 -0
- package/dist/search/index.js +62 -0
- package/dist/shipping/parcel-count-suggestion.d.ts +52 -0
- package/dist/shipping/parcel-count-suggestion.js +73 -0
- package/dist/shipping/parcel-rule.d.ts +48 -0
- package/dist/shipping/parcel-rule.js +91 -0
- package/dist/stock/index.d.ts +166 -0
- package/dist/stock/index.js +115 -0
- package/dist/stock/transfers.d.ts +520 -0
- package/dist/stock/transfers.js +437 -0
- package/dist/stored-value/index.d.ts +154 -0
- package/dist/stored-value/index.js +130 -0
- package/dist/tenant/capabilities.d.ts +10 -0
- package/dist/tenant/entitlements.d.ts +35 -0
- package/dist/tenant/entitlements.js +15 -0
- package/dist/tenant/field-groups.d.ts +64 -0
- package/dist/tenant/field-groups.js +34 -0
- package/dist/tenant/legal-entity.d.ts +32 -0
- package/dist/tenant/legal-entity.js +41 -0
- package/dist/tenant/notifications.d.ts +148 -0
- package/dist/tenant/notifications.js +79 -0
- package/dist/tenant/retention.d.ts +10 -4
- package/dist/tenant/settings-sources.d.ts +103 -0
- package/dist/tenant/settings-sources.js +92 -0
- package/dist/types.d.ts +86 -11
- package/dist/uploads/index.d.ts +11 -7
- package/dist/users/index.d.ts +104 -0
- package/dist/users/index.js +80 -0
- package/package.json +3 -2
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { Transport } from '@sixtyninecommerce/core';
|
|
2
|
+
import type { Call } from '../types.js';
|
|
3
|
+
import { type AssetsModule } from './assets.js';
|
|
4
|
+
import { type CollectionsModule } from './collections.js';
|
|
5
|
+
import { type FacetsModule } from './facets.js';
|
|
6
|
+
import { type OptionsModule } from './options.js';
|
|
7
|
+
import { type ProductsModule } from './products.js';
|
|
8
|
+
import { type ContentFacetSyncResult, type PropertiesModule } from './properties.js';
|
|
9
|
+
import { type VariantsModule } from './variants.js';
|
|
10
|
+
import { type VisibilityModule } from './visibility.js';
|
|
11
|
+
/**
|
|
12
|
+
* The catalogue (spec §9.2 `catalog`): products, variants, options, facets,
|
|
13
|
+
* collections, assets, storefront visibility and product properties — one
|
|
14
|
+
* resource per namespace, over the Admin API the dashboard itself uses.
|
|
15
|
+
*
|
|
16
|
+
* **Per-resource, not per-intent.** Saving a product form is several calls
|
|
17
|
+
* here (the product, its variants, its properties, its collections), and they
|
|
18
|
+
* are NOT one transaction: a failure part-way leaves the earlier writes in
|
|
19
|
+
* place. `products.save(input)` as one atomic intent operation is a later
|
|
20
|
+
* phase (spec §7, phase 6); until then, order your writes so a retry of the
|
|
21
|
+
* remainder is safe, and read back before retrying a create.
|
|
22
|
+
*
|
|
23
|
+
* **Idempotency.** No catalogue mutation deduplicates on `idempotencyKey`
|
|
24
|
+
* except `products.bulk`: elsewhere the key is sent and acts on nothing (see
|
|
25
|
+
* `Call`), so repeating a `create` makes a second product. Updates and deletes
|
|
26
|
+
* are naturally repeatable.
|
|
27
|
+
*
|
|
28
|
+
* **Lists** are `Page<T>` over the Admin API's `skip/take` (`limit` 1–1000,
|
|
29
|
+
* default 25). Every following page re-sends the same filter and the same
|
|
30
|
+
* per-call tenant.
|
|
31
|
+
*
|
|
32
|
+
* **Money** is integer minor units; a price input states its basis
|
|
33
|
+
* (`priceBasis`), and a basis other than the store's is refused rather than
|
|
34
|
+
* converted — see `catalog.variants`.
|
|
35
|
+
*
|
|
36
|
+
* **Time** inputs (`availableFrom`) need an explicit offset; outputs are
|
|
37
|
+
* ISO-8601 UTC.
|
|
38
|
+
*
|
|
39
|
+
* **Errors.** Vendure's own refusals keep its words and its code: an unknown
|
|
40
|
+
* id is `NotFoundError` (`ENTITY_NOT_FOUND`), a rejected value `ValidationError`
|
|
41
|
+
* (`USER_INPUT_ERROR`), a missing permission `PermissionDeniedError`
|
|
42
|
+
* (`FORBIDDEN`). A delete the engine declines at HTTP 200 (`NOT_DELETED`)
|
|
43
|
+
* becomes a `ConflictError` named `<RESOURCE>_NOT_DELETED` carrying the
|
|
44
|
+
* engine's reason. Module-specific codes are listed on each namespace.
|
|
45
|
+
*
|
|
46
|
+
* **An organization's catalogue** (multi-region spec §5.4). Products, variants,
|
|
47
|
+
* collections, facets, assets, option groups and property values a member
|
|
48
|
+
* store holds from its organization's workspace are changed in the workspace
|
|
49
|
+
* only, by everyone, SuperAdmin included: a write from the store, or one that
|
|
50
|
+
* reaches such a row through a product, a parent collection or an option group
|
|
51
|
+
* link, is refused `MANAGED_BY_ORGANIZATION` (422 `BusinessRuleError`), and
|
|
52
|
+
* the message says where to make the change instead. Each catalogue read
|
|
53
|
+
* carries `catalogueOwnership` (see `CatalogueOwnership`; the property groups
|
|
54
|
+
* `properties.values.get` answers carry `editableHere`): show the row
|
|
55
|
+
* read-only while `editableHere` is false.
|
|
56
|
+
* What the store adds to such a row stays its own to change: its prices, its
|
|
57
|
+
* stock at its own locations, its own facet values on the product, its own
|
|
58
|
+
* collections under a workspace collection. Requires a platform release that
|
|
59
|
+
* serves `catalogueOwnership` and `PropertyGroup.editableHere`: against an older
|
|
60
|
+
* engine every call that answers such a row, writes included, fails as a whole
|
|
61
|
+
* and writes nothing.
|
|
62
|
+
*/
|
|
63
|
+
export interface CatalogModule {
|
|
64
|
+
products: ProductsModule;
|
|
65
|
+
variants: VariantsModule;
|
|
66
|
+
/** Option groups ("Size") and options ("M"): what a product's variants differ by. */
|
|
67
|
+
options: OptionsModule;
|
|
68
|
+
facets: FacetsModule;
|
|
69
|
+
collections: CollectionsModule;
|
|
70
|
+
assets: AssetsModule;
|
|
71
|
+
visibility: VisibilityModule;
|
|
72
|
+
properties: PropertiesModule;
|
|
73
|
+
/**
|
|
74
|
+
* "Sync filter values" for one filterable `content_item` or `product` property, done by the
|
|
75
|
+
* engine (headless spec §7 `catalog.syncContentFacets`, by property, the unit the merchant syncs).
|
|
76
|
+
* Every filter value the property's values name gets its CURRENT label: a content item's title
|
|
77
|
+
* (read by the engine from the store's CMS content, drafts and archived items included), a
|
|
78
|
+
* product's name in the request's language. A `content_item` property whose SAVED configuration
|
|
79
|
+
* names fields to filter by also has its field-level facets brought in line with the items'
|
|
80
|
+
* field values: what the property was saved with decides, never an unsaved form. The store's
|
|
81
|
+
* products' filter assignments follow their property values, and a value no product names any
|
|
82
|
+
* more is removed.
|
|
83
|
+
*
|
|
84
|
+
* One transaction: the labels and the field facets are written together, or not at all. The
|
|
85
|
+
* labels are read first, so a content system that cannot be read refuses the call before
|
|
86
|
+
* anything changes. Repeating the call is safe: a label that did not change is not written
|
|
87
|
+
* again, so a repeat answers the same counts and changes nothing.
|
|
88
|
+
*
|
|
89
|
+
* Nothing runs it automatically in this release: rename a content item or a product, then call
|
|
90
|
+
* it (or press "Sync filter values") to update the filter label (ruling G17; an event-driven
|
|
91
|
+
* update is a later phase).
|
|
92
|
+
*
|
|
93
|
+
* Needs `UpdateCatalog`. Platform releases before this method do not have the mutation and refuse
|
|
94
|
+
* it as `ValidationError` `GRAPHQL_VALIDATION_FAILED` (400).
|
|
95
|
+
*
|
|
96
|
+
* Refusals (nothing is written), GraphQL errors mapped by `core`:
|
|
97
|
+
* - `PROPERTY_NOT_FOUND` → `NotFoundError` (404): no property with that id among this store's
|
|
98
|
+
* own (another store's included); `ENTITY_NOT_FOUND` (404) for an id that is not an id.
|
|
99
|
+
* - `PROPERTY_FACET_SYNC_INVALID` → `ValidationError` (400): the property is not filterable, or
|
|
100
|
+
* is neither a `content_item` nor a `product` property.
|
|
101
|
+
* - `MANAGED_BY_ORGANIZATION` → `BusinessRuleError` (422): a property of the store's
|
|
102
|
+
* organization workspace (`editableHere` false), or one whose filter values the workspace
|
|
103
|
+
* holds: sync it in the workspace.
|
|
104
|
+
* - `SHARED_FACET_NOT_ALLOWED` / `SHARED_PRODUCT_NOT_ALLOWED` → `PermissionDeniedError` (403):
|
|
105
|
+
* the property's filter, or a product it re-assigns, is also another store's, and you cannot
|
|
106
|
+
* change that store's catalogue.
|
|
107
|
+
* - `CMS_REQUEST_FAILED` → `BusinessRuleError` (422): the content system could not be read
|
|
108
|
+
* (unreachable, too slow, failing); try again.
|
|
109
|
+
* - `PROPERTY_SYNC_SOURCE_UNAVAILABLE` → `BusinessRuleError` (422): a `content_item` property on
|
|
110
|
+
* a platform with no content system wired.
|
|
111
|
+
* - `FORBIDDEN` → `PermissionDeniedError` (403): no `UpdateCatalog`.
|
|
112
|
+
*/
|
|
113
|
+
syncContentFacets(propertyId: string, options?: Call): Promise<ContentFacetSyncResult>;
|
|
114
|
+
}
|
|
115
|
+
export declare function createCatalogModule(transport: Transport): CatalogModule;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createAssetsModule } from './assets.js';
|
|
2
|
+
import { createCollectionsModule } from './collections.js';
|
|
3
|
+
import { createFacetsModule } from './facets.js';
|
|
4
|
+
import { createOptionsModule } from './options.js';
|
|
5
|
+
import { createProductsModule } from './products.js';
|
|
6
|
+
import { createPropertiesModule, syncContentFacets, } from './properties.js';
|
|
7
|
+
import { createVariantsModule } from './variants.js';
|
|
8
|
+
import { createVisibilityModule } from './visibility.js';
|
|
9
|
+
export function createCatalogModule(transport) {
|
|
10
|
+
return {
|
|
11
|
+
products: createProductsModule(transport),
|
|
12
|
+
variants: createVariantsModule(transport),
|
|
13
|
+
options: createOptionsModule(transport),
|
|
14
|
+
facets: createFacetsModule(transport),
|
|
15
|
+
collections: createCollectionsModule(transport),
|
|
16
|
+
assets: createAssetsModule(transport),
|
|
17
|
+
visibility: createVisibilityModule(transport),
|
|
18
|
+
properties: createPropertiesModule(transport),
|
|
19
|
+
syncContentFacets: (propertyId, options) => syncContentFacets(transport, propertyId, options),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Page, Transport } from '@sixtyninecommerce/core';
|
|
2
|
+
import type { Call, ListOptions } from '../types.js';
|
|
3
|
+
import { type CatalogueOwnership, type LanguageCode, type TranslationInput } from './types.js';
|
|
4
|
+
export interface ProductOption {
|
|
5
|
+
id: string;
|
|
6
|
+
code: string;
|
|
7
|
+
name: string;
|
|
8
|
+
groupId: string;
|
|
9
|
+
translations: Array<{
|
|
10
|
+
id: string;
|
|
11
|
+
languageCode: LanguageCode;
|
|
12
|
+
name: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
/** "Size", "Colour": what a product's variants differ by. */
|
|
16
|
+
export interface ProductOptionGroup {
|
|
17
|
+
id: string;
|
|
18
|
+
code: string;
|
|
19
|
+
name: string;
|
|
20
|
+
options: ProductOption[];
|
|
21
|
+
translations: Array<{
|
|
22
|
+
id: string;
|
|
23
|
+
languageCode: LanguageCode;
|
|
24
|
+
name: string;
|
|
25
|
+
}>;
|
|
26
|
+
/** The store's own option group, or its organization's; see {@link CatalogueOwnership}. */
|
|
27
|
+
catalogueOwnership: CatalogueOwnership;
|
|
28
|
+
}
|
|
29
|
+
export interface OptionTranslationInput extends TranslationInput {
|
|
30
|
+
name?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface CreateOptionGroupInput {
|
|
33
|
+
code: string;
|
|
34
|
+
translations: OptionTranslationInput[];
|
|
35
|
+
/** Created with the group, in this order. */
|
|
36
|
+
options?: Array<{
|
|
37
|
+
code: string;
|
|
38
|
+
translations: OptionTranslationInput[];
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
41
|
+
export interface UpdateOptionGroupInput {
|
|
42
|
+
id: string;
|
|
43
|
+
code?: string;
|
|
44
|
+
translations?: OptionTranslationInput[];
|
|
45
|
+
}
|
|
46
|
+
export interface CreateOptionInput {
|
|
47
|
+
productOptionGroupId: string;
|
|
48
|
+
code: string;
|
|
49
|
+
translations: OptionTranslationInput[];
|
|
50
|
+
}
|
|
51
|
+
export interface UpdateOptionInput {
|
|
52
|
+
id: string;
|
|
53
|
+
code?: string;
|
|
54
|
+
translations?: OptionTranslationInput[];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Option groups and their options. A group is attached to a product with
|
|
58
|
+
* `catalog.products.addOptionGroup`, and each variant then names one option per
|
|
59
|
+
* group (`optionIds`).
|
|
60
|
+
*
|
|
61
|
+
* Deletion refusals carry the engine's words: "Cannot delete the option group
|
|
62
|
+
* "{code}" as it is assigned to N Products" (unless `force`) and "Cannot delete
|
|
63
|
+
* the option "{code}" as it is being used by N ProductVariants" — both as
|
|
64
|
+
* `ConflictError` (`OPTION_GROUP_NOT_DELETED` / `OPTION_NOT_DELETED`).
|
|
65
|
+
*/
|
|
66
|
+
export interface OptionsModule {
|
|
67
|
+
groups: {
|
|
68
|
+
list(options?: ListOptions): Promise<Page<ProductOptionGroup>>;
|
|
69
|
+
get(id: string, options?: Call): Promise<ProductOptionGroup | null>;
|
|
70
|
+
create(input: CreateOptionGroupInput, options?: Call): Promise<ProductOptionGroup>;
|
|
71
|
+
update(input: UpdateOptionGroupInput, options?: Call): Promise<ProductOptionGroup>;
|
|
72
|
+
delete(id: string, options?: Call & {
|
|
73
|
+
force?: boolean;
|
|
74
|
+
}): Promise<void>;
|
|
75
|
+
};
|
|
76
|
+
create(input: CreateOptionInput, options?: Call): Promise<ProductOption>;
|
|
77
|
+
update(input: UpdateOptionInput, options?: Call): Promise<ProductOption>;
|
|
78
|
+
delete(id: string, options?: Call): Promise<void>;
|
|
79
|
+
}
|
|
80
|
+
export declare const OPTION_GROUP_FIELDS = "\n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n code\n name\n options { \n id\n code\n name\n groupId\n translations {\n id\n languageCode\n name\n }\n }\n translations {\n id\n languageCode\n name\n }\n";
|
|
81
|
+
export declare const OPTION_GROUPS_QUERY = "\n query CatalogOptionGroups($options: ProductOptionGroupListOptions) {\n productOptionGroups(options: $options) {\n items { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n code\n name\n options { \n id\n code\n name\n groupId\n translations {\n id\n languageCode\n name\n }\n }\n translations {\n id\n languageCode\n name\n }\n }\n totalItems\n }\n }\n";
|
|
82
|
+
export declare const OPTION_GROUP_QUERY = "\n query CatalogOptionGroup($id: ID!) {\n productOptionGroup(id: $id) { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n code\n name\n options { \n id\n code\n name\n groupId\n translations {\n id\n languageCode\n name\n }\n }\n translations {\n id\n languageCode\n name\n }\n }\n }\n";
|
|
83
|
+
export declare const CREATE_OPTION_GROUP_MUTATION = "\n mutation CatalogCreateOptionGroup($input: CreateProductOptionGroupInput!) {\n createProductOptionGroup(input: $input) { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n code\n name\n options { \n id\n code\n name\n groupId\n translations {\n id\n languageCode\n name\n }\n }\n translations {\n id\n languageCode\n name\n }\n }\n }\n";
|
|
84
|
+
export declare const UPDATE_OPTION_GROUP_MUTATION = "\n mutation CatalogUpdateOptionGroup($input: UpdateProductOptionGroupInput!) {\n updateProductOptionGroup(input: $input) { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n code\n name\n options { \n id\n code\n name\n groupId\n translations {\n id\n languageCode\n name\n }\n }\n translations {\n id\n languageCode\n name\n }\n }\n }\n";
|
|
85
|
+
export declare const DELETE_OPTION_GROUP_MUTATION = "\n mutation CatalogDeleteOptionGroup($id: ID!, $force: Boolean) {\n deleteProductOptionGroup(id: $id, force: $force) { \n result\n message\n }\n }\n";
|
|
86
|
+
export declare const CREATE_OPTION_MUTATION = "\n mutation CatalogCreateOption($input: CreateProductOptionInput!) {\n createProductOption(input: $input) { \n id\n code\n name\n groupId\n translations {\n id\n languageCode\n name\n }\n }\n }\n";
|
|
87
|
+
export declare const UPDATE_OPTION_MUTATION = "\n mutation CatalogUpdateOption($input: UpdateProductOptionInput!) {\n updateProductOption(input: $input) { \n id\n code\n name\n groupId\n translations {\n id\n languageCode\n name\n }\n }\n }\n";
|
|
88
|
+
export declare const DELETE_OPTION_MUTATION = "\n mutation CatalogDeleteOption($id: ID!) {\n deleteProductOption(id: $id) { \n result\n message\n }\n }\n";
|
|
89
|
+
export declare function createOptionsModule(transport: Transport): OptionsModule;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { assertDeleted, CATALOGUE_OWNERSHIP_FIELDS, DELETION_FIELDS, fieldOf, vendureListPage, } from './types.js';
|
|
2
|
+
const OPTION_FIELDS = /* GraphQL */ `
|
|
3
|
+
id
|
|
4
|
+
code
|
|
5
|
+
name
|
|
6
|
+
groupId
|
|
7
|
+
translations {
|
|
8
|
+
id
|
|
9
|
+
languageCode
|
|
10
|
+
name
|
|
11
|
+
}
|
|
12
|
+
`;
|
|
13
|
+
export const OPTION_GROUP_FIELDS = /* GraphQL */ `
|
|
14
|
+
id
|
|
15
|
+
${CATALOGUE_OWNERSHIP_FIELDS}
|
|
16
|
+
code
|
|
17
|
+
name
|
|
18
|
+
options { ${OPTION_FIELDS} }
|
|
19
|
+
translations {
|
|
20
|
+
id
|
|
21
|
+
languageCode
|
|
22
|
+
name
|
|
23
|
+
}
|
|
24
|
+
`;
|
|
25
|
+
export const OPTION_GROUPS_QUERY = /* GraphQL */ `
|
|
26
|
+
query CatalogOptionGroups($options: ProductOptionGroupListOptions) {
|
|
27
|
+
productOptionGroups(options: $options) {
|
|
28
|
+
items { ${OPTION_GROUP_FIELDS} }
|
|
29
|
+
totalItems
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
export const OPTION_GROUP_QUERY = /* GraphQL */ `
|
|
34
|
+
query CatalogOptionGroup($id: ID!) {
|
|
35
|
+
productOptionGroup(id: $id) { ${OPTION_GROUP_FIELDS} }
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
export const CREATE_OPTION_GROUP_MUTATION = /* GraphQL */ `
|
|
39
|
+
mutation CatalogCreateOptionGroup($input: CreateProductOptionGroupInput!) {
|
|
40
|
+
createProductOptionGroup(input: $input) { ${OPTION_GROUP_FIELDS} }
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
43
|
+
export const UPDATE_OPTION_GROUP_MUTATION = /* GraphQL */ `
|
|
44
|
+
mutation CatalogUpdateOptionGroup($input: UpdateProductOptionGroupInput!) {
|
|
45
|
+
updateProductOptionGroup(input: $input) { ${OPTION_GROUP_FIELDS} }
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
48
|
+
export const DELETE_OPTION_GROUP_MUTATION = /* GraphQL */ `
|
|
49
|
+
mutation CatalogDeleteOptionGroup($id: ID!, $force: Boolean) {
|
|
50
|
+
deleteProductOptionGroup(id: $id, force: $force) { ${DELETION_FIELDS} }
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
export const CREATE_OPTION_MUTATION = /* GraphQL */ `
|
|
54
|
+
mutation CatalogCreateOption($input: CreateProductOptionInput!) {
|
|
55
|
+
createProductOption(input: $input) { ${OPTION_FIELDS} }
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
export const UPDATE_OPTION_MUTATION = /* GraphQL */ `
|
|
59
|
+
mutation CatalogUpdateOption($input: UpdateProductOptionInput!) {
|
|
60
|
+
updateProductOption(input: $input) { ${OPTION_FIELDS} }
|
|
61
|
+
}
|
|
62
|
+
`;
|
|
63
|
+
export const DELETE_OPTION_MUTATION = /* GraphQL */ `
|
|
64
|
+
mutation CatalogDeleteOption($id: ID!) {
|
|
65
|
+
deleteProductOption(id: $id) { ${DELETION_FIELDS} }
|
|
66
|
+
}
|
|
67
|
+
`;
|
|
68
|
+
export function createOptionsModule(transport) {
|
|
69
|
+
const call = (document, field, variables, options) => fieldOf(transport, document, field, variables, options);
|
|
70
|
+
return {
|
|
71
|
+
groups: {
|
|
72
|
+
list: (options) => vendureListPage(transport, OPTION_GROUPS_QUERY, 'productOptionGroups', (skip, take) => ({ options: { skip, take } }), options),
|
|
73
|
+
get: (id, options) => call(OPTION_GROUP_QUERY, 'productOptionGroup', { id }, options),
|
|
74
|
+
create: (input, options) => call(CREATE_OPTION_GROUP_MUTATION, 'createProductOptionGroup', { input }, options),
|
|
75
|
+
update: (input, options) => call(UPDATE_OPTION_GROUP_MUTATION, 'updateProductOptionGroup', { input }, options),
|
|
76
|
+
async delete(id, options) {
|
|
77
|
+
const response = await call(DELETE_OPTION_GROUP_MUTATION, 'deleteProductOptionGroup', { id, force: options?.force ?? false }, options);
|
|
78
|
+
assertDeleted('OPTION_GROUP_NOT_DELETED', [response]);
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
create: (input, options) => call(CREATE_OPTION_MUTATION, 'createProductOption', { input }, options),
|
|
82
|
+
update: (input, options) => call(UPDATE_OPTION_MUTATION, 'updateProductOption', { input }, options),
|
|
83
|
+
async delete(id, options) {
|
|
84
|
+
const response = await call(DELETE_OPTION_MUTATION, 'deleteProductOption', { id }, options);
|
|
85
|
+
assertDeleted('OPTION_NOT_DELETED', [response]);
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Transport } from '@sixtyninecommerce/core';
|
|
2
|
+
import { type BulkActionRun } from '../jobs/bulk-action-run.js';
|
|
3
|
+
import type { JobHandle } from '../jobs/index.js';
|
|
4
|
+
import type { Call } from '../types.js';
|
|
5
|
+
/** What each product of one bulk run gets: switched on or off, deleted, or copied. */
|
|
6
|
+
export type ProductBulkAction = 'ENABLE' | 'DISABLE' | 'DELETE' | 'CLONE';
|
|
7
|
+
export declare const PRODUCT_BULK_ACTIONS: readonly ProductBulkAction[];
|
|
8
|
+
/** The engine's bound on one bulk run (`MAX_BULK_ACTION_ITEMS`). Split a larger selection. */
|
|
9
|
+
export declare const MAX_BULK_PRODUCTS = 50;
|
|
10
|
+
export interface ProductBulkInput {
|
|
11
|
+
action: ProductBulkAction;
|
|
12
|
+
/** 1 to {@link MAX_BULK_PRODUCTS} products of the store, each named once. */
|
|
13
|
+
productIds: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
/** A bulk product run, as `wait()` and `bulkRun()` answer it. */
|
|
16
|
+
export type ProductBulkRun = BulkActionRun<ProductBulkAction>;
|
|
17
|
+
export declare const BULK_PRODUCT_ACTION_MUTATION = "\n mutation BulkProductAction($input: BulkProductActionInput!, $idempotencyKey: String) {\n bulkProductAction(input: $input, idempotencyKey: $idempotencyKey) {\n runId\n }\n }\n";
|
|
18
|
+
/** `catalog.products.bulk`; see `ProductsModule.bulk`. */
|
|
19
|
+
export declare function bulkProducts(transport: Transport, input: ProductBulkInput, options?: Call): Promise<JobHandle<ProductBulkRun>>;
|
|
20
|
+
/** `catalog.products.bulkRun`; see `ProductsModule.bulkRun`. */
|
|
21
|
+
export declare function readProductBulkRun(transport: Transport, runId: string, options?: Call): Promise<ProductBulkRun>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { idempotencyKey, ValidationError } from '@sixtyninecommerce/core';
|
|
2
|
+
import { bulkActionHandle, readBulkActionRun, } from '../jobs/bulk-action-run.js';
|
|
3
|
+
import { fieldOf } from './types.js';
|
|
4
|
+
export const PRODUCT_BULK_ACTIONS = [
|
|
5
|
+
'ENABLE',
|
|
6
|
+
'DISABLE',
|
|
7
|
+
'DELETE',
|
|
8
|
+
'CLONE',
|
|
9
|
+
];
|
|
10
|
+
/** The engine's bound on one bulk run (`MAX_BULK_ACTION_ITEMS`). Split a larger selection. */
|
|
11
|
+
export const MAX_BULK_PRODUCTS = 50;
|
|
12
|
+
export const BULK_PRODUCT_ACTION_MUTATION = /* GraphQL */ `
|
|
13
|
+
mutation BulkProductAction($input: BulkProductActionInput!, $idempotencyKey: String) {
|
|
14
|
+
bulkProductAction(input: $input, idempotencyKey: $idempotencyKey) {
|
|
15
|
+
runId
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
`;
|
|
19
|
+
function refuse(message) {
|
|
20
|
+
return new ValidationError({
|
|
21
|
+
code: 'BULK_ACTION_INPUT_INVALID',
|
|
22
|
+
message,
|
|
23
|
+
status: 400,
|
|
24
|
+
service: 'vendure',
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** The engine's own checks of a submit (`BULK_ACTION_INPUT_INVALID`), before sending. */
|
|
28
|
+
function assertBulkInput(input) {
|
|
29
|
+
if (!PRODUCT_BULK_ACTIONS.includes(input?.action)) {
|
|
30
|
+
throw refuse(`"${String(input?.action)}" is not a bulk product action: ${PRODUCT_BULK_ACTIONS.join(', ')}. Nothing was sent.`);
|
|
31
|
+
}
|
|
32
|
+
const ids = input.productIds;
|
|
33
|
+
if (!Array.isArray(ids) || ids.length === 0) {
|
|
34
|
+
throw refuse('Name at least one product. Nothing was sent.');
|
|
35
|
+
}
|
|
36
|
+
if (ids.length > MAX_BULK_PRODUCTS) {
|
|
37
|
+
throw refuse(`Name at most ${String(MAX_BULK_PRODUCTS)} products in one bulk action; this one named ${String(ids.length)}. Split the selection into several actions. Nothing was sent.`);
|
|
38
|
+
}
|
|
39
|
+
if (new Set(ids.map((id) => String(id).toLowerCase())).size !== ids.length) {
|
|
40
|
+
throw refuse('The selection names a product more than once. Name each product once. Nothing was sent.');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** `catalog.products.bulk`; see `ProductsModule.bulk`. */
|
|
44
|
+
export async function bulkProducts(transport, input, options) {
|
|
45
|
+
assertBulkInput(input);
|
|
46
|
+
// Minted when the caller gave none, so a retry of THIS call by the transport or the caller's
|
|
47
|
+
// own code under the same options answers the same run instead of starting a second one.
|
|
48
|
+
const key = options?.idempotencyKey ?? idempotencyKey();
|
|
49
|
+
const { runId } = await fieldOf(transport, BULK_PRODUCT_ACTION_MUTATION, 'bulkProductAction', {
|
|
50
|
+
input: { action: input.action, productIds: [...input.productIds] },
|
|
51
|
+
idempotencyKey: key,
|
|
52
|
+
}, { ...options, idempotencyKey: key });
|
|
53
|
+
return bulkActionHandle(transport, runId, options);
|
|
54
|
+
}
|
|
55
|
+
/** `catalog.products.bulkRun`; see `ProductsModule.bulkRun`. */
|
|
56
|
+
export function readProductBulkRun(transport, runId, options) {
|
|
57
|
+
return readBulkActionRun(transport, runId, options);
|
|
58
|
+
}
|