storybooker 0.19.4 → 0.22.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -18
- package/dist/adapters/_internal/queue.d.mts +127 -0
- package/dist/aws-dynamodb.d.mts +22 -0
- package/dist/aws-dynamodb.mjs +118 -0
- package/dist/aws-dynamodb.mjs.map +1 -0
- package/dist/aws-s3.d.mts +20 -0
- package/dist/aws-s3.mjs +96 -0
- package/dist/aws-s3.mjs.map +1 -0
- package/dist/azure-blob-storage.d.mts +20 -0
- package/dist/azure-blob-storage.mjs +126 -0
- package/dist/azure-blob-storage.mjs.map +1 -0
- package/dist/azure-cosmos-db.d.mts +23 -0
- package/dist/azure-cosmos-db.mjs +87 -0
- package/dist/azure-cosmos-db.mjs.map +1 -0
- package/dist/azure-data-tables.d.mts +23 -0
- package/dist/azure-data-tables.mjs +127 -0
- package/dist/azure-data-tables.mjs.map +1 -0
- package/dist/azure-easy-auth.d.mts +50 -0
- package/dist/azure-easy-auth.mjs +88 -0
- package/dist/azure-easy-auth.mjs.map +1 -0
- package/dist/azure-functions.d.mts +62 -0
- package/dist/azure-functions.mjs +147 -0
- package/dist/azure-functions.mjs.map +1 -0
- package/dist/fs.d.mts +37 -0
- package/dist/fs.mjs +240 -0
- package/dist/fs.mjs.map +1 -0
- package/dist/gcp-big-table.d.mts +23 -0
- package/dist/gcp-big-table.mjs +92 -0
- package/dist/gcp-big-table.mjs.map +1 -0
- package/dist/gcp-firestore.d.mts +22 -0
- package/dist/gcp-firestore.mjs +87 -0
- package/dist/gcp-firestore.mjs.map +1 -0
- package/dist/gcp-storage.d.mts +20 -0
- package/dist/gcp-storage.mjs +96 -0
- package/dist/gcp-storage.mjs.map +1 -0
- package/dist/handlers/handle-process-zip.mjs +90 -0
- package/dist/handlers/handle-process-zip.mjs.map +1 -0
- package/dist/handlers/handle-purge.d.mts +12 -0
- package/dist/handlers/handle-purge.mjs +36 -0
- package/dist/handlers/handle-purge.mjs.map +1 -0
- package/dist/handlers/handle-serve-storybook.mjs +94 -0
- package/dist/handlers/handle-serve-storybook.mjs.map +1 -0
- package/dist/index.d.mts +28 -0
- package/dist/index.mjs +62 -0
- package/dist/index.mjs.map +1 -0
- package/dist/models/builds-model.mjs +248 -0
- package/dist/models/builds-model.mjs.map +1 -0
- package/dist/models/builds-schema.d.mts +171 -0
- package/dist/models/builds-schema.mjs +67 -0
- package/dist/models/builds-schema.mjs.map +1 -0
- package/dist/models/projects-model.mjs +122 -0
- package/dist/models/projects-model.mjs.map +1 -0
- package/dist/models/projects-schema.d.mts +70 -0
- package/dist/models/projects-schema.mjs +37 -0
- package/dist/models/projects-schema.mjs.map +1 -0
- package/dist/models/tags-model.mjs +110 -0
- package/dist/models/tags-model.mjs.map +1 -0
- package/dist/models/tags-schema.d.mts +76 -0
- package/dist/models/tags-schema.mjs +34 -0
- package/dist/models/tags-schema.mjs.map +1 -0
- package/dist/models/~model.mjs +43 -0
- package/dist/models/~model.mjs.map +1 -0
- package/dist/models/~shared-schema.d.mts +1 -0
- package/dist/models/~shared-schema.mjs +20 -0
- package/dist/models/~shared-schema.mjs.map +1 -0
- package/dist/mysql.d.mts +39 -0
- package/dist/mysql.mjs +151 -0
- package/dist/mysql.mjs.map +1 -0
- package/dist/redis.d.mts +33 -0
- package/dist/redis.mjs +118 -0
- package/dist/redis.mjs.map +1 -0
- package/dist/routers/account-router.mjs +91 -0
- package/dist/routers/account-router.mjs.map +1 -0
- package/dist/routers/builds-router.mjs +347 -0
- package/dist/routers/builds-router.mjs.map +1 -0
- package/dist/routers/projects-router.mjs +236 -0
- package/dist/routers/projects-router.mjs.map +1 -0
- package/dist/routers/root-router.mjs +108 -0
- package/dist/routers/root-router.mjs.map +1 -0
- package/dist/routers/tags-router.mjs +269 -0
- package/dist/routers/tags-router.mjs.map +1 -0
- package/dist/routers/tasks-router.mjs +71 -0
- package/dist/routers/tasks-router.mjs.map +1 -0
- package/dist/urls.d.mts +47 -0
- package/dist/urls.mjs +208 -0
- package/dist/urls.mjs.map +1 -0
- package/dist/utils/adapter-utils.d.mts +14 -0
- package/dist/utils/adapter-utils.mjs +14 -0
- package/dist/utils/adapter-utils.mjs.map +1 -0
- package/dist/utils/auth.mjs +25 -0
- package/dist/utils/auth.mjs.map +1 -0
- package/dist/utils/error.d.mts +21 -0
- package/dist/utils/error.mjs +109 -0
- package/dist/utils/error.mjs.map +1 -0
- package/dist/utils/file-utils.mjs +16 -0
- package/dist/utils/file-utils.mjs.map +1 -0
- package/dist/utils/openapi-utils.mjs +45 -0
- package/dist/utils/openapi-utils.mjs.map +1 -0
- package/dist/utils/request.mjs +35 -0
- package/dist/utils/request.mjs.map +1 -0
- package/dist/utils/response.mjs +24 -0
- package/dist/utils/response.mjs.map +1 -0
- package/dist/utils/store.mjs +54 -0
- package/dist/utils/store.mjs.map +1 -0
- package/dist/utils/ui-utils.mjs +38 -0
- package/dist/utils/ui-utils.mjs.map +1 -0
- package/dist/utils/url-utils.d.mts +10 -0
- package/dist/utils/url-utils.mjs +54 -0
- package/dist/utils/url-utils.mjs.map +1 -0
- package/dist/~internal/adapter/auth.d.mts +123 -0
- package/dist/~internal/adapter/auth.mjs +20 -0
- package/dist/~internal/adapter/auth.mjs.map +1 -0
- package/dist/~internal/adapter/database.d.mts +240 -0
- package/dist/~internal/adapter/database.mjs +63 -0
- package/dist/~internal/adapter/database.mjs.map +1 -0
- package/dist/~internal/adapter/logger.d.mts +34 -0
- package/dist/~internal/adapter/logger.mjs +13 -0
- package/dist/~internal/adapter/logger.mjs.map +1 -0
- package/dist/~internal/adapter/storage.d.mts +208 -0
- package/dist/~internal/adapter/storage.mjs +63 -0
- package/dist/~internal/adapter/storage.mjs.map +1 -0
- package/dist/~internal/adapter/ui.d.mts +109 -0
- package/dist/~internal/adapter/ui.mjs +1 -0
- package/dist/~internal/adapter.d.mts +8 -0
- package/dist/~internal/adapter.mjs +6 -0
- package/dist/~internal/constants.d.mts +24 -0
- package/dist/~internal/constants.mjs +32 -0
- package/dist/~internal/constants.mjs.map +1 -0
- package/dist/~internal/mimes.d.mts +449 -0
- package/dist/~internal/mimes.mjs +454 -0
- package/dist/~internal/mimes.mjs.map +1 -0
- package/dist/~internal/router.d.mts +1651 -0
- package/dist/~internal/router.mjs +39 -0
- package/dist/~internal/router.mjs.map +1 -0
- package/dist/~internal/types.d.mts +77 -0
- package/dist/~internal/types.mjs +1 -0
- package/dist/~internal/utils.d.mts +4 -0
- package/dist/~internal/utils.mjs +5 -0
- package/openapi.json +3162 -0
- package/package.json +148 -27
- package/src/adapters/_internal/auth.ts +135 -0
- package/src/adapters/_internal/database.ts +241 -0
- package/src/adapters/_internal/index.ts +8 -0
- package/src/adapters/_internal/logger.ts +41 -0
- package/src/adapters/_internal/queue.ts +151 -0
- package/src/adapters/_internal/storage.ts +197 -0
- package/src/adapters/_internal/ui.ts +103 -0
- package/src/adapters/aws-dynamodb.ts +201 -0
- package/src/adapters/aws-s3.ts +160 -0
- package/src/adapters/azure-blob-storage.ts +223 -0
- package/src/adapters/azure-cosmos-db.ts +158 -0
- package/src/adapters/azure-data-tables.ts +223 -0
- package/src/adapters/azure-easy-auth.ts +174 -0
- package/src/adapters/azure-functions.ts +242 -0
- package/src/adapters/fs.ts +398 -0
- package/src/adapters/gcp-big-table.ts +157 -0
- package/src/adapters/gcp-firestore.ts +146 -0
- package/src/adapters/gcp-storage.ts +141 -0
- package/src/adapters/mysql.ts +296 -0
- package/src/adapters/redis.ts +242 -0
- package/src/handlers/handle-process-zip.ts +117 -0
- package/src/handlers/handle-purge.ts +65 -0
- package/src/handlers/handle-serve-storybook.ts +101 -0
- package/src/index.ts +81 -16
- package/src/mocks/mock-auth-service.ts +51 -0
- package/src/mocks/mock-store.ts +26 -0
- package/src/models/builds-model.ts +373 -0
- package/src/models/builds-schema.ts +84 -0
- package/src/models/projects-model.ts +177 -0
- package/src/models/projects-schema.ts +69 -0
- package/src/models/tags-model.ts +138 -0
- package/src/models/tags-schema.ts +45 -0
- package/src/models/~model.ts +79 -0
- package/src/models/~shared-schema.ts +14 -0
- package/src/routers/_app-router.ts +57 -0
- package/src/routers/account-router.ts +136 -0
- package/src/routers/builds-router.ts +464 -0
- package/src/routers/projects-router.ts +309 -0
- package/src/routers/root-router.ts +127 -0
- package/src/routers/tags-router.ts +339 -0
- package/src/routers/tasks-router.ts +75 -0
- package/src/types.ts +107 -0
- package/src/urls.ts +327 -0
- package/src/utils/adapter-utils.ts +26 -0
- package/src/utils/auth.test.ts +71 -0
- package/src/utils/auth.ts +39 -0
- package/src/utils/constants.ts +31 -0
- package/src/utils/date-utils.ts +10 -0
- package/src/utils/error.test.ts +86 -0
- package/src/utils/error.ts +140 -0
- package/src/utils/file-utils.test.ts +65 -0
- package/src/utils/file-utils.ts +43 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/mime-utils.ts +457 -0
- package/src/utils/openapi-utils.ts +49 -0
- package/src/utils/request.ts +97 -0
- package/src/utils/response.ts +20 -0
- package/src/utils/store.ts +85 -0
- package/src/utils/story-utils.ts +42 -0
- package/src/utils/text-utils.ts +10 -0
- package/src/utils/ui-utils.ts +57 -0
- package/src/utils/url-utils.ts +113 -0
- package/dist/index.js +0 -554
- package/src/commands/create.ts +0 -263
- package/src/commands/purge.ts +0 -70
- package/src/commands/test.ts +0 -42
- package/src/service-schema.d.ts +0 -2023
- package/src/utils/auth-utils.ts +0 -31
- package/src/utils/pkg-utils.ts +0 -37
- package/src/utils/sb-build.ts +0 -55
- package/src/utils/sb-test.ts +0 -115
- package/src/utils/schema-utils.ts +0 -123
- package/src/utils/stream-utils.ts +0 -72
- package/src/utils/types.ts +0 -4
- package/src/utils/zip.ts +0 -77
package/package.json
CHANGED
|
@@ -1,50 +1,171 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "storybooker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0-canary.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"
|
|
6
|
-
"description": "Storybooker CLI for uploading builds and files.",
|
|
5
|
+
"description": "Manage Storybook instances on your own infrastructure with ease.",
|
|
7
6
|
"author": {
|
|
8
7
|
"name": "Siddhant Gupta",
|
|
9
8
|
"url": "https://guptasiddhant.com"
|
|
10
9
|
},
|
|
11
|
-
"files": [
|
|
12
|
-
"src",
|
|
13
|
-
"dist"
|
|
14
|
-
],
|
|
15
10
|
"homepage": "https://storybooker.js.org",
|
|
16
11
|
"repository": {
|
|
17
12
|
"type": "git",
|
|
18
|
-
"url": "https://github.com/
|
|
19
|
-
"directory": "packages/
|
|
13
|
+
"url": "https://github.com/GuptaSiddhant/storybooker",
|
|
14
|
+
"directory": "packages/core"
|
|
20
15
|
},
|
|
16
|
+
"files": [
|
|
17
|
+
"adapters",
|
|
18
|
+
"src",
|
|
19
|
+
"dist",
|
|
20
|
+
"openapi.json"
|
|
21
|
+
],
|
|
21
22
|
"license": "MIT",
|
|
22
23
|
"sideEffects": false,
|
|
23
24
|
"scripts": {
|
|
24
25
|
"build": "tsdown",
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"fmt": "prettier src --write --config ../../.prettierrc",
|
|
29
|
-
"lint": "oxlint --type-aware ./src",
|
|
26
|
+
"dev": "tsdown -w",
|
|
27
|
+
"fmt": "oxfmt -c ../../.oxfmtrc.json ./src",
|
|
28
|
+
"lint": "oxlint --type-aware --type-check --import-plugin ./src",
|
|
30
29
|
"lint:fix": "yarn lint --fix",
|
|
31
|
-
"openapi": "
|
|
32
|
-
"
|
|
30
|
+
"openapi": "node ./scripts/gen-openapi-json.ts",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"test:coverage": "vitest run --coverage",
|
|
33
|
+
"test:watch": "vitest"
|
|
33
34
|
},
|
|
34
35
|
"dependencies": {
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
36
|
+
"@hono/swagger-ui": "^0.5.2",
|
|
37
|
+
"@hono/zod-openapi": "^1.1.5",
|
|
38
|
+
"@remix-run/headers": "^0.16.0",
|
|
39
|
+
"decompress": "^4.0.0",
|
|
40
|
+
"hono": "^4.11.0",
|
|
41
|
+
"js-yaml": "^4.1.1",
|
|
42
|
+
"zod": "^4.2.0"
|
|
38
43
|
},
|
|
39
44
|
"devDependencies": {
|
|
45
|
+
"@aws-sdk/client-dynamodb": "^3.0.0",
|
|
46
|
+
"@aws-sdk/client-s3": "^3.0.0",
|
|
47
|
+
"@azure/cosmos": "^4.5.1",
|
|
48
|
+
"@azure/data-tables": "^13.0.0",
|
|
49
|
+
"@azure/functions": "^4.0.0",
|
|
50
|
+
"@azure/storage-blob": "^12.0.0",
|
|
51
|
+
"@google-cloud/bigtable": "^6.0.0",
|
|
52
|
+
"@google-cloud/firestore": "^7.0.0",
|
|
53
|
+
"@google-cloud/storage": "^7.0.0",
|
|
54
|
+
"@types/decompress": "^4.0.0",
|
|
55
|
+
"@types/js-yaml": "^4.0.9",
|
|
40
56
|
"@types/node": "^22.0.0",
|
|
41
|
-
"@
|
|
42
|
-
"@
|
|
43
|
-
"
|
|
44
|
-
"oxlint": "^1.
|
|
45
|
-
"oxlint-tsgolint": "^0.
|
|
46
|
-
"
|
|
47
|
-
"tsdown": "^0.
|
|
48
|
-
"
|
|
57
|
+
"@typescript/native-preview": "7.0.0-dev.20251217.1",
|
|
58
|
+
"@vitest/coverage-v8": "^4.0.0",
|
|
59
|
+
"oxfmt": "^0.18.0",
|
|
60
|
+
"oxlint": "^1.33.0",
|
|
61
|
+
"oxlint-tsgolint": "^0.9.1",
|
|
62
|
+
"redis": "^5.10.0",
|
|
63
|
+
"tsdown": "^0.18.1",
|
|
64
|
+
"vitest": "^4.0.0"
|
|
65
|
+
},
|
|
66
|
+
"peerDependencies": {
|
|
67
|
+
"@aws-sdk/client-dynamodb": "^3.0.0",
|
|
68
|
+
"@aws-sdk/client-s3": "^3.0.0",
|
|
69
|
+
"@azure/cosmos": "^4.0.0",
|
|
70
|
+
"@azure/data-tables": "^13.0.0",
|
|
71
|
+
"@azure/functions": "^4.0.0",
|
|
72
|
+
"@azure/storage-blob": "^12.0.0",
|
|
73
|
+
"@google-cloud/bigtable": "^6.0.0",
|
|
74
|
+
"@google-cloud/firestore": "^7.0.0",
|
|
75
|
+
"@google-cloud/storage": "^7.0.0",
|
|
76
|
+
"redis": "^5.0.0"
|
|
77
|
+
},
|
|
78
|
+
"peerDependenciesMeta": {
|
|
79
|
+
"@aws-sdk/client-dynamodb": {
|
|
80
|
+
"optional": true
|
|
81
|
+
},
|
|
82
|
+
"@aws-sdk/client-s3": {
|
|
83
|
+
"optional": true
|
|
84
|
+
},
|
|
85
|
+
"@azure/cosmos": {
|
|
86
|
+
"optional": true
|
|
87
|
+
},
|
|
88
|
+
"@azure/data-tables": {
|
|
89
|
+
"optional": true
|
|
90
|
+
},
|
|
91
|
+
"@azure/functions": {
|
|
92
|
+
"optional": true
|
|
93
|
+
},
|
|
94
|
+
"@azure/storage-blob": {
|
|
95
|
+
"optional": true
|
|
96
|
+
},
|
|
97
|
+
"@google-cloud/bigtable": {
|
|
98
|
+
"optional": true
|
|
99
|
+
},
|
|
100
|
+
"@google-cloud/firestore": {
|
|
101
|
+
"optional": true
|
|
102
|
+
},
|
|
103
|
+
"@google-cloud/storage": {
|
|
104
|
+
"optional": true
|
|
105
|
+
},
|
|
106
|
+
"redis": {
|
|
107
|
+
"optional": true
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"main": "./dist/index.mjs",
|
|
111
|
+
"module": "./dist/index.mjs",
|
|
112
|
+
"types": "./dist/index.d.mts",
|
|
113
|
+
"exports": {
|
|
114
|
+
".": "./dist/index.mjs",
|
|
115
|
+
"./~internal/adapter": "./dist/~internal/adapter.mjs",
|
|
116
|
+
"./~internal/adapter/auth": "./dist/~internal/adapter/auth.mjs",
|
|
117
|
+
"./~internal/adapter/database": "./dist/~internal/adapter/database.mjs",
|
|
118
|
+
"./~internal/adapter/logger": "./dist/~internal/adapter/logger.mjs",
|
|
119
|
+
"./~internal/adapter/storage": "./dist/~internal/adapter/storage.mjs",
|
|
120
|
+
"./~internal/adapter/ui": "./dist/~internal/adapter/ui.mjs",
|
|
121
|
+
"./~internal/constants": "./dist/~internal/constants.mjs",
|
|
122
|
+
"./~internal/mimes": "./dist/~internal/mimes.mjs",
|
|
123
|
+
"./~internal/router": "./dist/~internal/router.mjs",
|
|
124
|
+
"./~internal/types": "./dist/~internal/types.mjs",
|
|
125
|
+
"./~internal/utils": "./dist/~internal/utils.mjs",
|
|
126
|
+
"./aws-dynamodb": "./dist/aws-dynamodb.mjs",
|
|
127
|
+
"./aws-s3": "./dist/aws-s3.mjs",
|
|
128
|
+
"./azure-blob-storage": "./dist/azure-blob-storage.mjs",
|
|
129
|
+
"./azure-cosmos-db": "./dist/azure-cosmos-db.mjs",
|
|
130
|
+
"./azure-data-tables": "./dist/azure-data-tables.mjs",
|
|
131
|
+
"./azure-easy-auth": "./dist/azure-easy-auth.mjs",
|
|
132
|
+
"./azure-functions": "./dist/azure-functions.mjs",
|
|
133
|
+
"./fs": "./dist/fs.mjs",
|
|
134
|
+
"./gcp-big-table": "./dist/gcp-big-table.mjs",
|
|
135
|
+
"./gcp-firestore": "./dist/gcp-firestore.mjs",
|
|
136
|
+
"./gcp-storage": "./dist/gcp-storage.mjs",
|
|
137
|
+
"./mysql": "./dist/mysql.mjs",
|
|
138
|
+
"./redis": "./dist/redis.mjs",
|
|
139
|
+
"./package.json": "./package.json"
|
|
140
|
+
},
|
|
141
|
+
"publishConfig": {
|
|
142
|
+
"exports": {
|
|
143
|
+
".": "./dist/index.mjs",
|
|
144
|
+
"./~internal/adapter": "./dist/~internal/adapter.mjs",
|
|
145
|
+
"./~internal/adapter/auth": "./dist/~internal/adapter/auth.mjs",
|
|
146
|
+
"./~internal/adapter/database": "./dist/~internal/adapter/database.mjs",
|
|
147
|
+
"./~internal/adapter/logger": "./dist/~internal/adapter/logger.mjs",
|
|
148
|
+
"./~internal/adapter/storage": "./dist/~internal/adapter/storage.mjs",
|
|
149
|
+
"./~internal/adapter/ui": "./dist/~internal/adapter/ui.mjs",
|
|
150
|
+
"./~internal/constants": "./dist/~internal/constants.mjs",
|
|
151
|
+
"./~internal/mimes": "./dist/~internal/mimes.mjs",
|
|
152
|
+
"./~internal/router": "./dist/~internal/router.mjs",
|
|
153
|
+
"./~internal/types": "./dist/~internal/types.mjs",
|
|
154
|
+
"./~internal/utils": "./dist/~internal/utils.mjs",
|
|
155
|
+
"./aws-dynamodb": "./dist/aws-dynamodb.mjs",
|
|
156
|
+
"./aws-s3": "./dist/aws-s3.mjs",
|
|
157
|
+
"./azure-blob-storage": "./dist/azure-blob-storage.mjs",
|
|
158
|
+
"./azure-cosmos-db": "./dist/azure-cosmos-db.mjs",
|
|
159
|
+
"./azure-data-tables": "./dist/azure-data-tables.mjs",
|
|
160
|
+
"./azure-easy-auth": "./dist/azure-easy-auth.mjs",
|
|
161
|
+
"./azure-functions": "./dist/azure-functions.mjs",
|
|
162
|
+
"./fs": "./dist/fs.mjs",
|
|
163
|
+
"./gcp-big-table": "./dist/gcp-big-table.mjs",
|
|
164
|
+
"./gcp-firestore": "./dist/gcp-firestore.mjs",
|
|
165
|
+
"./gcp-storage": "./dist/gcp-storage.mjs",
|
|
166
|
+
"./mysql": "./dist/mysql.mjs",
|
|
167
|
+
"./redis": "./dist/redis.mjs",
|
|
168
|
+
"./package.json": "./package.json"
|
|
169
|
+
}
|
|
49
170
|
}
|
|
50
171
|
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { StoryBookerAdapterMetadata } from "../../utils/adapter-utils.ts";
|
|
2
|
+
import type { LoggerAdapter } from "./logger.ts";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Service adapter to manage authentication.
|
|
6
|
+
*
|
|
7
|
+
* The service is responsible to authorise users from
|
|
8
|
+
* accessing the app.
|
|
9
|
+
*/
|
|
10
|
+
export interface AuthAdapter<AuthUser extends StoryBookerUser = StoryBookerUser> {
|
|
11
|
+
/**
|
|
12
|
+
* Metadata about the adapter.
|
|
13
|
+
*/
|
|
14
|
+
metadata: StoryBookerAdapterMetadata;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* An optional method that is called on app boot-up
|
|
18
|
+
* to run async setup functions.
|
|
19
|
+
* @param options Common options like abortSignal.
|
|
20
|
+
* @throws if an error occur during initialisation.
|
|
21
|
+
*/
|
|
22
|
+
init?: (options: Omit<AuthAdapterOptions, "request">) => Promise<void>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get details about the user and permissions based on incoming request.
|
|
26
|
+
*
|
|
27
|
+
* @param options Common options like abortSignal.
|
|
28
|
+
*
|
|
29
|
+
* @throws an error or response (redirect-to-login) if it is a unauthenticated/unauthorised request.
|
|
30
|
+
*/
|
|
31
|
+
getUserDetails: (options: AuthAdapterOptions) => Promise<AuthUser | null>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get user to login from UI. The returning response should create auth session.
|
|
35
|
+
* User will be redirected automatically after function is resolved.
|
|
36
|
+
*
|
|
37
|
+
* @param options Common options like abortSignal.
|
|
38
|
+
*/
|
|
39
|
+
login: (options: AuthAdapterOptions) => Promise<Response> | Response;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get user to logout from UI. The returning response should clear auth session.
|
|
43
|
+
* User will be redirected automatically after function is resolved.
|
|
44
|
+
*
|
|
45
|
+
* @param options Common options like abortSignal.
|
|
46
|
+
*/
|
|
47
|
+
logout: (user: AuthUser, options: AuthAdapterOptions) => Promise<Response> | Response;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Render custom HTML in account page. Must return valid HTML string;
|
|
51
|
+
*
|
|
52
|
+
* @param options Common options like abortSignal.
|
|
53
|
+
*/
|
|
54
|
+
renderAccountDetails?: (user: AuthUser, options: AuthAdapterOptions) => Promise<string> | string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Type for the callback function to check permissions.
|
|
59
|
+
*
|
|
60
|
+
* @param options Common options like abortSignal.
|
|
61
|
+
*
|
|
62
|
+
* @returns true to allow access, or following to deny:
|
|
63
|
+
* - false - returns 403 response
|
|
64
|
+
* - Response - returns the specified HTTP response
|
|
65
|
+
*/
|
|
66
|
+
export type AuthAdapterAuthorise<AuthUser extends StoryBookerUser = StoryBookerUser> = (
|
|
67
|
+
params: {
|
|
68
|
+
permission: StoryBookerPermissionWithKey;
|
|
69
|
+
user: AuthUser;
|
|
70
|
+
},
|
|
71
|
+
options: AuthAdapterOptions,
|
|
72
|
+
) => Promise<boolean | Response> | boolean | Response;
|
|
73
|
+
|
|
74
|
+
/** Type of permission to check */
|
|
75
|
+
export interface StoryBookerPermission {
|
|
76
|
+
action: StoryBookerPermissionAction;
|
|
77
|
+
projectId?: string;
|
|
78
|
+
resource: StoryBookerPermissionResource;
|
|
79
|
+
}
|
|
80
|
+
/** Permission object with key */
|
|
81
|
+
export type StoryBookerPermissionWithKey = StoryBookerPermission & {
|
|
82
|
+
key: StoryBookerPermissionKey;
|
|
83
|
+
};
|
|
84
|
+
/** Permission in a string format */
|
|
85
|
+
export type StoryBookerPermissionKey =
|
|
86
|
+
`${StoryBookerPermissionResource}:${StoryBookerPermissionAction}`;
|
|
87
|
+
/** Type of possible resources to check permissions for */
|
|
88
|
+
export type StoryBookerPermissionResource = "project" | "build" | "tag";
|
|
89
|
+
/** Type of possible actions to check permissions for */
|
|
90
|
+
export type StoryBookerPermissionAction = "create" | "read" | "update" | "delete";
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Base representation of a generic User
|
|
94
|
+
*/
|
|
95
|
+
export interface StoryBookerUser {
|
|
96
|
+
/** Name of the user displayed in UI. */
|
|
97
|
+
displayName: string;
|
|
98
|
+
/** Unique ID of the user. Could be email-address. */
|
|
99
|
+
id: string;
|
|
100
|
+
/** Static URL for User's avatar shown in UI. */
|
|
101
|
+
imageUrl?: string;
|
|
102
|
+
/** Title or Team-name of the User shown in UI. */
|
|
103
|
+
title?: string;
|
|
104
|
+
/** Permissions assigned to the user. Missing permissions are considered false. */
|
|
105
|
+
permissions: Partial<Record<StoryBookerPermissionKey, boolean>>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Common Auth adapter options. */
|
|
109
|
+
export interface AuthAdapterOptions {
|
|
110
|
+
/** A signal that can be used to cancel the request handling. */
|
|
111
|
+
abortSignal?: AbortSignal;
|
|
112
|
+
/** Incoming request (cloned) */
|
|
113
|
+
request: Request;
|
|
114
|
+
/** Logger */
|
|
115
|
+
logger: LoggerAdapter;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const StoryBookerPermissionsAllEnabled = {
|
|
119
|
+
"build:create": true,
|
|
120
|
+
"build:delete": true,
|
|
121
|
+
"project:update": true,
|
|
122
|
+
"build:read": true,
|
|
123
|
+
"tag:delete": true,
|
|
124
|
+
"build:update": true,
|
|
125
|
+
"tag:create": true,
|
|
126
|
+
"project:read": true,
|
|
127
|
+
"project:create": true,
|
|
128
|
+
"tag:read": true,
|
|
129
|
+
"project:delete": true,
|
|
130
|
+
"tag:update": true,
|
|
131
|
+
} satisfies Record<StoryBookerPermissionKey, true>;
|
|
132
|
+
|
|
133
|
+
export const StoryBookerPermissionsList = Object.keys(
|
|
134
|
+
StoryBookerPermissionsAllEnabled,
|
|
135
|
+
) as StoryBookerPermissionKey[];
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// oxlint-disable max-classes-per-file
|
|
2
|
+
|
|
3
|
+
import { HTTPException } from "hono/http-exception";
|
|
4
|
+
import type { ContentfulStatusCode } from "hono/utils/http-status";
|
|
5
|
+
import type { StoryBookerAdapterMetadata } from "../../utils/adapter-utils.ts";
|
|
6
|
+
import type { LoggerAdapter } from "./logger.ts";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Service adapter to interact with database.
|
|
10
|
+
*
|
|
11
|
+
* @description
|
|
12
|
+
* The adapter should provide callbacks to CRUD operations
|
|
13
|
+
* to an existing database.
|
|
14
|
+
*
|
|
15
|
+
* - `collection`: A collection/container/table to hold items.
|
|
16
|
+
* - `document`: A single entry in collection which contains key-value pairs (no nested data).
|
|
17
|
+
* Each document has a key 'id` which is unique in the collection.
|
|
18
|
+
*
|
|
19
|
+
* @throws {DatabaseNotInitializedError} if the DB service is not connected.
|
|
20
|
+
* @throws {CollectionAlreadyExistsError} if the collection already exists.
|
|
21
|
+
* @throws {CollectionDoesNotExistError} if the collection does not exist.
|
|
22
|
+
* @throws {DocumentAlreadyExistsError} if the document already exists in the collection.
|
|
23
|
+
* @throws {DocumentDoesNotExistError} if the document does not exist in the collection.
|
|
24
|
+
* @throws {CustomError} if some other error occurs.
|
|
25
|
+
*/
|
|
26
|
+
export interface DatabaseAdapter<
|
|
27
|
+
DbDocument extends StoryBookerDatabaseDocument = StoryBookerDatabaseDocument,
|
|
28
|
+
> {
|
|
29
|
+
/**
|
|
30
|
+
* Metadata about the adapter.
|
|
31
|
+
*/
|
|
32
|
+
metadata: StoryBookerAdapterMetadata;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* An optional method that is called on app boot-up
|
|
36
|
+
* to run async setup functions.
|
|
37
|
+
* @param options Common options like abortSignal.
|
|
38
|
+
* @throws if an error occur during initialisation.
|
|
39
|
+
*/
|
|
40
|
+
init?: (options: DatabaseAdapterOptions) => Promise<void>;
|
|
41
|
+
|
|
42
|
+
// Collections (group of items. aka Tables)
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* List all collections available in the DB.
|
|
46
|
+
* @param options Common options like abortSignal.
|
|
47
|
+
* @returns A list of names/IDs of the collections.
|
|
48
|
+
* @throws {DatabaseNotInitializedError} if the DB service is not connected.
|
|
49
|
+
*/
|
|
50
|
+
listCollections: (options: DatabaseAdapterOptions) => Promise<string[]>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Create a collection used for different projects.
|
|
54
|
+
* @param collectionId ID of the collection
|
|
55
|
+
* @param options Common options like abortSignal.
|
|
56
|
+
* @throws {DatabaseNotInitializedError} if the DB service is not connected.
|
|
57
|
+
* @throws {CollectionAlreadyExistsError} if collection with ID already exists.
|
|
58
|
+
*/
|
|
59
|
+
createCollection: (collectionId: string, options: DatabaseAdapterOptions) => Promise<void>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Delete an existing collection.
|
|
63
|
+
* @param collectionId ID of the collection
|
|
64
|
+
* @param options Common options like abortSignal.
|
|
65
|
+
* @throws {DatabaseNotInitializedError} if the DB service is not connected.
|
|
66
|
+
* @throws {CollectionDoesNotExistError} if collection with ID does not exist.
|
|
67
|
+
*/
|
|
68
|
+
deleteCollection: (collectionId: string, options: DatabaseAdapterOptions) => Promise<void>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Check if collection exists.
|
|
72
|
+
* @param collectionId ID of the collection
|
|
73
|
+
* @param options Common options like abortSignal.
|
|
74
|
+
* @returns if collection is available of not
|
|
75
|
+
* @throws never.
|
|
76
|
+
*/
|
|
77
|
+
hasCollection: (collectionId: string, options: DatabaseAdapterOptions) => Promise<boolean>;
|
|
78
|
+
|
|
79
|
+
// Documents (items, entries, rows, etc)
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* List all documents available in the requested collection.
|
|
83
|
+
* @param collectionId ID of the collection
|
|
84
|
+
* @param listOptions Options to format/sort the result
|
|
85
|
+
* @param options Common options like abortSignal.
|
|
86
|
+
* @returns List of documents
|
|
87
|
+
* @throws if the collection does not exist.
|
|
88
|
+
*/
|
|
89
|
+
listDocuments: (
|
|
90
|
+
collectionId: string,
|
|
91
|
+
listOptions: DatabaseDocumentListOptions<DbDocument>,
|
|
92
|
+
options: DatabaseAdapterOptions,
|
|
93
|
+
) => Promise<DbDocument[]>;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Create a new document in the collection.
|
|
97
|
+
* @param collectionId ID of the collection
|
|
98
|
+
* @param documentData Data to be stored
|
|
99
|
+
* @param options Common options like abortSignal.
|
|
100
|
+
* @throws if the collection does not exist.
|
|
101
|
+
*/
|
|
102
|
+
createDocument: (
|
|
103
|
+
collectionId: string,
|
|
104
|
+
documentData: DbDocument,
|
|
105
|
+
options: DatabaseAdapterOptions,
|
|
106
|
+
) => Promise<void>;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get matching document data available in the requested collection.
|
|
110
|
+
* @param collectionId ID of the collection
|
|
111
|
+
* @param documentId ID of the document
|
|
112
|
+
* @param options Common options like abortSignal.
|
|
113
|
+
* @returns Data of the document
|
|
114
|
+
* @throws if the collection or document does not exist.
|
|
115
|
+
*/
|
|
116
|
+
getDocument: (
|
|
117
|
+
collectionId: string,
|
|
118
|
+
documentId: string,
|
|
119
|
+
options: DatabaseAdapterOptions,
|
|
120
|
+
) => Promise<DbDocument>;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Check matching document data available in the requested collection.
|
|
124
|
+
* @param collectionId ID of the collection
|
|
125
|
+
* @param documentId ID of the document
|
|
126
|
+
* @param options Common options like abortSignal.
|
|
127
|
+
* @returns if document is available of not
|
|
128
|
+
* @throws if the collection does not exists.
|
|
129
|
+
*/
|
|
130
|
+
hasDocument: (
|
|
131
|
+
collectionId: string,
|
|
132
|
+
documentId: string,
|
|
133
|
+
options: DatabaseAdapterOptions,
|
|
134
|
+
) => Promise<boolean>;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Update matching document data available in the requested collection.
|
|
138
|
+
* @param collectionId ID of the collection
|
|
139
|
+
* @param documentId ID of the document
|
|
140
|
+
* @param documentData Partial data to be updated.
|
|
141
|
+
* @param options Common options like abortSignal.
|
|
142
|
+
* @throws if the collection or document does not exist.
|
|
143
|
+
*/
|
|
144
|
+
updateDocument: (
|
|
145
|
+
collectionId: string,
|
|
146
|
+
documentId: string,
|
|
147
|
+
documentData: Partial<Omit<DbDocument, "id">>,
|
|
148
|
+
options: DatabaseAdapterOptions,
|
|
149
|
+
) => Promise<void>;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Delete matching document available in the requested collection.
|
|
153
|
+
* @param collectionId ID of the collection
|
|
154
|
+
* @param documentId ID of the document
|
|
155
|
+
* @param options Common options like abortSignal.
|
|
156
|
+
* @throws if the collection or document does not exist.
|
|
157
|
+
*/
|
|
158
|
+
deleteDocument: (
|
|
159
|
+
collectionId: string,
|
|
160
|
+
documentId: string,
|
|
161
|
+
options: DatabaseAdapterOptions,
|
|
162
|
+
) => Promise<void>;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Base Document shape used in StoryBooker Database.
|
|
167
|
+
* Should always contain a filed 'id' with string value.
|
|
168
|
+
*/
|
|
169
|
+
export interface StoryBookerDatabaseDocument {
|
|
170
|
+
id: string;
|
|
171
|
+
updatedAt: string;
|
|
172
|
+
createdAt: string;
|
|
173
|
+
[key: string]: unknown;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** Common Database adapter options. */
|
|
177
|
+
export interface DatabaseAdapterOptions {
|
|
178
|
+
/** A signal that can be used to cancel the request handling. */
|
|
179
|
+
abortSignal?: AbortSignal;
|
|
180
|
+
/** Logger */
|
|
181
|
+
logger: LoggerAdapter;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export interface DatabaseDocumentListOptions<Item extends { id: string }> {
|
|
185
|
+
limit?: number;
|
|
186
|
+
filter?: string | ((item: Item) => boolean);
|
|
187
|
+
select?: string[];
|
|
188
|
+
sort?: "latest" | ((item1: Item, item2: Item) => number);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Pre-defined Database adapter errors
|
|
193
|
+
* that can be used across different adapters.
|
|
194
|
+
*
|
|
195
|
+
* Throws {HTTPException} with relevant status codes.
|
|
196
|
+
*/
|
|
197
|
+
export const DatabaseAdapterErrors = {
|
|
198
|
+
DatabaseNotInitializedError: class extends HTTPException {
|
|
199
|
+
constructor(cause?: unknown) {
|
|
200
|
+
super(500, { cause, message: "Database adapter is not initialized." });
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
CollectionAlreadyExistsError: class extends HTTPException {
|
|
204
|
+
constructor(collectionId: string, cause?: unknown) {
|
|
205
|
+
super(409, {
|
|
206
|
+
cause,
|
|
207
|
+
message: `Database collection '${collectionId}' already exists.`,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
CollectionDoesNotExistError: class extends HTTPException {
|
|
212
|
+
constructor(collectionId: string, cause?: unknown) {
|
|
213
|
+
super(404, {
|
|
214
|
+
cause,
|
|
215
|
+
message: `Database collection '${collectionId}' does not exist.`,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
DocumentAlreadyExistsError: class extends HTTPException {
|
|
220
|
+
constructor(collectionId: string, documentId: string, cause?: unknown) {
|
|
221
|
+
super(409, {
|
|
222
|
+
cause,
|
|
223
|
+
message: `Database document '${documentId}' already exists in collection '${collectionId}'.`,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
DocumentDoesNotExistError: class extends HTTPException {
|
|
228
|
+
constructor(collectionId: string, documentId: string, cause?: unknown) {
|
|
229
|
+
super(404, {
|
|
230
|
+
cause,
|
|
231
|
+
message: `Database document '${documentId}' does not exist in collection '${collectionId}'.`,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
CustomError: class extends HTTPException {
|
|
236
|
+
constructor(status: number | undefined, message: string, cause?: unknown) {
|
|
237
|
+
super(status as ContentfulStatusCode, { cause, message });
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
// oxlint-disable-next-line no-explicit-any
|
|
241
|
+
} satisfies Record<string, new (...args: any[]) => HTTPException>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// oxlint-disable no-barrel-file
|
|
2
|
+
export * from "./auth.ts";
|
|
3
|
+
export * from "./database.ts";
|
|
4
|
+
export * from "./logger.ts";
|
|
5
|
+
export * from "./queue.ts";
|
|
6
|
+
export * from "./storage.ts";
|
|
7
|
+
export * from "./ui.ts";
|
|
8
|
+
export type { StoryBookerAdapterMetadata } from "../../utils/adapter-utils.ts";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { StoryBookerAdapterMetadata } from "../../utils/adapter-utils.ts";
|
|
2
|
+
|
|
3
|
+
// oxlint-disable no-console
|
|
4
|
+
/**
|
|
5
|
+
* Service adapter to log to desired destination.
|
|
6
|
+
*
|
|
7
|
+
* The service should contain method to `log` and report `error`.
|
|
8
|
+
* It can optionally have `debug` callback for debug messages.
|
|
9
|
+
*
|
|
10
|
+
* @default NodeJS.console
|
|
11
|
+
*/
|
|
12
|
+
export interface LoggerAdapter {
|
|
13
|
+
/**
|
|
14
|
+
* Metadata about the adapter.
|
|
15
|
+
*/
|
|
16
|
+
metadata: StoryBookerAdapterMetadata;
|
|
17
|
+
/**
|
|
18
|
+
* Optional debug logs
|
|
19
|
+
*/
|
|
20
|
+
debug?: (...args: unknown[]) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Error logs
|
|
23
|
+
*/
|
|
24
|
+
error: (...args: unknown[]) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Normal logs
|
|
27
|
+
*/
|
|
28
|
+
log: (...args: unknown[]) => void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function createConsoleLoggerAdapter(): LoggerAdapter {
|
|
32
|
+
return {
|
|
33
|
+
metadata: {
|
|
34
|
+
name: "console",
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
debug: console.debug.bind(console),
|
|
38
|
+
error: console.error.bind(console),
|
|
39
|
+
log: console.log.bind(console),
|
|
40
|
+
};
|
|
41
|
+
}
|