@shopware-ag/app-server-sdk 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +52 -41
  2. package/dist/commonjs/integration/better-sqlite3.d.ts +11 -0
  3. package/dist/commonjs/integration/better-sqlite3.d.ts.map +1 -0
  4. package/dist/commonjs/integration/better-sqlite3.js +58 -0
  5. package/dist/commonjs/integration/better-sqlite3.js.map +1 -0
  6. package/dist/commonjs/integration/bun-sqlite.d.ts +11 -0
  7. package/dist/commonjs/integration/bun-sqlite.d.ts.map +1 -0
  8. package/dist/commonjs/integration/bun-sqlite.js +60 -0
  9. package/dist/commonjs/integration/bun-sqlite.js.map +1 -0
  10. package/dist/commonjs/integration/cloudflare-kv.d.ts +20 -0
  11. package/dist/commonjs/integration/cloudflare-kv.d.ts.map +1 -0
  12. package/dist/commonjs/integration/cloudflare-kv.js +49 -0
  13. package/dist/commonjs/integration/cloudflare-kv.js.map +1 -0
  14. package/dist/commonjs/integration/deno-kv.d.ts +18 -0
  15. package/dist/commonjs/integration/deno-kv.d.ts.map +1 -0
  16. package/dist/commonjs/integration/deno-kv.js +52 -0
  17. package/dist/commonjs/integration/deno-kv.js.map +1 -0
  18. package/dist/commonjs/integration/dynamodb.d.ts +13 -0
  19. package/dist/commonjs/integration/dynamodb.d.ts.map +1 -0
  20. package/dist/commonjs/integration/dynamodb.js +73 -0
  21. package/dist/commonjs/integration/dynamodb.js.map +1 -0
  22. package/dist/commonjs/integration/hono.d.ts +29 -0
  23. package/dist/commonjs/integration/hono.d.ts.map +1 -0
  24. package/dist/commonjs/integration/hono.js +105 -0
  25. package/dist/commonjs/integration/hono.js.map +1 -0
  26. package/dist/esm/integration/better-sqlite3.d.ts +11 -0
  27. package/dist/esm/integration/better-sqlite3.d.ts.map +1 -0
  28. package/dist/esm/integration/better-sqlite3.js +51 -0
  29. package/dist/esm/integration/better-sqlite3.js.map +1 -0
  30. package/dist/esm/integration/bun-sqlite.d.ts +11 -0
  31. package/dist/esm/integration/bun-sqlite.d.ts.map +1 -0
  32. package/dist/esm/integration/bun-sqlite.js +56 -0
  33. package/dist/esm/integration/bun-sqlite.js.map +1 -0
  34. package/dist/esm/integration/cloudflare-kv.d.ts +20 -0
  35. package/dist/esm/integration/cloudflare-kv.d.ts.map +1 -0
  36. package/dist/esm/integration/cloudflare-kv.js +45 -0
  37. package/dist/esm/integration/cloudflare-kv.js.map +1 -0
  38. package/dist/esm/integration/deno-kv.d.ts +18 -0
  39. package/dist/esm/integration/deno-kv.d.ts.map +1 -0
  40. package/dist/esm/integration/deno-kv.js +48 -0
  41. package/dist/esm/integration/deno-kv.js.map +1 -0
  42. package/dist/esm/integration/dynamodb.d.ts +13 -0
  43. package/dist/esm/integration/dynamodb.d.ts.map +1 -0
  44. package/dist/esm/integration/dynamodb.js +69 -0
  45. package/dist/esm/integration/dynamodb.js.map +1 -0
  46. package/dist/esm/integration/hono.d.ts +29 -0
  47. package/dist/esm/integration/hono.d.ts.map +1 -0
  48. package/dist/esm/integration/hono.js +102 -0
  49. package/dist/esm/integration/hono.js.map +1 -0
  50. package/package.json +117 -6
package/README.md CHANGED
@@ -1,51 +1,62 @@
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
8
- import { AppServer, InMemoryShopRepository } from "@shopware-ag/app-server-sdk";
9
- import { ActionButtonRequest } from "@shopware-ag/app-server-sdk/types";
10
- import { createNotificationResponse } from "@shopware-ag/app-server-sdk/helper/app-actions";
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
11
 
12
- const app = new AppServer(
13
- {
14
- appName: "MyApp",
15
- appSecret: "my-secret",
16
- authorizeCallbackUrl: "http://localhost:3000/app/callback",
17
- },
18
- new InMemoryShopRepository(),
19
- );
12
+ ## How to use it?
13
+
14
+ ```bash
15
+ npm install @shopware-ag/app-server-sdk --save
16
+ ```
17
+
18
+ ## Example
19
+
20
+ ```typescript
21
+ import { AppServer, InMemoryShopRepository } from '@shopware-ag/app-server-sdk'
22
+ import { createNotificationResponse } from '@shopware-ag/app-server-sdk/helper/app-actions'
23
+
24
+ const app = new AppServer({
25
+ appName: 'MyApp',
26
+ appSecret: 'my-secret',
27
+ authorizeCallbackUrl: 'http://localhost:3000/authorize/callback',
28
+ }, new InMemoryShopRepository());
20
29
 
21
30
  const server = Bun.serve({
22
- port: 3000,
23
- async fetch(request) {
24
- const { pathname } = new URL(request.url);
25
- if (pathname === "/app/register") {
26
- return app.registration.authorize(request);
27
- } else if (pathname === "/app/callback") {
28
- return app.registration.authorizeCallback(request);
29
- } else if (pathname === "/app/product") {
30
- const context =
31
- await app.contextResolver.fromAPI<ActionButtonRequest>(request);
32
-
33
- // do something with payload, and http client
34
-
35
- const notification = createNotificationResponse(
36
- "success",
37
- "Product created",
38
- );
39
-
40
- // sign the response, with the shop secret
41
- await app.signer.signResponse(notification, context.shop.getShopSecret());
42
-
43
- return notification;
44
- }
45
-
46
- return new Response("Not found", { status: 404 });
47
- },
31
+ port: 3000,
32
+ async fetch(request) {
33
+ const { pathname } = new URL(request.url);
34
+ if (pathname === '/authorize') {
35
+ return app.registration.authorize(request);
36
+ } else if (pathname === '/authorize/callback') {
37
+ return app.registration.authorizeCallback(request);
38
+ } else if (pathname === '/app/product') {
39
+ const context = await app.contextResolver.fromSource(request);
40
+
41
+ // do something with payload, and http client
42
+
43
+ const notification = createNotificationResponse('success', 'Product created');
44
+
45
+ // sign the response, with the shop secret
46
+ await app.signer.signResponse(notification, context.shop.getShopSecret());
47
+
48
+ return resp;
49
+ }
50
+
51
+ return new Response('Not found', { status: 404 });
52
+ },
48
53
  });
49
54
 
50
55
  console.log(`Listening on localhost:${server.port}`);
51
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,11 @@
1
+ import { type ShopRepositoryInterface, SimpleShop } from "../repository.js";
2
+ import Database from "better-sqlite3";
3
+ export declare class BetterSqlite3Repository implements ShopRepositoryInterface<SimpleShop> {
4
+ db: Database.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=better-sqlite3.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"better-sqlite3.d.ts","sourceRoot":"","sources":["../../../src/integration/better-sqlite3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,qBAAa,uBACZ,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAE9C,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;gBACV,QAAQ,EAAE,MAAM;IAetB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA0BnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG3C"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BetterSqlite3Repository = void 0;
7
+ const repository_js_1 = require("../repository.js");
8
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
9
+ class BetterSqlite3Repository {
10
+ db;
11
+ constructor(fileName) {
12
+ this.db = new better_sqlite3_1.default(fileName);
13
+ this.db.pragma("journal_mode = WAL");
14
+ this.db.exec(`
15
+ CREATE TABLE IF NOT EXISTS shop (
16
+ id TEXT PRIMARY KEY,
17
+ active BOOLEAN DEFAULT 1,
18
+ url TEXT NOT NULL,
19
+ secret TEXT NOT NULL,
20
+ client_id TEXT NULL,
21
+ client_secret TEXT NULL
22
+ );
23
+ `);
24
+ }
25
+ async createShop(id, url, secret) {
26
+ const shop = await this.getShopById(id);
27
+ if (shop) {
28
+ return await this.updateShop(shop);
29
+ }
30
+ this.db
31
+ .prepare("INSERT INTO shop (id, url, secret) VALUES (?, ?, ?)")
32
+ .run(id, url, secret);
33
+ }
34
+ async getShopById(id) {
35
+ const result = this.db
36
+ .prepare("SELECT * FROM shop WHERE id = ?")
37
+ .get(id);
38
+ if (!result) {
39
+ return null;
40
+ }
41
+ const shop = new repository_js_1.SimpleShop(result.id, result.url, result.secret);
42
+ if (result.client_id && result.client_secret) {
43
+ shop.setShopCredentials(result.client_id, result.client_secret);
44
+ }
45
+ shop.setShopActive(result.active === 1);
46
+ return shop;
47
+ }
48
+ async updateShop(shop) {
49
+ this.db
50
+ .prepare("UPDATE shop SET url = ?, secret = ?, client_id = ?, client_secret = ?, active = ? WHERE id = ?")
51
+ .run(shop.getShopUrl(), shop.getShopSecret(), shop.getShopClientId(), shop.getShopClientSecret(), +shop.getShopActive(), shop.getShopId());
52
+ }
53
+ async deleteShop(id) {
54
+ this.db.prepare("DELETE FROM shop where id = ?").run(id);
55
+ }
56
+ }
57
+ exports.BetterSqlite3Repository = BetterSqlite3Repository;
58
+ //# sourceMappingURL=better-sqlite3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"better-sqlite3.js","sourceRoot":"","sources":["../../../src/integration/better-sqlite3.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4E;AAE5E,oEAAsC;AAEtC,MAAa,uBAAuB;IAGnC,EAAE,CAAoB;IACtB,YAAY,QAAgB;QAC3B,IAAI,CAAC,EAAE,GAAG,IAAI,wBAAQ,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrC,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;aACL,OAAO,CAAC,qDAAqD,CAAC;aAC9D,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAU;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE;aACpB,OAAO,CAAC,iCAAiC,CAAC;aAC1C,GAAG,CAAC,EAAE,CAOP,CAAC;QAEF,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,KAAK,CAAC,CAAC,CAAC;QAExC,OAAO,IAAI,CAAC;IACb,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,IAAgB;QAChC,IAAI,CAAC,EAAE;aACL,OAAO,CACP,gGAAgG,CAChG;aACA,GAAG,CACH,IAAI,CAAC,UAAU,EAAE,EACjB,IAAI,CAAC,aAAa,EAAE,EACpB,IAAI,CAAC,eAAe,EAAE,EACtB,IAAI,CAAC,mBAAmB,EAAE,EAC1B,CAAC,IAAI,CAAC,aAAa,EAAE,EACrB,IAAI,CAAC,SAAS,EAAE,CAChB,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,EAAU;QAC1B,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;CACD;AA1ED,0DA0EC","sourcesContent":["import { type ShopRepositoryInterface, SimpleShop } from \"../repository.js\";\n\nimport Database from \"better-sqlite3\";\n\nexport class BetterSqlite3Repository\n\timplements ShopRepositoryInterface<SimpleShop>\n{\n\tdb: Database.Database;\n\tconstructor(fileName: string) {\n\t\tthis.db = new Database(fileName);\n\t\tthis.db.pragma(\"journal_mode = WAL\");\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\n\t\t\t.prepare(\"INSERT INTO shop (id, url, secret) VALUES (?, ?, ?)\")\n\t\t\t.run(id, url, secret);\n\t}\n\n\tasync getShopById(id: string): Promise<SimpleShop | null> {\n\t\tconst result = this.db\n\t\t\t.prepare(\"SELECT * FROM shop WHERE id = ?\")\n\t\t\t.get(id) as null | {\n\t\t\tid: string;\n\t\t\tactive: number;\n\t\t\turl: string;\n\t\t\tsecret: string;\n\t\t\tclient_id?: string;\n\t\t\tclient_secret?: string;\n\t\t};\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 === 1);\n\n\t\treturn shop;\n\t}\n\tasync updateShop(shop: SimpleShop): Promise<void> {\n\t\tthis.db\n\t\t\t.prepare(\n\t\t\t\t\"UPDATE shop SET url = ?, secret = ?, client_id = ?, client_secret = ?, active = ? WHERE id = ?\",\n\t\t\t)\n\t\t\t.run(\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\t+shop.getShopActive(),\n\t\t\t\tshop.getShopId(),\n\t\t\t);\n\t}\n\tasync deleteShop(id: string): Promise<void> {\n\t\tthis.db.prepare(\"DELETE FROM shop where id = ?\").run(id);\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,20 @@
1
+ import { SimpleShop } from "../repository.js";
2
+ import type { ShopRepositoryInterface } from "../repository.js";
3
+ /**
4
+ * Cloudflare KV integration
5
+ * @module
6
+ */
7
+ /**
8
+ * Cloudflare KV implementation of the ShopRepositoryInterface
9
+ */
10
+ export declare class CloudflareShopRepository implements ShopRepositoryInterface<SimpleShop> {
11
+ private storage;
12
+ constructor(storage: KVNamespace);
13
+ createShop(id: string, url: string, secret: string): Promise<void>;
14
+ deleteShop(id: string): Promise<void>;
15
+ getShopById(id: string): Promise<SimpleShop | null>;
16
+ updateShop(shop: SimpleShop): Promise<void>;
17
+ protected serializeShop(shop: SimpleShop): string;
18
+ protected deserializeShop(data: string): SimpleShop;
19
+ }
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"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CloudflareShopRepository = void 0;
4
+ const repository_js_1 = require("../repository.js");
5
+ /**
6
+ * Cloudflare KV integration
7
+ * @module
8
+ */
9
+ /**
10
+ * Cloudflare KV implementation of the ShopRepositoryInterface
11
+ */
12
+ class CloudflareShopRepository {
13
+ storage;
14
+ constructor(storage) {
15
+ this.storage = storage;
16
+ this.storage = storage;
17
+ }
18
+ async createShop(id, url, secret) {
19
+ await this.storage.put(id, this.serializeShop(new repository_js_1.SimpleShop(id, url, secret)));
20
+ }
21
+ async deleteShop(id) {
22
+ await this.storage.delete(id);
23
+ }
24
+ async getShopById(id) {
25
+ const kvObj = await this.storage.get(id);
26
+ if (kvObj === null) {
27
+ return null;
28
+ }
29
+ return this.deserializeShop(kvObj);
30
+ }
31
+ async updateShop(shop) {
32
+ await this.storage.put(shop.getShopId(), this.serializeShop(shop));
33
+ }
34
+ serializeShop(shop) {
35
+ return JSON.stringify(shop);
36
+ }
37
+ deserializeShop(data) {
38
+ const obj = JSON.parse(data);
39
+ const shop = new repository_js_1.SimpleShop(obj.shopId || "", obj.shopUrl || "", obj.shopSecret || "");
40
+ shop.setShopCredentials(obj.shopClientId || "", obj.shopClientSecret || "");
41
+ if (obj.shopActive === undefined) {
42
+ obj.shopActive = true;
43
+ }
44
+ shop.setShopActive(obj.shopActive);
45
+ return shop;
46
+ }
47
+ }
48
+ exports.CloudflareShopRepository = CloudflareShopRepository;
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,18 @@
1
+ import { SimpleShop } from "../repository.js";
2
+ import type { ShopRepositoryInterface } from "../repository.js";
3
+ /**
4
+ * Deno KV integration
5
+ * @module
6
+ */
7
+ /**
8
+ * DenoKVRepository is a ShopRepositoryInterface implementation that uses the Deno KV storage to save the shop data
9
+ */
10
+ export declare class DenoKVRepository implements ShopRepositoryInterface<SimpleShop> {
11
+ private namespace;
12
+ constructor(namespace?: string);
13
+ createShop(id: string, url: string, secret: string): Promise<void>;
14
+ getShopById(id: string): Promise<SimpleShop | null>;
15
+ updateShop(shop: SimpleShop): Promise<void>;
16
+ deleteShop(id: string): Promise<void>;
17
+ }
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"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DenoKVRepository = void 0;
4
+ const repository_js_1 = require("../repository.js");
5
+ /**
6
+ * Deno KV integration
7
+ * @module
8
+ */
9
+ /**
10
+ * DenoKVRepository is a ShopRepositoryInterface implementation that uses the Deno KV storage to save the shop data
11
+ */
12
+ class DenoKVRepository {
13
+ namespace;
14
+ constructor(namespace = "shops") {
15
+ this.namespace = namespace;
16
+ }
17
+ async createShop(id, url, secret) {
18
+ // @ts-ignore
19
+ const kv = await Deno.openKv();
20
+ await kv.set([this.namespace, id], new repository_js_1.SimpleShop(id, url, secret));
21
+ }
22
+ async getShopById(id) {
23
+ // @ts-ignore
24
+ const kv = await Deno.openKv();
25
+ const result = await kv.get([this.namespace, id]);
26
+ if (result.key === null) {
27
+ return null;
28
+ }
29
+ const data = result.value;
30
+ if (data.shopActive === undefined) {
31
+ data.shopActive = true;
32
+ }
33
+ const shop = new repository_js_1.SimpleShop(data.shopId, data.shopUrl, data.shopSecret);
34
+ shop.setShopActive(data.shopActive);
35
+ if (data.shopClientId && data.shopClientSecret) {
36
+ shop.setShopCredentials(data.shopClientId, data.shopClientSecret);
37
+ }
38
+ return shop;
39
+ }
40
+ async updateShop(shop) {
41
+ // @ts-ignore
42
+ const kv = await Deno.openKv();
43
+ await kv.set([this.namespace, shop.getShopId()], shop);
44
+ }
45
+ async deleteShop(id) {
46
+ // @ts-ignore
47
+ const kv = await Deno.openKv();
48
+ await kv.delete([this.namespace, id]);
49
+ }
50
+ }
51
+ exports.DenoKVRepository = DenoKVRepository;
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,13 @@
1
+ import type { DynamoDBClient } from "@aws-sdk/client-dynamodb";
2
+ import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
3
+ import { type ShopRepositoryInterface, SimpleShop } from "../repository.js";
4
+ export declare class DynamoDBRepository implements ShopRepositoryInterface<SimpleShop> {
5
+ docClient: DynamoDBDocumentClient;
6
+ tableName: string;
7
+ constructor(client: DynamoDBClient, tableName: string);
8
+ createShop(id: string, url: string, secret: string): Promise<void>;
9
+ getShopById(id: string): Promise<SimpleShop | null>;
10
+ updateShop(shop: SimpleShop): Promise<void>;
11
+ deleteShop(id: string): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=dynamodb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamodb.d.ts","sourceRoot":"","sources":["../../../src/integration/dynamodb.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAEN,sBAAsB,EAGtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,uBAAuB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5E,qBAAa,kBAAmB,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAC7E,SAAS,EAAE,sBAAsB,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;gBAEN,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM;IAK/C,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBlE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAoCnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB3C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAU3C"}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DynamoDBRepository = void 0;
4
+ const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
5
+ const repository_js_1 = require("../repository.js");
6
+ class DynamoDBRepository {
7
+ docClient;
8
+ tableName;
9
+ constructor(client, tableName) {
10
+ this.tableName = tableName;
11
+ this.docClient = lib_dynamodb_1.DynamoDBDocumentClient.from(client);
12
+ }
13
+ async createShop(id, url, secret) {
14
+ const cmd = new lib_dynamodb_1.PutCommand({
15
+ TableName: this.tableName,
16
+ Item: {
17
+ id: id,
18
+ active: true,
19
+ url: url,
20
+ secret: secret,
21
+ clientId: null,
22
+ clientSecret: null,
23
+ },
24
+ });
25
+ await this.docClient.send(cmd);
26
+ }
27
+ async getShopById(id) {
28
+ const cmd = new lib_dynamodb_1.GetCommand({
29
+ TableName: this.tableName,
30
+ Key: {
31
+ id: id,
32
+ },
33
+ });
34
+ const response = await this.docClient.send(cmd);
35
+ if (!response.Item) {
36
+ return null;
37
+ }
38
+ const shop = new repository_js_1.SimpleShop(response.Item.id, response.Item.url, response.Item.secret);
39
+ if (response.Item.active === undefined) {
40
+ response.Item.active = true;
41
+ }
42
+ shop.setShopActive(response.Item.active);
43
+ if (response.Item.clientId) {
44
+ shop.setShopCredentials(response.Item.clientId, response.Item.clientSecret);
45
+ }
46
+ return shop;
47
+ }
48
+ async updateShop(shop) {
49
+ const cmd = new lib_dynamodb_1.PutCommand({
50
+ TableName: this.tableName,
51
+ Item: {
52
+ id: shop.getShopId(),
53
+ active: shop.getShopActive(),
54
+ url: shop.getShopUrl(),
55
+ secret: shop.getShopSecret(),
56
+ clientId: shop.getShopClientId(),
57
+ clientSecret: shop.getShopClientSecret(),
58
+ },
59
+ });
60
+ await this.docClient.send(cmd);
61
+ }
62
+ async deleteShop(id) {
63
+ const cmd = new lib_dynamodb_1.DeleteCommand({
64
+ TableName: this.tableName,
65
+ Key: {
66
+ id: id,
67
+ },
68
+ });
69
+ await this.docClient.send(cmd);
70
+ }
71
+ }
72
+ exports.DynamoDBRepository = DynamoDBRepository;
73
+ //# sourceMappingURL=dynamodb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamodb.js","sourceRoot":"","sources":["../../../src/integration/dynamodb.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DynamoDBClient } from \"@aws-sdk/client-dynamodb\";\nimport {\n\tDeleteCommand,\n\tDynamoDBDocumentClient,\n\tGetCommand,\n\tPutCommand,\n} from \"@aws-sdk/lib-dynamodb\";\nimport { type ShopRepositoryInterface, SimpleShop } from \"../repository.js\";\n\nexport class DynamoDBRepository implements ShopRepositoryInterface<SimpleShop> {\n\tdocClient: DynamoDBDocumentClient;\n\ttableName: string;\n\n\tconstructor(client: DynamoDBClient, tableName: string) {\n\t\tthis.tableName = tableName;\n\t\tthis.docClient = DynamoDBDocumentClient.from(client);\n\t}\n\n\tasync createShop(id: string, url: string, secret: string): Promise<void> {\n\t\tconst cmd = new PutCommand({\n\t\t\tTableName: this.tableName,\n\t\t\tItem: {\n\t\t\t\tid: id,\n\t\t\t\tactive: true,\n\t\t\t\turl: url,\n\t\t\t\tsecret: secret,\n\t\t\t\tclientId: null,\n\t\t\t\tclientSecret: null,\n\t\t\t},\n\t\t});\n\n\t\tawait this.docClient.send(cmd);\n\t}\n\n\tasync getShopById(id: string): Promise<SimpleShop | null> {\n\t\tconst cmd = new GetCommand({\n\t\t\tTableName: this.tableName,\n\t\t\tKey: {\n\t\t\t\tid: id,\n\t\t\t},\n\t\t});\n\n\t\tconst response = await this.docClient.send(cmd);\n\n\t\tif (!response.Item) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst shop = new SimpleShop(\n\t\t\tresponse.Item.id,\n\t\t\tresponse.Item.url,\n\t\t\tresponse.Item.secret,\n\t\t);\n\n\t\tif (response.Item.active === undefined) {\n\t\t\tresponse.Item.active = true;\n\t\t}\n\n\t\tshop.setShopActive(response.Item.active);\n\n\t\tif (response.Item.clientId) {\n\t\t\tshop.setShopCredentials(\n\t\t\t\tresponse.Item.clientId,\n\t\t\t\tresponse.Item.clientSecret,\n\t\t\t);\n\t\t}\n\n\t\treturn shop;\n\t}\n\n\tasync updateShop(shop: SimpleShop): Promise<void> {\n\t\tconst cmd = new PutCommand({\n\t\t\tTableName: this.tableName,\n\t\t\tItem: {\n\t\t\t\tid: shop.getShopId(),\n\t\t\t\tactive: shop.getShopActive(),\n\t\t\t\turl: shop.getShopUrl(),\n\t\t\t\tsecret: shop.getShopSecret(),\n\t\t\t\tclientId: shop.getShopClientId(),\n\t\t\t\tclientSecret: shop.getShopClientSecret(),\n\t\t\t},\n\t\t});\n\n\t\tawait this.docClient.send(cmd);\n\t}\n\n\tasync deleteShop(id: string): Promise<void> {\n\t\tconst cmd = new DeleteCommand({\n\t\t\tTableName: this.tableName,\n\t\t\tKey: {\n\t\t\t\tid: id,\n\t\t\t},\n\t\t});\n\n\t\tawait this.docClient.send(cmd);\n\t}\n}\n"]}
@@ -0,0 +1,29 @@
1
+ import { AppServer } from "../app.js";
2
+ import type { Context } from "../context-resolver.js";
3
+ import type { ShopInterface, ShopRepositoryInterface } from "../repository.js";
4
+ import type { Hono, Context as HonoContext } from "hono";
5
+ declare module "hono" {
6
+ interface ContextVariableMap {
7
+ app: AppServer<ShopInterface>;
8
+ shop: ShopInterface;
9
+ context: Context<ShopInterface, unknown>;
10
+ }
11
+ }
12
+ interface MiddlewareConfig {
13
+ appName: string | ((c: HonoContext) => string);
14
+ appSecret: string | ((c: HonoContext) => string);
15
+ appUrl?: string | null;
16
+ registrationUrl?: string | null;
17
+ registerConfirmationUrl?: string | null;
18
+ appActivateUrl?: string | null;
19
+ appDeactivateUrl?: string | null;
20
+ appDeleteUrl?: string | null;
21
+ appPath?: string | null;
22
+ shopRepository: ShopRepositoryInterface | ((c: HonoContext) => ShopRepositoryInterface);
23
+ }
24
+ /**
25
+ * Configure the Hono server to handle the app registration and context resolution
26
+ */
27
+ export declare function configureAppServer(hono: Hono, cfg: MiddlewareConfig): void;
28
+ export {};
29
+ //# sourceMappingURL=hono.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hono.d.ts","sourceRoot":"","sources":["../../../src/integration/hono.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,MAAM,CAAC;AAEzD,OAAO,QAAQ,MAAM,CAAC;IACrB,UAAU,kBAAkB;QAE3B,GAAG,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;QAC9B,IAAI,EAAE,aAAa,CAAC;QAEpB,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;KACzC;CACD;AAED,UAAU,gBAAgB;IACzB,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,MAAM,CAAC,CAAC;IAC/C,SAAS,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,MAAM,CAAC,CAAC;IACjD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EACX,uBAAuB,GACvB,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,uBAAuB,CAAC,CAAC;CACjD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,QAqHnE"}