@shopware/api-client 0.3.0 → 0.4.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/dist/index.mjs CHANGED
@@ -1,5 +1,11 @@
1
1
  import { ofetch } from 'ofetch';
2
2
 
3
+ var __defProp = Object.defineProperty;
4
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
+ var __publicField = (obj, key, value) => {
6
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
+ return value;
8
+ };
3
9
  class ApiClientError extends Error {
4
10
  constructor(response) {
5
11
  let message = "Failed request";
@@ -9,9 +15,33 @@ class ApiClientError extends Error {
9
15
  pointer = `[${error.source.pointer}]`;
10
16
  }
11
17
  return `${message2}
12
- - [${error.title}]${pointer} ${error.detail}`;
18
+ - [${error.title}]${pointer} ${error.detail ?? ""}`;
13
19
  }, "");
14
20
  super(message);
21
+ /**
22
+ * Flag to indicate if the request was successful.
23
+ */
24
+ __publicField(this, "ok");
25
+ /**
26
+ * HTTP status code of the response.
27
+ */
28
+ __publicField(this, "status");
29
+ /**
30
+ * HTTP status text of the response.
31
+ */
32
+ __publicField(this, "statusText");
33
+ /**
34
+ * URL of the request.
35
+ */
36
+ __publicField(this, "url");
37
+ /**
38
+ * Details of the error.
39
+ */
40
+ __publicField(this, "details");
41
+ /**
42
+ * Headers of the response.
43
+ */
44
+ __publicField(this, "headers");
15
45
  this.name = "ApiClientError";
16
46
  this.details = response._data || {
17
47
  errors: [{ title: "Unknown error", detail: "" }]
@@ -27,6 +57,41 @@ function errorInterceptor(response) {
27
57
  throw new ApiClientError(response);
28
58
  }
29
59
 
60
+ function transformPathToQuery(path, params) {
61
+ const [, method, pathDefinition, headerParams] = path.split(" ");
62
+ const [requestPath, queryParams] = pathDefinition.split("?");
63
+ const pathParams = requestPath.match(/{[^}]+}/g)?.map((param) => param.substring(1, param.length - 1)) || [];
64
+ const requestPathWithParams = pathParams.reduce((acc, paramName) => {
65
+ return acc.replace(`{${paramName}}`, params[paramName]);
66
+ }, requestPath);
67
+ const queryParamNames = queryParams?.split(",") || [];
68
+ const headerParamnames = headerParams?.split(",") || [];
69
+ const headers = {};
70
+ headerParamnames.forEach((paramName) => {
71
+ headers[paramName] = params[paramName];
72
+ });
73
+ const query = {};
74
+ queryParamNames.forEach((paramName) => {
75
+ let queryParamName = paramName;
76
+ if (Array.isArray(params[paramName]) && !queryParamName.includes("[]")) {
77
+ queryParamName += "[]";
78
+ }
79
+ query[queryParamName] = params[paramName];
80
+ });
81
+ const returnOptions = {
82
+ method: method.toUpperCase(),
83
+ headers,
84
+ query
85
+ };
86
+ Object.keys(params).forEach((key) => {
87
+ if (!pathParams.includes(key) && !queryParamNames.includes(key) && !headerParamnames.includes(key)) {
88
+ returnOptions.body ?? (returnOptions.body = {});
89
+ Reflect.set(returnOptions.body, key, params[key]);
90
+ }
91
+ });
92
+ return [requestPathWithParams, returnOptions];
93
+ }
94
+
30
95
  function createAPIClient(params) {
31
96
  const defaultHeaders = {
32
97
  "sw-access-key": params.accessToken
@@ -69,39 +134,105 @@ function createAPIClient(params) {
69
134
  invoke
70
135
  };
71
136
  }
72
- function transformPathToQuery(path, params) {
73
- const [, method, pathDefinition, headerParams] = path.split(" ");
74
- const [requestPath, queryParams] = pathDefinition.split("?");
75
- const pathParams = requestPath.match(/{[^}]+}/g)?.map((param) => param.substring(1, param.length - 1)) || [];
76
- const requestPathWithParams = pathParams.reduce((acc, paramName) => {
77
- return acc.replace(`{${paramName}}`, params[paramName]);
78
- }, requestPath);
79
- const queryParamNames = queryParams?.split(",") || [];
80
- const headerParamnames = headerParams?.split(",") || [];
81
- const headers = {};
82
- headerParamnames.forEach((paramName) => {
83
- headers[paramName] = params[paramName];
84
- });
85
- const query = {};
86
- queryParamNames.forEach((paramName) => {
87
- let queryParamName = paramName;
88
- if (Array.isArray(params[paramName]) && !queryParamName.includes("[]")) {
89
- queryParamName += "[]";
137
+ function createAuthorizationHeader(token) {
138
+ if (!token)
139
+ return null;
140
+ if (token.startsWith("Bearer "))
141
+ return token;
142
+ return `Bearer ${token}`;
143
+ }
144
+ function createAdminAPIClient(params) {
145
+ const sessionData = {
146
+ accessToken: params.sessionData?.accessToken || "",
147
+ refreshToken: params.sessionData?.refreshToken || "",
148
+ expirationTime: Number(params.sessionData?.expirationTime || 0)
149
+ };
150
+ function updateSessionData(responseData) {
151
+ if (responseData?.access_token) {
152
+ defaultHeaders.Authorization = createAuthorizationHeader(
153
+ responseData.access_token
154
+ );
155
+ sessionData.accessToken = responseData.access_token;
156
+ sessionData.refreshToken = responseData.refresh_token;
157
+ sessionData.expirationTime = Date.now() + responseData.expires_in * 1e3;
158
+ params.onAuthChange?.({
159
+ ...sessionData
160
+ });
90
161
  }
91
- query[queryParamName] = params[paramName];
92
- });
93
- const returnOptions = {
94
- method: method.toUpperCase(),
95
- headers,
96
- query
162
+ }
163
+ function setSessionData(data) {
164
+ sessionData.accessToken = data.accessToken;
165
+ sessionData.refreshToken = data.refreshToken;
166
+ sessionData.expirationTime = data.expirationTime;
167
+ return getSessionData();
168
+ }
169
+ function getSessionData() {
170
+ return { ...sessionData };
171
+ }
172
+ const defaultHeaders = {
173
+ Authorization: createAuthorizationHeader(sessionData.accessToken)
97
174
  };
98
- Object.keys(params).forEach((key) => {
99
- if (!pathParams.includes(key) && !queryParamNames.includes(key) && !headerParamnames.includes(key)) {
100
- returnOptions.body ?? (returnOptions.body = {});
101
- Reflect.set(returnOptions.body, key, params[key]);
175
+ const apiFetch = ofetch.create({
176
+ baseURL: params.baseURL,
177
+ async onRequest({ request, options }) {
178
+ const isExpired = sessionData.expirationTime <= Date.now();
179
+ if (isExpired && !request.toString().includes("/oauth/token")) {
180
+ await ofetch("/oauth/token", {
181
+ baseURL: params.baseURL,
182
+ method: "POST",
183
+ body: {
184
+ grant_type: "refresh_token",
185
+ client_id: "administration",
186
+ refresh_token: sessionData.refreshToken || ""
187
+ },
188
+ headers: defaultHeaders,
189
+ onResponseError({ response }) {
190
+ errorInterceptor(response);
191
+ },
192
+ onResponse(context) {
193
+ updateSessionData(context.response._data);
194
+ }
195
+ });
196
+ }
197
+ },
198
+ async onResponse(context) {
199
+ updateSessionData(context.response._data);
200
+ },
201
+ async onResponseError({ request, response, options }) {
202
+ errorInterceptor(response);
102
203
  }
103
204
  });
104
- return [requestPathWithParams, returnOptions];
205
+ async function invoke(pathParam, params2) {
206
+ const [requestPath, options] = transformPathToQuery(
207
+ pathParam,
208
+ params2
209
+ );
210
+ return apiFetch(
211
+ requestPath,
212
+ {
213
+ ...options,
214
+ headers: {
215
+ ...defaultHeaders,
216
+ ...options.headers
217
+ }
218
+ }
219
+ );
220
+ }
221
+ return {
222
+ /**
223
+ * Invoke API request based on provided path definition.
224
+ */
225
+ invoke,
226
+ /**
227
+ * Enables to change session data in runtime. Useful for testing purposes.
228
+ * Setting session data with this methis will **not** fire `onAuthChange` hook.
229
+ */
230
+ setSessionData,
231
+ /**
232
+ * Returns current session data. Useful for testing purposes, as in most cases you'll want to use `onAuthChange` hook for that.
233
+ */
234
+ getSessionData
235
+ };
105
236
  }
106
237
 
107
- export { ApiClientError, createAPIClient, transformPathToQuery };
238
+ export { ApiClientError, createAPIClient, createAdminAPIClient };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopware/api-client",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Shopware client for API connection.",
5
5
  "author": "Shopware",
6
6
  "repository": {
@@ -18,25 +18,37 @@
18
18
  },
19
19
  "license": "MIT",
20
20
  "module": "./dist/index.mjs",
21
+ "main": "./dist/index.cjs",
21
22
  "types": "./dist/index.d.ts",
22
23
  "files": [
23
24
  "dist",
24
- "api-types"
25
+ "api-types",
26
+ "admin-api-types"
25
27
  ],
26
28
  "exports": {
27
- "import": "./dist/index.mjs"
29
+ ".": {
30
+ "require": {
31
+ "types": "./dist/index.d.cts",
32
+ "default": "./dist/index.cjs"
33
+ },
34
+ "import": {
35
+ "types": "./dist/index.d.mts",
36
+ "default": "./dist/index.mjs"
37
+ }
38
+ }
28
39
  },
29
40
  "devDependencies": {
30
41
  "@types/prettier": "^3.0.0",
31
42
  "@vitest/coverage-c8": "^0.33.0",
32
- "prettier": "^3.0.0",
33
- "vitest": "^0.33.0",
34
- "@shopware/api-gen": "0.0.6",
35
- "eslint-config-shopware": "0.0.5",
43
+ "prettier": "^3.0.3",
44
+ "unbuild": "^2.0.0",
45
+ "vitest": "^0.34.3",
46
+ "@shopware/api-gen": "0.0.7",
47
+ "eslint-config-shopware": "0.0.6",
36
48
  "tsconfig": "0.0.0"
37
49
  },
38
50
  "dependencies": {
39
- "ofetch": "^1.1.1"
51
+ "ofetch": "^1.3.3"
40
52
  },
41
53
  "scripts": {
42
54
  "build": "export NODE_ENV=production && unbuild && pnpm build:types",