@shopware-ag/app-server-sdk 1.1.3 → 1.1.4
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/commonjs/http-client.d.ts +1 -1
- package/dist/commonjs/http-client.d.ts.map +1 -1
- package/dist/commonjs/http-client.js +6 -2
- package/dist/commonjs/http-client.js.map +1 -1
- package/dist/esm/http-client.d.ts +1 -1
- package/dist/esm/http-client.d.ts.map +1 -1
- package/dist/esm/http-client.js +6 -2
- package/dist/esm/http-client.js.map +1 -1
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@ export declare class HttpClient {
|
|
|
13
13
|
/**
|
|
14
14
|
* Permform a POST request
|
|
15
15
|
*/
|
|
16
|
-
post<ResponseType>(url: string, json?: object, headers?: Record<string, string>): Promise<HttpClientResponse<ResponseType>>;
|
|
16
|
+
post<ResponseType>(url: string, json?: object | FormData | Blob, headers?: Record<string, string>): Promise<HttpClientResponse<ResponseType>>;
|
|
17
17
|
/**
|
|
18
18
|
* Permform a PUT request
|
|
19
19
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/http-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;GAEG;AACH,qBAAa,UAAU;IAGV,OAAO,CAAC,IAAI;IAFxB,OAAO,CAAC,OAAO,CAAmD;gBAE9C,IAAI,EAAE,aAAa;IAOvC;;OAEG;IACG,GAAG,CAAC,YAAY,EACrB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAI5C;;OAEG;IACG,IAAI,CAAC,YAAY,EACtB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,
|
|
1
|
+
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/http-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;GAEG;AACH,qBAAa,UAAU;IAGV,OAAO,CAAC,IAAI;IAFxB,OAAO,CAAC,OAAO,CAAmD;gBAE9C,IAAI,EAAE,aAAa;IAOvC;;OAEG;IACG,GAAG,CAAC,YAAY,EACrB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAI5C;;OAEG;IACG,IAAI,CAAC,YAAY,EACtB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,MAAM,GAAG,QAAQ,GAAG,IAAS,EACnC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAkB5C;;OAEG;IACG,GAAG,CAAC,YAAY,EACrB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,MAAW,EACjB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAO5C;;OAEG;IACG,KAAK,CAAC,YAAY,EACvB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,MAAW,EACjB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAO5C;;OAEG;IACG,MAAM,CAAC,YAAY,EACxB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,MAAW,EACjB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;YAO9B,OAAO;IAyCrB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;CAuDjC;AAED;;GAEG;AACH,qBAAa,kBAAkB,CAAC,YAAY;IAEnC,UAAU,EAAE,MAAM;IAClB,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,OAAO;gBAFhB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,OAAO;CAExB;AAED,KAAK,qBAAqB,GAAG;IAC5B,MAAM,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;CACJ,CAAC;AAEF;;GAEG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;IAG/C,QAAQ,EAAE,kBAAkB,CAAC,MAAM,CAAC;gBAD3C,MAAM,EAAE,MAAM,EACP,QAAQ,EAAE,kBAAkB,CAAC,MAAM,CAAC;CAM5C;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAGxC,QAAQ,EAAE,kBAAkB,CAAC,qBAAqB,CAAC;gBAD1D,MAAM,EAAE,MAAM,EACP,QAAQ,EAAE,kBAAkB,CAAC,qBAAqB,CAAC;CAM3D"}
|
|
@@ -24,9 +24,13 @@ class HttpClient {
|
|
|
24
24
|
* Permform a POST request
|
|
25
25
|
*/
|
|
26
26
|
async post(url, json = {}, headers = {}) {
|
|
27
|
-
|
|
27
|
+
let data = json;
|
|
28
|
+
if (!(json instanceof Blob) && !(json instanceof FormData)) {
|
|
29
|
+
headers["content-type"] = "application/json";
|
|
30
|
+
data = JSON.stringify(json);
|
|
31
|
+
}
|
|
28
32
|
headers.accept = "application/json";
|
|
29
|
-
return await this.request("POST", url,
|
|
33
|
+
return await this.request("POST", url, data, headers);
|
|
30
34
|
}
|
|
31
35
|
/**
|
|
32
36
|
* Permform a PUT request
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../src/http-client.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ShopInterface } from \"./repository.js\";\n\n/**\n * HttpClient is a simple wrapper around the fetch API, pre-configured with the shop's URL and access token\n */\nexport class HttpClient {\n\tprivate storage: { expiresIn: Date | null; token: string | null };\n\n\tconstructor(private shop: ShopInterface) {\n\t\tthis.storage = {\n\t\t\ttoken: null,\n\t\t\texpiresIn: null,\n\t\t};\n\t}\n\n\t/**\n\t * Permform a GET request\n\t */\n\tasync get<ResponseType>(\n\t\turl: string,\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\treturn await this.request(\"GET\", url, null, headers);\n\t}\n\n\t/**\n\t * Permform a POST request\n\t */\n\tasync post<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"POST\", url, JSON.stringify(json), headers);\n\t}\n\n\t/**\n\t * Permform a PUT request\n\t */\n\tasync put<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"PUT\", url, JSON.stringify(json), headers);\n\t}\n\n\t/**\n\t * Permform a PATCH request\n\t */\n\tasync patch<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"PATCH\", url, JSON.stringify(json), headers);\n\t}\n\n\t/**\n\t * Permform a DELETE request\n\t */\n\tasync delete<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"DELETE\", url, JSON.stringify(json), headers);\n\t}\n\n\tprivate async request<ResponseType>(\n\t\tmethod: string,\n\t\turl: string,\n\t\tbody: string | null = \"\",\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\tconst f = await globalThis.fetch(`${this.shop.getShopUrl()}/api${url}`, {\n\t\t\tbody,\n\t\t\theaders: Object.assign(\n\t\t\t\t{\n\t\t\t\t\tAuthorization: `Bearer ${await this.getToken()}`,\n\t\t\t\t},\n\t\t\t\theaders,\n\t\t\t),\n\t\t\tmethod,\n\t\t});\n\n\t\t// Obtain new token\n\t\tif (!f.ok && f.status === 401) {\n\t\t\tthis.storage.expiresIn = null;\n\n\t\t\treturn await this.request(method, url, body, headers);\n\t\t}\n\t\tif (!f.ok) {\n\t\t\tthrow new ApiClientRequestFailed(\n\t\t\t\tthis.shop.getShopId(),\n\t\t\t\tnew HttpClientResponse(f.status, await f.json(), f.headers),\n\t\t\t);\n\t\t}\n\n\t\tif (f.status === 204) {\n\t\t\treturn new HttpClientResponse<ResponseType>(\n\t\t\t\tf.status,\n\t\t\t\t{} as ResponseType,\n\t\t\t\tf.headers,\n\t\t\t);\n\t\t}\n\n\t\treturn new HttpClientResponse(f.status, await f.json(), f.headers);\n\t}\n\n\t/**\n\t * Obtain a valid bearer token\n\t */\n\tasync getToken(): Promise<string> {\n\t\tif (this.storage.expiresIn === null) {\n\t\t\tconst auth = await globalThis.fetch(\n\t\t\t\t`${this.shop.getShopUrl()}/api/oauth/token`,\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\tgrant_type: \"client_credentials\",\n\t\t\t\t\t\tclient_id: this.shop.getShopClientId(),\n\t\t\t\t\t\tclient_secret: this.shop.getShopClientSecret(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!auth.ok) {\n\t\t\t\tconst contentType = auth.headers.get(\"content-type\") || \"text/plain\";\n\t\t\t\tlet body = \"\";\n\n\t\t\t\tif (contentType.indexOf(\"application/json\") !== -1) {\n\t\t\t\t\tbody = await auth.json();\n\t\t\t\t} else {\n\t\t\t\t\tbody = await auth.text();\n\t\t\t\t}\n\n\t\t\t\tthrow new ApiClientAuthenticationFailed(\n\t\t\t\t\tthis.shop.getShopId(),\n\t\t\t\t\tnew HttpClientResponse<string>(auth.status, body, auth.headers),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst expireDate = new Date();\n\t\t\tconst authBody = (await auth.json()) as {\n\t\t\t\taccess_token: string;\n\t\t\t\texpires_in: number;\n\t\t\t};\n\t\t\tthis.storage.token = authBody.access_token;\n\t\t\texpireDate.setSeconds(expireDate.getSeconds() + authBody.expires_in);\n\t\t\tthis.storage.expiresIn = expireDate;\n\n\t\t\treturn this.storage.token as string;\n\t\t}\n\n\t\tif (this.storage.expiresIn.getTime() < new Date().getTime()) {\n\t\t\t// Expired\n\n\t\t\tthis.storage.expiresIn = null;\n\n\t\t\treturn await this.getToken();\n\t\t}\n\n\t\treturn this.storage.token as string;\n\t}\n}\n\n/**\n * HttpClientResponse is the response object of the HttpClient\n */\nexport class HttpClientResponse<ResponseType> {\n\tconstructor(\n\t\tpublic statusCode: number,\n\t\tpublic body: ResponseType,\n\t\tpublic headers: Headers,\n\t) {}\n}\n\ntype ShopwareErrorResponse = {\n\terrors: {\n\t\tcode: string;\n\t\tstatus: string;\n\t\ttitle: string;\n\t\tdetail: string;\n\t}[];\n};\n\n/**\n * ApiClientAuthenticationFailed is thrown when the authentication to the shop's API fails\n */\nexport class ApiClientAuthenticationFailed extends Error {\n\tconstructor(\n\t\tshopId: string,\n\t\tpublic response: HttpClientResponse<string>,\n\t) {\n\t\tsuper(\n\t\t\t`The api client authentication to shop with id: ${shopId} with response: ${JSON.stringify(response.body)}`,\n\t\t);\n\t}\n}\n\n/**\n * ApiClientRequestFailed is thrown when the request to the shop's API fails\n */\nexport class ApiClientRequestFailed extends Error {\n\tconstructor(\n\t\tshopId: string,\n\t\tpublic response: HttpClientResponse<ShopwareErrorResponse>,\n\t) {\n\t\tconst message = response.body.errors.map((e) => e.detail).join(\", \");\n\n\t\tsuper(`Request failed with error: ${message} for shop with id: ${shopId}`);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../src/http-client.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ShopInterface } from \"./repository.js\";\n\n/**\n * HttpClient is a simple wrapper around the fetch API, pre-configured with the shop's URL and access token\n */\nexport class HttpClient {\n\tprivate storage: { expiresIn: Date | null; token: string | null };\n\n\tconstructor(private shop: ShopInterface) {\n\t\tthis.storage = {\n\t\t\ttoken: null,\n\t\t\texpiresIn: null,\n\t\t};\n\t}\n\n\t/**\n\t * Permform a GET request\n\t */\n\tasync get<ResponseType>(\n\t\turl: string,\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\treturn await this.request(\"GET\", url, null, headers);\n\t}\n\n\t/**\n\t * Permform a POST request\n\t */\n\tasync post<ResponseType>(\n\t\turl: string,\n\t\tjson: object | FormData | Blob = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\tlet data: object | FormData | Blob | string = json;\n\n\t\tif (!(json instanceof Blob) && !(json instanceof FormData)) {\n\t\t\theaders[\"content-type\"] = \"application/json\";\n\t\t\tdata = JSON.stringify(json);\n\t\t}\n\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\n\t\t\t\"POST\",\n\t\t\turl,\n\t\t\tdata as FormData | Blob | string,\n\t\t\theaders,\n\t\t);\n\t}\n\n\t/**\n\t * Permform a PUT request\n\t */\n\tasync put<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"PUT\", url, JSON.stringify(json), headers);\n\t}\n\n\t/**\n\t * Permform a PATCH request\n\t */\n\tasync patch<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"PATCH\", url, JSON.stringify(json), headers);\n\t}\n\n\t/**\n\t * Permform a DELETE request\n\t */\n\tasync delete<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"DELETE\", url, JSON.stringify(json), headers);\n\t}\n\n\tprivate async request<ResponseType>(\n\t\tmethod: string,\n\t\turl: string,\n\t\tbody: string | FormData | Blob | null = \"\",\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\tconst f = await globalThis.fetch(`${this.shop.getShopUrl()}/api${url}`, {\n\t\t\tbody,\n\t\t\theaders: Object.assign(\n\t\t\t\t{\n\t\t\t\t\tAuthorization: `Bearer ${await this.getToken()}`,\n\t\t\t\t},\n\t\t\t\theaders,\n\t\t\t),\n\t\t\tmethod,\n\t\t});\n\n\t\t// Obtain new token\n\t\tif (!f.ok && f.status === 401) {\n\t\t\tthis.storage.expiresIn = null;\n\n\t\t\treturn await this.request(method, url, body, headers);\n\t\t}\n\t\tif (!f.ok) {\n\t\t\tthrow new ApiClientRequestFailed(\n\t\t\t\tthis.shop.getShopId(),\n\t\t\t\tnew HttpClientResponse(f.status, await f.json(), f.headers),\n\t\t\t);\n\t\t}\n\n\t\tif (f.status === 204) {\n\t\t\treturn new HttpClientResponse<ResponseType>(\n\t\t\t\tf.status,\n\t\t\t\t{} as ResponseType,\n\t\t\t\tf.headers,\n\t\t\t);\n\t\t}\n\n\t\treturn new HttpClientResponse(f.status, await f.json(), f.headers);\n\t}\n\n\t/**\n\t * Obtain a valid bearer token\n\t */\n\tasync getToken(): Promise<string> {\n\t\tif (this.storage.expiresIn === null) {\n\t\t\tconst auth = await globalThis.fetch(\n\t\t\t\t`${this.shop.getShopUrl()}/api/oauth/token`,\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\tgrant_type: \"client_credentials\",\n\t\t\t\t\t\tclient_id: this.shop.getShopClientId(),\n\t\t\t\t\t\tclient_secret: this.shop.getShopClientSecret(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!auth.ok) {\n\t\t\t\tconst contentType = auth.headers.get(\"content-type\") || \"text/plain\";\n\t\t\t\tlet body = \"\";\n\n\t\t\t\tif (contentType.indexOf(\"application/json\") !== -1) {\n\t\t\t\t\tbody = await auth.json();\n\t\t\t\t} else {\n\t\t\t\t\tbody = await auth.text();\n\t\t\t\t}\n\n\t\t\t\tthrow new ApiClientAuthenticationFailed(\n\t\t\t\t\tthis.shop.getShopId(),\n\t\t\t\t\tnew HttpClientResponse<string>(auth.status, body, auth.headers),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst expireDate = new Date();\n\t\t\tconst authBody = (await auth.json()) as {\n\t\t\t\taccess_token: string;\n\t\t\t\texpires_in: number;\n\t\t\t};\n\t\t\tthis.storage.token = authBody.access_token;\n\t\t\texpireDate.setSeconds(expireDate.getSeconds() + authBody.expires_in);\n\t\t\tthis.storage.expiresIn = expireDate;\n\n\t\t\treturn this.storage.token as string;\n\t\t}\n\n\t\tif (this.storage.expiresIn.getTime() < new Date().getTime()) {\n\t\t\t// Expired\n\n\t\t\tthis.storage.expiresIn = null;\n\n\t\t\treturn await this.getToken();\n\t\t}\n\n\t\treturn this.storage.token as string;\n\t}\n}\n\n/**\n * HttpClientResponse is the response object of the HttpClient\n */\nexport class HttpClientResponse<ResponseType> {\n\tconstructor(\n\t\tpublic statusCode: number,\n\t\tpublic body: ResponseType,\n\t\tpublic headers: Headers,\n\t) {}\n}\n\ntype ShopwareErrorResponse = {\n\terrors: {\n\t\tcode: string;\n\t\tstatus: string;\n\t\ttitle: string;\n\t\tdetail: string;\n\t}[];\n};\n\n/**\n * ApiClientAuthenticationFailed is thrown when the authentication to the shop's API fails\n */\nexport class ApiClientAuthenticationFailed extends Error {\n\tconstructor(\n\t\tshopId: string,\n\t\tpublic response: HttpClientResponse<string>,\n\t) {\n\t\tsuper(\n\t\t\t`The api client authentication to shop with id: ${shopId} with response: ${JSON.stringify(response.body)}`,\n\t\t);\n\t}\n}\n\n/**\n * ApiClientRequestFailed is thrown when the request to the shop's API fails\n */\nexport class ApiClientRequestFailed extends Error {\n\tconstructor(\n\t\tshopId: string,\n\t\tpublic response: HttpClientResponse<ShopwareErrorResponse>,\n\t) {\n\t\tconst message = response.body.errors.map((e) => e.detail).join(\", \");\n\n\t\tsuper(`Request failed with error: ${message} for shop with id: ${shopId}`);\n\t}\n}\n"]}
|
|
@@ -13,7 +13,7 @@ export declare class HttpClient {
|
|
|
13
13
|
/**
|
|
14
14
|
* Permform a POST request
|
|
15
15
|
*/
|
|
16
|
-
post<ResponseType>(url: string, json?: object, headers?: Record<string, string>): Promise<HttpClientResponse<ResponseType>>;
|
|
16
|
+
post<ResponseType>(url: string, json?: object | FormData | Blob, headers?: Record<string, string>): Promise<HttpClientResponse<ResponseType>>;
|
|
17
17
|
/**
|
|
18
18
|
* Permform a PUT request
|
|
19
19
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/http-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;GAEG;AACH,qBAAa,UAAU;IAGV,OAAO,CAAC,IAAI;IAFxB,OAAO,CAAC,OAAO,CAAmD;gBAE9C,IAAI,EAAE,aAAa;IAOvC;;OAEG;IACG,GAAG,CAAC,YAAY,EACrB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAI5C;;OAEG;IACG,IAAI,CAAC,YAAY,EACtB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,
|
|
1
|
+
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/http-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;GAEG;AACH,qBAAa,UAAU;IAGV,OAAO,CAAC,IAAI;IAFxB,OAAO,CAAC,OAAO,CAAmD;gBAE9C,IAAI,EAAE,aAAa;IAOvC;;OAEG;IACG,GAAG,CAAC,YAAY,EACrB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAI5C;;OAEG;IACG,IAAI,CAAC,YAAY,EACtB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,MAAM,GAAG,QAAQ,GAAG,IAAS,EACnC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAkB5C;;OAEG;IACG,GAAG,CAAC,YAAY,EACrB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,MAAW,EACjB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAO5C;;OAEG;IACG,KAAK,CAAC,YAAY,EACvB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,MAAW,EACjB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAO5C;;OAEG;IACG,MAAM,CAAC,YAAY,EACxB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,MAAW,EACjB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;YAO9B,OAAO;IAyCrB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;CAuDjC;AAED;;GAEG;AACH,qBAAa,kBAAkB,CAAC,YAAY;IAEnC,UAAU,EAAE,MAAM;IAClB,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,OAAO;gBAFhB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,OAAO;CAExB;AAED,KAAK,qBAAqB,GAAG;IAC5B,MAAM,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;CACJ,CAAC;AAEF;;GAEG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;IAG/C,QAAQ,EAAE,kBAAkB,CAAC,MAAM,CAAC;gBAD3C,MAAM,EAAE,MAAM,EACP,QAAQ,EAAE,kBAAkB,CAAC,MAAM,CAAC;CAM5C;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAGxC,QAAQ,EAAE,kBAAkB,CAAC,qBAAqB,CAAC;gBAD1D,MAAM,EAAE,MAAM,EACP,QAAQ,EAAE,kBAAkB,CAAC,qBAAqB,CAAC;CAM3D"}
|
package/dist/esm/http-client.js
CHANGED
|
@@ -21,9 +21,13 @@ export class HttpClient {
|
|
|
21
21
|
* Permform a POST request
|
|
22
22
|
*/
|
|
23
23
|
async post(url, json = {}, headers = {}) {
|
|
24
|
-
|
|
24
|
+
let data = json;
|
|
25
|
+
if (!(json instanceof Blob) && !(json instanceof FormData)) {
|
|
26
|
+
headers["content-type"] = "application/json";
|
|
27
|
+
data = JSON.stringify(json);
|
|
28
|
+
}
|
|
25
29
|
headers.accept = "application/json";
|
|
26
|
-
return await this.request("POST", url,
|
|
30
|
+
return await this.request("POST", url, data, headers);
|
|
27
31
|
}
|
|
28
32
|
/**
|
|
29
33
|
* Permform a PUT request
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../src/http-client.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ShopInterface } from \"./repository.js\";\n\n/**\n * HttpClient is a simple wrapper around the fetch API, pre-configured with the shop's URL and access token\n */\nexport class HttpClient {\n\tprivate storage: { expiresIn: Date | null; token: string | null };\n\n\tconstructor(private shop: ShopInterface) {\n\t\tthis.storage = {\n\t\t\ttoken: null,\n\t\t\texpiresIn: null,\n\t\t};\n\t}\n\n\t/**\n\t * Permform a GET request\n\t */\n\tasync get<ResponseType>(\n\t\turl: string,\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\treturn await this.request(\"GET\", url, null, headers);\n\t}\n\n\t/**\n\t * Permform a POST request\n\t */\n\tasync post<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"POST\", url, JSON.stringify(json), headers);\n\t}\n\n\t/**\n\t * Permform a PUT request\n\t */\n\tasync put<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"PUT\", url, JSON.stringify(json), headers);\n\t}\n\n\t/**\n\t * Permform a PATCH request\n\t */\n\tasync patch<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"PATCH\", url, JSON.stringify(json), headers);\n\t}\n\n\t/**\n\t * Permform a DELETE request\n\t */\n\tasync delete<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"DELETE\", url, JSON.stringify(json), headers);\n\t}\n\n\tprivate async request<ResponseType>(\n\t\tmethod: string,\n\t\turl: string,\n\t\tbody: string | null = \"\",\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\tconst f = await globalThis.fetch(`${this.shop.getShopUrl()}/api${url}`, {\n\t\t\tbody,\n\t\t\theaders: Object.assign(\n\t\t\t\t{\n\t\t\t\t\tAuthorization: `Bearer ${await this.getToken()}`,\n\t\t\t\t},\n\t\t\t\theaders,\n\t\t\t),\n\t\t\tmethod,\n\t\t});\n\n\t\t// Obtain new token\n\t\tif (!f.ok && f.status === 401) {\n\t\t\tthis.storage.expiresIn = null;\n\n\t\t\treturn await this.request(method, url, body, headers);\n\t\t}\n\t\tif (!f.ok) {\n\t\t\tthrow new ApiClientRequestFailed(\n\t\t\t\tthis.shop.getShopId(),\n\t\t\t\tnew HttpClientResponse(f.status, await f.json(), f.headers),\n\t\t\t);\n\t\t}\n\n\t\tif (f.status === 204) {\n\t\t\treturn new HttpClientResponse<ResponseType>(\n\t\t\t\tf.status,\n\t\t\t\t{} as ResponseType,\n\t\t\t\tf.headers,\n\t\t\t);\n\t\t}\n\n\t\treturn new HttpClientResponse(f.status, await f.json(), f.headers);\n\t}\n\n\t/**\n\t * Obtain a valid bearer token\n\t */\n\tasync getToken(): Promise<string> {\n\t\tif (this.storage.expiresIn === null) {\n\t\t\tconst auth = await globalThis.fetch(\n\t\t\t\t`${this.shop.getShopUrl()}/api/oauth/token`,\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\tgrant_type: \"client_credentials\",\n\t\t\t\t\t\tclient_id: this.shop.getShopClientId(),\n\t\t\t\t\t\tclient_secret: this.shop.getShopClientSecret(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!auth.ok) {\n\t\t\t\tconst contentType = auth.headers.get(\"content-type\") || \"text/plain\";\n\t\t\t\tlet body = \"\";\n\n\t\t\t\tif (contentType.indexOf(\"application/json\") !== -1) {\n\t\t\t\t\tbody = await auth.json();\n\t\t\t\t} else {\n\t\t\t\t\tbody = await auth.text();\n\t\t\t\t}\n\n\t\t\t\tthrow new ApiClientAuthenticationFailed(\n\t\t\t\t\tthis.shop.getShopId(),\n\t\t\t\t\tnew HttpClientResponse<string>(auth.status, body, auth.headers),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst expireDate = new Date();\n\t\t\tconst authBody = (await auth.json()) as {\n\t\t\t\taccess_token: string;\n\t\t\t\texpires_in: number;\n\t\t\t};\n\t\t\tthis.storage.token = authBody.access_token;\n\t\t\texpireDate.setSeconds(expireDate.getSeconds() + authBody.expires_in);\n\t\t\tthis.storage.expiresIn = expireDate;\n\n\t\t\treturn this.storage.token as string;\n\t\t}\n\n\t\tif (this.storage.expiresIn.getTime() < new Date().getTime()) {\n\t\t\t// Expired\n\n\t\t\tthis.storage.expiresIn = null;\n\n\t\t\treturn await this.getToken();\n\t\t}\n\n\t\treturn this.storage.token as string;\n\t}\n}\n\n/**\n * HttpClientResponse is the response object of the HttpClient\n */\nexport class HttpClientResponse<ResponseType> {\n\tconstructor(\n\t\tpublic statusCode: number,\n\t\tpublic body: ResponseType,\n\t\tpublic headers: Headers,\n\t) {}\n}\n\ntype ShopwareErrorResponse = {\n\terrors: {\n\t\tcode: string;\n\t\tstatus: string;\n\t\ttitle: string;\n\t\tdetail: string;\n\t}[];\n};\n\n/**\n * ApiClientAuthenticationFailed is thrown when the authentication to the shop's API fails\n */\nexport class ApiClientAuthenticationFailed extends Error {\n\tconstructor(\n\t\tshopId: string,\n\t\tpublic response: HttpClientResponse<string>,\n\t) {\n\t\tsuper(\n\t\t\t`The api client authentication to shop with id: ${shopId} with response: ${JSON.stringify(response.body)}`,\n\t\t);\n\t}\n}\n\n/**\n * ApiClientRequestFailed is thrown when the request to the shop's API fails\n */\nexport class ApiClientRequestFailed extends Error {\n\tconstructor(\n\t\tshopId: string,\n\t\tpublic response: HttpClientResponse<ShopwareErrorResponse>,\n\t) {\n\t\tconst message = response.body.errors.map((e) => e.detail).join(\", \");\n\n\t\tsuper(`Request failed with error: ${message} for shop with id: ${shopId}`);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../src/http-client.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ShopInterface } from \"./repository.js\";\n\n/**\n * HttpClient is a simple wrapper around the fetch API, pre-configured with the shop's URL and access token\n */\nexport class HttpClient {\n\tprivate storage: { expiresIn: Date | null; token: string | null };\n\n\tconstructor(private shop: ShopInterface) {\n\t\tthis.storage = {\n\t\t\ttoken: null,\n\t\t\texpiresIn: null,\n\t\t};\n\t}\n\n\t/**\n\t * Permform a GET request\n\t */\n\tasync get<ResponseType>(\n\t\turl: string,\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\treturn await this.request(\"GET\", url, null, headers);\n\t}\n\n\t/**\n\t * Permform a POST request\n\t */\n\tasync post<ResponseType>(\n\t\turl: string,\n\t\tjson: object | FormData | Blob = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\tlet data: object | FormData | Blob | string = json;\n\n\t\tif (!(json instanceof Blob) && !(json instanceof FormData)) {\n\t\t\theaders[\"content-type\"] = \"application/json\";\n\t\t\tdata = JSON.stringify(json);\n\t\t}\n\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\n\t\t\t\"POST\",\n\t\t\turl,\n\t\t\tdata as FormData | Blob | string,\n\t\t\theaders,\n\t\t);\n\t}\n\n\t/**\n\t * Permform a PUT request\n\t */\n\tasync put<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"PUT\", url, JSON.stringify(json), headers);\n\t}\n\n\t/**\n\t * Permform a PATCH request\n\t */\n\tasync patch<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"PATCH\", url, JSON.stringify(json), headers);\n\t}\n\n\t/**\n\t * Permform a DELETE request\n\t */\n\tasync delete<ResponseType>(\n\t\turl: string,\n\t\tjson: object = {},\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\theaders[\"content-type\"] = \"application/json\";\n\t\theaders.accept = \"application/json\";\n\n\t\treturn await this.request(\"DELETE\", url, JSON.stringify(json), headers);\n\t}\n\n\tprivate async request<ResponseType>(\n\t\tmethod: string,\n\t\turl: string,\n\t\tbody: string | FormData | Blob | null = \"\",\n\t\theaders: Record<string, string> = {},\n\t): Promise<HttpClientResponse<ResponseType>> {\n\t\tconst f = await globalThis.fetch(`${this.shop.getShopUrl()}/api${url}`, {\n\t\t\tbody,\n\t\t\theaders: Object.assign(\n\t\t\t\t{\n\t\t\t\t\tAuthorization: `Bearer ${await this.getToken()}`,\n\t\t\t\t},\n\t\t\t\theaders,\n\t\t\t),\n\t\t\tmethod,\n\t\t});\n\n\t\t// Obtain new token\n\t\tif (!f.ok && f.status === 401) {\n\t\t\tthis.storage.expiresIn = null;\n\n\t\t\treturn await this.request(method, url, body, headers);\n\t\t}\n\t\tif (!f.ok) {\n\t\t\tthrow new ApiClientRequestFailed(\n\t\t\t\tthis.shop.getShopId(),\n\t\t\t\tnew HttpClientResponse(f.status, await f.json(), f.headers),\n\t\t\t);\n\t\t}\n\n\t\tif (f.status === 204) {\n\t\t\treturn new HttpClientResponse<ResponseType>(\n\t\t\t\tf.status,\n\t\t\t\t{} as ResponseType,\n\t\t\t\tf.headers,\n\t\t\t);\n\t\t}\n\n\t\treturn new HttpClientResponse(f.status, await f.json(), f.headers);\n\t}\n\n\t/**\n\t * Obtain a valid bearer token\n\t */\n\tasync getToken(): Promise<string> {\n\t\tif (this.storage.expiresIn === null) {\n\t\t\tconst auth = await globalThis.fetch(\n\t\t\t\t`${this.shop.getShopUrl()}/api/oauth/token`,\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\tgrant_type: \"client_credentials\",\n\t\t\t\t\t\tclient_id: this.shop.getShopClientId(),\n\t\t\t\t\t\tclient_secret: this.shop.getShopClientSecret(),\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (!auth.ok) {\n\t\t\t\tconst contentType = auth.headers.get(\"content-type\") || \"text/plain\";\n\t\t\t\tlet body = \"\";\n\n\t\t\t\tif (contentType.indexOf(\"application/json\") !== -1) {\n\t\t\t\t\tbody = await auth.json();\n\t\t\t\t} else {\n\t\t\t\t\tbody = await auth.text();\n\t\t\t\t}\n\n\t\t\t\tthrow new ApiClientAuthenticationFailed(\n\t\t\t\t\tthis.shop.getShopId(),\n\t\t\t\t\tnew HttpClientResponse<string>(auth.status, body, auth.headers),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst expireDate = new Date();\n\t\t\tconst authBody = (await auth.json()) as {\n\t\t\t\taccess_token: string;\n\t\t\t\texpires_in: number;\n\t\t\t};\n\t\t\tthis.storage.token = authBody.access_token;\n\t\t\texpireDate.setSeconds(expireDate.getSeconds() + authBody.expires_in);\n\t\t\tthis.storage.expiresIn = expireDate;\n\n\t\t\treturn this.storage.token as string;\n\t\t}\n\n\t\tif (this.storage.expiresIn.getTime() < new Date().getTime()) {\n\t\t\t// Expired\n\n\t\t\tthis.storage.expiresIn = null;\n\n\t\t\treturn await this.getToken();\n\t\t}\n\n\t\treturn this.storage.token as string;\n\t}\n}\n\n/**\n * HttpClientResponse is the response object of the HttpClient\n */\nexport class HttpClientResponse<ResponseType> {\n\tconstructor(\n\t\tpublic statusCode: number,\n\t\tpublic body: ResponseType,\n\t\tpublic headers: Headers,\n\t) {}\n}\n\ntype ShopwareErrorResponse = {\n\terrors: {\n\t\tcode: string;\n\t\tstatus: string;\n\t\ttitle: string;\n\t\tdetail: string;\n\t}[];\n};\n\n/**\n * ApiClientAuthenticationFailed is thrown when the authentication to the shop's API fails\n */\nexport class ApiClientAuthenticationFailed extends Error {\n\tconstructor(\n\t\tshopId: string,\n\t\tpublic response: HttpClientResponse<string>,\n\t) {\n\t\tsuper(\n\t\t\t`The api client authentication to shop with id: ${shopId} with response: ${JSON.stringify(response.body)}`,\n\t\t);\n\t}\n}\n\n/**\n * ApiClientRequestFailed is thrown when the request to the shop's API fails\n */\nexport class ApiClientRequestFailed extends Error {\n\tconstructor(\n\t\tshopId: string,\n\t\tpublic response: HttpClientResponse<ShopwareErrorResponse>,\n\t) {\n\t\tconst message = response.body.errors.map((e) => e.detail).join(\", \");\n\n\t\tsuper(`Request failed with error: ${message} for shop with id: ${shopId}`);\n\t}\n}\n"]}
|