@shopware-ag/app-server-sdk 1.0.0 → 1.1.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.
Files changed (210) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +23 -4
  3. package/dist/commonjs/context-resolver.test.d.ts +2 -0
  4. package/dist/commonjs/context-resolver.test.d.ts.map +1 -0
  5. package/dist/commonjs/context-resolver.test.js +81 -0
  6. package/dist/commonjs/context-resolver.test.js.map +1 -0
  7. package/dist/commonjs/helper/app-actions.test.d.ts +2 -0
  8. package/dist/commonjs/helper/app-actions.test.d.ts.map +1 -0
  9. package/dist/commonjs/helper/app-actions.test.js +31 -0
  10. package/dist/commonjs/helper/app-actions.test.js.map +1 -0
  11. package/dist/commonjs/http-client.test.d.ts +2 -0
  12. package/dist/commonjs/http-client.test.d.ts.map +1 -0
  13. package/dist/commonjs/http-client.test.js +71 -0
  14. package/dist/commonjs/http-client.test.js.map +1 -0
  15. package/dist/commonjs/integration/bun-sqlite.d.ts +11 -0
  16. package/dist/commonjs/integration/bun-sqlite.d.ts.map +1 -0
  17. package/dist/commonjs/integration/bun-sqlite.js +60 -0
  18. package/dist/commonjs/integration/bun-sqlite.js.map +1 -0
  19. package/dist/commonjs/integration/bun-sqlite.test.d.ts +2 -0
  20. package/dist/commonjs/integration/bun-sqlite.test.d.ts.map +1 -0
  21. package/dist/commonjs/integration/bun-sqlite.test.js +24 -0
  22. package/dist/commonjs/integration/bun-sqlite.test.js.map +1 -0
  23. package/dist/{deno/service/cloudflare.d.ts → commonjs/integration/cloudflare-kv.d.ts} +1 -24
  24. package/dist/commonjs/integration/cloudflare-kv.d.ts.map +1 -0
  25. package/dist/commonjs/{service/cloudflare.js → integration/cloudflare-kv.js} +5 -1
  26. package/dist/commonjs/integration/cloudflare-kv.js.map +1 -0
  27. package/dist/commonjs/integration/cloudflare.test.d.ts +2 -0
  28. package/dist/commonjs/integration/cloudflare.test.d.ts.map +1 -0
  29. package/dist/commonjs/integration/cloudflare.test.js +39 -0
  30. package/dist/commonjs/integration/cloudflare.test.js.map +1 -0
  31. package/dist/{esm/service/deno.d.ts → commonjs/integration/deno-kv.d.ts} +1 -1
  32. package/dist/commonjs/integration/deno-kv.d.ts.map +1 -0
  33. package/dist/commonjs/{service/deno.js → integration/deno-kv.js} +5 -1
  34. package/dist/commonjs/integration/deno-kv.js.map +1 -0
  35. package/dist/commonjs/integration/deno.test.d.ts +2 -0
  36. package/dist/commonjs/integration/deno.test.d.ts.map +1 -0
  37. package/dist/commonjs/integration/deno.test.js +48 -0
  38. package/dist/commonjs/integration/deno.test.js.map +1 -0
  39. package/dist/commonjs/integration/dynamodb.d.ts +13 -0
  40. package/dist/commonjs/integration/dynamodb.d.ts.map +1 -0
  41. package/dist/commonjs/integration/dynamodb.js +73 -0
  42. package/dist/commonjs/integration/dynamodb.js.map +1 -0
  43. package/dist/commonjs/integration/dynamodb.test.d.ts +2 -0
  44. package/dist/commonjs/integration/dynamodb.test.d.ts.map +1 -0
  45. package/dist/commonjs/integration/dynamodb.test.js +132 -0
  46. package/dist/commonjs/integration/dynamodb.test.js.map +1 -0
  47. package/dist/commonjs/integration/hono.d.ts +29 -0
  48. package/dist/commonjs/integration/hono.d.ts.map +1 -0
  49. package/dist/commonjs/{framework → integration}/hono.js +25 -4
  50. package/dist/commonjs/integration/hono.js.map +1 -0
  51. package/dist/commonjs/integration/hono.test.d.ts +2 -0
  52. package/dist/commonjs/integration/hono.test.d.ts.map +1 -0
  53. package/dist/commonjs/integration/hono.test.js +86 -0
  54. package/dist/commonjs/integration/hono.test.js.map +1 -0
  55. package/dist/commonjs/registration.d.ts +24 -0
  56. package/dist/commonjs/registration.d.ts.map +1 -1
  57. package/dist/commonjs/registration.js +42 -3
  58. package/dist/commonjs/registration.js.map +1 -1
  59. package/dist/commonjs/registration.test.d.ts +2 -0
  60. package/dist/commonjs/registration.test.d.ts.map +1 -0
  61. package/dist/commonjs/registration.test.js +59 -0
  62. package/dist/commonjs/registration.test.js.map +1 -0
  63. package/dist/commonjs/repository.d.ts +5 -1
  64. package/dist/commonjs/repository.d.ts.map +1 -1
  65. package/dist/commonjs/repository.js +7 -1
  66. package/dist/commonjs/repository.js.map +1 -1
  67. package/dist/commonjs/repository.test.d.ts +2 -0
  68. package/dist/commonjs/repository.test.d.ts.map +1 -0
  69. package/dist/commonjs/repository.test.js +32 -0
  70. package/dist/commonjs/repository.test.js.map +1 -0
  71. package/dist/commonjs/signer.test.d.ts +2 -0
  72. package/dist/commonjs/signer.test.d.ts.map +1 -0
  73. package/dist/commonjs/signer.test.js +25 -0
  74. package/dist/commonjs/signer.test.js.map +1 -0
  75. package/dist/esm/context-resolver.test.d.ts +2 -0
  76. package/dist/esm/context-resolver.test.d.ts.map +1 -0
  77. package/dist/esm/context-resolver.test.js +79 -0
  78. package/dist/esm/context-resolver.test.js.map +1 -0
  79. package/dist/esm/helper/app-actions.test.d.ts +2 -0
  80. package/dist/esm/helper/app-actions.test.d.ts.map +1 -0
  81. package/dist/esm/helper/app-actions.test.js +29 -0
  82. package/dist/esm/helper/app-actions.test.js.map +1 -0
  83. package/dist/esm/http-client.test.d.ts +2 -0
  84. package/dist/esm/http-client.test.d.ts.map +1 -0
  85. package/dist/esm/http-client.test.js +69 -0
  86. package/dist/esm/http-client.test.js.map +1 -0
  87. package/dist/esm/integration/bun-sqlite.d.ts +11 -0
  88. package/dist/esm/integration/bun-sqlite.d.ts.map +1 -0
  89. package/dist/esm/integration/bun-sqlite.js +56 -0
  90. package/dist/esm/integration/bun-sqlite.js.map +1 -0
  91. package/dist/esm/integration/bun-sqlite.test.d.ts +2 -0
  92. package/dist/esm/integration/bun-sqlite.test.d.ts.map +1 -0
  93. package/dist/esm/integration/bun-sqlite.test.js +22 -0
  94. package/dist/esm/integration/bun-sqlite.test.js.map +1 -0
  95. package/dist/{commonjs/service/cloudflare.d.ts → esm/integration/cloudflare-kv.d.ts} +1 -24
  96. package/dist/esm/integration/cloudflare-kv.d.ts.map +1 -0
  97. package/dist/esm/{service/cloudflare.js → integration/cloudflare-kv.js} +5 -1
  98. package/dist/esm/integration/cloudflare-kv.js.map +1 -0
  99. package/dist/esm/integration/cloudflare.test.d.ts +2 -0
  100. package/dist/esm/integration/cloudflare.test.d.ts.map +1 -0
  101. package/dist/esm/integration/cloudflare.test.js +37 -0
  102. package/dist/esm/integration/cloudflare.test.js.map +1 -0
  103. package/dist/{commonjs/service/deno.d.ts → esm/integration/deno-kv.d.ts} +1 -1
  104. package/dist/esm/integration/deno-kv.d.ts.map +1 -0
  105. package/dist/{deno/service/deno.js → esm/integration/deno-kv.js} +5 -1
  106. package/dist/esm/integration/deno-kv.js.map +1 -0
  107. package/dist/esm/integration/deno.test.d.ts +2 -0
  108. package/dist/esm/integration/deno.test.d.ts.map +1 -0
  109. package/dist/esm/integration/deno.test.js +46 -0
  110. package/dist/esm/integration/deno.test.js.map +1 -0
  111. package/dist/esm/integration/dynamodb.d.ts +13 -0
  112. package/dist/esm/integration/dynamodb.d.ts.map +1 -0
  113. package/dist/esm/integration/dynamodb.js +69 -0
  114. package/dist/esm/integration/dynamodb.js.map +1 -0
  115. package/dist/esm/integration/dynamodb.test.d.ts +2 -0
  116. package/dist/esm/integration/dynamodb.test.d.ts.map +1 -0
  117. package/dist/esm/integration/dynamodb.test.js +130 -0
  118. package/dist/esm/integration/dynamodb.test.js.map +1 -0
  119. package/dist/esm/integration/hono.d.ts +29 -0
  120. package/dist/esm/integration/hono.d.ts.map +1 -0
  121. package/dist/{deno/framework → esm/integration}/hono.js +25 -4
  122. package/dist/esm/integration/hono.js.map +1 -0
  123. package/dist/esm/integration/hono.test.d.ts +2 -0
  124. package/dist/esm/integration/hono.test.d.ts.map +1 -0
  125. package/dist/esm/integration/hono.test.js +84 -0
  126. package/dist/esm/integration/hono.test.js.map +1 -0
  127. package/dist/esm/registration.d.ts +24 -0
  128. package/dist/esm/registration.d.ts.map +1 -1
  129. package/dist/esm/registration.js +42 -3
  130. package/dist/esm/registration.js.map +1 -1
  131. package/dist/esm/registration.test.d.ts +2 -0
  132. package/dist/esm/registration.test.d.ts.map +1 -0
  133. package/dist/esm/registration.test.js +57 -0
  134. package/dist/esm/registration.test.js.map +1 -0
  135. package/dist/esm/repository.d.ts +5 -1
  136. package/dist/esm/repository.d.ts.map +1 -1
  137. package/dist/esm/repository.js +7 -1
  138. package/dist/esm/repository.js.map +1 -1
  139. package/dist/esm/repository.test.d.ts +2 -0
  140. package/dist/esm/repository.test.d.ts.map +1 -0
  141. package/dist/esm/repository.test.js +30 -0
  142. package/dist/esm/repository.test.js.map +1 -0
  143. package/dist/esm/signer.test.d.ts +2 -0
  144. package/dist/esm/signer.test.d.ts.map +1 -0
  145. package/dist/esm/signer.test.js +23 -0
  146. package/dist/esm/signer.test.js.map +1 -0
  147. package/package.json +87 -16
  148. package/dist/commonjs/framework/hono.d.ts +0 -36
  149. package/dist/commonjs/framework/hono.d.ts.map +0 -1
  150. package/dist/commonjs/framework/hono.js.map +0 -1
  151. package/dist/commonjs/service/cloudflare.d.ts.map +0 -1
  152. package/dist/commonjs/service/cloudflare.js.map +0 -1
  153. package/dist/commonjs/service/deno.d.ts.map +0 -1
  154. package/dist/commonjs/service/deno.js.map +0 -1
  155. package/dist/deno/app.d.ts +0 -31
  156. package/dist/deno/app.d.ts.map +0 -1
  157. package/dist/deno/app.js +0 -21
  158. package/dist/deno/app.js.map +0 -1
  159. package/dist/deno/context-resolver.d.ts +0 -30
  160. package/dist/deno/context-resolver.d.ts.map +0 -1
  161. package/dist/deno/context-resolver.js +0 -65
  162. package/dist/deno/context-resolver.js.map +0 -1
  163. package/dist/deno/framework/hono.d.ts +0 -36
  164. package/dist/deno/framework/hono.d.ts.map +0 -1
  165. package/dist/deno/framework/hono.js.map +0 -1
  166. package/dist/deno/helper/app-actions.d.ts +0 -13
  167. package/dist/deno/helper/app-actions.d.ts.map +0 -1
  168. package/dist/deno/helper/app-actions.js +0 -49
  169. package/dist/deno/helper/app-actions.js.map +0 -1
  170. package/dist/deno/http-client.d.ts +0 -67
  171. package/dist/deno/http-client.d.ts.map +0 -1
  172. package/dist/deno/http-client.js +0 -148
  173. package/dist/deno/http-client.js.map +0 -1
  174. package/dist/deno/mod.d.ts +0 -6
  175. package/dist/deno/mod.d.ts.map +0 -1
  176. package/dist/deno/mod.js +0 -5
  177. package/dist/deno/mod.js.map +0 -1
  178. package/dist/deno/package.json +0 -3
  179. package/dist/deno/registration.d.ts +0 -18
  180. package/dist/deno/registration.d.ts.map +0 -1
  181. package/dist/deno/registration.js +0 -84
  182. package/dist/deno/registration.js.map +0 -1
  183. package/dist/deno/repository.d.ts +0 -51
  184. package/dist/deno/repository.d.ts.map +0 -1
  185. package/dist/deno/repository.js +0 -63
  186. package/dist/deno/repository.js.map +0 -1
  187. package/dist/deno/service/cloudflare.d.ts.map +0 -1
  188. package/dist/deno/service/cloudflare.js +0 -41
  189. package/dist/deno/service/cloudflare.js.map +0 -1
  190. package/dist/deno/service/deno.d.ts +0 -18
  191. package/dist/deno/service/deno.d.ts.map +0 -1
  192. package/dist/deno/service/deno.js.map +0 -1
  193. package/dist/deno/signer.d.ts +0 -12
  194. package/dist/deno/signer.d.ts.map +0 -1
  195. package/dist/deno/signer.js +0 -54
  196. package/dist/deno/signer.js.map +0 -1
  197. package/dist/deno/types.d.ts +0 -28
  198. package/dist/deno/types.d.ts.map +0 -1
  199. package/dist/deno/types.js +0 -2
  200. package/dist/deno/types.js.map +0 -1
  201. package/dist/esm/framework/hono.d.ts +0 -36
  202. package/dist/esm/framework/hono.d.ts.map +0 -1
  203. package/dist/esm/framework/hono.js +0 -81
  204. package/dist/esm/framework/hono.js.map +0 -1
  205. package/dist/esm/service/cloudflare.d.ts +0 -43
  206. package/dist/esm/service/cloudflare.d.ts.map +0 -1
  207. package/dist/esm/service/cloudflare.js.map +0 -1
  208. package/dist/esm/service/deno.d.ts.map +0 -1
  209. package/dist/esm/service/deno.js +0 -44
  210. package/dist/esm/service/deno.js.map +0 -1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Friends of Shopware
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 CHANGED
@@ -1,10 +1,23 @@
1
- # App Server
1
+ # Shopware App Server SDK in TypeScript
2
2
 
3
- This package can be used to create a Shopware App Backend. It's build independent of any JavaScript framework. It relies on Fetch-standardized Request and Response objects.
3
+ This SDK is written in pure Typescript with portability in mind being able to use it on Node (20+), Deno, Cloudflare Worker or other runtimes.
4
4
 
5
- ## Standalone example with Bun
5
+ ## Features
6
6
 
7
- ```js
7
+ - Provides registration process for app
8
+ - Verify and signing of requests / responses
9
+ - preconfigured API Client
10
+ - Complete Registration Handshake between Shopware and this
11
+
12
+ ## How to use it?
13
+
14
+ ```bash
15
+ npm install @shopware-ag/app-server-sdk --save
16
+ ```
17
+
18
+ ## Example
19
+
20
+ ```typescript
8
21
  import { AppServer, InMemoryShopRepository } from '@shopware-ag/app-server-sdk'
9
22
  import { createNotificationResponse } from '@shopware-ag/app-server-sdk/helper/app-actions'
10
23
 
@@ -41,3 +54,9 @@ const server = Bun.serve({
41
54
 
42
55
  console.log(`Listening on localhost:${server.port}`);
43
56
  ```
57
+
58
+ Checkout the [examples](./examples) folder for more examples using:
59
+
60
+ - [Cloudflare Worker with Hono](./examples/cloudflare-hono)
61
+ - [Deno with Hono](./examples/deno-hono)
62
+ - [Node with Hono](./examples/node-hono)
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=context-resolver.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-resolver.test.d.ts","sourceRoot":"","sources":["../../src/context-resolver.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const bun_test_1 = require("bun:test");
4
+ const app_js_1 = require("../src/app.js");
5
+ const context_resolver_js_1 = require("../src/context-resolver.js");
6
+ const repository_js_1 = require("../src/repository.js");
7
+ (0, bun_test_1.describe)("Context Resolver", async () => {
8
+ const app = new app_js_1.AppServer({
9
+ appName: "test",
10
+ appSecret: "test",
11
+ authorizeCallbackUrl: "test",
12
+ }, new repository_js_1.InMemoryShopRepository());
13
+ await app.repository.createShop("blaa", "test", "test");
14
+ const contextResolver = new context_resolver_js_1.ContextResolver(app);
15
+ (0, bun_test_1.test)("fromBrowser: shop does not exist", async () => {
16
+ (0, bun_test_1.expect)(contextResolver.fromBrowser(new Request("https://example.com/?shop-id=test&shopware-shop-signature=aaa"))).rejects.toThrowError("Cannot find shop by id test");
17
+ });
18
+ (0, bun_test_1.test)("fromBrowser: missing header", async () => {
19
+ (0, bun_test_1.expect)(contextResolver.fromBrowser(new Request("https://example.com/?shop-id=blaa"))).rejects.toThrowError("Missing shopware-shop-signature query parameter");
20
+ });
21
+ (0, bun_test_1.test)("fromBrowser: shop exists", async () => {
22
+ app.signer.verifyGetRequest = bun_test_1.jest.fn().mockResolvedValue(true);
23
+ const context = await contextResolver.fromBrowser(new Request("https://example.com/?shop-id=blaa&shopware-shop-signature=aaa"));
24
+ (0, bun_test_1.expect)(context.payload).toEqual({
25
+ "shop-id": "blaa",
26
+ "shopware-shop-signature": "aaa",
27
+ });
28
+ });
29
+ (0, bun_test_1.test)("fromSource: missing signature header", async () => {
30
+ (0, bun_test_1.expect)(contextResolver.fromAPI(new Request("https://example.com/", {
31
+ body: JSON.stringify({
32
+ source: {
33
+ shopId: "blaa",
34
+ },
35
+ }),
36
+ }))).rejects.toThrowError("Missing shopware-shop-signature header");
37
+ });
38
+ (0, bun_test_1.test)("fromSource: shop does not exists", async () => {
39
+ (0, bun_test_1.expect)(contextResolver.fromAPI(new Request("https://example.com/", {
40
+ headers: {
41
+ "shopware-shop-signature": "aaa",
42
+ },
43
+ body: JSON.stringify({
44
+ source: {
45
+ shopId: "test",
46
+ },
47
+ }),
48
+ }))).rejects.toThrowError("Cannot find shop by id test");
49
+ });
50
+ (0, bun_test_1.test)("fromSource: invalid signature", async () => {
51
+ (0, bun_test_1.expect)(contextResolver.fromAPI(new Request("https://example.com/", {
52
+ headers: {
53
+ "shopware-shop-signature": "aaa",
54
+ },
55
+ body: JSON.stringify({
56
+ source: {
57
+ shopId: "blaa",
58
+ },
59
+ }),
60
+ }))).rejects.toThrowError("Invalid signature");
61
+ });
62
+ (0, bun_test_1.test)("fromSource: resolved", async () => {
63
+ app.signer.verify = bun_test_1.jest.fn().mockResolvedValue(true);
64
+ const ctx = await contextResolver.fromAPI(new Request("https://example.com/", {
65
+ headers: {
66
+ "shopware-shop-signature": "aaa",
67
+ },
68
+ body: JSON.stringify({
69
+ source: {
70
+ shopId: "blaa",
71
+ },
72
+ }),
73
+ }));
74
+ (0, bun_test_1.expect)(ctx.payload).toEqual({
75
+ source: {
76
+ shopId: "blaa",
77
+ },
78
+ });
79
+ });
80
+ });
81
+ //# sourceMappingURL=context-resolver.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-resolver.test.js","sourceRoot":"","sources":["../../src/context-resolver.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, jest, test } from \"bun:test\";\nimport { AppServer } from \"../src/app.js\";\nimport { ContextResolver } from \"../src/context-resolver.js\";\nimport { InMemoryShopRepository, SimpleShop } from \"../src/repository.js\";\n\ndescribe(\"Context Resolver\", async () => {\n\tconst app = new AppServer(\n\t\t{\n\t\t\tappName: \"test\",\n\t\t\tappSecret: \"test\",\n\t\t\tauthorizeCallbackUrl: \"test\",\n\t\t},\n\t\tnew InMemoryShopRepository(),\n\t);\n\n\tawait app.repository.createShop(\"blaa\", \"test\", \"test\");\n\n\tconst contextResolver = new ContextResolver(app);\n\n\ttest(\"fromBrowser: shop does not exist\", async () => {\n\t\texpect(\n\t\t\tcontextResolver.fromBrowser(\n\t\t\t\tnew Request(\n\t\t\t\t\t\"https://example.com/?shop-id=test&shopware-shop-signature=aaa\",\n\t\t\t\t),\n\t\t\t),\n\t\t).rejects.toThrowError(\"Cannot find shop by id test\");\n\t});\n\n\ttest(\"fromBrowser: missing header\", async () => {\n\t\texpect(\n\t\t\tcontextResolver.fromBrowser(\n\t\t\t\tnew Request(\"https://example.com/?shop-id=blaa\"),\n\t\t\t),\n\t\t).rejects.toThrowError(\"Missing shopware-shop-signature query parameter\");\n\t});\n\n\ttest(\"fromBrowser: shop exists\", async () => {\n\t\tapp.signer.verifyGetRequest = jest.fn().mockResolvedValue(true);\n\n\t\tconst context = await contextResolver.fromBrowser(\n\t\t\tnew Request(\n\t\t\t\t\"https://example.com/?shop-id=blaa&shopware-shop-signature=aaa\",\n\t\t\t),\n\t\t);\n\n\t\texpect(context.payload).toEqual({\n\t\t\t\"shop-id\": \"blaa\",\n\t\t\t\"shopware-shop-signature\": \"aaa\",\n\t\t});\n\t});\n\n\ttest(\"fromSource: missing signature header\", async () => {\n\t\texpect(\n\t\t\tcontextResolver.fromAPI(\n\t\t\t\tnew Request(\"https://example.com/\", {\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\tsource: {\n\t\t\t\t\t\t\tshopId: \"blaa\",\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t}),\n\t\t\t),\n\t\t).rejects.toThrowError(\"Missing shopware-shop-signature header\");\n\t});\n\n\ttest(\"fromSource: shop does not exists\", async () => {\n\t\texpect(\n\t\t\tcontextResolver.fromAPI(\n\t\t\t\tnew Request(\"https://example.com/\", {\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"shopware-shop-signature\": \"aaa\",\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\tsource: {\n\t\t\t\t\t\t\tshopId: \"test\",\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t}),\n\t\t\t),\n\t\t).rejects.toThrowError(\"Cannot find shop by id test\");\n\t});\n\n\ttest(\"fromSource: invalid signature\", async () => {\n\t\texpect(\n\t\t\tcontextResolver.fromAPI(\n\t\t\t\tnew Request(\"https://example.com/\", {\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"shopware-shop-signature\": \"aaa\",\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\tsource: {\n\t\t\t\t\t\t\tshopId: \"blaa\",\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t}),\n\t\t\t),\n\t\t).rejects.toThrowError(\"Invalid signature\");\n\t});\n\n\ttest(\"fromSource: resolved\", async () => {\n\t\tapp.signer.verify = jest.fn().mockResolvedValue(true);\n\n\t\tconst ctx = await contextResolver.fromAPI(\n\t\t\tnew Request(\"https://example.com/\", {\n\t\t\t\theaders: {\n\t\t\t\t\t\"shopware-shop-signature\": \"aaa\",\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tsource: {\n\t\t\t\t\t\tshopId: \"blaa\",\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t}),\n\t\t);\n\n\t\texpect(ctx.payload).toEqual({\n\t\t\tsource: {\n\t\t\t\tshopId: \"blaa\",\n\t\t\t},\n\t\t});\n\t});\n});\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=app-actions.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-actions.test.d.ts","sourceRoot":"","sources":["../../../src/helper/app-actions.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const bun_test_1 = require("bun:test");
4
+ const app_actions_js_1 = require("../../src/helper/app-actions.js");
5
+ (0, bun_test_1.describe)("AppActions", async () => {
6
+ (0, bun_test_1.test)("createNewTabResponse", async () => {
7
+ const resp = (0, app_actions_js_1.createNewTabResponse)("test");
8
+ (0, bun_test_1.expect)(resp.headers.get("content-type")).toBe("application/json");
9
+ (0, bun_test_1.expect)(await resp.text()).toBe(JSON.stringify({
10
+ actionType: "openNewTab",
11
+ payload: { redirectUrl: "test" },
12
+ }));
13
+ });
14
+ (0, bun_test_1.test)("createNotificationResponse", async () => {
15
+ const resp = (0, app_actions_js_1.createNotificationResponse)("success", "test");
16
+ (0, bun_test_1.expect)(resp.headers.get("content-type")).toBe("application/json");
17
+ (0, bun_test_1.expect)(await resp.text()).toBe(JSON.stringify({
18
+ actionType: "notification",
19
+ payload: { status: "success", message: "test" },
20
+ }));
21
+ });
22
+ (0, bun_test_1.test)("createModalResponse", async () => {
23
+ const resp = (0, app_actions_js_1.createModalResponse)("test", "small", true);
24
+ (0, bun_test_1.expect)(resp.headers.get("content-type")).toBe("application/json");
25
+ (0, bun_test_1.expect)(await resp.text()).toBe(JSON.stringify({
26
+ actionType: "openModal",
27
+ payload: { iframeUrl: "test", size: "small", expand: true },
28
+ }));
29
+ });
30
+ });
31
+ //# sourceMappingURL=app-actions.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-actions.test.js","sourceRoot":"","sources":["../../../src/helper/app-actions.test.ts"],"names":[],"mappings":";;AAAA,uCAAkD;AAClD,oEAIyC;AAEzC,IAAA,mBAAQ,EAAC,YAAY,EAAE,KAAK,IAAI,EAAE;IACjC,IAAA,eAAI,EAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,IAAI,GAAG,IAAA,qCAAoB,EAAC,MAAM,CAAC,CAAC;QAE1C,IAAA,iBAAM,EAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClE,IAAA,iBAAM,EAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAC7B,IAAI,CAAC,SAAS,CAAC;YACd,UAAU,EAAE,YAAY;YACxB,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE;SAChC,CAAC,CACF,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAA,eAAI,EAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,IAAI,GAAG,IAAA,2CAA0B,EAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAE3D,IAAA,iBAAM,EAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClE,IAAA,iBAAM,EAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAC7B,IAAI,CAAC,SAAS,CAAC;YACd,UAAU,EAAE,cAAc;YAC1B,OAAO,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE;SAC/C,CAAC,CACF,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAA,eAAI,EAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;QACtC,MAAM,IAAI,GAAG,IAAA,oCAAmB,EAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAExD,IAAA,iBAAM,EAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClE,IAAA,iBAAM,EAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAC7B,IAAI,CAAC,SAAS,CAAC;YACd,UAAU,EAAE,WAAW;YACvB,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE;SAC3D,CAAC,CACF,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, test } from \"bun:test\";\nimport {\n\tcreateModalResponse,\n\tcreateNewTabResponse,\n\tcreateNotificationResponse,\n} from \"../../src/helper/app-actions.js\";\n\ndescribe(\"AppActions\", async () => {\n\ttest(\"createNewTabResponse\", async () => {\n\t\tconst resp = createNewTabResponse(\"test\");\n\n\t\texpect(resp.headers.get(\"content-type\")).toBe(\"application/json\");\n\t\texpect(await resp.text()).toBe(\n\t\t\tJSON.stringify({\n\t\t\t\tactionType: \"openNewTab\",\n\t\t\t\tpayload: { redirectUrl: \"test\" },\n\t\t\t}),\n\t\t);\n\t});\n\n\ttest(\"createNotificationResponse\", async () => {\n\t\tconst resp = createNotificationResponse(\"success\", \"test\");\n\n\t\texpect(resp.headers.get(\"content-type\")).toBe(\"application/json\");\n\t\texpect(await resp.text()).toBe(\n\t\t\tJSON.stringify({\n\t\t\t\tactionType: \"notification\",\n\t\t\t\tpayload: { status: \"success\", message: \"test\" },\n\t\t\t}),\n\t\t);\n\t});\n\n\ttest(\"createModalResponse\", async () => {\n\t\tconst resp = createModalResponse(\"test\", \"small\", true);\n\n\t\texpect(resp.headers.get(\"content-type\")).toBe(\"application/json\");\n\t\texpect(await resp.text()).toBe(\n\t\t\tJSON.stringify({\n\t\t\t\tactionType: \"openModal\",\n\t\t\t\tpayload: { iframeUrl: \"test\", size: \"small\", expand: true },\n\t\t\t}),\n\t\t);\n\t});\n});\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=http-client.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.test.d.ts","sourceRoot":"","sources":["../../src/http-client.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const bun_test_1 = require("bun:test");
4
+ const http_client_js_1 = require("../src/http-client.js");
5
+ const repository_js_1 = require("../src/repository.js");
6
+ (0, bun_test_1.describe)("HTTP Client", async () => {
7
+ (0, bun_test_1.test)("getToken", async () => {
8
+ const mockFetch = (0, bun_test_1.spyOn)(global, "fetch").mockImplementation(() => Promise.resolve(new Response('{"access_token": "test", "expires_in": 3600}')));
9
+ const client = new http_client_js_1.HttpClient(new repository_js_1.SimpleShop("blaa", "test", "test"));
10
+ (0, bun_test_1.expect)(client.getToken()).resolves.toBe("test");
11
+ // We fetched already once the token, so the second time we should get it from the storage
12
+ await client.getToken();
13
+ (0, bun_test_1.expect)(mockFetch.mock.calls).toBeArrayOfSize(1);
14
+ mockFetch.mockRestore();
15
+ });
16
+ (0, bun_test_1.test)("getToken: failed request", async () => {
17
+ const mockFetch = (0, bun_test_1.spyOn)(global, "fetch").mockImplementation(() => Promise.resolve(new Response('{"error": "invalid_grant"}', { status: 400 })));
18
+ const client = new http_client_js_1.HttpClient(new repository_js_1.SimpleShop("blaa", "test", "test"));
19
+ (0, bun_test_1.expect)(client.getToken()).rejects.toThrowError("The api client authentication to shop with id: blaa");
20
+ mockFetch.mockRestore();
21
+ });
22
+ (0, bun_test_1.test)("getToken: expired refetch", async () => {
23
+ const mockFetch = (0, bun_test_1.spyOn)(global, "fetch").mockImplementation(() => Promise.resolve(new Response('{"access_token": "test", "expires_in": -500}')));
24
+ const client = new http_client_js_1.HttpClient(new repository_js_1.SimpleShop("blaa", "test", "test"));
25
+ (0, bun_test_1.expect)(client.getToken()).resolves.toBe("test");
26
+ (0, bun_test_1.expect)(mockFetch.mock.calls).toBeArrayOfSize(1);
27
+ (0, bun_test_1.expect)(client.getToken()).resolves.toBe("test");
28
+ (0, bun_test_1.expect)(mockFetch.mock.calls).toBeArrayOfSize(2);
29
+ mockFetch.mockRestore();
30
+ });
31
+ (0, bun_test_1.test)("get, post, put, patch, delete", async () => {
32
+ const mockFetch = (0, bun_test_1.spyOn)(global, "fetch").mockImplementationOnce(() => Promise.resolve(new Response('{"access_token": "test", "expires_in": 5000}')));
33
+ const client = new http_client_js_1.HttpClient(new repository_js_1.SimpleShop("blaa", "test", "test"));
34
+ mockFetch.mockImplementation(() => Promise.resolve(new Response('{"data": "test"}')));
35
+ (0, bun_test_1.expect)(client.get("/test")).resolves.toEqual({
36
+ body: { data: "test" },
37
+ headers: new Headers(),
38
+ statusCode: 200,
39
+ });
40
+ (0, bun_test_1.expect)(client.post("/test", { data: "test" })).resolves.toEqual({
41
+ body: { data: "test" },
42
+ headers: new Headers(),
43
+ statusCode: 200,
44
+ });
45
+ (0, bun_test_1.expect)(client.put("/test", { data: "test" })).resolves.toEqual({
46
+ body: { data: "test" },
47
+ headers: new Headers(),
48
+ statusCode: 200,
49
+ });
50
+ (0, bun_test_1.expect)(client.patch("/test", { data: "test" })).resolves.toEqual({
51
+ body: { data: "test" },
52
+ headers: new Headers(),
53
+ statusCode: 200,
54
+ });
55
+ (0, bun_test_1.expect)(client.delete("/test")).resolves.toEqual({
56
+ body: { data: "test" },
57
+ headers: new Headers(),
58
+ statusCode: 200,
59
+ });
60
+ (0, bun_test_1.expect)(mockFetch.mock.calls).toBeArrayOfSize(6);
61
+ mockFetch.mockRestore();
62
+ });
63
+ (0, bun_test_1.test)("get: request failed", async () => {
64
+ const mockFetch = (0, bun_test_1.spyOn)(global, "fetch").mockImplementationOnce(() => Promise.resolve(new Response('{"access_token": "test", "expires_in": 5000}')));
65
+ const client = new http_client_js_1.HttpClient(new repository_js_1.SimpleShop("blaa", "test", "test"));
66
+ mockFetch.mockImplementation(() => Promise.resolve(new Response('{"data": "test"}', { status: 400 })));
67
+ (0, bun_test_1.expect)(client.get("/test")).rejects.toThrowError("The api request failed with status code: 400 for shop with id: blaa");
68
+ mockFetch.mockRestore();
69
+ });
70
+ });
71
+ //# sourceMappingURL=http-client.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.test.js","sourceRoot":"","sources":["../../src/http-client.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, spyOn, test } from \"bun:test\";\nimport { HttpClient } from \"../src/http-client.js\";\nimport { SimpleShop } from \"../src/repository.js\";\n\ndescribe(\"HTTP Client\", async () => {\n\ttest(\"getToken\", async () => {\n\t\tconst mockFetch = spyOn(global, \"fetch\").mockImplementation(() =>\n\t\t\tPromise.resolve(\n\t\t\t\tnew Response('{\"access_token\": \"test\", \"expires_in\": 3600}'),\n\t\t\t),\n\t\t);\n\n\t\tconst client = new HttpClient(new SimpleShop(\"blaa\", \"test\", \"test\"));\n\t\texpect(client.getToken()).resolves.toBe(\"test\");\n\n\t\t// We fetched already once the token, so the second time we should get it from the storage\n\t\tawait client.getToken();\n\n\t\texpect(mockFetch.mock.calls).toBeArrayOfSize(1);\n\n\t\tmockFetch.mockRestore();\n\t});\n\n\ttest(\"getToken: failed request\", async () => {\n\t\tconst mockFetch = spyOn(global, \"fetch\").mockImplementation(() =>\n\t\t\tPromise.resolve(\n\t\t\t\tnew Response('{\"error\": \"invalid_grant\"}', { status: 400 }),\n\t\t\t),\n\t\t);\n\n\t\tconst client = new HttpClient(new SimpleShop(\"blaa\", \"test\", \"test\"));\n\t\texpect(client.getToken()).rejects.toThrowError(\n\t\t\t\"The api client authentication to shop with id: blaa\",\n\t\t);\n\n\t\tmockFetch.mockRestore();\n\t});\n\n\ttest(\"getToken: expired refetch\", async () => {\n\t\tconst mockFetch = spyOn(global, \"fetch\").mockImplementation(() =>\n\t\t\tPromise.resolve(\n\t\t\t\tnew Response('{\"access_token\": \"test\", \"expires_in\": -500}'),\n\t\t\t),\n\t\t);\n\n\t\tconst client = new HttpClient(new SimpleShop(\"blaa\", \"test\", \"test\"));\n\t\texpect(client.getToken()).resolves.toBe(\"test\");\n\n\t\texpect(mockFetch.mock.calls).toBeArrayOfSize(1);\n\n\t\texpect(client.getToken()).resolves.toBe(\"test\");\n\n\t\texpect(mockFetch.mock.calls).toBeArrayOfSize(2);\n\n\t\tmockFetch.mockRestore();\n\t});\n\n\ttest(\"get, post, put, patch, delete\", async () => {\n\t\tconst mockFetch = spyOn(global, \"fetch\").mockImplementationOnce(() =>\n\t\t\tPromise.resolve(\n\t\t\t\tnew Response('{\"access_token\": \"test\", \"expires_in\": 5000}'),\n\t\t\t),\n\t\t);\n\n\t\tconst client = new HttpClient(new SimpleShop(\"blaa\", \"test\", \"test\"));\n\n\t\tmockFetch.mockImplementation(() =>\n\t\t\tPromise.resolve(new Response('{\"data\": \"test\"}')),\n\t\t);\n\n\t\texpect(client.get(\"/test\")).resolves.toEqual({\n\t\t\tbody: { data: \"test\" },\n\t\t\theaders: new Headers(),\n\t\t\tstatusCode: 200,\n\t\t});\n\t\texpect(client.post(\"/test\", { data: \"test\" })).resolves.toEqual({\n\t\t\tbody: { data: \"test\" },\n\t\t\theaders: new Headers(),\n\t\t\tstatusCode: 200,\n\t\t});\n\t\texpect(client.put(\"/test\", { data: \"test\" })).resolves.toEqual({\n\t\t\tbody: { data: \"test\" },\n\t\t\theaders: new Headers(),\n\t\t\tstatusCode: 200,\n\t\t});\n\t\texpect(client.patch(\"/test\", { data: \"test\" })).resolves.toEqual({\n\t\t\tbody: { data: \"test\" },\n\t\t\theaders: new Headers(),\n\t\t\tstatusCode: 200,\n\t\t});\n\t\texpect(client.delete(\"/test\")).resolves.toEqual({\n\t\t\tbody: { data: \"test\" },\n\t\t\theaders: new Headers(),\n\t\t\tstatusCode: 200,\n\t\t});\n\n\t\texpect(mockFetch.mock.calls).toBeArrayOfSize(6);\n\n\t\tmockFetch.mockRestore();\n\t});\n\n\ttest(\"get: request failed\", async () => {\n\t\tconst mockFetch = spyOn(global, \"fetch\").mockImplementationOnce(() =>\n\t\t\tPromise.resolve(\n\t\t\t\tnew Response('{\"access_token\": \"test\", \"expires_in\": 5000}'),\n\t\t\t),\n\t\t);\n\n\t\tconst client = new HttpClient(new SimpleShop(\"blaa\", \"test\", \"test\"));\n\n\t\tmockFetch.mockImplementation(() =>\n\t\t\tPromise.resolve(new Response('{\"data\": \"test\"}', { status: 400 })),\n\t\t);\n\n\t\texpect(client.get(\"/test\")).rejects.toThrowError(\n\t\t\t\"The api request failed with status code: 400 for shop with id: blaa\",\n\t\t);\n\n\t\tmockFetch.mockRestore();\n\t});\n});\n"]}
@@ -0,0 +1,11 @@
1
+ import { type ShopRepositoryInterface, SimpleShop } from "../repository.js";
2
+ import { Database } from "bun:sqlite";
3
+ export declare class BunSqliteRepository implements ShopRepositoryInterface<SimpleShop> {
4
+ db: Database;
5
+ constructor(fileName: string);
6
+ createShop(id: string, url: string, secret: string): Promise<void>;
7
+ getShopById(id: string): Promise<SimpleShop | null>;
8
+ updateShop(shop: SimpleShop): Promise<void>;
9
+ deleteShop(id: string): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=bun-sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun-sqlite.d.ts","sourceRoot":"","sources":["../../../src/integration/bun-sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,qBAAa,mBACZ,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAE9C,EAAE,EAAE,QAAQ,CAAC;gBACD,QAAQ,EAAE,MAAM;IActB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAclE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA4BnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAa3C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG3C"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BunSqliteRepository = void 0;
4
+ const repository_js_1 = require("../repository.js");
5
+ const bun_sqlite_1 = require("bun:sqlite");
6
+ class BunSqliteRepository {
7
+ db;
8
+ constructor(fileName) {
9
+ this.db = new bun_sqlite_1.Database(fileName);
10
+ this.db.exec(`
11
+ CREATE TABLE IF NOT EXISTS shop (
12
+ id TEXT PRIMARY KEY,
13
+ active BOOLEAN DEFAULT 1,
14
+ url TEXT NOT NULL,
15
+ secret TEXT NOT NULL,
16
+ client_id TEXT NULL,
17
+ client_secret TEXT NULL
18
+ );
19
+ `);
20
+ }
21
+ async createShop(id, url, secret) {
22
+ const shop = await this.getShopById(id);
23
+ if (shop) {
24
+ return await this.updateShop(shop);
25
+ }
26
+ this.db.exec("INSERT INTO shop (id, url, secret) VALUES (?, ?, ?)", [
27
+ id,
28
+ url,
29
+ secret,
30
+ ]);
31
+ }
32
+ async getShopById(id) {
33
+ const query = this.db.query("SELECT * FROM shop WHERE id = ?");
34
+ const result = query.get(id);
35
+ if (!result) {
36
+ return null;
37
+ }
38
+ const shop = new repository_js_1.SimpleShop(result.id, result.url, result.secret);
39
+ if (result.client_id && result.client_secret) {
40
+ shop.setShopCredentials(result.client_id, result.client_secret);
41
+ }
42
+ shop.setShopActive(result.active);
43
+ return shop;
44
+ }
45
+ async updateShop(shop) {
46
+ this.db.exec("UPDATE shop SET url = ?, secret = ?, client_id = ?, client_secret = ?, active = ? WHERE id = ?", [
47
+ shop.getShopUrl(),
48
+ shop.getShopSecret(),
49
+ shop.getShopClientId(),
50
+ shop.getShopClientSecret(),
51
+ shop.getShopActive(),
52
+ shop.getShopId(),
53
+ ]);
54
+ }
55
+ async deleteShop(id) {
56
+ this.db.exec("DELETE FROM shop where id = ?", [id]);
57
+ }
58
+ }
59
+ exports.BunSqliteRepository = BunSqliteRepository;
60
+ //# sourceMappingURL=bun-sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun-sqlite.js","sourceRoot":"","sources":["../../../src/integration/bun-sqlite.ts"],"names":[],"mappings":";;;AAAA,oDAA4E;AAE5E,2CAAsC;AAEtC,MAAa,mBAAmB;IAG/B,EAAE,CAAW;IACb,YAAY,QAAgB;QAC3B,IAAI,CAAC,EAAE,GAAG,IAAI,qBAAQ,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;OASR,CAAC,CAAC;IACR,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,GAAW,EAAE,MAAc;QACvD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAExC,IAAI,IAAI,EAAE,CAAC;YACV,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,qDAAqD,EAAE;YACnE,EAAE;YACF,GAAG;YACH,MAAM;SACN,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAU;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAUzB,iCAAiC,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE7B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,0BAAU,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAElE,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YAC9C,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAElC,OAAO,IAAI,CAAC;IACb,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,IAAgB;QAChC,IAAI,CAAC,EAAE,CAAC,IAAI,CACX,gGAAgG,EAChG;YACC,IAAI,CAAC,UAAU,EAAE;YACjB,IAAI,CAAC,aAAa,EAAE;YACpB,IAAI,CAAC,eAAe,EAAE;YACtB,IAAI,CAAC,mBAAmB,EAAE;YAC1B,IAAI,CAAC,aAAa,EAAE;YACpB,IAAI,CAAC,SAAS,EAAE;SAChB,CACD,CAAC;IACH,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,EAAU;QAC1B,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,+BAA+B,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;CACD;AA5ED,kDA4EC","sourcesContent":["import { type ShopRepositoryInterface, SimpleShop } from \"../repository.js\";\n\nimport { Database } from \"bun:sqlite\";\n\nexport class BunSqliteRepository\n\timplements ShopRepositoryInterface<SimpleShop>\n{\n\tdb: Database;\n\tconstructor(fileName: string) {\n\t\tthis.db = new Database(fileName);\n\t\tthis.db.exec(`\n CREATE TABLE IF NOT EXISTS shop (\n id TEXT PRIMARY KEY,\n active BOOLEAN DEFAULT 1,\n url TEXT NOT NULL,\n secret TEXT NOT NULL,\n client_id TEXT NULL,\n client_secret TEXT NULL\n );\n `);\n\t}\n\n\tasync createShop(id: string, url: string, secret: string): Promise<void> {\n\t\tconst shop = await this.getShopById(id);\n\n\t\tif (shop) {\n\t\t\treturn await this.updateShop(shop);\n\t\t}\n\n\t\tthis.db.exec(\"INSERT INTO shop (id, url, secret) VALUES (?, ?, ?)\", [\n\t\t\tid,\n\t\t\turl,\n\t\t\tsecret,\n\t\t]);\n\t}\n\n\tasync getShopById(id: string): Promise<SimpleShop | null> {\n\t\tconst query = this.db.query<\n\t\t\t{\n\t\t\t\tid: string;\n\t\t\t\tactive: boolean;\n\t\t\t\turl: string;\n\t\t\t\tsecret: string;\n\t\t\t\tclient_id?: string;\n\t\t\t\tclient_secret?: string;\n\t\t\t},\n\t\t\tstring\n\t\t>(\"SELECT * FROM shop WHERE id = ?\");\n\t\tconst result = query.get(id);\n\n\t\tif (!result) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst shop = new SimpleShop(result.id, result.url, result.secret);\n\n\t\tif (result.client_id && result.client_secret) {\n\t\t\tshop.setShopCredentials(result.client_id, result.client_secret);\n\t\t}\n\n\t\tshop.setShopActive(result.active);\n\n\t\treturn shop;\n\t}\n\tasync updateShop(shop: SimpleShop): Promise<void> {\n\t\tthis.db.exec(\n\t\t\t\"UPDATE shop SET url = ?, secret = ?, client_id = ?, client_secret = ?, active = ? WHERE id = ?\",\n\t\t\t[\n\t\t\t\tshop.getShopUrl(),\n\t\t\t\tshop.getShopSecret(),\n\t\t\t\tshop.getShopClientId(),\n\t\t\t\tshop.getShopClientSecret(),\n\t\t\t\tshop.getShopActive(),\n\t\t\t\tshop.getShopId(),\n\t\t\t],\n\t\t);\n\t}\n\tasync deleteShop(id: string): Promise<void> {\n\t\tthis.db.exec(\"DELETE FROM shop where id = ?\", [id]);\n\t}\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bun-sqlite.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun-sqlite.test.d.ts","sourceRoot":"","sources":["../../../src/integration/bun-sqlite.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const bun_test_1 = require("bun:test");
4
+ const repository_js_1 = require("../repository.js");
5
+ const bun_sqlite_js_1 = require("./bun-sqlite.js");
6
+ (0, bun_test_1.describe)("Bun SQLite", async () => {
7
+ (0, bun_test_1.test)("createShop", async () => {
8
+ const repo = new bun_sqlite_js_1.BunSqliteRepository(":memory:");
9
+ await repo.createShop("test", "test", "test");
10
+ const shop = await repo.getShopById("test");
11
+ (0, bun_test_1.expect)(shop).not.toBeNull();
12
+ (0, bun_test_1.expect)(shop?.getShopId()).toBe("test");
13
+ (0, bun_test_1.expect)(shop?.getShopUrl()).toBe("test");
14
+ (0, bun_test_1.expect)(shop?.getShopSecret()).toBe("test");
15
+ await repo.deleteShop("test");
16
+ (0, bun_test_1.expect)(repo.getShopById("test")).resolves.toBeNull();
17
+ await repo.createShop("test", "test", "test");
18
+ (0, bun_test_1.expect)(repo.getShopById("test")).resolves.not.toBeNull();
19
+ await repo.updateShop(new repository_js_1.SimpleShop("test", "foo.com", "test"));
20
+ const updatedShop = await repo.getShopById("test");
21
+ (0, bun_test_1.expect)(updatedShop?.getShopUrl()).toBe("foo.com");
22
+ });
23
+ });
24
+ //# sourceMappingURL=bun-sqlite.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun-sqlite.test.js","sourceRoot":"","sources":["../../../src/integration/bun-sqlite.test.ts"],"names":[],"mappings":";;AAAA,uCAAkD;AAClD,oDAA8C;AAC9C,mDAAsD;AAEtD,IAAA,mBAAQ,EAAC,YAAY,EAAE,KAAK,IAAI,EAAE;IACjC,IAAA,eAAI,EAAC,YAAY,EAAE,KAAK,IAAI,EAAE;QAC7B,MAAM,IAAI,GAAG,IAAI,mCAAmB,CAAC,UAAU,CAAC,CAAC;QAEjD,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAE9C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE5C,IAAA,iBAAM,EAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAE5B,IAAA,iBAAM,EAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,IAAA,iBAAM,EAAC,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,IAAA,iBAAM,EAAC,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE3C,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAE9B,IAAA,iBAAM,EAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAErD,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAE9C,IAAA,iBAAM,EAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAEzD,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,0BAAU,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;QAEjE,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAEnD,IAAA,iBAAM,EAAC,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, test } from \"bun:test\";\nimport { SimpleShop } from \"../repository.js\";\nimport { BunSqliteRepository } from \"./bun-sqlite.js\";\n\ndescribe(\"Bun SQLite\", async () => {\n\ttest(\"createShop\", async () => {\n\t\tconst repo = new BunSqliteRepository(\":memory:\");\n\n\t\tawait repo.createShop(\"test\", \"test\", \"test\");\n\n\t\tconst shop = await repo.getShopById(\"test\");\n\n\t\texpect(shop).not.toBeNull();\n\n\t\texpect(shop?.getShopId()).toBe(\"test\");\n\t\texpect(shop?.getShopUrl()).toBe(\"test\");\n\t\texpect(shop?.getShopSecret()).toBe(\"test\");\n\n\t\tawait repo.deleteShop(\"test\");\n\n\t\texpect(repo.getShopById(\"test\")).resolves.toBeNull();\n\n\t\tawait repo.createShop(\"test\", \"test\", \"test\");\n\n\t\texpect(repo.getShopById(\"test\")).resolves.not.toBeNull();\n\n\t\tawait repo.updateShop(new SimpleShop(\"test\", \"foo.com\", \"test\"));\n\n\t\tconst updatedShop = await repo.getShopById(\"test\");\n\n\t\texpect(updatedShop?.getShopUrl()).toBe(\"foo.com\");\n\t});\n});\n"]}
@@ -17,27 +17,4 @@ export declare class CloudflareShopRepository implements ShopRepositoryInterface
17
17
  protected serializeShop(shop: SimpleShop): string;
18
18
  protected deserializeShop(data: string): SimpleShop;
19
19
  }
20
- /**
21
- * Cloudflare KV
22
- */
23
- export declare interface KVNamespace<Key extends string = string> {
24
- get(key: Key, options?: Partial<KVNamespaceGetOptions<undefined>>): Promise<string | null>;
25
- put(key: Key, value: string | ArrayBuffer | ArrayBufferView | ReadableStream, options?: KVNamespacePutOptions): Promise<void>;
26
- delete(key: Key): Promise<void>;
27
- }
28
- /**
29
- * Cloudflare KV get options
30
- */
31
- export declare interface KVNamespaceGetOptions<Type> {
32
- type: Type;
33
- cacheTtl?: number;
34
- }
35
- /**
36
- * Cloudflare KV put options
37
- */
38
- export declare interface KVNamespacePutOptions {
39
- expiration?: number;
40
- expirationTtl?: number;
41
- metadata?: any | null;
42
- }
43
- //# sourceMappingURL=cloudflare.d.ts.map
20
+ //# sourceMappingURL=cloudflare-kv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare-kv.d.ts","sourceRoot":"","sources":["../../../src/integration/cloudflare-kv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAEhE;;;GAGG;AAEH;;GAEG;AACH,qBAAa,wBACZ,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAElC,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,WAAW;IAIlC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlE,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAUnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjD,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IAIjD,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;CAmBnD"}
@@ -38,8 +38,12 @@ class CloudflareShopRepository {
38
38
  const obj = JSON.parse(data);
39
39
  const shop = new repository_js_1.SimpleShop(obj.shopId || "", obj.shopUrl || "", obj.shopSecret || "");
40
40
  shop.setShopCredentials(obj.shopClientId || "", obj.shopClientSecret || "");
41
+ if (obj.shopActive === undefined) {
42
+ obj.shopActive = true;
43
+ }
44
+ shop.setShopActive(obj.shopActive);
41
45
  return shop;
42
46
  }
43
47
  }
44
48
  exports.CloudflareShopRepository = CloudflareShopRepository;
45
- //# sourceMappingURL=cloudflare.js.map
49
+ //# sourceMappingURL=cloudflare-kv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare-kv.js","sourceRoot":"","sources":["../../../src/integration/cloudflare-kv.ts"],"names":[],"mappings":";;;AAAA,oDAA8C;AAG9C;;;GAGG;AAEH;;GAEG;AACH,MAAa,wBAAwB;IAGhB;IAApB,YAAoB,OAAoB;QAApB,YAAO,GAAP,OAAO,CAAa;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,GAAW,EAAE,MAAc;QACvD,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CACrB,EAAE,EACF,IAAI,CAAC,aAAa,CAAC,IAAI,0BAAU,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CACnD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAU;QAC1B,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAU;QAC3B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEzC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACb,CAAC;QAED,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAgB;QAChC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IACpE,CAAC;IAES,aAAa,CAAC,IAAgB;QACvC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAES,eAAe,CAAC,IAAY;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE7B,MAAM,IAAI,GAAG,IAAI,0BAAU,CAC1B,GAAG,CAAC,MAAM,IAAI,EAAE,EAChB,GAAG,CAAC,OAAO,IAAI,EAAE,EACjB,GAAG,CAAC,UAAU,IAAI,EAAE,CACpB,CAAC;QAEF,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,EAAE,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;QAE5E,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAEnC,OAAO,IAAI,CAAC;IACb,CAAC;CACD;AAvDD,4DAuDC","sourcesContent":["import { SimpleShop } from \"../repository.js\";\nimport type { ShopRepositoryInterface } from \"../repository.js\";\n\n/**\n * Cloudflare KV integration\n * @module\n */\n\n/**\n * Cloudflare KV implementation of the ShopRepositoryInterface\n */\nexport class CloudflareShopRepository\n\timplements ShopRepositoryInterface<SimpleShop>\n{\n\tconstructor(private storage: KVNamespace) {\n\t\tthis.storage = storage;\n\t}\n\n\tasync createShop(id: string, url: string, secret: string): Promise<void> {\n\t\tawait this.storage.put(\n\t\t\tid,\n\t\t\tthis.serializeShop(new SimpleShop(id, url, secret)),\n\t\t);\n\t}\n\n\tasync deleteShop(id: string): Promise<void> {\n\t\tawait this.storage.delete(id);\n\t}\n\n\tasync getShopById(id: string): Promise<SimpleShop | null> {\n\t\tconst kvObj = await this.storage.get(id);\n\n\t\tif (kvObj === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.deserializeShop(kvObj);\n\t}\n\n\tasync updateShop(shop: SimpleShop): Promise<void> {\n\t\tawait this.storage.put(shop.getShopId(), this.serializeShop(shop));\n\t}\n\n\tprotected serializeShop(shop: SimpleShop): string {\n\t\treturn JSON.stringify(shop);\n\t}\n\n\tprotected deserializeShop(data: string): SimpleShop {\n\t\tconst obj = JSON.parse(data);\n\n\t\tconst shop = new SimpleShop(\n\t\t\tobj.shopId || \"\",\n\t\t\tobj.shopUrl || \"\",\n\t\t\tobj.shopSecret || \"\",\n\t\t);\n\n\t\tshop.setShopCredentials(obj.shopClientId || \"\", obj.shopClientSecret || \"\");\n\n\t\tif (obj.shopActive === undefined) {\n\t\t\tobj.shopActive = true;\n\t\t}\n\n\t\tshop.setShopActive(obj.shopActive);\n\n\t\treturn shop;\n\t}\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cloudflare.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare.test.d.ts","sourceRoot":"","sources":["../../../src/integration/cloudflare.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //
4
+ const bun_test_1 = require("bun:test");
5
+ const cloudflare_kv_js_1 = require("../../src/integration/cloudflare-kv.js");
6
+ const repository_js_1 = require("../../src/repository.js");
7
+ (0, bun_test_1.describe)("Cloudflare", async () => {
8
+ (0, bun_test_1.test)("createShop", async () => {
9
+ const repo = new cloudflare_kv_js_1.CloudflareShopRepository(new MockedKVNamespace());
10
+ await repo.createShop("test", "test", "test");
11
+ const shop = await repo.getShopById("test");
12
+ (0, bun_test_1.expect)(shop).not.toBeNull();
13
+ (0, bun_test_1.expect)(shop?.getShopId()).toBe("test");
14
+ (0, bun_test_1.expect)(shop?.getShopUrl()).toBe("test");
15
+ (0, bun_test_1.expect)(shop?.getShopSecret()).toBe("test");
16
+ await repo.deleteShop("test");
17
+ (0, bun_test_1.expect)(repo.getShopById("test")).resolves.toBeNull();
18
+ await repo.updateShop(new repository_js_1.SimpleShop("test", "test", "test"));
19
+ (0, bun_test_1.expect)(repo.getShopById("test")).resolves.not.toBeNull();
20
+ });
21
+ });
22
+ class MockedKVNamespace {
23
+ storage;
24
+ constructor() {
25
+ this.storage = new Map();
26
+ }
27
+ get(key, options) {
28
+ return Promise.resolve(this.storage.get(key) || null);
29
+ }
30
+ put(key, value, options) {
31
+ this.storage.set(key, value);
32
+ return Promise.resolve();
33
+ }
34
+ delete(key) {
35
+ this.storage.delete(key);
36
+ return Promise.resolve();
37
+ }
38
+ }
39
+ //# sourceMappingURL=cloudflare.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare.test.js","sourceRoot":"","sources":["../../../src/integration/cloudflare.test.ts"],"names":[],"mappings":";;AAAA,EAAE;AACF,uCAAkD;AAClD,6EAAkF;AAClF,2DAAqD;AAErD,IAAA,mBAAQ,EAAC,YAAY,EAAE,KAAK,IAAI,EAAE;IACjC,IAAA,eAAI,EAAC,YAAY,EAAE,KAAK,IAAI,EAAE;QAC7B,MAAM,IAAI,GAAG,IAAI,2CAAwB,CACxC,IAAI,iBAAiB,EAA4B,CACjD,CAAC;QAEF,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAE9C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE5C,IAAA,iBAAM,EAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAE5B,IAAA,iBAAM,EAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvC,IAAA,iBAAM,EAAC,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,IAAA,iBAAM,EAAC,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE3C,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAE9B,IAAA,iBAAM,EAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAErD,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,0BAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAE9D,IAAA,iBAAM,EAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;IAC1D,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,MAAM,iBAAiB;IACtB,OAAO,CAAsB;IAC7B;QACC,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;IAC1B,CAAC;IAED,GAAG,CACF,GAAW,EACX,OAAmD;QAEnD,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC;IACvD,CAAC;IACD,GAAG,CACF,GAAW,EACX,KAA8D,EAC9D,OAA+B;QAE/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAe,CAAC,CAAC;QACvC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;IACD,MAAM,CAAC,GAAW;QACjB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;CACD","sourcesContent":["//\nimport { describe, expect, test } from \"bun:test\";\nimport { CloudflareShopRepository } from \"../../src/integration/cloudflare-kv.js\";\nimport { SimpleShop } from \"../../src/repository.js\";\n\ndescribe(\"Cloudflare\", async () => {\n\ttest(\"createShop\", async () => {\n\t\tconst repo = new CloudflareShopRepository(\n\t\t\tnew MockedKVNamespace() as unknown as KVNamespace,\n\t\t);\n\n\t\tawait repo.createShop(\"test\", \"test\", \"test\");\n\n\t\tconst shop = await repo.getShopById(\"test\");\n\n\t\texpect(shop).not.toBeNull();\n\n\t\texpect(shop?.getShopId()).toBe(\"test\");\n\t\texpect(shop?.getShopUrl()).toBe(\"test\");\n\t\texpect(shop?.getShopSecret()).toBe(\"test\");\n\n\t\tawait repo.deleteShop(\"test\");\n\n\t\texpect(repo.getShopById(\"test\")).resolves.toBeNull();\n\n\t\tawait repo.updateShop(new SimpleShop(\"test\", \"test\", \"test\"));\n\n\t\texpect(repo.getShopById(\"test\")).resolves.not.toBeNull();\n\t});\n});\n\nclass MockedKVNamespace {\n\tstorage: Map<string, string>;\n\tconstructor() {\n\t\tthis.storage = new Map();\n\t}\n\n\tget(\n\t\tkey: string,\n\t\toptions?: Partial<KVNamespaceGetOptions<undefined>>,\n\t): Promise<string | null> {\n\t\treturn Promise.resolve(this.storage.get(key) || null);\n\t}\n\tput(\n\t\tkey: string,\n\t\tvalue: string | ArrayBuffer | ArrayBufferView | ReadableStream,\n\t\toptions?: KVNamespacePutOptions,\n\t): Promise<void> {\n\t\tthis.storage.set(key, value as string);\n\t\treturn Promise.resolve();\n\t}\n\tdelete(key: string): Promise<void> {\n\t\tthis.storage.delete(key);\n\t\treturn Promise.resolve();\n\t}\n}\n"]}
@@ -15,4 +15,4 @@ export declare class DenoKVRepository implements ShopRepositoryInterface<SimpleS
15
15
  updateShop(shop: SimpleShop): Promise<void>;
16
16
  deleteShop(id: string): Promise<void>;
17
17
  }
18
- //# sourceMappingURL=deno.d.ts.map
18
+ //# sourceMappingURL=deno-kv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deno-kv.d.ts","sourceRoot":"","sources":["../../../src/integration/deno-kv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAEhE;;;GAGG;AAEH;;GAEG;AACH,qBAAa,gBAAiB,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAC/D,OAAO,CAAC,SAAS;gBAAT,SAAS,SAAU;IAEjC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAiCnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAM3C"}
@@ -27,7 +27,11 @@ class DenoKVRepository {
27
27
  return null;
28
28
  }
29
29
  const data = result.value;
30
+ if (data.shopActive === undefined) {
31
+ data.shopActive = true;
32
+ }
30
33
  const shop = new repository_js_1.SimpleShop(data.shopId, data.shopUrl, data.shopSecret);
34
+ shop.setShopActive(data.shopActive);
31
35
  if (data.shopClientId && data.shopClientSecret) {
32
36
  shop.setShopCredentials(data.shopClientId, data.shopClientSecret);
33
37
  }
@@ -45,4 +49,4 @@ class DenoKVRepository {
45
49
  }
46
50
  }
47
51
  exports.DenoKVRepository = DenoKVRepository;
48
- //# sourceMappingURL=deno.js.map
52
+ //# sourceMappingURL=deno-kv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deno-kv.js","sourceRoot":"","sources":["../../../src/integration/deno-kv.ts"],"names":[],"mappings":";;;AAAA,oDAA8C;AAG9C;;;GAGG;AAEH;;GAEG;AACH,MAAa,gBAAgB;IACR;IAApB,YAAoB,YAAY,OAAO;QAAnB,cAAS,GAAT,SAAS,CAAU;IAAG,CAAC;IAE3C,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,GAAW,EAAE,MAAc;QACvD,aAAa;QACb,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAE/B,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,IAAI,0BAAU,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAU;QAC3B,aAAa;QACb,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAE/B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;QAElD,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,KAOnB,CAAC;QAEF,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACxB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,0BAAU,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACxE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEpC,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAChD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACnE,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAgB;QAChC,aAAa;QACb,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAE/B,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAU;QAC1B,aAAa;QACb,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAE/B,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;IACvC,CAAC;CACD;AAxDD,4CAwDC","sourcesContent":["import { SimpleShop } from \"../repository.js\";\nimport type { ShopRepositoryInterface } from \"../repository.js\";\n\n/**\n * Deno KV integration\n * @module\n */\n\n/**\n * DenoKVRepository is a ShopRepositoryInterface implementation that uses the Deno KV storage to save the shop data\n */\nexport class DenoKVRepository implements ShopRepositoryInterface<SimpleShop> {\n\tconstructor(private namespace = \"shops\") {}\n\n\tasync createShop(id: string, url: string, secret: string): Promise<void> {\n\t\t// @ts-ignore\n\t\tconst kv = await Deno.openKv();\n\n\t\tawait kv.set([this.namespace, id], new SimpleShop(id, url, secret));\n\t}\n\n\tasync getShopById(id: string): Promise<SimpleShop | null> {\n\t\t// @ts-ignore\n\t\tconst kv = await Deno.openKv();\n\n\t\tconst result = await kv.get([this.namespace, id]);\n\n\t\tif (result.key === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst data = result.value as {\n\t\t\tshopId: string;\n\t\t\tshopActive: boolean | undefined;\n\t\t\tshopUrl: string;\n\t\t\tshopSecret: string;\n\t\t\tshopClientId: string | null;\n\t\t\tshopClientSecret: string | null;\n\t\t};\n\n\t\tif (data.shopActive === undefined) {\n\t\t\tdata.shopActive = true;\n\t\t}\n\n\t\tconst shop = new SimpleShop(data.shopId, data.shopUrl, data.shopSecret);\n\t\tshop.setShopActive(data.shopActive);\n\n\t\tif (data.shopClientId && data.shopClientSecret) {\n\t\t\tshop.setShopCredentials(data.shopClientId, data.shopClientSecret);\n\t\t}\n\n\t\treturn shop;\n\t}\n\n\tasync updateShop(shop: SimpleShop): Promise<void> {\n\t\t// @ts-ignore\n\t\tconst kv = await Deno.openKv();\n\n\t\tawait kv.set([this.namespace, shop.getShopId()], shop);\n\t}\n\n\tasync deleteShop(id: string): Promise<void> {\n\t\t// @ts-ignore\n\t\tconst kv = await Deno.openKv();\n\n\t\tawait kv.delete([this.namespace, id]);\n\t}\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=deno.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deno.test.d.ts","sourceRoot":"","sources":["../../../src/integration/deno.test.ts"],"names":[],"mappings":""}