@propeller-commerce/propeller-sdk-v2 0.16.0 → 0.18.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 CHANGED
@@ -3,6 +3,82 @@
3
3
  All notable changes to `@propeller-commerce/propeller-sdk-v2` are documented here.
4
4
 
5
5
  ---
6
+ ## [0.18.0] - 2026-09-24
7
+
8
+ `product` and `cluster` can now be scoped to a contact and a company, so a
9
+ storefront can ask the assortment question the API was always able to answer.
10
+
11
+ ### Added
12
+
13
+ - **`userId` and `companyId` on the `product` and `cluster` queries.** Both
14
+ arguments have always existed on the schema — the generated operations simply
15
+ did not declare or forward them, so there was no way to reach them through the
16
+ SDK and every call resolved against the bearer token's own identity.
17
+
18
+ This is what left a direct link to a product outside the company's POSITIVE
19
+ orderlist opening normally while listings and search correctly hid it: the
20
+ listing queries scope by identity, the single-entity ones could not. With the
21
+ arguments in place, `product(productId:, userId:, companyId:)` answers
22
+ `PRODUCT_NOT_FOUND` for a product outside the contact's assortment, which is
23
+ the correct answer and what a host needs in order to 404 the page. (PWP-1015)
24
+
25
+ Both are optional and default to undefined, so every existing call is
26
+ unchanged.
27
+
28
+ ### Notes for consumers
29
+
30
+ - The API rejects a `companyId` the contact does not belong to ("Unauthorized
31
+ use of companyId"), so a company restored from storage must be validated
32
+ against the contact's companies before it is sent.
33
+ - Three adjacent gaps were found while checking this and are deliberately NOT
34
+ in this release, because each is a behaviour change rather than an additive
35
+ argument: `product`/`cluster` also accept `hidden`, `clusterConfig` forwards
36
+ only `clusterId` (so it is not identity-scoped either), and
37
+ `orderGetPDF`/`quoteGetPDF` accept a `revisionNumber`. Say the word and they
38
+ can go in one follow-up rather than three.
39
+
40
+ ---
41
+
42
+
43
+ ## [0.17.0] - 2026-09-23
44
+
45
+ Spare-parts machine fields come back in every language the tenant authored,
46
+ instead of only the one the query asked for.
47
+
48
+ ### Changed
49
+
50
+ - **`SparePartsMachineMinimalFields` no longer passes `(language: $language)`
51
+ to `name`, `description` and `slug`.** The field argument narrowed each of
52
+ them to a single language, which defeated the cross-language fallback every
53
+ consumer implements (`getLocalizedValue` returns the first non-empty entry).
54
+ A machine authored without a slug in the tree language came back with an
55
+ empty `slug`, the UI could not build an href, and the row was dropped from
56
+ the list entirely — a customer saw three of four machines with nothing saying
57
+ so (PWP-993).
58
+
59
+ The query-level `machine(… language: $language)` argument is untouched: it
60
+ still selects the tree. Only the per-node localized fields widen.
61
+
62
+ Affects `machine`, `machines`, `machineCreate` and `machineUpsert`. All four
63
+ keep `$language` — `MediaImageFields.alt(language: $language)` still
64
+ references it — so no operation is left with an unused variable.
65
+
66
+ **Consumers that assumed `name[0]` is the requested language must resolve by
67
+ language instead.** `getLocalizedValue` / `getLanguageString` in core-ui
68
+ already do, so react-ui and vue-ui needed no change.
69
+
70
+ Verified against a tenant whose machines are authored EN-only, where both
71
+ forms return one entry; the multilingual path follows the behaviour recorded
72
+ in PWP-1010(b) and still wants confirming on a multilingual tenant.
73
+
74
+ ### Documentation
75
+
76
+ - **`sum` / `sumNet` on `CartMainItem`, `CartBaseItem` and `TenderMainItem` now
77
+ lead with the warning that they are PER UOM, not line totals**, and point at
78
+ `totalSum` / `totalSumNet`. The description was always accurate but the name
79
+ reads like a line total, so `items.reduce((a, l) => a + l.sum, 0)` looks
80
+ right, compiles green, and returns a number that is wrong by a factor of the
81
+ quantity — a 30-piece line at €15.09 produced €15.09 (PWP-1006).
6
82
 
7
83
  ## [0.16.0] - 2026-08-04
8
84
 
@@ -1798,6 +1798,8 @@ export interface ClusterVariables {
1798
1798
  language?: string;
1799
1799
  applyOrderlists?: boolean;
1800
1800
  orderlistIds?: number[];
1801
+ userId?: number;
1802
+ companyId?: number;
1801
1803
  priceCalculateProductInput?: PriceCalculateProductInput;
1802
1804
  userBulkPriceProductInput?: UserBulkPriceProductInput;
1803
1805
  attributeResultSearchInput?: AttributeResultSearchInput;
@@ -3820,6 +3822,8 @@ export interface ProductVariables {
3820
3822
  language?: string;
3821
3823
  applyOrderlists?: boolean;
3822
3824
  orderlistIds?: number[];
3825
+ userId?: number;
3826
+ companyId?: number;
3823
3827
  priceCalculateProductInput?: PriceCalculateProductInput;
3824
3828
  userBulkPriceProductInput?: UserBulkPriceProductInput;
3825
3829
  attributeResultSearchInput?: AttributeResultSearchInput;
@@ -842,13 +842,15 @@ fragment ClusterConfigSettingFields on ClusterConfigSetting {
842
842
  priority
843
843
  }
844
844
 
845
- query cluster(\$clusterId: Int, \$slug: String, \$language: String, \$applyOrderlists: Boolean, \$orderlistIds: [Int!], \$priceCalculateProductInput: PriceCalculateProductInput, \$userBulkPriceProductInput: UserBulkPriceProductInput, \$attributeResultSearchInput: AttributeResultSearchInput, \$imageSearchFilters: MediaImageProductSearchInput, \$mediaVideoSearchInput: MediaVideoProductSearchInput, \$mediaDocumentSearchInput: MediaDocumentProductSearchInput, \$imageVariantFilters: TransformationsInput!) {
845
+ query cluster(\$clusterId: Int, \$slug: String, \$language: String, \$applyOrderlists: Boolean, \$orderlistIds: [Int!], \$userId: Int, \$companyId: Int, \$priceCalculateProductInput: PriceCalculateProductInput, \$userBulkPriceProductInput: UserBulkPriceProductInput, \$attributeResultSearchInput: AttributeResultSearchInput, \$imageSearchFilters: MediaImageProductSearchInput, \$mediaVideoSearchInput: MediaVideoProductSearchInput, \$mediaDocumentSearchInput: MediaDocumentProductSearchInput, \$imageVariantFilters: TransformationsInput!) {
846
846
  cluster(
847
847
  clusterId: \$clusterId
848
848
  slug: \$slug
849
849
  language: \$language
850
850
  applyOrderlists: \$applyOrderlists
851
851
  orderlistIds: \$orderlistIds
852
+ userId: \$userId
853
+ companyId: \$companyId
852
854
  ) {
853
855
  ...ClusterFields
854
856
  }
@@ -17,13 +17,13 @@ fragment SparePartsMachineMinimalFields on SparePartsMachine {
17
17
  media {
18
18
  ...SparePartsMachineMediaImagesOnlyFields
19
19
  }
20
- name(language: \$language) {
20
+ name {
21
21
  ...LocalizedStringFields
22
22
  }
23
- description(language: \$language) {
23
+ description {
24
24
  ...LocalizedStringFields
25
25
  }
26
- slug(language: \$language) {
26
+ slug {
27
27
  ...LocalizedStringFields
28
28
  }
29
29
  }
@@ -17,13 +17,13 @@ fragment SparePartsMachineMinimalFields on SparePartsMachine {
17
17
  media {
18
18
  ...SparePartsMachineMediaImagesOnlyFields
19
19
  }
20
- name(language: \$language) {
20
+ name {
21
21
  ...LocalizedStringFields
22
22
  }
23
- description(language: \$language) {
23
+ description {
24
24
  ...LocalizedStringFields
25
25
  }
26
- slug(language: \$language) {
26
+ slug {
27
27
  ...LocalizedStringFields
28
28
  }
29
29
  }
@@ -17,13 +17,13 @@ fragment SparePartsMachineMinimalFields on SparePartsMachine {
17
17
  media {
18
18
  ...SparePartsMachineMediaImagesOnlyFields
19
19
  }
20
- name(language: \$language) {
20
+ name {
21
21
  ...LocalizedStringFields
22
22
  }
23
- description(language: \$language) {
23
+ description {
24
24
  ...LocalizedStringFields
25
25
  }
26
- slug(language: \$language) {
26
+ slug {
27
27
  ...LocalizedStringFields
28
28
  }
29
29
  }
@@ -29,13 +29,13 @@ fragment SparePartsMachineMinimalFields on SparePartsMachine {
29
29
  media {
30
30
  ...SparePartsMachineMediaImagesOnlyFields
31
31
  }
32
- name(language: \$language) {
32
+ name {
33
33
  ...LocalizedStringFields
34
34
  }
35
- description(language: \$language) {
35
+ description {
36
36
  ...LocalizedStringFields
37
37
  }
38
- slug(language: \$language) {
38
+ slug {
39
39
  ...LocalizedStringFields
40
40
  }
41
41
  }
@@ -712,7 +712,7 @@ fragment SurchargeFields on Surcharge {
712
712
  validTo
713
713
  }
714
714
 
715
- query product(\$productId: Int, \$slug: String, \$sku: String, \$language: String, \$applyOrderlists: Boolean, \$orderlistIds: [Int!], \$priceCalculateProductInput: PriceCalculateProductInput, \$userBulkPriceProductInput: UserBulkPriceProductInput, \$attributeResultSearchInput: AttributeResultSearchInput, \$imageSearchFilters: MediaImageProductSearchInput, \$mediaVideoSearchInput: MediaVideoProductSearchInput, \$mediaDocumentSearchInput: MediaDocumentProductSearchInput, \$imageVariantFilters: TransformationsInput!) {
715
+ query product(\$productId: Int, \$slug: String, \$sku: String, \$language: String, \$applyOrderlists: Boolean, \$orderlistIds: [Int!], \$userId: Int, \$companyId: Int, \$priceCalculateProductInput: PriceCalculateProductInput, \$userBulkPriceProductInput: UserBulkPriceProductInput, \$attributeResultSearchInput: AttributeResultSearchInput, \$imageSearchFilters: MediaImageProductSearchInput, \$mediaVideoSearchInput: MediaVideoProductSearchInput, \$mediaDocumentSearchInput: MediaDocumentProductSearchInput, \$imageVariantFilters: TransformationsInput!) {
716
716
  product(
717
717
  productId: \$productId
718
718
  slug: \$slug
@@ -720,6 +720,8 @@ query product(\$productId: Int, \$slug: String, \$sku: String, \$language: Strin
720
720
  language: \$language
721
721
  applyOrderlists: \$applyOrderlists
722
722
  orderlistIds: \$orderlistIds
723
+ userId: \$userId
724
+ companyId: \$companyId
723
725
  ) {
724
726
  ...ProductFields
725
727
  }
@@ -24,9 +24,20 @@ export interface CartBaseItem extends ICartBaseItem {
24
24
  totalPrice: number;
25
25
  /** Total net price for this cart item, including item specific discounts. */
26
26
  totalPriceNet: number;
27
- /** Gross sum of the main cart price and the prices of its child items per UOM. No item specific discounts are applied to this price. */
27
+ /**
28
+ * PER UOM, *not* the line total — despite the name. Gross sum of the main
29
+ * price and the prices of its child items, for ONE unit, with no item
30
+ * specific discounts applied.
31
+ *
32
+ * For the line total use {@link totalSum}. Summing `sum` across a cart
33
+ * under-reports every line by a factor of its quantity, and does it silently:
34
+ * the result is a plausible number and the types are green.
35
+ */
28
36
  sum: number;
29
- /** Net sum of the main cart price and the prices of its child items per UOM. No item specific discounts are applied to this price. */
37
+ /**
38
+ * PER UOM, *not* the line total — see {@link sum}. For the line total use
39
+ * {@link totalSumNet}.
40
+ */
30
41
  sumNet: number;
31
42
  /** Total gross sum of the main cart price and the prices of its child items. Including item specific discounts. */
32
43
  totalSum: number;
@@ -32,9 +32,20 @@ export interface CartMainItem extends ICartBaseItem {
32
32
  totalPrice: number;
33
33
  /** Total net price for this cart item, including item specific discounts. */
34
34
  totalPriceNet: number;
35
- /** Gross sum of the main cart price and the prices of its child items per UOM. No item specific discounts are applied to this price. */
35
+ /**
36
+ * PER UOM, *not* the line total — despite the name. Gross sum of the main
37
+ * price and the prices of its child items, for ONE unit, with no item
38
+ * specific discounts applied.
39
+ *
40
+ * For the line total use {@link totalSum}. Summing `sum` across a cart
41
+ * under-reports every line by a factor of its quantity, and does it silently:
42
+ * the result is a plausible number and the types are green.
43
+ */
36
44
  sum: number;
37
- /** Net sum of the main cart price and the prices of its child items per UOM. No item specific discounts are applied to this price. */
45
+ /**
46
+ * PER UOM, *not* the line total — see {@link sum}. For the line total use
47
+ * {@link totalSumNet}.
48
+ */
38
49
  sumNet: number;
39
50
  /** Total gross sum of the main cart price and the prices of its child items. Including item specific discounts. */
40
51
  totalSum: number;
@@ -75,9 +75,20 @@ export interface TenderMainItem extends ITenderBaseItem {
75
75
  surcharges?: TenderItemSurcharge[];
76
76
  /** The tender/order item's child items. E.g. surcharges, incentives, etc. */
77
77
  childItems?: ITenderBaseItem[];
78
- /** The gross price per UOM of this tender/order item, with item specific incentives and extra costs applied to this price. VAT excluding */
78
+ /**
79
+ * PER UOM, *not* the line total — despite the name. The gross price for ONE
80
+ * unit of this tender/order item, with item specific incentives and extra
81
+ * costs applied. VAT EXCLUDING (this API labels the ex-VAT figure "gross").
82
+ *
83
+ * For the line total use {@link totalSum}. Summing `sum` across the items
84
+ * under-reports every line by a factor of its quantity, and does it silently:
85
+ * the result is a plausible number and the types are green (PWP-1006).
86
+ */
79
87
  sum: number;
80
- /** The price per UOM of this tender/order item, with item specific incentives and extra costs applied to this price. VAT including */
88
+ /**
89
+ * PER UOM, *not* the line total — see {@link sum}. VAT INCLUDING. For the
90
+ * line total use {@link totalSumNet}.
91
+ */
81
92
  sumNet: number;
82
93
  /** The total gross price of this tender/order item, with item specific incentives and extra costs applied to this price. VAT excluding */
83
94
  totalSum: number;
@@ -839,13 +839,15 @@ fragment ClusterConfigSettingFields on ClusterConfigSetting {
839
839
  priority
840
840
  }
841
841
 
842
- query cluster(\$clusterId: Int, \$slug: String, \$language: String, \$applyOrderlists: Boolean, \$orderlistIds: [Int!], \$priceCalculateProductInput: PriceCalculateProductInput, \$userBulkPriceProductInput: UserBulkPriceProductInput, \$attributeResultSearchInput: AttributeResultSearchInput, \$imageSearchFilters: MediaImageProductSearchInput, \$mediaVideoSearchInput: MediaVideoProductSearchInput, \$mediaDocumentSearchInput: MediaDocumentProductSearchInput, \$imageVariantFilters: TransformationsInput!) {
842
+ query cluster(\$clusterId: Int, \$slug: String, \$language: String, \$applyOrderlists: Boolean, \$orderlistIds: [Int!], \$userId: Int, \$companyId: Int, \$priceCalculateProductInput: PriceCalculateProductInput, \$userBulkPriceProductInput: UserBulkPriceProductInput, \$attributeResultSearchInput: AttributeResultSearchInput, \$imageSearchFilters: MediaImageProductSearchInput, \$mediaVideoSearchInput: MediaVideoProductSearchInput, \$mediaDocumentSearchInput: MediaDocumentProductSearchInput, \$imageVariantFilters: TransformationsInput!) {
843
843
  cluster(
844
844
  clusterId: \$clusterId
845
845
  slug: \$slug
846
846
  language: \$language
847
847
  applyOrderlists: \$applyOrderlists
848
848
  orderlistIds: \$orderlistIds
849
+ userId: \$userId
850
+ companyId: \$companyId
849
851
  ) {
850
852
  ...ClusterFields
851
853
  }
@@ -14,13 +14,13 @@ fragment SparePartsMachineMinimalFields on SparePartsMachine {
14
14
  media {
15
15
  ...SparePartsMachineMediaImagesOnlyFields
16
16
  }
17
- name(language: \$language) {
17
+ name {
18
18
  ...LocalizedStringFields
19
19
  }
20
- description(language: \$language) {
20
+ description {
21
21
  ...LocalizedStringFields
22
22
  }
23
- slug(language: \$language) {
23
+ slug {
24
24
  ...LocalizedStringFields
25
25
  }
26
26
  }
@@ -14,13 +14,13 @@ fragment SparePartsMachineMinimalFields on SparePartsMachine {
14
14
  media {
15
15
  ...SparePartsMachineMediaImagesOnlyFields
16
16
  }
17
- name(language: \$language) {
17
+ name {
18
18
  ...LocalizedStringFields
19
19
  }
20
- description(language: \$language) {
20
+ description {
21
21
  ...LocalizedStringFields
22
22
  }
23
- slug(language: \$language) {
23
+ slug {
24
24
  ...LocalizedStringFields
25
25
  }
26
26
  }
@@ -14,13 +14,13 @@ fragment SparePartsMachineMinimalFields on SparePartsMachine {
14
14
  media {
15
15
  ...SparePartsMachineMediaImagesOnlyFields
16
16
  }
17
- name(language: \$language) {
17
+ name {
18
18
  ...LocalizedStringFields
19
19
  }
20
- description(language: \$language) {
20
+ description {
21
21
  ...LocalizedStringFields
22
22
  }
23
- slug(language: \$language) {
23
+ slug {
24
24
  ...LocalizedStringFields
25
25
  }
26
26
  }
@@ -26,13 +26,13 @@ fragment SparePartsMachineMinimalFields on SparePartsMachine {
26
26
  media {
27
27
  ...SparePartsMachineMediaImagesOnlyFields
28
28
  }
29
- name(language: \$language) {
29
+ name {
30
30
  ...LocalizedStringFields
31
31
  }
32
- description(language: \$language) {
32
+ description {
33
33
  ...LocalizedStringFields
34
34
  }
35
- slug(language: \$language) {
35
+ slug {
36
36
  ...LocalizedStringFields
37
37
  }
38
38
  }
@@ -709,7 +709,7 @@ fragment SurchargeFields on Surcharge {
709
709
  validTo
710
710
  }
711
711
 
712
- query product(\$productId: Int, \$slug: String, \$sku: String, \$language: String, \$applyOrderlists: Boolean, \$orderlistIds: [Int!], \$priceCalculateProductInput: PriceCalculateProductInput, \$userBulkPriceProductInput: UserBulkPriceProductInput, \$attributeResultSearchInput: AttributeResultSearchInput, \$imageSearchFilters: MediaImageProductSearchInput, \$mediaVideoSearchInput: MediaVideoProductSearchInput, \$mediaDocumentSearchInput: MediaDocumentProductSearchInput, \$imageVariantFilters: TransformationsInput!) {
712
+ query product(\$productId: Int, \$slug: String, \$sku: String, \$language: String, \$applyOrderlists: Boolean, \$orderlistIds: [Int!], \$userId: Int, \$companyId: Int, \$priceCalculateProductInput: PriceCalculateProductInput, \$userBulkPriceProductInput: UserBulkPriceProductInput, \$attributeResultSearchInput: AttributeResultSearchInput, \$imageSearchFilters: MediaImageProductSearchInput, \$mediaVideoSearchInput: MediaVideoProductSearchInput, \$mediaDocumentSearchInput: MediaDocumentProductSearchInput, \$imageVariantFilters: TransformationsInput!) {
713
713
  product(
714
714
  productId: \$productId
715
715
  slug: \$slug
@@ -717,6 +717,8 @@ query product(\$productId: Int, \$slug: String, \$sku: String, \$language: Strin
717
717
  language: \$language
718
718
  applyOrderlists: \$applyOrderlists
719
719
  orderlistIds: \$orderlistIds
720
+ userId: \$userId
721
+ companyId: \$companyId
720
722
  ) {
721
723
  ...ProductFields
722
724
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@propeller-commerce/propeller-sdk-v2",
3
- "version": "0.16.0",
3
+ "version": "0.18.0",
4
4
  "description": "TypeScript GraphQL client for Propeller eCommerce V2 Platform - works with React, Vue, Angular and all JavaScript frameworks",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",