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.
Files changed (215) hide show
  1. package/README.md +40 -18
  2. package/dist/adapters/_internal/queue.d.mts +127 -0
  3. package/dist/aws-dynamodb.d.mts +22 -0
  4. package/dist/aws-dynamodb.mjs +118 -0
  5. package/dist/aws-dynamodb.mjs.map +1 -0
  6. package/dist/aws-s3.d.mts +20 -0
  7. package/dist/aws-s3.mjs +96 -0
  8. package/dist/aws-s3.mjs.map +1 -0
  9. package/dist/azure-blob-storage.d.mts +20 -0
  10. package/dist/azure-blob-storage.mjs +126 -0
  11. package/dist/azure-blob-storage.mjs.map +1 -0
  12. package/dist/azure-cosmos-db.d.mts +23 -0
  13. package/dist/azure-cosmos-db.mjs +87 -0
  14. package/dist/azure-cosmos-db.mjs.map +1 -0
  15. package/dist/azure-data-tables.d.mts +23 -0
  16. package/dist/azure-data-tables.mjs +127 -0
  17. package/dist/azure-data-tables.mjs.map +1 -0
  18. package/dist/azure-easy-auth.d.mts +50 -0
  19. package/dist/azure-easy-auth.mjs +88 -0
  20. package/dist/azure-easy-auth.mjs.map +1 -0
  21. package/dist/azure-functions.d.mts +62 -0
  22. package/dist/azure-functions.mjs +147 -0
  23. package/dist/azure-functions.mjs.map +1 -0
  24. package/dist/fs.d.mts +37 -0
  25. package/dist/fs.mjs +240 -0
  26. package/dist/fs.mjs.map +1 -0
  27. package/dist/gcp-big-table.d.mts +23 -0
  28. package/dist/gcp-big-table.mjs +92 -0
  29. package/dist/gcp-big-table.mjs.map +1 -0
  30. package/dist/gcp-firestore.d.mts +22 -0
  31. package/dist/gcp-firestore.mjs +87 -0
  32. package/dist/gcp-firestore.mjs.map +1 -0
  33. package/dist/gcp-storage.d.mts +20 -0
  34. package/dist/gcp-storage.mjs +96 -0
  35. package/dist/gcp-storage.mjs.map +1 -0
  36. package/dist/handlers/handle-process-zip.mjs +90 -0
  37. package/dist/handlers/handle-process-zip.mjs.map +1 -0
  38. package/dist/handlers/handle-purge.d.mts +12 -0
  39. package/dist/handlers/handle-purge.mjs +36 -0
  40. package/dist/handlers/handle-purge.mjs.map +1 -0
  41. package/dist/handlers/handle-serve-storybook.mjs +94 -0
  42. package/dist/handlers/handle-serve-storybook.mjs.map +1 -0
  43. package/dist/index.d.mts +28 -0
  44. package/dist/index.mjs +62 -0
  45. package/dist/index.mjs.map +1 -0
  46. package/dist/models/builds-model.mjs +248 -0
  47. package/dist/models/builds-model.mjs.map +1 -0
  48. package/dist/models/builds-schema.d.mts +171 -0
  49. package/dist/models/builds-schema.mjs +67 -0
  50. package/dist/models/builds-schema.mjs.map +1 -0
  51. package/dist/models/projects-model.mjs +122 -0
  52. package/dist/models/projects-model.mjs.map +1 -0
  53. package/dist/models/projects-schema.d.mts +70 -0
  54. package/dist/models/projects-schema.mjs +37 -0
  55. package/dist/models/projects-schema.mjs.map +1 -0
  56. package/dist/models/tags-model.mjs +110 -0
  57. package/dist/models/tags-model.mjs.map +1 -0
  58. package/dist/models/tags-schema.d.mts +76 -0
  59. package/dist/models/tags-schema.mjs +34 -0
  60. package/dist/models/tags-schema.mjs.map +1 -0
  61. package/dist/models/~model.mjs +43 -0
  62. package/dist/models/~model.mjs.map +1 -0
  63. package/dist/models/~shared-schema.d.mts +1 -0
  64. package/dist/models/~shared-schema.mjs +20 -0
  65. package/dist/models/~shared-schema.mjs.map +1 -0
  66. package/dist/mysql.d.mts +39 -0
  67. package/dist/mysql.mjs +151 -0
  68. package/dist/mysql.mjs.map +1 -0
  69. package/dist/redis.d.mts +33 -0
  70. package/dist/redis.mjs +118 -0
  71. package/dist/redis.mjs.map +1 -0
  72. package/dist/routers/account-router.mjs +91 -0
  73. package/dist/routers/account-router.mjs.map +1 -0
  74. package/dist/routers/builds-router.mjs +347 -0
  75. package/dist/routers/builds-router.mjs.map +1 -0
  76. package/dist/routers/projects-router.mjs +236 -0
  77. package/dist/routers/projects-router.mjs.map +1 -0
  78. package/dist/routers/root-router.mjs +108 -0
  79. package/dist/routers/root-router.mjs.map +1 -0
  80. package/dist/routers/tags-router.mjs +269 -0
  81. package/dist/routers/tags-router.mjs.map +1 -0
  82. package/dist/routers/tasks-router.mjs +71 -0
  83. package/dist/routers/tasks-router.mjs.map +1 -0
  84. package/dist/urls.d.mts +47 -0
  85. package/dist/urls.mjs +208 -0
  86. package/dist/urls.mjs.map +1 -0
  87. package/dist/utils/adapter-utils.d.mts +14 -0
  88. package/dist/utils/adapter-utils.mjs +14 -0
  89. package/dist/utils/adapter-utils.mjs.map +1 -0
  90. package/dist/utils/auth.mjs +25 -0
  91. package/dist/utils/auth.mjs.map +1 -0
  92. package/dist/utils/error.d.mts +21 -0
  93. package/dist/utils/error.mjs +109 -0
  94. package/dist/utils/error.mjs.map +1 -0
  95. package/dist/utils/file-utils.mjs +16 -0
  96. package/dist/utils/file-utils.mjs.map +1 -0
  97. package/dist/utils/openapi-utils.mjs +45 -0
  98. package/dist/utils/openapi-utils.mjs.map +1 -0
  99. package/dist/utils/request.mjs +35 -0
  100. package/dist/utils/request.mjs.map +1 -0
  101. package/dist/utils/response.mjs +24 -0
  102. package/dist/utils/response.mjs.map +1 -0
  103. package/dist/utils/store.mjs +54 -0
  104. package/dist/utils/store.mjs.map +1 -0
  105. package/dist/utils/ui-utils.mjs +38 -0
  106. package/dist/utils/ui-utils.mjs.map +1 -0
  107. package/dist/utils/url-utils.d.mts +10 -0
  108. package/dist/utils/url-utils.mjs +54 -0
  109. package/dist/utils/url-utils.mjs.map +1 -0
  110. package/dist/~internal/adapter/auth.d.mts +123 -0
  111. package/dist/~internal/adapter/auth.mjs +20 -0
  112. package/dist/~internal/adapter/auth.mjs.map +1 -0
  113. package/dist/~internal/adapter/database.d.mts +240 -0
  114. package/dist/~internal/adapter/database.mjs +63 -0
  115. package/dist/~internal/adapter/database.mjs.map +1 -0
  116. package/dist/~internal/adapter/logger.d.mts +34 -0
  117. package/dist/~internal/adapter/logger.mjs +13 -0
  118. package/dist/~internal/adapter/logger.mjs.map +1 -0
  119. package/dist/~internal/adapter/storage.d.mts +208 -0
  120. package/dist/~internal/adapter/storage.mjs +63 -0
  121. package/dist/~internal/adapter/storage.mjs.map +1 -0
  122. package/dist/~internal/adapter/ui.d.mts +109 -0
  123. package/dist/~internal/adapter/ui.mjs +1 -0
  124. package/dist/~internal/adapter.d.mts +8 -0
  125. package/dist/~internal/adapter.mjs +6 -0
  126. package/dist/~internal/constants.d.mts +24 -0
  127. package/dist/~internal/constants.mjs +32 -0
  128. package/dist/~internal/constants.mjs.map +1 -0
  129. package/dist/~internal/mimes.d.mts +449 -0
  130. package/dist/~internal/mimes.mjs +454 -0
  131. package/dist/~internal/mimes.mjs.map +1 -0
  132. package/dist/~internal/router.d.mts +1651 -0
  133. package/dist/~internal/router.mjs +39 -0
  134. package/dist/~internal/router.mjs.map +1 -0
  135. package/dist/~internal/types.d.mts +77 -0
  136. package/dist/~internal/types.mjs +1 -0
  137. package/dist/~internal/utils.d.mts +4 -0
  138. package/dist/~internal/utils.mjs +5 -0
  139. package/openapi.json +3162 -0
  140. package/package.json +148 -27
  141. package/src/adapters/_internal/auth.ts +135 -0
  142. package/src/adapters/_internal/database.ts +241 -0
  143. package/src/adapters/_internal/index.ts +8 -0
  144. package/src/adapters/_internal/logger.ts +41 -0
  145. package/src/adapters/_internal/queue.ts +151 -0
  146. package/src/adapters/_internal/storage.ts +197 -0
  147. package/src/adapters/_internal/ui.ts +103 -0
  148. package/src/adapters/aws-dynamodb.ts +201 -0
  149. package/src/adapters/aws-s3.ts +160 -0
  150. package/src/adapters/azure-blob-storage.ts +223 -0
  151. package/src/adapters/azure-cosmos-db.ts +158 -0
  152. package/src/adapters/azure-data-tables.ts +223 -0
  153. package/src/adapters/azure-easy-auth.ts +174 -0
  154. package/src/adapters/azure-functions.ts +242 -0
  155. package/src/adapters/fs.ts +398 -0
  156. package/src/adapters/gcp-big-table.ts +157 -0
  157. package/src/adapters/gcp-firestore.ts +146 -0
  158. package/src/adapters/gcp-storage.ts +141 -0
  159. package/src/adapters/mysql.ts +296 -0
  160. package/src/adapters/redis.ts +242 -0
  161. package/src/handlers/handle-process-zip.ts +117 -0
  162. package/src/handlers/handle-purge.ts +65 -0
  163. package/src/handlers/handle-serve-storybook.ts +101 -0
  164. package/src/index.ts +81 -16
  165. package/src/mocks/mock-auth-service.ts +51 -0
  166. package/src/mocks/mock-store.ts +26 -0
  167. package/src/models/builds-model.ts +373 -0
  168. package/src/models/builds-schema.ts +84 -0
  169. package/src/models/projects-model.ts +177 -0
  170. package/src/models/projects-schema.ts +69 -0
  171. package/src/models/tags-model.ts +138 -0
  172. package/src/models/tags-schema.ts +45 -0
  173. package/src/models/~model.ts +79 -0
  174. package/src/models/~shared-schema.ts +14 -0
  175. package/src/routers/_app-router.ts +57 -0
  176. package/src/routers/account-router.ts +136 -0
  177. package/src/routers/builds-router.ts +464 -0
  178. package/src/routers/projects-router.ts +309 -0
  179. package/src/routers/root-router.ts +127 -0
  180. package/src/routers/tags-router.ts +339 -0
  181. package/src/routers/tasks-router.ts +75 -0
  182. package/src/types.ts +107 -0
  183. package/src/urls.ts +327 -0
  184. package/src/utils/adapter-utils.ts +26 -0
  185. package/src/utils/auth.test.ts +71 -0
  186. package/src/utils/auth.ts +39 -0
  187. package/src/utils/constants.ts +31 -0
  188. package/src/utils/date-utils.ts +10 -0
  189. package/src/utils/error.test.ts +86 -0
  190. package/src/utils/error.ts +140 -0
  191. package/src/utils/file-utils.test.ts +65 -0
  192. package/src/utils/file-utils.ts +43 -0
  193. package/src/utils/index.ts +3 -0
  194. package/src/utils/mime-utils.ts +457 -0
  195. package/src/utils/openapi-utils.ts +49 -0
  196. package/src/utils/request.ts +97 -0
  197. package/src/utils/response.ts +20 -0
  198. package/src/utils/store.ts +85 -0
  199. package/src/utils/story-utils.ts +42 -0
  200. package/src/utils/text-utils.ts +10 -0
  201. package/src/utils/ui-utils.ts +57 -0
  202. package/src/utils/url-utils.ts +113 -0
  203. package/dist/index.js +0 -554
  204. package/src/commands/create.ts +0 -263
  205. package/src/commands/purge.ts +0 -70
  206. package/src/commands/test.ts +0 -42
  207. package/src/service-schema.d.ts +0 -2023
  208. package/src/utils/auth-utils.ts +0 -31
  209. package/src/utils/pkg-utils.ts +0 -37
  210. package/src/utils/sb-build.ts +0 -55
  211. package/src/utils/sb-test.ts +0 -115
  212. package/src/utils/schema-utils.ts +0 -123
  213. package/src/utils/stream-utils.ts +0 -72
  214. package/src/utils/types.ts +0 -4
  215. package/src/utils/zip.ts +0 -77
@@ -0,0 +1,140 @@
1
+ import type { ErrorHandler, MiddlewareHandler } from "hono";
2
+ import { HTTPException } from "hono/http-exception";
3
+ import type { ServerErrorStatusCode } from "hono/utils/http-status";
4
+ import { z } from "zod";
5
+ import { createConsoleLoggerAdapter, type LoggerAdapter } from "../adapters/_internal/index.ts";
6
+ import type { RouterOptions, StoryBookerUser } from "../types.ts";
7
+ import { getStoreOrNull } from "../utils/store.ts";
8
+ import { DEFAULT_LOCALE } from "./constants.ts";
9
+ import { checkIsHTMLRequest } from "./request.ts";
10
+ import { uiResultResponse } from "./ui-utils.ts";
11
+
12
+ /**
13
+ * A function type for parsing custom errors.
14
+ * Return `undefined` from parser if the service should handle the error.
15
+ */
16
+ export type ErrorParser = (error: unknown) => ParsedError | undefined;
17
+ /** Parsed error information. */
18
+ export interface ParsedError {
19
+ errorMessage: string;
20
+ errorStatus?: number;
21
+ errorType: string;
22
+ }
23
+
24
+ export function parseErrorMessage(error: unknown, errorParser?: ErrorParser): ParsedError {
25
+ if (!error) {
26
+ return { errorMessage: "", errorType: "unknown" };
27
+ }
28
+
29
+ const customErrorParser = errorParser ?? getStoreOrNull()?.errorParser;
30
+ const customErrorResult = customErrorParser?.(error);
31
+ if (customErrorResult !== undefined) {
32
+ return customErrorResult;
33
+ }
34
+
35
+ if (typeof error === "string") {
36
+ return { errorMessage: error, errorType: "string" };
37
+ }
38
+
39
+ if (error instanceof HTTPException) {
40
+ const { message, status } = unwrapHttpException(error);
41
+ return {
42
+ errorMessage: message,
43
+ errorStatus: status,
44
+ errorType: "HTTPException",
45
+ };
46
+ }
47
+
48
+ if (error instanceof z.core.$ZodError) {
49
+ return {
50
+ errorMessage: z.prettifyError(error),
51
+ errorStatus: 400,
52
+ errorType: "Zod",
53
+ };
54
+ }
55
+
56
+ if (error instanceof Error || (error && typeof error === "object" && "message" in error)) {
57
+ return { errorMessage: String(error.message), errorType: "error" };
58
+ }
59
+
60
+ return { errorMessage: String(error), errorType: "unknown" };
61
+ }
62
+
63
+ const zodValidationErrorSchema = z.object({
64
+ success: z.literal(false),
65
+ error: z.object({
66
+ name: z.literal("ZodError"),
67
+ message: z.string(),
68
+ }),
69
+ });
70
+ export function prettifyZodValidationErrorMiddleware(logger: LoggerAdapter): MiddlewareHandler {
71
+ return async (ctx, next) => {
72
+ await next();
73
+
74
+ const resContentType = ctx.res.headers.get("Content-Type") ?? "";
75
+ if (ctx.res.status === 400 && resContentType.startsWith("application/json")) {
76
+ const result = zodValidationErrorSchema.safeParse(await ctx.res.clone().json());
77
+ if (result.success) {
78
+ const issues = JSON.parse(result.data.error.message) as z.core.$ZodIssue[];
79
+ const message = `Validation error:\n${z.prettifyError({ issues })}`;
80
+ logger.error(`[Zod] ${message}`);
81
+ throw new HTTPException(400, { message, res: ctx.res });
82
+ }
83
+ }
84
+ };
85
+ }
86
+
87
+ export function onUnhandledErrorHandler<User extends StoryBookerUser>(
88
+ options: RouterOptions<User>,
89
+ ): ErrorHandler {
90
+ return (error, ctx) => {
91
+ if (error instanceof Response) {
92
+ return error;
93
+ }
94
+ const logger = options.logger ?? createConsoleLoggerAdapter();
95
+
96
+ const parsedError = parseErrorMessage(error);
97
+ const { errorMessage, errorStatus, errorType } = parsedError;
98
+ logger.error(`[${errorType}:${errorStatus}] ${errorMessage}`);
99
+
100
+ if (options?.ui?.renderErrorPage && checkIsHTMLRequest(false, ctx.req.raw)) {
101
+ const result = options.ui.renderErrorPage(parsedError, {
102
+ isAuthEnabled: Boolean(options.auth),
103
+ locale: DEFAULT_LOCALE,
104
+ logger,
105
+ url: ctx.req.url,
106
+ user: null,
107
+ adaptersMetadata: {},
108
+ });
109
+
110
+ return uiResultResponse(ctx, result, {
111
+ status: (errorStatus as ServerErrorStatusCode) ?? 500,
112
+ });
113
+ }
114
+
115
+ return new Response(errorMessage, { status: errorStatus ?? 500, statusText: errorType });
116
+ };
117
+ }
118
+
119
+ function unwrapHttpException(error: HTTPException): {
120
+ message: string;
121
+ status?: number;
122
+ } {
123
+ let causeMessage = "";
124
+ let causeStatus: number | undefined = error.status;
125
+
126
+ if (error.cause) {
127
+ if (error.cause instanceof HTTPException) {
128
+ const { message, status } = unwrapHttpException(error.cause);
129
+ causeMessage = message;
130
+ causeStatus = status;
131
+ } else {
132
+ const { errorMessage } = parseErrorMessage(error.cause);
133
+ causeMessage = errorMessage;
134
+ }
135
+ }
136
+
137
+ const errorStatus = causeStatus ?? error.status;
138
+ const errorMessage = causeMessage ? `${error.message}\n ↳ ${causeMessage}` : error.message;
139
+ return { message: errorMessage, status: errorStatus };
140
+ }
@@ -0,0 +1,65 @@
1
+ import * as fs from "node:fs";
2
+ import * as os from "node:os";
3
+ import * as path from "node:path";
4
+ import { Readable } from "node:stream";
5
+ import { describe, expect, it } from "vitest";
6
+ import { writeStreamToFile, writeWebStreamToFile } from "./file-utils.ts";
7
+
8
+ describe("writeStreamToFile", () => {
9
+ it("should work with node-readable", async () => {
10
+ const dirpath = fs.mkdtempSync(path.join(os.tmpdir(), "file-utils-test"));
11
+ const filepath = path.join(dirpath, "output.txt");
12
+
13
+ const data = ["hello", "world"];
14
+ const readable = Readable.from(data);
15
+ await writeStreamToFile(filepath, readable);
16
+
17
+ const fileContent = fs.readFileSync(filepath, "utf8");
18
+ expect(fileContent).toBe(data.join(""));
19
+ fs.rmSync(dirpath, { recursive: true, force: true });
20
+ });
21
+
22
+ it("should work with web-readable", async () => {
23
+ const dirpath = fs.mkdtempSync(path.join(os.tmpdir(), "file-utils-test"));
24
+ const filepath = path.join(dirpath, "output.txt");
25
+
26
+ const data = ["hello", "world"];
27
+
28
+ const readable = readableStreamFromArray(data);
29
+ await writeStreamToFile(filepath, readable);
30
+
31
+ const fileContent = fs.readFileSync(filepath, "utf8");
32
+ expect(fileContent).toBe(data.join(""));
33
+ fs.rmSync(dirpath, { recursive: true, force: true });
34
+ });
35
+ });
36
+
37
+ describe("writeWebStreamToFile", () => {
38
+ it("should work", async () => {
39
+ const dirpath = fs.mkdtempSync(path.join(os.tmpdir(), "file-utils-test"));
40
+ const filepath = path.join(dirpath, "output.txt");
41
+
42
+ const data = ["hello", "world"];
43
+
44
+ const readable = readableStreamFromArray(data);
45
+ await writeWebStreamToFile(readable, filepath);
46
+
47
+ const fileContent = fs.readFileSync(filepath, "utf8");
48
+ expect(fileContent).toBe(data.join(""));
49
+ fs.rmSync(dirpath, { recursive: true, force: true });
50
+ });
51
+ });
52
+
53
+ function readableStreamFromArray<Type>(arr: Type[]): ReadableStream<Type> {
54
+ let index = 0;
55
+ return new ReadableStream({
56
+ pull(controller) {
57
+ if (index < arr.length) {
58
+ controller.enqueue(arr[index]);
59
+ index += 1;
60
+ } else {
61
+ controller.close();
62
+ }
63
+ },
64
+ });
65
+ }
@@ -0,0 +1,43 @@
1
+ import { once } from "node:events";
2
+ import { createWriteStream } from "node:fs";
3
+ import { Readable } from "node:stream";
4
+ import type { ReadableStream as WebReadableStream } from "node:stream/web";
5
+
6
+ export async function writeStreamToFile(
7
+ filePath: string,
8
+ stream: Readable | ReadableStream,
9
+ ): Promise<void> {
10
+ const writable = createWriteStream(filePath);
11
+ const readable =
12
+ stream instanceof Readable ? stream : Readable.fromWeb(stream as WebReadableStream);
13
+ for await (const chunk of readable) {
14
+ if (!writable.write(chunk)) {
15
+ // Wait if backpressure is applied
16
+ await once(writable, "drain");
17
+ }
18
+ }
19
+ writable.end();
20
+ await once(writable, "finish");
21
+ }
22
+
23
+ export function writeWebStreamToFile(
24
+ webReadableStream: ReadableStream,
25
+ outputPath: string,
26
+ ): Promise<null> {
27
+ // Convert WebReadableStream to Node.js Readable stream
28
+ const nodeReadableStream = Readable.fromWeb(webReadableStream as WebReadableStream);
29
+
30
+ // Create a writable file stream
31
+ const fileWritableStream = createWriteStream(outputPath);
32
+
33
+ // Pipe the Node.js readable stream to the writable file stream
34
+ nodeReadableStream.pipe(fileWritableStream);
35
+
36
+ // Return a promise that resolves when writing is finished
37
+ return new Promise((resolve, reject) => {
38
+ fileWritableStream.on("finish", () => {
39
+ resolve(null);
40
+ });
41
+ fileWritableStream.on("error", reject);
42
+ });
43
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./constants.ts";
2
+ export { parseErrorMessage, type ErrorParser, type ParsedError } from "./error.ts";
3
+ export { generatePrefixFromBaseRoute, urlJoin } from "./url-utils.ts";