@commercelayer/sdk 6.0.0-alfa.1 → 6.0.0-alfa.2

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.
@@ -2,14 +2,14 @@ import * as api from './api';
2
2
  import type { ApiError } from './error';
3
3
  import type { ErrorInterceptor, InterceptorType, RawResponseReader, RequestInterceptor, ResponseInterceptor } from './interceptor';
4
4
  import { type ResourcesInitConfig } from './resource';
5
- declare const OPEN_API_SCHEMA_VERSION = "5.0.0";
5
+ declare const OPEN_API_SCHEMA_VERSION = "5.1.0";
6
6
  export { OPEN_API_SCHEMA_VERSION };
7
7
  type SdkConfig = {};
8
8
  type CommerceLayerInitConfig = SdkConfig & ResourcesInitConfig;
9
9
  type CommerceLayerConfig = Partial<CommerceLayerInitConfig>;
10
10
  declare class CommerceLayerClient {
11
11
  #private;
12
- readonly openApiSchemaVersion = "5.0.0";
12
+ readonly openApiSchemaVersion = "5.1.0";
13
13
  addresses: api.Addresses;
14
14
  adjustments: api.Adjustments;
15
15
  adyen_gateways: api.AdyenGateways;
@@ -45,7 +45,7 @@ const resource_1 = __importDefault(require("./resource"));
45
45
  const debug_1 = __importDefault(require("./debug"));
46
46
  const debug = (0, debug_1.default)('commercelayer');
47
47
  // Autogenerated schema version number, do not remove this line
48
- const OPEN_API_SCHEMA_VERSION = '5.0.0';
48
+ const OPEN_API_SCHEMA_VERSION = '5.1.0';
49
49
  exports.OPEN_API_SCHEMA_VERSION = OPEN_API_SCHEMA_VERSION;
50
50
  class CommerceLayerClient {
51
51
  // ##__CL_RESOURCES_DEF_STOP__##
@@ -8,5 +8,8 @@ declare const config: {
8
8
  readonly timeout: 15000;
9
9
  readonly requiredAttributes: readonly ["organization", "accessToken"];
10
10
  };
11
+ readonly jsonapi: {
12
+ readonly maxResourceIncluded: 2;
13
+ };
11
14
  };
12
15
  export default config;
package/lib/cjs/config.js CHANGED
@@ -11,6 +11,9 @@ const config = {
11
11
  client: {
12
12
  timeout: 15000,
13
13
  requiredAttributes: ['organization', 'accessToken'],
14
+ },
15
+ jsonapi: {
16
+ maxResourceIncluded: 2
14
17
  }
15
18
  };
16
19
  exports.default = config;
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.normalize = exports.denormalize = void 0;
7
7
  const common_1 = require("./common");
8
+ const config_1 = __importDefault(require("./config"));
8
9
  const debug_1 = __importDefault(require("./debug"));
9
10
  const debug = (0, debug_1.default)('jsonapi');
10
11
  // DENORMALIZATION
@@ -31,7 +32,7 @@ const findIncluded = (rel, included = []) => {
31
32
  });
32
33
  return inc || rel;
33
34
  };
34
- const denormalizeResource = (res, included) => {
35
+ const denormalizeResource = (res, included, chain = []) => {
35
36
  debug('denormalize resource: %O, %o', res, included || {});
36
37
  if (!res)
37
38
  return res;
@@ -44,10 +45,14 @@ const denormalizeResource = (res, included) => {
44
45
  Object.keys(res.relationships).forEach(key => {
45
46
  const rel = res.relationships[key].data;
46
47
  if (rel) {
47
- if (Array.isArray(rel))
48
- resource[key] = rel.map((r) => denormalizeResource(findIncluded(r, included), included));
49
- else
50
- resource[key] = denormalizeResource(findIncluded(rel, included), included);
48
+ if (chain.filter(r => (r.id === rel.id) && (r.type === rel.type)).length >= config_1.default.jsonapi.maxResourceIncluded)
49
+ resource[key] = rel;
50
+ else {
51
+ if (Array.isArray(rel))
52
+ resource[key] = rel.map((r) => denormalizeResource(findIncluded(r, included), included, [...chain, r]));
53
+ else
54
+ resource[key] = denormalizeResource(findIncluded(rel, included), included, [...chain, rel]);
55
+ }
51
56
  }
52
57
  else if (rel === null)
53
58
  resource[key] = null;
@@ -1,5 +1,5 @@
1
1
  import type { ResourceType } from "./resource";
2
- type QueryFilter = Record<string, string | number | boolean | object>;
2
+ type QueryFilter = Record<string, string | number | boolean | object | Array<string | number>>;
3
3
  interface QueryParamsRetrieve {
4
4
  include?: string[];
5
5
  fields?: string[] | Record<string, string[]>;
package/lib/cjs/query.js CHANGED
@@ -5,7 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.isParamsList = exports.generateQueryStringParams = void 0;
7
7
  const debug_1 = __importDefault(require("./debug"));
8
+ const error_1 = require("./error");
8
9
  const debug = (0, debug_1.default)('query');
10
+ const arrayFilters = ['_any', '_all', '_in'];
11
+ const objectFilters = ['_jcont'];
9
12
  const isParamsList = (params) => {
10
13
  return params && (params.filters || params.pageNumber || params.pageSize || params.sort);
11
14
  };
@@ -42,7 +45,21 @@ const generateQueryStringParams = (params, res) => {
42
45
  // Filters
43
46
  if (params.filters) {
44
47
  Object.entries(params.filters).forEach(([p, v]) => {
45
- qp[`filter[q][${p}]`] = (typeof v === 'object') ? JSON.stringify(v) : String(v);
48
+ const filter = p.substring(p.lastIndexOf('_'));
49
+ let val;
50
+ if (Array.isArray(v)) {
51
+ if (!arrayFilters.includes(filter))
52
+ throw new error_1.SdkError({ message: `Wrong ${filter} filter: Array value is supported only for the following filters: ${arrayFilters.join(', ')}`, type: error_1.ErrorType.REQUEST });
53
+ val = v.join(',');
54
+ }
55
+ else if (typeof v === 'object') {
56
+ if (!objectFilters.includes(filter))
57
+ throw new error_1.SdkError({ message: `Wrong ${filter} filter: Object value is supported only for the following filters: ${objectFilters.join(', ')}`, type: error_1.ErrorType.REQUEST });
58
+ val = JSON.stringify(v);
59
+ }
60
+ else
61
+ val = String(v);
62
+ qp[`filter[q][${p}]`] = val;
46
63
  });
47
64
  }
48
65
  }
@@ -1,4 +1,4 @@
1
- import { type ApiClientInitConfig } from './client';
1
+ import ApiClient, { type ApiClientInitConfig } from './client';
2
2
  import type { QueryParamsRetrieve, QueryParamsList, QueryFilter, QueryParams } from './query';
3
3
  import type { ResourceTypeLock } from './api';
4
4
  import type { InterceptorManager } from './interceptor';
@@ -56,6 +56,7 @@ declare class ResourceAdapter {
56
56
  get interceptors(): InterceptorManager;
57
57
  private localConfig;
58
58
  config(config: ResourcesConfig): ResourceAdapter;
59
+ get client(): Readonly<ApiClient>;
59
60
  singleton<R extends Resource>(resource: ResourceType, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise<R>;
60
61
  retrieve<R extends Resource>(resource: ResourceId, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise<R>;
61
62
  list<R extends Resource>(resource: ResourceType, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<R>>;
@@ -70,7 +71,9 @@ declare abstract class ApiResourceBase<R extends Resource> {
70
71
  constructor(adapter: ResourceAdapter);
71
72
  abstract relationship(id: string | ResourceId | null): ResourceRel;
72
73
  abstract type(): ResourceTypeLock;
73
- parse(resource: string): R | R[];
74
+ parse(resource: string, options?: {
75
+ ignoreSlug?: boolean;
76
+ }): R | R[];
74
77
  update(resource: ResourceUpdate, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise<R>;
75
78
  }
76
79
  declare abstract class ApiResource<R extends Resource> extends ApiResourceBase<R> {
@@ -57,11 +57,9 @@ class ResourceAdapter {
57
57
  __classPrivateFieldGet(this, _ResourceAdapter_client, "f").config(config);
58
58
  return this;
59
59
  }
60
- /*
61
- get clientInstance(): ApiClient {
62
- return this.#client
60
+ get client() {
61
+ return __classPrivateFieldGet(this, _ResourceAdapter_client, "f");
63
62
  }
64
- */
65
63
  async singleton(resource, params, options) {
66
64
  debug('singleton: %o, %O, %O', resource, params || {}, options || {});
67
65
  const queryParams = (0, query_1.generateQueryStringParams)(params, resource);
@@ -146,11 +144,20 @@ class ApiResourceBase {
146
144
  debug('new resource instance: %s', this.type());
147
145
  this.resources = adapter;
148
146
  }
149
- parse(resource) {
147
+ parse(resource, options) {
150
148
  try {
151
149
  const res = JSON.parse(resource);
152
- if (res.data?.type !== this.type())
153
- throw new error_1.SdkError({ message: `Invalid resource type [${res.data?.type}]`, type: error_1.ErrorType.PARSE });
150
+ // Resource type always checked
151
+ const rtype = res.data?.type;
152
+ if (rtype !== this.type())
153
+ throw new error_1.SdkError({ message: `Invalid resource type [${rtype}]`, type: error_1.ErrorType.PARSE });
154
+ // Parse options
155
+ const { ignoreSlug } = options || {};
156
+ if (!ignoreSlug) {
157
+ const links = res.data.links.self;
158
+ if (!links || !String(links).match(`^${this.resources.client.baseUrl}/${this.type()}/*`))
159
+ throw new error_1.SdkError({ message: `Resource contains invalid links [${links}]`, type: error_1.ErrorType.PARSE });
160
+ }
154
161
  return (0, jsonapi_1.denormalize)(res);
155
162
  }
156
163
  catch (error) {
@@ -1,8 +1,8 @@
1
1
  import { ApiResource } from '../resource';
2
2
  import type { Resource, ResourceId, ResourcesConfig, ResourceRel, ListResponse } from '../resource';
3
3
  import type { QueryParamsList } from '../query';
4
- import type { EventCallback } from './event_callbacks';
5
4
  import type { Webhook } from './webhooks';
5
+ import type { EventCallback } from './event_callbacks';
6
6
  type EventType = 'events';
7
7
  type EventRel = ResourceRel & {
8
8
  type: EventType;
@@ -10,13 +10,13 @@ type EventRel = ResourceRel & {
10
10
  interface Event extends Resource {
11
11
  readonly type: EventType;
12
12
  name: string;
13
- last_event_callbacks?: EventCallback[] | null;
14
13
  webhooks?: Webhook[] | null;
14
+ last_event_callbacks?: EventCallback[] | null;
15
15
  }
16
16
  declare class Events extends ApiResource<Event> {
17
17
  static readonly TYPE: EventType;
18
- last_event_callbacks(eventId: string | Event, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<EventCallback>>;
19
18
  webhooks(eventId: string | Event, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<Webhook>>;
19
+ last_event_callbacks(eventId: string | Event, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<EventCallback>>;
20
20
  isEvent(resource: any): resource is Event;
21
21
  relationship(id: string | ResourceId | null): EventRel;
22
22
  type(): EventType;
@@ -2,14 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const resource_1 = require("../resource");
4
4
  class Events extends resource_1.ApiResource {
5
- async last_event_callbacks(eventId, params, options) {
6
- const _eventId = eventId.id || eventId;
7
- return this.resources.fetch({ type: 'event_callbacks' }, `events/${_eventId}/last_event_callbacks`, params, options);
8
- }
9
5
  async webhooks(eventId, params, options) {
10
6
  const _eventId = eventId.id || eventId;
11
7
  return this.resources.fetch({ type: 'webhooks' }, `events/${_eventId}/webhooks`, params, options);
12
8
  }
9
+ async last_event_callbacks(eventId, params, options) {
10
+ const _eventId = eventId.id || eventId;
11
+ return this.resources.fetch({ type: 'event_callbacks' }, `events/${_eventId}/last_event_callbacks`, params, options);
12
+ }
13
13
  isEvent(resource) {
14
14
  return resource.type && (resource.type === Events.TYPE);
15
15
  }
@@ -22,6 +22,7 @@ interface Organization extends Resource {
22
22
  max_concurrent_cleanups?: number | null;
23
23
  order_number_editable_test?: boolean | null;
24
24
  order_number_editable_live?: boolean | null;
25
+ config?: Record<string, any> | null;
25
26
  }
26
27
  declare class Organizations extends ApiSingleton<Organization> {
27
28
  static readonly TYPE: OrganizationType;
@@ -10,6 +10,7 @@ import type { ShippingMethod, ShippingMethodType } from './shipping_methods';
10
10
  import type { DeliveryLeadTime } from './delivery_lead_times';
11
11
  import type { StockLineItem } from './stock_line_items';
12
12
  import type { StockTransfer } from './stock_transfers';
13
+ import type { LineItem } from './line_items';
13
14
  import type { CarrierAccount } from './carrier_accounts';
14
15
  import type { Parcel } from './parcels';
15
16
  import type { Attachment } from './attachments';
@@ -72,6 +73,7 @@ interface Shipment extends Resource {
72
73
  delivery_lead_time?: DeliveryLeadTime | null;
73
74
  stock_line_items?: StockLineItem[] | null;
74
75
  stock_transfers?: StockTransfer[] | null;
76
+ line_items?: LineItem[] | null;
75
77
  available_shipping_methods?: ShippingMethod[] | null;
76
78
  carrier_accounts?: CarrierAccount[] | null;
77
79
  parcels?: Parcel[] | null;
@@ -122,6 +124,7 @@ declare class Shipments extends ApiResource<Shipment> {
122
124
  delivery_lead_time(shipmentId: string | Shipment, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise<DeliveryLeadTime>;
123
125
  stock_line_items(shipmentId: string | Shipment, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<StockLineItem>>;
124
126
  stock_transfers(shipmentId: string | Shipment, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<StockTransfer>>;
127
+ line_items(shipmentId: string | Shipment, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<LineItem>>;
125
128
  available_shipping_methods(shipmentId: string | Shipment, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<ShippingMethod>>;
126
129
  carrier_accounts(shipmentId: string | Shipment, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<CarrierAccount>>;
127
130
  parcels(shipmentId: string | Shipment, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<Parcel>>;
@@ -51,6 +51,10 @@ class Shipments extends resource_1.ApiResource {
51
51
  const _shipmentId = shipmentId.id || shipmentId;
52
52
  return this.resources.fetch({ type: 'stock_transfers' }, `shipments/${_shipmentId}/stock_transfers`, params, options);
53
53
  }
54
+ async line_items(shipmentId, params, options) {
55
+ const _shipmentId = shipmentId.id || shipmentId;
56
+ return this.resources.fetch({ type: 'line_items' }, `shipments/${_shipmentId}/line_items`, params, options);
57
+ }
54
58
  async available_shipping_methods(shipmentId, params, options) {
55
59
  const _shipmentId = shipmentId.id || shipmentId;
56
60
  return this.resources.fetch({ type: 'shipping_methods' }, `shipments/${_shipmentId}/available_shipping_methods`, params, options);
@@ -2,14 +2,14 @@ import * as api from './api';
2
2
  import type { ApiError } from './error';
3
3
  import type { ErrorInterceptor, InterceptorType, RawResponseReader, RequestInterceptor, ResponseInterceptor } from './interceptor';
4
4
  import { type ResourcesInitConfig } from './resource';
5
- declare const OPEN_API_SCHEMA_VERSION = "5.0.0";
5
+ declare const OPEN_API_SCHEMA_VERSION = "5.1.0";
6
6
  export { OPEN_API_SCHEMA_VERSION };
7
7
  type SdkConfig = {};
8
8
  type CommerceLayerInitConfig = SdkConfig & ResourcesInitConfig;
9
9
  type CommerceLayerConfig = Partial<CommerceLayerInitConfig>;
10
10
  declare class CommerceLayerClient {
11
11
  #private;
12
- readonly openApiSchemaVersion = "5.0.0";
12
+ readonly openApiSchemaVersion = "5.1.0";
13
13
  addresses: api.Addresses;
14
14
  adjustments: api.Adjustments;
15
15
  adyen_gateways: api.AdyenGateways;
@@ -4,7 +4,7 @@ import ResourceAdapter from './resource';
4
4
  import Debug from './debug';
5
5
  const debug = Debug('commercelayer');
6
6
  // Autogenerated schema version number, do not remove this line
7
- const OPEN_API_SCHEMA_VERSION = '5.0.0';
7
+ const OPEN_API_SCHEMA_VERSION = '5.1.0';
8
8
  export { OPEN_API_SCHEMA_VERSION };
9
9
  class CommerceLayerClient {
10
10
  // static get openApiSchemaVersion(): string { return OPEN_API_SCHEMA_VERSION }
@@ -8,5 +8,8 @@ declare const config: {
8
8
  readonly timeout: 15000;
9
9
  readonly requiredAttributes: readonly ["organization", "accessToken"];
10
10
  };
11
+ readonly jsonapi: {
12
+ readonly maxResourceIncluded: 2;
13
+ };
11
14
  };
12
15
  export default config;
package/lib/esm/config.js CHANGED
@@ -9,6 +9,9 @@ const config = {
9
9
  client: {
10
10
  timeout: 15000,
11
11
  requiredAttributes: ['organization', 'accessToken'],
12
+ },
13
+ jsonapi: {
14
+ maxResourceIncluded: 2
12
15
  }
13
16
  };
14
17
  export default config;
@@ -1,4 +1,5 @@
1
1
  import { isResourceId, isResourceType } from './common';
2
+ import config from './config';
2
3
  import Debug from './debug';
3
4
  const debug = Debug('jsonapi');
4
5
  // DENORMALIZATION
@@ -24,7 +25,7 @@ const findIncluded = (rel, included = []) => {
24
25
  });
25
26
  return inc || rel;
26
27
  };
27
- const denormalizeResource = (res, included) => {
28
+ const denormalizeResource = (res, included, chain = []) => {
28
29
  debug('denormalize resource: %O, %o', res, included || {});
29
30
  if (!res)
30
31
  return res;
@@ -37,10 +38,14 @@ const denormalizeResource = (res, included) => {
37
38
  Object.keys(res.relationships).forEach(key => {
38
39
  const rel = res.relationships[key].data;
39
40
  if (rel) {
40
- if (Array.isArray(rel))
41
- resource[key] = rel.map((r) => denormalizeResource(findIncluded(r, included), included));
42
- else
43
- resource[key] = denormalizeResource(findIncluded(rel, included), included);
41
+ if (chain.filter(r => (r.id === rel.id) && (r.type === rel.type)).length >= config.jsonapi.maxResourceIncluded)
42
+ resource[key] = rel;
43
+ else {
44
+ if (Array.isArray(rel))
45
+ resource[key] = rel.map((r) => denormalizeResource(findIncluded(r, included), included, [...chain, r]));
46
+ else
47
+ resource[key] = denormalizeResource(findIncluded(rel, included), included, [...chain, rel]);
48
+ }
44
49
  }
45
50
  else if (rel === null)
46
51
  resource[key] = null;
@@ -1,5 +1,5 @@
1
1
  import type { ResourceType } from "./resource";
2
- type QueryFilter = Record<string, string | number | boolean | object>;
2
+ type QueryFilter = Record<string, string | number | boolean | object | Array<string | number>>;
3
3
  interface QueryParamsRetrieve {
4
4
  include?: string[];
5
5
  fields?: string[] | Record<string, string[]>;
package/lib/esm/query.js CHANGED
@@ -1,5 +1,8 @@
1
1
  import Debug from './debug';
2
+ import { ErrorType, SdkError } from "./error";
2
3
  const debug = Debug('query');
4
+ const arrayFilters = ['_any', '_all', '_in'];
5
+ const objectFilters = ['_jcont'];
3
6
  const isParamsList = (params) => {
4
7
  return params && (params.filters || params.pageNumber || params.pageSize || params.sort);
5
8
  };
@@ -35,7 +38,21 @@ const generateQueryStringParams = (params, res) => {
35
38
  // Filters
36
39
  if (params.filters) {
37
40
  Object.entries(params.filters).forEach(([p, v]) => {
38
- qp[`filter[q][${p}]`] = (typeof v === 'object') ? JSON.stringify(v) : String(v);
41
+ const filter = p.substring(p.lastIndexOf('_'));
42
+ let val;
43
+ if (Array.isArray(v)) {
44
+ if (!arrayFilters.includes(filter))
45
+ throw new SdkError({ message: `Wrong ${filter} filter: Array value is supported only for the following filters: ${arrayFilters.join(', ')}`, type: ErrorType.REQUEST });
46
+ val = v.join(',');
47
+ }
48
+ else if (typeof v === 'object') {
49
+ if (!objectFilters.includes(filter))
50
+ throw new SdkError({ message: `Wrong ${filter} filter: Object value is supported only for the following filters: ${objectFilters.join(', ')}`, type: ErrorType.REQUEST });
51
+ val = JSON.stringify(v);
52
+ }
53
+ else
54
+ val = String(v);
55
+ qp[`filter[q][${p}]`] = val;
39
56
  });
40
57
  }
41
58
  }
@@ -1,4 +1,4 @@
1
- import { type ApiClientInitConfig } from './client';
1
+ import ApiClient, { type ApiClientInitConfig } from './client';
2
2
  import type { QueryParamsRetrieve, QueryParamsList, QueryFilter, QueryParams } from './query';
3
3
  import type { ResourceTypeLock } from './api';
4
4
  import type { InterceptorManager } from './interceptor';
@@ -56,6 +56,7 @@ declare class ResourceAdapter {
56
56
  get interceptors(): InterceptorManager;
57
57
  private localConfig;
58
58
  config(config: ResourcesConfig): ResourceAdapter;
59
+ get client(): Readonly<ApiClient>;
59
60
  singleton<R extends Resource>(resource: ResourceType, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise<R>;
60
61
  retrieve<R extends Resource>(resource: ResourceId, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise<R>;
61
62
  list<R extends Resource>(resource: ResourceType, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<R>>;
@@ -70,7 +71,9 @@ declare abstract class ApiResourceBase<R extends Resource> {
70
71
  constructor(adapter: ResourceAdapter);
71
72
  abstract relationship(id: string | ResourceId | null): ResourceRel;
72
73
  abstract type(): ResourceTypeLock;
73
- parse(resource: string): R | R[];
74
+ parse(resource: string, options?: {
75
+ ignoreSlug?: boolean;
76
+ }): R | R[];
74
77
  update(resource: ResourceUpdate, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise<R>;
75
78
  }
76
79
  declare abstract class ApiResource<R extends Resource> extends ApiResourceBase<R> {
@@ -40,11 +40,9 @@ class ResourceAdapter {
40
40
  this.#client.config(config);
41
41
  return this;
42
42
  }
43
- /*
44
- get clientInstance(): ApiClient {
45
- return this.#client
43
+ get client() {
44
+ return this.#client;
46
45
  }
47
- */
48
46
  async singleton(resource, params, options) {
49
47
  debug('singleton: %o, %O, %O', resource, params || {}, options || {});
50
48
  const queryParams = generateQueryStringParams(params, resource);
@@ -130,11 +128,20 @@ class ApiResourceBase {
130
128
  debug('new resource instance: %s', this.type());
131
129
  this.resources = adapter;
132
130
  }
133
- parse(resource) {
131
+ parse(resource, options) {
134
132
  try {
135
133
  const res = JSON.parse(resource);
136
- if (res.data?.type !== this.type())
137
- throw new SdkError({ message: `Invalid resource type [${res.data?.type}]`, type: ErrorType.PARSE });
134
+ // Resource type always checked
135
+ const rtype = res.data?.type;
136
+ if (rtype !== this.type())
137
+ throw new SdkError({ message: `Invalid resource type [${rtype}]`, type: ErrorType.PARSE });
138
+ // Parse options
139
+ const { ignoreSlug } = options || {};
140
+ if (!ignoreSlug) {
141
+ const links = res.data.links.self;
142
+ if (!links || !String(links).match(`^${this.resources.client.baseUrl}/${this.type()}/*`))
143
+ throw new SdkError({ message: `Resource contains invalid links [${links}]`, type: ErrorType.PARSE });
144
+ }
138
145
  return denormalize(res);
139
146
  }
140
147
  catch (error) {
@@ -1,8 +1,8 @@
1
1
  import { ApiResource } from '../resource';
2
2
  import type { Resource, ResourceId, ResourcesConfig, ResourceRel, ListResponse } from '../resource';
3
3
  import type { QueryParamsList } from '../query';
4
- import type { EventCallback } from './event_callbacks';
5
4
  import type { Webhook } from './webhooks';
5
+ import type { EventCallback } from './event_callbacks';
6
6
  type EventType = 'events';
7
7
  type EventRel = ResourceRel & {
8
8
  type: EventType;
@@ -10,13 +10,13 @@ type EventRel = ResourceRel & {
10
10
  interface Event extends Resource {
11
11
  readonly type: EventType;
12
12
  name: string;
13
- last_event_callbacks?: EventCallback[] | null;
14
13
  webhooks?: Webhook[] | null;
14
+ last_event_callbacks?: EventCallback[] | null;
15
15
  }
16
16
  declare class Events extends ApiResource<Event> {
17
17
  static readonly TYPE: EventType;
18
- last_event_callbacks(eventId: string | Event, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<EventCallback>>;
19
18
  webhooks(eventId: string | Event, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<Webhook>>;
19
+ last_event_callbacks(eventId: string | Event, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<EventCallback>>;
20
20
  isEvent(resource: any): resource is Event;
21
21
  relationship(id: string | ResourceId | null): EventRel;
22
22
  type(): EventType;
@@ -1,14 +1,14 @@
1
1
  import { ApiResource } from '../resource';
2
2
  class Events extends ApiResource {
3
3
  static TYPE = 'events';
4
- async last_event_callbacks(eventId, params, options) {
5
- const _eventId = eventId.id || eventId;
6
- return this.resources.fetch({ type: 'event_callbacks' }, `events/${_eventId}/last_event_callbacks`, params, options);
7
- }
8
4
  async webhooks(eventId, params, options) {
9
5
  const _eventId = eventId.id || eventId;
10
6
  return this.resources.fetch({ type: 'webhooks' }, `events/${_eventId}/webhooks`, params, options);
11
7
  }
8
+ async last_event_callbacks(eventId, params, options) {
9
+ const _eventId = eventId.id || eventId;
10
+ return this.resources.fetch({ type: 'event_callbacks' }, `events/${_eventId}/last_event_callbacks`, params, options);
11
+ }
12
12
  isEvent(resource) {
13
13
  return resource.type && (resource.type === Events.TYPE);
14
14
  }
@@ -22,6 +22,7 @@ interface Organization extends Resource {
22
22
  max_concurrent_cleanups?: number | null;
23
23
  order_number_editable_test?: boolean | null;
24
24
  order_number_editable_live?: boolean | null;
25
+ config?: Record<string, any> | null;
25
26
  }
26
27
  declare class Organizations extends ApiSingleton<Organization> {
27
28
  static readonly TYPE: OrganizationType;
@@ -10,6 +10,7 @@ import type { ShippingMethod, ShippingMethodType } from './shipping_methods';
10
10
  import type { DeliveryLeadTime } from './delivery_lead_times';
11
11
  import type { StockLineItem } from './stock_line_items';
12
12
  import type { StockTransfer } from './stock_transfers';
13
+ import type { LineItem } from './line_items';
13
14
  import type { CarrierAccount } from './carrier_accounts';
14
15
  import type { Parcel } from './parcels';
15
16
  import type { Attachment } from './attachments';
@@ -72,6 +73,7 @@ interface Shipment extends Resource {
72
73
  delivery_lead_time?: DeliveryLeadTime | null;
73
74
  stock_line_items?: StockLineItem[] | null;
74
75
  stock_transfers?: StockTransfer[] | null;
76
+ line_items?: LineItem[] | null;
75
77
  available_shipping_methods?: ShippingMethod[] | null;
76
78
  carrier_accounts?: CarrierAccount[] | null;
77
79
  parcels?: Parcel[] | null;
@@ -122,6 +124,7 @@ declare class Shipments extends ApiResource<Shipment> {
122
124
  delivery_lead_time(shipmentId: string | Shipment, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise<DeliveryLeadTime>;
123
125
  stock_line_items(shipmentId: string | Shipment, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<StockLineItem>>;
124
126
  stock_transfers(shipmentId: string | Shipment, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<StockTransfer>>;
127
+ line_items(shipmentId: string | Shipment, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<LineItem>>;
125
128
  available_shipping_methods(shipmentId: string | Shipment, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<ShippingMethod>>;
126
129
  carrier_accounts(shipmentId: string | Shipment, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<CarrierAccount>>;
127
130
  parcels(shipmentId: string | Shipment, params?: QueryParamsList, options?: ResourcesConfig): Promise<ListResponse<Parcel>>;
@@ -50,6 +50,10 @@ class Shipments extends ApiResource {
50
50
  const _shipmentId = shipmentId.id || shipmentId;
51
51
  return this.resources.fetch({ type: 'stock_transfers' }, `shipments/${_shipmentId}/stock_transfers`, params, options);
52
52
  }
53
+ async line_items(shipmentId, params, options) {
54
+ const _shipmentId = shipmentId.id || shipmentId;
55
+ return this.resources.fetch({ type: 'line_items' }, `shipments/${_shipmentId}/line_items`, params, options);
56
+ }
53
57
  async available_shipping_methods(shipmentId, params, options) {
54
58
  const _shipmentId = shipmentId.id || shipmentId;
55
59
  return this.resources.fetch({ type: 'shipping_methods' }, `shipments/${_shipmentId}/available_shipping_methods`, params, options);