@commercelayer/provisioning-sdk 1.0.0-beta.1

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.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +415 -0
  3. package/lib/cjs/api.d.ts +41 -0
  4. package/lib/cjs/api.js +37 -0
  5. package/lib/cjs/client.d.ts +39 -0
  6. package/lib/cjs/client.js +121 -0
  7. package/lib/cjs/commercelayer.d.ts +36 -0
  8. package/lib/cjs/commercelayer.js +126 -0
  9. package/lib/cjs/common.d.ts +5 -0
  10. package/lib/cjs/common.js +12 -0
  11. package/lib/cjs/config.d.ts +12 -0
  12. package/lib/cjs/config.js +16 -0
  13. package/lib/cjs/debug.d.ts +3 -0
  14. package/lib/cjs/debug.js +38 -0
  15. package/lib/cjs/error.d.ts +31 -0
  16. package/lib/cjs/error.js +77 -0
  17. package/lib/cjs/index.d.ts +7 -0
  18. package/lib/cjs/index.js +13 -0
  19. package/lib/cjs/interceptor.d.ts +25 -0
  20. package/lib/cjs/interceptor.js +2 -0
  21. package/lib/cjs/jsonapi.d.ts +5 -0
  22. package/lib/cjs/jsonapi.js +89 -0
  23. package/lib/cjs/model.d.ts +10 -0
  24. package/lib/cjs/model.js +3 -0
  25. package/lib/cjs/query.d.ts +17 -0
  26. package/lib/cjs/query.js +52 -0
  27. package/lib/cjs/resource.d.ts +86 -0
  28. package/lib/cjs/resource.js +191 -0
  29. package/lib/cjs/resources/api_credentials.d.ts +55 -0
  30. package/lib/cjs/resources/api_credentials.js +33 -0
  31. package/lib/cjs/resources/memberships.d.ts +46 -0
  32. package/lib/cjs/resources/memberships.js +37 -0
  33. package/lib/cjs/resources/organizations.d.ts +78 -0
  34. package/lib/cjs/resources/organizations.js +34 -0
  35. package/lib/cjs/resources/permissions.d.ts +52 -0
  36. package/lib/cjs/resources/permissions.js +34 -0
  37. package/lib/cjs/resources/roles.d.ts +47 -0
  38. package/lib/cjs/resources/roles.js +42 -0
  39. package/lib/cjs/resources/user.d.ts +29 -0
  40. package/lib/cjs/resources/user.js +19 -0
  41. package/lib/cjs/resources/versions.d.ts +22 -0
  42. package/lib/cjs/resources/versions.js +16 -0
  43. package/lib/cjs/static.d.ts +9 -0
  44. package/lib/cjs/static.js +45 -0
  45. package/lib/cjs/util.d.ts +9 -0
  46. package/lib/cjs/util.js +15 -0
  47. package/lib/esm/api.d.ts +41 -0
  48. package/lib/esm/api.js +24 -0
  49. package/lib/esm/client.d.ts +39 -0
  50. package/lib/esm/client.js +116 -0
  51. package/lib/esm/commercelayer.d.ts +36 -0
  52. package/lib/esm/commercelayer.js +97 -0
  53. package/lib/esm/common.d.ts +5 -0
  54. package/lib/esm/common.js +8 -0
  55. package/lib/esm/config.d.ts +12 -0
  56. package/lib/esm/config.js +14 -0
  57. package/lib/esm/debug.d.ts +3 -0
  58. package/lib/esm/debug.js +36 -0
  59. package/lib/esm/error.d.ts +31 -0
  60. package/lib/esm/error.js +69 -0
  61. package/lib/esm/index.d.ts +7 -0
  62. package/lib/esm/index.js +4 -0
  63. package/lib/esm/interceptor.d.ts +25 -0
  64. package/lib/esm/interceptor.js +1 -0
  65. package/lib/esm/jsonapi.d.ts +5 -0
  66. package/lib/esm/jsonapi.js +82 -0
  67. package/lib/esm/model.d.ts +10 -0
  68. package/lib/esm/model.js +2 -0
  69. package/lib/esm/query.d.ts +17 -0
  70. package/lib/esm/query.js +45 -0
  71. package/lib/esm/resource.d.ts +86 -0
  72. package/lib/esm/resource.js +184 -0
  73. package/lib/esm/resources/api_credentials.d.ts +55 -0
  74. package/lib/esm/resources/api_credentials.js +31 -0
  75. package/lib/esm/resources/memberships.d.ts +46 -0
  76. package/lib/esm/resources/memberships.js +35 -0
  77. package/lib/esm/resources/organizations.d.ts +78 -0
  78. package/lib/esm/resources/organizations.js +32 -0
  79. package/lib/esm/resources/permissions.d.ts +52 -0
  80. package/lib/esm/resources/permissions.js +32 -0
  81. package/lib/esm/resources/roles.d.ts +47 -0
  82. package/lib/esm/resources/roles.js +40 -0
  83. package/lib/esm/resources/user.d.ts +29 -0
  84. package/lib/esm/resources/user.js +17 -0
  85. package/lib/esm/resources/versions.d.ts +22 -0
  86. package/lib/esm/resources/versions.js +14 -0
  87. package/lib/esm/static.d.ts +9 -0
  88. package/lib/esm/static.js +19 -0
  89. package/lib/esm/util.d.ts +9 -0
  90. package/lib/esm/util.js +11 -0
  91. package/lib/tsconfig.esm.tsbuildinfo +1 -0
  92. package/lib/tsconfig.tsbuildinfo +1 -0
  93. package/package.json +69 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) [2023] [Commerce Layer]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,415 @@
1
+ # Commerce Layer Provisioning SDK
2
+
3
+ [![Version](https://img.shields.io/npm/v/@commercelayer/sdk.svg)](https://npmjs.org/package/@commercelayer/sdk)
4
+ [![Downloads/week](https://img.shields.io/npm/dw/@commercelayer/sdk.svg)](https://npmjs.org/package/@commercelayer/sdk)
5
+ [![License](https://img.shields.io/npm/l/@commercelayer/sdk.svg)](https://github.com/commercelayer/commercelayer-sdk/blob/master/package.json)
6
+ [![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release)
7
+ [![Release](https://github.com/commercelayer/commercelayer-sdk/actions/workflows/semantic-release.yml/badge.svg)](https://github.com/commercelayer/commercelayer-sdk/actions/workflows/semantic-release.yml)
8
+ [![CodeQL](https://github.com/commercelayer/commercelayer-cli/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/commercelayer/commercelayer-cli/actions/workflows/codeql-analysis.yml)
9
+ [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript%205-%230074c1.svg)](https://www.typescriptlang.org/)
10
+
11
+ A JavaScript Library wrapper that makes it quick and easy to interact with the [Commerce Layer API](https://docs.commercelayer.io/developers).
12
+
13
+ ## What is Commerce Layer?
14
+
15
+ [Commerce Layer](https://commercelayer.io) is a multi-market commerce API and order management system that lets you add global shopping capabilities to any website, mobile app, chatbot, wearable, voice, or IoT device, with ease. Compose your stack with the best-of-breed tools you already mastered and love. Make any experience shoppable, anywhere, through a blazing-fast, enterprise-grade, and secure API.
16
+
17
+ ## Table of contents
18
+
19
+ - [Getting started](#getting-started)
20
+ - [Installation](#installation)
21
+ - [Authentication](#authentication)
22
+ - [Import](#import)
23
+ - [SDK usage](#sdk-usage)
24
+ - [Overriding credentials](#overriding-credentials)
25
+ - [Handling validation errors](#handling-validation-errors)
26
+ - [Contributors guide](#contributors-guide)
27
+ - [Need help?](#need-help)
28
+ - [License](#license)
29
+
30
+ ---
31
+
32
+ ## Getting started
33
+
34
+ To get started with Commerce Layer JS SDK you need to install it, get the credentials that will allow you to perform your API calls, and import the SDK into your application's code. The sections below explain how to achieve this.
35
+
36
+ > If you want, you can also read [this tutorial](https://commercelayer.io/blog/getting-started-with-commerce-layer-javascript-sdk) from Commerce Layer's blog.
37
+
38
+ ### Installation
39
+
40
+ Commerce Layer JS SDK is available as an [npm](https://www.npmjs.com/package/@commercelayer/sdk) and [yarn](https://yarnpkg.com/package/@commercelayer/sdk) package that you can install with the command below:
41
+
42
+ ```shell
43
+ npm install @commercelayer/sdk
44
+
45
+ // or
46
+
47
+ yarn add @commercelayer/sdk
48
+ ```
49
+
50
+ ### Authentication
51
+
52
+ All requests to Commerce Layer API must be authenticated with an [OAuth2](https://oauth.net/2) bearer token. Hence, before starting to use this SDK you need to get a valid access token. Kindly check [our documentation](https://docs.commercelayer.io/developers/authentication) for more information about the available authorization flows.
53
+
54
+ > Feel free to use [Commerce Layer JS Auth](https://github.com/commercelayer/commercelayer-js-auth), a JavaScript library that helps you wrap our authentication API.
55
+
56
+ ### Import
57
+
58
+ You can use the ES6 default import with the SDK like so:
59
+
60
+ ```javascript
61
+ import CommerceLayer from '@commercelayer/sdk'
62
+
63
+ const cl = CommerceLayer({
64
+ organization: 'your-organization-slug',
65
+ accessToken: 'your-access-token'
66
+ })
67
+ ```
68
+
69
+ ## SDK usage
70
+
71
+ The JavaScript SDK is a wrapper around Commerce Layer API which means you would still be making API requests but with a different syntax. For now, we don't have comprehensive SDK documentation for every single resource our API supports (about 400+ endpoints), hence you will need to rely on our comprehensive [API Reference](https://docs.commercelayer.io/core/v/api-reference) as you go about using this SDK. So for example, if you want to create an order, take a look at the [Order object](https://docs.commercelayer.io/core/v/api-reference/orders/object) or the [Create an order](https://docs.commercelayer.io/core/v/api-reference/orders/create) documentation to see the required attributes and/or relationships. The same goes for every other supported resource.
72
+
73
+ To show you how things work, we will use the [SKUs](https://docs.commercelayer.io/core/v/api-reference/skus) and [Shipping Categories](https://docs.commercelayer.io/core/v/api-reference/shipping_categories) resource in the following examples. The code snippets below show how to use the SDK when performing the standard CRUD operations provided by our REST API. Kindly check our [API reference](https://docs.commercelayer.io/core/v/api-reference) for the complete list of available **resources** and their **attributes**.
74
+
75
+ ### Create
76
+
77
+ <details>
78
+ <summary>How to create an SKU</summary>
79
+ <br />
80
+
81
+ ```javascript
82
+ // Select the shipping category (it's a required relationship for the SKU resource)
83
+ const shippingCategories = await cl.shipping_categories.list({ filters: { name_eq: 'Merchandising' } })
84
+
85
+ const attributes = {
86
+ code: 'TSHIRTMM000000FFFFFFXL',
87
+ name: 'Black Men T-shirt with White Logo (XL)',
88
+ description: "A very beautiful and cozy mens t-shirt",
89
+ weight: "500",
90
+ unit_of_weight: "gr"
91
+ shipping_category: cl.shipping_categories.relationship(shippingCategories[0].id), // assigns the relationship
92
+ }
93
+
94
+ const newSku = await cl.skus.create(attributes)
95
+ ```
96
+
97
+ ℹ️ Check our API reference for more information on how to [create an SKU](https://docs.commercelayer.io/developers/v/api-reference/skus/create).
98
+ </details>
99
+
100
+ ### Retrieve / List
101
+
102
+ <details>
103
+ <summary>How to fetch a single SKU</summary>
104
+ <br />
105
+
106
+ ```javascript
107
+ // Fetch the SKU by ID
108
+ const sku = await cl.skus.retrieve('BxAkSVqKEn')
109
+
110
+ // Fetch all SKUs and filter by code
111
+ const sku = await cl.skus.list({ filters: { code_eq: 'TSHIRTMM000000FFFFFFXLXX' } })
112
+
113
+ // Fetch the first SKU of the list
114
+ const sku = (await cl.skus.list()).first()
115
+
116
+ // Fetch the last SKU of the list
117
+ const sku = (await cl.skus.list()).last()
118
+ ```
119
+
120
+ ℹ️ Check our API reference for more information on how to [retrieve an SKU](https://docs.commercelayer.io/developers/v/api-reference/skus/retrieve).
121
+ </details>
122
+
123
+ <details>
124
+ <summary>How to fetch a collection of SKUs</summary>
125
+ <br />
126
+
127
+ ```javascript
128
+ // Fetch all the SKUs
129
+ const skus = await cl.skus.list()
130
+ ```
131
+
132
+ When fetching a collection of resources you can leverage the `meta` attribute to get its `meta` information like so:
133
+
134
+ ```javascript
135
+ const skus = await cl.skus.list()
136
+ const meta = skus.meta
137
+ ```
138
+
139
+ ℹ️ Check our API reference for more information on how to [list all SKUs](https://docs.commercelayer.io/developers/v/api-reference/skus/list).
140
+ </details>
141
+
142
+ <details>
143
+ <summary>How to fetch a collection of SKUs and sort the results</summary>
144
+ <br />
145
+
146
+ ```javascript
147
+ // Sort the results by creation date in ascending order (default)
148
+ const skus = await cl.skus.list({ sort: { created_at: 'asc' } })
149
+
150
+ // Sort the results by creation date in descending order
151
+ const skus = await cl.skus.list({ sort: { created_at: 'desc' } })
152
+ ```
153
+
154
+ ℹ️ Check our API reference for more information on how to [sort results](https://docs.commercelayer.io/developers/sorting-results).
155
+ </details>
156
+
157
+ <details>
158
+ <summary>How to fetch a collection of SKUs and include associations</summary>
159
+ <br />
160
+
161
+ ```javascript
162
+ // Include an association (prices)
163
+ const skus = await cl.skus.list({ include: [ 'prices' ] })
164
+
165
+ // Include an association (stock items)
166
+ const skus = await cl.skus.list({ include: [ 'stock_items' ] })
167
+ ```
168
+
169
+ ℹ️ Check our API reference for more information on how to [include associations](https://docs.commercelayer.io/developers/including-associations).
170
+ </details>
171
+
172
+ <details>
173
+ <summary>How to fetch a collection of SKUs and return specific fields (sparse fieldsets)</summary>
174
+ <br />
175
+
176
+ ```javascript
177
+ // Request the API to return only specific fields
178
+ const skus = await cl.skus.list({ fields: { skus: [ 'name', 'metadata' ] } })
179
+
180
+ // Request the API to return only specific fields of the included resource
181
+ const skus = await cl.skus.list({ include: [ 'prices' ], fields: { prices: [ 'currency_code', 'formatted_amount' ] } })
182
+ ```
183
+
184
+ ℹ️ Check our API reference for more information on how to [use sparse fieldsets](https://docs.commercelayer.io/developers/sparse-fieldsets).
185
+ </details>
186
+
187
+ <details>
188
+ <summary>How to fetch a collection of SKUs and filter data</summary>
189
+ <br />
190
+
191
+ ```javascript
192
+ // Filter all the SKUs fetching only the ones whose code starts with the string "TSHIRT"
193
+ const skus = await cl.skus.list({ filters: { code_start: 'TSHIRT' } })
194
+
195
+ // Filter all the SKUs fetching only the ones whose code ends with the string "XLXX"
196
+ const skus = await cl.skus.list({ filters: { code_end: 'XLXX' } })
197
+
198
+ // Filter all the SKUs fetching only the ones whose name contains the string "White Logo"
199
+ const skus = await cl.skus.list({ filters: { name_cont: 'White Logo' } })
200
+
201
+ // Filter all the SKUs fetching only the ones created between two specific dates
202
+ // (filters combined according to the AND logic)
203
+ const skus = await cl.skus.list({ filters: { created_at_gt: '2018-01-01', created_at_lt: '2018-01-31'} })
204
+
205
+ // Filters all the SKUs fetching only the ones created or updated after a specific date
206
+ // (attributes combined according to the OR logic)
207
+ const skus = await cl.skus.list({ filters: { updated_at_or_created_at_gt: '2019-10-10' } })
208
+
209
+ // Filters all the SKUs fetching only the ones whose name contains the string "Black"
210
+ // and whose shipping category name starts with the string "MERCH"
211
+ const skus = await cl.skus.list({ filters: { name_cont: 'Black', shipping_category_name_start: 'MERCH'} })
212
+ ```
213
+
214
+ ℹ️ Check our API reference for more information on how to [filter data](https://docs.commercelayer.io/developers/filtering-data).
215
+ </details>
216
+
217
+ <details>
218
+ <summary>How to paginate a collection of SKUs</summary>
219
+ <br />
220
+
221
+ When you fetch a collection of resources, you get paginated results. You can request specific pages or items in a page like so:
222
+
223
+ ```javascript
224
+ // Fetch the SKUs, setting the page number to 3 and the page size to 5
225
+ const skus = await cl.skus.list({ pageNumber: 3, pageSize: 5 })
226
+
227
+ // Get the total number of SKUs in the collection
228
+ const skuCount = skus.meta.recordCount
229
+
230
+ // Get the total number of pages
231
+ const pageCount = skus.meta.pageCount
232
+ ```
233
+
234
+ > PS: the default page number is **1**, the default page size is **10**, and the maximum page size allowed is **25**.
235
+
236
+ ℹ️ Check our API reference for more information on how [pagination](https://docs.commercelayer.io/developers/pagination) works.
237
+ </details>
238
+
239
+ <details>
240
+ <summary>How to iterate through a collection of SKUs</summary>
241
+ <br />
242
+
243
+ To execute a function for every item of a collection, use the `map()` method like so:
244
+
245
+ ```javascript
246
+ // Fetch the whole list of SKUs (1st page) and print their names and codes to console
247
+ const skus = await cl.skus.list()
248
+ skus.map(p => console.log('Product: ' + p.name + ' - Code: ' + p.code))
249
+ ```
250
+
251
+ </details>
252
+
253
+ <!-- <details>
254
+ <summary>How to build complex queries</summary>
255
+ <br />
256
+
257
+ Coming soon...
258
+ </details> -->
259
+
260
+ <details>
261
+ <summary>How to fetch resource relationships</summary>
262
+ <br />
263
+
264
+ Many resources have relationships with other resources and instead of including these associations as seen above, you can fetch them directly. This way, in the case of 1-to-N relationships, you can filter or sort the resulting collection as standard resources.
265
+
266
+ ```javascript
267
+ // Fetch 1-to-1 related resource: billing address of an order
268
+ const billingAddress = cl.orders.billing_address('xYZkjABcde')
269
+
270
+ // Fetch 1-to-N related resources: orders associated to a customer
271
+ const orders = cl.customers.orders('XyzKjAbCDe', { fields: ['status', 'number'] })
272
+ ```
273
+
274
+ In general:
275
+
276
+ - An API endpoint like `/api/customers` or `/api/customers/<customerId>` translates to `cl.customers` or `cl.customers('<customerId>')` with the SDK.
277
+ - 1-to-1 relationship API endpoints like `/api/orders/<orderId>/shipping_address` translates to `cl.orders('<orderId>', { include: ['shipping_address'] }}` with the SDK.
278
+ - 1-to-N relationship API endpoints like `/api/customers/<customerId>?include=orders` or `/api/customers/<customerId>/orders` translates to `cl.customers.retrieve('customerId', { include: ['orders'] })` or `cl.customers.orders('<customerId>')` with the SDK.
279
+
280
+ ℹ️ Check our API reference for more information on how to [fetch relationships](https://docs.commercelayer.io/core/fetching-relationships).
281
+ </details>
282
+
283
+ <details>
284
+ <summary>How to count resources</summary>
285
+ <br />
286
+
287
+ Many times you simply need to count how many resources exist with
288
+ certain characteristics. You can then call the special `count`
289
+ function passing a filter to get as result the total number of
290
+ resources.
291
+
292
+ ```javascript
293
+ // Get the total number of placed orders
294
+ const placedOrders = cl.orders.count({ filters: { status_eq: 'placed' } })
295
+
296
+ ```
297
+
298
+ </details>
299
+
300
+ ### Update
301
+
302
+ <details>
303
+ <summary>How to update an existing SKU</summary>
304
+ <br />
305
+
306
+ ```javascript
307
+ const sku = {
308
+ id: 'xYZkjABcde',
309
+ description: 'Updated description...',
310
+ imageUrl: 'https://img.yourdomain.com/skus/new-image.png'
311
+ }
312
+
313
+ cl.skus.update(sku) // updates the SKU on the server
314
+ ```
315
+
316
+ ℹ️ Check our API reference for more information on how to [update an SKU](https://docs.commercelayer.io/developers/v/api-reference/skus/update).
317
+ </details>
318
+
319
+ ### Delete
320
+
321
+ <details>
322
+ <summary>How to delete an existing SKU</summary>
323
+ <br />
324
+
325
+ ```javascript
326
+ cl.skus.delete('xYZkjABcde') // persisted deletion
327
+ ```
328
+
329
+ ℹ️ Check our API reference for more information on how to [delete an SKU](https://docs.commercelayer.io/developers/v/api-reference/skus/delete).
330
+ </details>
331
+
332
+ ## Overriding credentials
333
+
334
+ If needed, Commerce Layer JS SDK lets you change the client configuration and set it at a request level. To do that, just use the `config()` method or pass the `options` parameter and authenticate the API call with the desired credentials:
335
+
336
+ ```javascript
337
+ // Permanently change configuration at client level
338
+ cl.config({ organization: 'you-organization-slug', accessToken: 'your-access-token' })
339
+ const skus = await cl.skus.list()
340
+
341
+ or
342
+
343
+ // Use configuration at request level
344
+ cl.skus.list({}, { organization: 'you-organization-slug', accessToken: 'your-access-token' })
345
+ ```
346
+
347
+ ## Handling validation errors
348
+
349
+ Commerce Layer API returns specific errors (with extra information) on each attribute of a single resource. You can inspect them to properly handle validation errors (if any). To do that, use the `errors` attribute of the catched error:
350
+
351
+ ```javascript
352
+ // Log error messages to console:
353
+ const attributes = { code: 'TSHIRTMM000000FFFFFFXL', name: '' }
354
+
355
+ const newSku = await cl.skus.create(attributes).catch(error => console.log(error.errors))
356
+
357
+ // Logged errors
358
+ /*
359
+ [
360
+ {
361
+ title: "can't be blank",
362
+ detail: "name - can't be blank",
363
+ code: 'VALIDATION_ERROR',
364
+ source: { pointer: '/data/attributes/name' },
365
+ status: '422',
366
+ meta: { error: 'blank' }
367
+ },
368
+ {
369
+ title: 'has already been taken',
370
+ detail: 'code - has already been taken',
371
+ code: 'VALIDATION_ERROR',
372
+ source: { pointer: '/data/attributes/code' },
373
+ status: '422',
374
+ meta: { error: 'taken', value: 'TSHIRTMM000000FFFFFFXL' }
375
+ },
376
+ {
377
+ title: "can't be blank",
378
+ detail: "shipping_category - can't be blank",
379
+ code: 'VALIDATION_ERROR',
380
+ source: { pointer: '/data/relationships/shipping_category' },
381
+ status: '422',
382
+ meta: { error: 'blank' }
383
+ }
384
+ ]
385
+ */
386
+
387
+ ```
388
+
389
+ ℹ️ Check our API reference for more information about the [errors](https://docs.commercelayer.io/developers/handling-errors) returned by the API.
390
+
391
+ ## Contributors guide
392
+
393
+ 1. Fork [this repository](https://github.com/commercelayer/commercelayer-sdk) (learn how to do this [here](https://help.github.com/articles/fork-a-repo)).
394
+
395
+ 2. Clone the forked repository like so:
396
+
397
+ ```shell
398
+ git clone https://github.com/<your username>/commercelayer-sdk.git && cd commercelayer-sdk
399
+ ```
400
+
401
+ 3. Make your changes and create a pull request ([learn how to do this](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request)).
402
+
403
+ 4. Someone will attend to your pull request and provide some feedback.
404
+
405
+ ## Need help?
406
+
407
+ 1. Join [Commerce Layer's Slack community](https://slack.commercelayer.app).
408
+
409
+ 2. Create an [issue](https://github.com/commercelayer/commercelayer-cli/issues) in this repository.
410
+
411
+ 3. Ping us [on Twitter](https://twitter.com/commercelayer).
412
+
413
+ ## License
414
+
415
+ This repository is published under the [MIT](LICENSE) license.
@@ -0,0 +1,41 @@
1
+ import type { Resource, ResourceRel } from './resource';
2
+ import type { VersionType } from './resources/versions';
3
+ /**
4
+ * ©2023 Commerce Layer Inc.
5
+ **/
6
+ export { default as ApiCredentials } from './resources/api_credentials';
7
+ export { default as Memberships } from './resources/memberships';
8
+ export { default as Organizations } from './resources/organizations';
9
+ export { default as Permissions } from './resources/permissions';
10
+ export { default as Roles } from './resources/roles';
11
+ export { default as Users } from './resources/user';
12
+ export { default as Versions } from './resources/versions';
13
+ export type ResourceTypeLock = 'api_credentials' | 'memberships' | 'organizations' | 'permissions' | 'roles' | 'user' | 'versions';
14
+ export declare const resourceList: readonly ["api_credentials", "memberships", "organizations", "permissions", "roles", "user", "versions"];
15
+ export type RetrievableResourceType = ResourceTypeLock;
16
+ export type RetrievableResource = Resource & {
17
+ type: RetrievableResourceType;
18
+ };
19
+ export type ListableResourceType = Exclude<ResourceTypeLock, 'user'>;
20
+ export type ListableResource = Resource & {
21
+ type: ListableResourceType;
22
+ };
23
+ export type CreatableResourceType = 'api_credentials' | 'memberships' | 'organizations' | 'permissions' | 'roles';
24
+ export type CreatableResource = Resource & {
25
+ type: CreatableResourceType;
26
+ };
27
+ export type UpdatableResourceType = 'api_credentials' | 'memberships' | 'organizations' | 'permissions' | 'roles';
28
+ export type UpdatableResource = Resource & {
29
+ type: UpdatableResourceType;
30
+ };
31
+ export type DeletableResourceType = 'api_credentials' | 'memberships';
32
+ export type DeletableResource = Resource & {
33
+ type: DeletableResourceType;
34
+ };
35
+ export type VersionableResourceType = 'memberships' | 'permissions' | 'roles';
36
+ export type VersionableResource = Resource & {
37
+ type: VersionableResourceType;
38
+ versions?: Array<ResourceRel & {
39
+ type: VersionType;
40
+ }> | null;
41
+ };
package/lib/cjs/api.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.resourceList = exports.Versions = exports.Users = exports.Roles = exports.Permissions = exports.Organizations = exports.Memberships = exports.ApiCredentials = void 0;
7
+ // ##__API_RESOURCES_START__##
8
+ // ##__API_RESOURCES_TEMPLATE:: export { default as ##__RESOURCE_CLASS__## } from './resources/##__RESOURCE_TYPE__##'
9
+ /**
10
+ * ©2023 Commerce Layer Inc.
11
+ **/
12
+ var api_credentials_1 = require("./resources/api_credentials");
13
+ Object.defineProperty(exports, "ApiCredentials", { enumerable: true, get: function () { return __importDefault(api_credentials_1).default; } });
14
+ var memberships_1 = require("./resources/memberships");
15
+ Object.defineProperty(exports, "Memberships", { enumerable: true, get: function () { return __importDefault(memberships_1).default; } });
16
+ var organizations_1 = require("./resources/organizations");
17
+ Object.defineProperty(exports, "Organizations", { enumerable: true, get: function () { return __importDefault(organizations_1).default; } });
18
+ var permissions_1 = require("./resources/permissions");
19
+ Object.defineProperty(exports, "Permissions", { enumerable: true, get: function () { return __importDefault(permissions_1).default; } });
20
+ var roles_1 = require("./resources/roles");
21
+ Object.defineProperty(exports, "Roles", { enumerable: true, get: function () { return __importDefault(roles_1).default; } });
22
+ var user_1 = require("./resources/user");
23
+ Object.defineProperty(exports, "Users", { enumerable: true, get: function () { return __importDefault(user_1).default; } });
24
+ var versions_1 = require("./resources/versions");
25
+ Object.defineProperty(exports, "Versions", { enumerable: true, get: function () { return __importDefault(versions_1).default; } });
26
+ // ##__API_RESOURCE_TYPES_STOP__##
27
+ exports.resourceList = [
28
+ // ##__API_RESOURCE_LIST_START__##
29
+ 'api_credentials',
30
+ 'memberships',
31
+ 'organizations',
32
+ 'permissions',
33
+ 'roles',
34
+ 'user',
35
+ 'versions'
36
+ // ##__API_RESOURCE_LIST_STOP__##
37
+ ];
@@ -0,0 +1,39 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import type { AxiosAdapter, AxiosProxyConfig, Method } from 'axios';
4
+ import type { InterceptorManager } from './interceptor';
5
+ import type { Agent as HttpAgent } from 'http';
6
+ import type { Agent as HttpsAgent } from 'https';
7
+ type ProxyConfig = AxiosProxyConfig | false;
8
+ type Adapter = AxiosAdapter;
9
+ type RequestParams = Record<string, string | number | boolean>;
10
+ type RequestHeaders = Record<string, string>;
11
+ type RequestConfig = {
12
+ timeout?: number;
13
+ params?: RequestParams;
14
+ httpAgent?: HttpAgent;
15
+ httpsAgent?: HttpsAgent;
16
+ proxy?: ProxyConfig;
17
+ headers?: RequestHeaders;
18
+ };
19
+ type ApiConfig = {
20
+ domain?: string;
21
+ accessToken: string;
22
+ };
23
+ type ApiClientInitConfig = ApiConfig & RequestConfig & {
24
+ adapter?: Adapter;
25
+ };
26
+ type ApiClientConfig = Partial<ApiClientInitConfig>;
27
+ declare class ApiClient {
28
+ #private;
29
+ static create(options: ApiClientInitConfig): ApiClient;
30
+ baseUrl: string;
31
+ interceptors: InterceptorManager;
32
+ private constructor();
33
+ config(config: ApiClientConfig): ApiClient;
34
+ adapter(adapter: Adapter): ApiClient;
35
+ request(method: Method, path: string, body?: any, options?: ApiClientConfig): Promise<any>;
36
+ private customHeaders;
37
+ }
38
+ export default ApiClient;
39
+ export type { ApiClientInitConfig, ApiClientConfig, RequestConfig };
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ var _ApiClient_accessToken, _ApiClient_client;
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ const axios_1 = __importDefault(require("axios"));
19
+ const error_1 = require("./error");
20
+ const config_1 = __importDefault(require("./config"));
21
+ const debug_1 = __importDefault(require("./debug"));
22
+ const debug = (0, debug_1.default)('client');
23
+ const baseURL = (domain) => {
24
+ return `https://provisioning.${domain || config_1.default.default.domain}/api`;
25
+ };
26
+ class ApiClient {
27
+ static create(options) {
28
+ for (const attr of config_1.default.client.requiredAttributes)
29
+ if (!options || !options[attr])
30
+ throw new error_1.SdkError({ message: `Undefined '${attr}' parameter` });
31
+ return new ApiClient(options);
32
+ }
33
+ constructor(options) {
34
+ _ApiClient_accessToken.set(this, void 0);
35
+ _ApiClient_client.set(this, void 0);
36
+ debug('new client instance %O', options);
37
+ this.baseUrl = baseURL(options.domain);
38
+ __classPrivateFieldSet(this, _ApiClient_accessToken, options.accessToken, "f");
39
+ const axiosConfig = {
40
+ timeout: options.timeout || config_1.default.client.timeout,
41
+ proxy: options.proxy,
42
+ httpAgent: options.httpAgent,
43
+ httpsAgent: options.httpsAgent,
44
+ };
45
+ // Set custom headers
46
+ const customHeaders = this.customHeaders(options.headers);
47
+ const axiosOptions = {
48
+ baseURL: this.baseUrl,
49
+ timeout: config_1.default.client.timeout,
50
+ headers: {
51
+ ...customHeaders,
52
+ 'Accept': 'application/vnd.api+json',
53
+ 'Content-Type': 'application/vnd.api+json',
54
+ 'Authorization': 'Bearer ' + __classPrivateFieldGet(this, _ApiClient_accessToken, "f")
55
+ },
56
+ ...axiosConfig
57
+ };
58
+ if (options.adapter)
59
+ axiosOptions.adapter = options.adapter;
60
+ debug('axios options: %O', axiosOptions);
61
+ __classPrivateFieldSet(this, _ApiClient_client, axios_1.default.create(axiosOptions), "f");
62
+ this.interceptors = __classPrivateFieldGet(this, _ApiClient_client, "f").interceptors;
63
+ }
64
+ config(config) {
65
+ debug('config %o', config);
66
+ const def = __classPrivateFieldGet(this, _ApiClient_client, "f").defaults;
67
+ // Axios config
68
+ if (config.timeout)
69
+ def.timeout = config.timeout;
70
+ if (config.proxy)
71
+ def.proxy = config.proxy;
72
+ if (config.httpAgent)
73
+ def.httpAgent = config.httpAgent;
74
+ if (config.httpsAgent)
75
+ def.httpsAgent = config.httpsAgent;
76
+ // API Client config
77
+ if (config.accessToken) {
78
+ __classPrivateFieldSet(this, _ApiClient_accessToken, config.accessToken, "f");
79
+ def.headers.common.Authorization = 'Bearer ' + __classPrivateFieldGet(this, _ApiClient_accessToken, "f");
80
+ }
81
+ if (config.headers)
82
+ def.headers.common = this.customHeaders(config.headers);
83
+ if (config.adapter)
84
+ this.adapter(config.adapter);
85
+ return this;
86
+ }
87
+ adapter(adapter) {
88
+ if (adapter)
89
+ __classPrivateFieldGet(this, _ApiClient_client, "f").defaults.adapter = adapter;
90
+ return this;
91
+ }
92
+ async request(method, path, body, options) {
93
+ debug('request %s %s, %O, %O', method, path, body || {}, options || {});
94
+ const data = body ? { data: body } : undefined;
95
+ const url = path;
96
+ // Runtime request parameters
97
+ // const baseUrl = options?.organization ? baseURL(options.organization, options.domain) : undefined
98
+ const accessToken = (options === null || options === void 0 ? void 0 : options.accessToken) || __classPrivateFieldGet(this, _ApiClient_accessToken, "f");
99
+ const headers = this.customHeaders(options === null || options === void 0 ? void 0 : options.headers);
100
+ if (accessToken)
101
+ headers.Authorization = 'Bearer ' + accessToken;
102
+ const requestParams = { method, url, data, ...options, headers };
103
+ debug('request params: %O', requestParams);
104
+ // const start = Date.now()
105
+ return __classPrivateFieldGet(this, _ApiClient_client, "f").request(requestParams)
106
+ .then(response => response.data)
107
+ .catch(error => (0, error_1.handleError)(error));
108
+ // .finally(() => console.log(`<<-- ${method} ${path} ${Date.now() - start}`))
109
+ }
110
+ customHeaders(headers) {
111
+ const customHeaders = {};
112
+ if (headers) {
113
+ for (const [name, value] of Object.entries(headers))
114
+ if (!['accept', 'content-type', 'authorization'].includes(name.toLowerCase()))
115
+ customHeaders[name] = value;
116
+ }
117
+ return customHeaders;
118
+ }
119
+ }
120
+ _ApiClient_accessToken = new WeakMap(), _ApiClient_client = new WeakMap();
121
+ exports.default = ApiClient;