@prosewire/sdk 0.2.0 → 0.4.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["uuid","uuid","pageNumber","pageSize"],"sources":["../../contract/src/schemas.ts","../../contract/src/router.ts","../../contract/src/transport.ts","../src/index.ts"],"sourcesContent":["import { Effect, Schema } from \"effect\";\n\nconst withDefault = <S extends Schema.Constraint>(\n schema: S,\n value: S[\"Encoded\"],\n) => Schema.withDecodingDefaultKey(Effect.succeed(value))(schema);\n\nconst uuid = Schema.String.check(Schema.isUUID());\nconst isoDateTime = Schema.String.check(\n Schema.isPattern(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$/),\n);\nconst url = Schema.String.check(\n Schema.isPattern(/^[a-z][a-z\\d+.-]*:\\/\\/\\S+$/i),\n);\nconst nullable = <S extends Schema.Top>(schema: S) => Schema.NullOr(schema);\n\nexport const postStatus = Schema.Literals([\n \"draft\",\n \"scheduled\",\n \"published\",\n \"archived\",\n]);\n\nexport const authorOutput = Schema.Struct({\n id: uuid,\n name: Schema.String,\n slug: Schema.String,\n bio: nullable(Schema.String),\n avatarUrl: nullable(Schema.String),\n jobTitle: nullable(Schema.String),\n credentials: nullable(Schema.String),\n});\n\nexport const categoryOutput = Schema.Struct({\n id: uuid,\n name: Schema.String,\n slug: Schema.String,\n description: nullable(Schema.String),\n});\n\nexport const postOutput = Schema.Struct({\n id: uuid,\n blogId: uuid,\n title: Schema.String,\n slug: Schema.String,\n excerpt: Schema.String,\n contentMarkdown: Schema.String,\n contentHtml: Schema.String,\n coverImageUrl: nullable(Schema.String),\n coverImageAlt: nullable(Schema.String),\n status: postStatus,\n locale: Schema.String,\n featured: Schema.Boolean,\n seoTitle: nullable(Schema.String),\n seoDescription: nullable(Schema.String),\n focusKeyword: nullable(Schema.String),\n canonicalUrl: nullable(Schema.String),\n publishedAt: nullable(isoDateTime),\n scheduledAt: nullable(isoDateTime),\n createdAt: isoDateTime,\n updatedAt: isoDateTime,\n author: authorOutput,\n categories: Schema.Array(categoryOutput),\n});\n\nconst authorId = uuid;\nconst title = Schema.Trim.pipe(\n Schema.check(Schema.isMinLength(1), Schema.isMaxLength(180)),\n);\nconst slug = Schema.Trim.pipe(\n Schema.check(\n Schema.isMinLength(1),\n Schema.isMaxLength(120),\n Schema.isPattern(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),\n ),\n);\nconst excerpt = Schema.String.check(Schema.isMaxLength(500));\nconst contentMarkdown = Schema.String;\nconst coverImageUrl = nullable(url);\nconst coverImageAlt = nullable(\n Schema.String.check(Schema.isMaxLength(180)),\n);\nconst locale = Schema.String.check(\n Schema.isMinLength(2),\n Schema.isMaxLength(10),\n);\nconst featured = Schema.Boolean;\nconst seoTitle = nullable(Schema.String.check(Schema.isMaxLength(70)));\nconst seoDescription = nullable(\n Schema.String.check(Schema.isMaxLength(180)),\n);\nconst focusKeyword = nullable(\n Schema.String.check(Schema.isMaxLength(120)),\n);\nconst canonicalUrl = nullable(url);\nconst scheduledAt = nullable(isoDateTime);\nconst categoryIds = Schema.Array(uuid);\n\nexport const postCreateInput = Schema.Struct({\n blogId: uuid,\n authorId,\n title,\n slug,\n excerpt: Schema.optionalKey(excerpt),\n contentMarkdown: withDefault(contentMarkdown, \"\"),\n coverImageUrl: Schema.optionalKey(coverImageUrl),\n coverImageAlt: Schema.optionalKey(coverImageAlt),\n status: withDefault(postStatus, \"draft\"),\n locale: withDefault(locale, \"en\"),\n featured: withDefault(featured, false),\n seoTitle: Schema.optionalKey(seoTitle),\n seoDescription: Schema.optionalKey(seoDescription),\n focusKeyword: Schema.optionalKey(focusKeyword),\n canonicalUrl: Schema.optionalKey(canonicalUrl),\n scheduledAt: Schema.optionalKey(scheduledAt),\n categoryIds: withDefault(categoryIds, []),\n});\n\nexport const postUpdateInput = Schema.Struct({\n authorId: Schema.optionalKey(authorId),\n title: Schema.optionalKey(title),\n slug: Schema.optionalKey(slug),\n excerpt: Schema.optionalKey(excerpt),\n contentMarkdown: Schema.optionalKey(contentMarkdown),\n coverImageUrl: Schema.optionalKey(coverImageUrl),\n coverImageAlt: Schema.optionalKey(coverImageAlt),\n status: Schema.optionalKey(postStatus),\n locale: Schema.optionalKey(locale),\n featured: Schema.optionalKey(featured),\n seoTitle: Schema.optionalKey(seoTitle),\n seoDescription: Schema.optionalKey(seoDescription),\n focusKeyword: Schema.optionalKey(focusKeyword),\n canonicalUrl: Schema.optionalKey(canonicalUrl),\n scheduledAt: Schema.optionalKey(scheduledAt),\n categoryIds: Schema.optionalKey(categoryIds),\n});\n\nexport const blogOutput = Schema.Struct({\n id: uuid,\n name: Schema.String,\n slug: Schema.String,\n description: Schema.String,\n locale: Schema.String,\n accentColor: Schema.String,\n customCss: Schema.String,\n publicUrl: nullable(Schema.String),\n createdAt: isoDateTime,\n updatedAt: isoDateTime,\n});\n\nexport const publicBlogOutput = Schema.Struct({\n id: uuid,\n name: Schema.String,\n slug: Schema.String,\n description: Schema.String,\n locale: Schema.String,\n accentColor: Schema.String,\n publicUrl: nullable(Schema.String),\n createdAt: isoDateTime,\n updatedAt: isoDateTime,\n});\n\nexport const publicPostOutput = Schema.Struct({\n id: uuid,\n slug: Schema.String,\n title: Schema.String,\n excerpt: Schema.String,\n contentMarkdown: Schema.String,\n contentHtml: Schema.String,\n coverImageUrl: nullable(Schema.String),\n coverImageAlt: nullable(Schema.String),\n status: postStatus,\n locale: Schema.String,\n featured: Schema.Boolean,\n publishedAt: nullable(isoDateTime),\n updatedAt: isoDateTime,\n readingMinutes: Schema.Number,\n seoTitle: nullable(Schema.String),\n seoDescription: nullable(Schema.String),\n canonicalUrl: nullable(Schema.String),\n author: authorOutput,\n categories: Schema.Array(categoryOutput),\n});\n\nexport const publicPostPage = Schema.Struct({\n blog: publicBlogOutput,\n posts: Schema.Array(publicPostOutput),\n categories: Schema.Array(categoryOutput),\n pagination: Schema.Struct({\n page: Schema.Int,\n pageSize: Schema.Int,\n hasMore: Schema.Boolean,\n }),\n});\n\nexport const publicPostResult = Schema.Struct({\n blog: publicBlogOutput,\n post: publicPostOutput,\n});\n\nexport const paginatedPosts = Schema.Struct({\n items: Schema.Array(postOutput),\n total: Schema.Int,\n page: Schema.Int,\n pageSize: Schema.Int,\n});\n\nexport type PostStatus = typeof postStatus.Type;\nexport type Post = typeof postOutput.Type;\nexport type Blog = typeof blogOutput.Type;\nexport type PublicBlog = typeof publicBlogOutput.Type;\nexport type PublicAuthor = typeof authorOutput.Type;\nexport type PublicCategory = typeof categoryOutput.Type;\nexport type PublicPost = typeof publicPostOutput.Type;\nexport type PublicPostPage = typeof publicPostPage.Type;\nexport type PublicPostResult = typeof publicPostResult.Type;\nexport type PostCreateInput = typeof postCreateInput.Type;\nexport type PostCreateEncodedInput = typeof postCreateInput.Encoded;\nexport type PostUpdateInput = typeof postUpdateInput.Type;\nexport type PostUpdateEncodedInput = typeof postUpdateInput.Encoded;\nexport type PaginatedPosts = typeof paginatedPosts.Type;\n","import { Schema } from \"effect\";\nimport {\n HttpApi,\n HttpApiEndpoint,\n HttpApiGroup,\n HttpApiSchema,\n OpenApi,\n} from \"effect/unstable/httpapi\";\nimport {\n blogOutput,\n paginatedPosts,\n postCreateInput,\n postOutput,\n postStatus,\n postUpdateInput,\n} from \"./schemas.ts\";\n\nexport class ApiInputRejected extends Schema.TaggedError<ApiInputRejected>()(\n \"ApiInputRejected\",\n { message: Schema.String },\n { httpApiStatus: 400 },\n) {}\n\nexport class ApiAuthenticationFailed extends Schema.TaggedError<ApiAuthenticationFailed>()(\n \"ApiAuthenticationFailed\",\n { message: Schema.String },\n { httpApiStatus: 401 },\n) {}\n\nexport class ApiAccessDenied extends Schema.TaggedError<ApiAccessDenied>()(\n \"ApiAccessDenied\",\n { message: Schema.String },\n { httpApiStatus: 403 },\n) {}\n\nexport class ApiPostNotFound extends Schema.TaggedError<ApiPostNotFound>()(\n \"ApiPostNotFound\",\n { message: Schema.String },\n { httpApiStatus: 404 },\n) {}\n\nexport class ApiUnavailable extends Schema.TaggedError<ApiUnavailable>()(\n \"ApiUnavailable\",\n { message: Schema.String },\n { httpApiStatus: 500 },\n) {}\n\nexport const apiErrors = [\n ApiInputRejected,\n ApiAuthenticationFailed,\n ApiAccessDenied,\n ApiPostNotFound,\n ApiUnavailable,\n] as const;\n\nconst uuid = Schema.String.check(Schema.isUUID());\nconst pageNumber = Schema.NumberFromString.pipe(\n Schema.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(1)),\n);\nconst pageSize = Schema.NumberFromString.pipe(\n Schema.check(\n Schema.isInt(),\n Schema.isGreaterThanOrEqualTo(1),\n Schema.isLessThanOrEqualTo(100),\n ),\n);\n\nconst health = HttpApiGroup.make(\"health\").add(\n HttpApiEndpoint.get(\"check\", \"/health\", {\n success: Schema.Struct({\n status: Schema.Literal(\"ok\"),\n version: Schema.String,\n }),\n error: ApiUnavailable,\n }).annotate(OpenApi.Summary, \"Database readiness probe\"),\n);\n\nconst blogs = HttpApiGroup.make(\"blogs\").add(\n HttpApiEndpoint.get(\"list\", \"/blogs\", {\n success: Schema.Array(blogOutput),\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"List blogs\"),\n);\n\nconst posts = HttpApiGroup.make(\"posts\")\n .add(\n HttpApiEndpoint.get(\"list\", \"/posts\", {\n query: {\n blog: Schema.optionalKey(Schema.String),\n search: Schema.optionalKey(Schema.String),\n status: Schema.optionalKey(postStatus),\n page: Schema.optionalKey(pageNumber),\n pageSize: Schema.optionalKey(pageSize),\n },\n success: paginatedPosts,\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"List posts\"),\n )\n .add(\n HttpApiEndpoint.get(\"get\", \"/posts/:id\", {\n params: { id: uuid },\n success: postOutput,\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"Get a post\"),\n )\n .add(\n HttpApiEndpoint.post(\"create\", \"/posts\", {\n payload: postCreateInput,\n success: postOutput.pipe(HttpApiSchema.status(200)),\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"Create a post\"),\n )\n .add(\n HttpApiEndpoint.patch(\"update\", \"/posts/:id\", {\n params: { id: uuid },\n payload: postUpdateInput,\n success: postOutput,\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"Update a post\"),\n )\n .add(\n HttpApiEndpoint.delete(\"archive\", \"/posts/:id\", {\n params: { id: uuid },\n success: Schema.Struct({ ok: Schema.Literal(true) }),\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"Archive a post\"),\n );\n\nexport const api = HttpApi.make(\"ProsewireApi\")\n .add(health, blogs, posts)\n .prefix(\"/api/v1\")\n .annotate(OpenApi.Title, \"Prosewire private API\")\n .annotate(OpenApi.Version, \"1.0.0\");\n\n/** @deprecated Use `api`. Kept as a source-compatible migration alias. */\nexport const contract = api;\nexport type Contract = typeof api;\n","import { Schema } from \"effect\";\nimport {\n ApiInputRejected,\n ApiPostNotFound,\n} from \"./router.ts\";\nimport {\n postCreateInput,\n postStatus,\n postUpdateInput,\n type PostCreateInput,\n type PostStatus,\n type PostUpdateInput,\n} from \"./schemas.ts\";\n\nconst uuid = Schema.String.check(Schema.isUUID());\nconst pageNumber = Schema.NumberFromString.pipe(\n Schema.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(1)),\n);\nconst pageSize = Schema.NumberFromString.pipe(\n Schema.check(\n Schema.isInt(),\n Schema.isGreaterThanOrEqualTo(1),\n Schema.isLessThanOrEqualTo(100),\n ),\n);\n\nexport interface PostListRequest {\n readonly blog?: string | undefined;\n readonly search?: string | undefined;\n readonly status?: PostStatus | undefined;\n readonly page: number;\n readonly pageSize: number;\n}\n\nexport type PrivateApiRequest =\n | { readonly _tag: \"Health\" }\n | { readonly _tag: \"ListBlogs\" }\n | { readonly _tag: \"ListPosts\"; readonly input: PostListRequest }\n | { readonly _tag: \"GetPost\"; readonly id: string }\n | { readonly _tag: \"CreatePost\"; readonly input: PostCreateInput }\n | {\n readonly _tag: \"UpdatePost\";\n readonly id: string;\n readonly input: PostUpdateInput;\n }\n | { readonly _tag: \"ArchivePost\"; readonly id: string };\n\nasync function decode<S extends Schema.ConstraintDecoder<unknown>>(\n schema: S,\n value: unknown,\n message: string,\n): Promise<S[\"Type\"]> {\n try {\n return await Schema.decodeUnknownPromise(schema)(value);\n } catch {\n throw new ApiInputRejected({ message });\n }\n}\n\nasync function json(request: Request): Promise<unknown> {\n try {\n return await request.json();\n } catch {\n throw new ApiInputRejected({ message: \"Invalid JSON request body\" });\n }\n}\n\nasync function identifier(pathname: string): Promise<string | undefined> {\n const match = /^\\/api\\/v1\\/posts\\/([^/]+)$/.exec(pathname);\n if (!match?.[1]) return undefined;\n let value: string;\n try {\n value = decodeURIComponent(match[1]);\n } catch {\n throw new ApiInputRejected({ message: \"Invalid post id\" });\n }\n return decode(uuid, value, \"Invalid post id\");\n}\n\nexport async function decodePrivateApiRequest(\n request: Request,\n): Promise<PrivateApiRequest> {\n const { pathname, searchParams } = new URL(request.url);\n if (request.method === \"GET\" && pathname === \"/api/v1/health\") {\n return { _tag: \"Health\" };\n }\n if (request.method === \"GET\" && pathname === \"/api/v1/blogs\") {\n return { _tag: \"ListBlogs\" };\n }\n if (request.method === \"GET\" && pathname === \"/api/v1/posts\") {\n const statusValue = searchParams.get(\"status\");\n return {\n _tag: \"ListPosts\",\n input: {\n ...(searchParams.has(\"blog\")\n ? { blog: searchParams.get(\"blog\") ?? undefined }\n : {}),\n ...(searchParams.has(\"search\")\n ? { search: searchParams.get(\"search\") ?? undefined }\n : {}),\n ...(statusValue === null\n ? {}\n : {\n status: await decode(\n postStatus,\n statusValue,\n \"Invalid post status\",\n ),\n }),\n page: searchParams.has(\"page\")\n ? await decode(\n pageNumber,\n searchParams.get(\"page\"),\n \"Invalid pagination parameters\",\n )\n : 1,\n pageSize: searchParams.has(\"pageSize\")\n ? await decode(\n pageSize,\n searchParams.get(\"pageSize\"),\n \"Invalid pagination parameters\",\n )\n : 20,\n },\n };\n }\n\n const id = await identifier(pathname);\n if (id && request.method === \"GET\") return { _tag: \"GetPost\", id };\n if (pathname === \"/api/v1/posts\" && request.method === \"POST\") {\n return {\n _tag: \"CreatePost\",\n input: await decode(\n postCreateInput,\n await json(request),\n \"Invalid post input\",\n ),\n };\n }\n if (id && request.method === \"PATCH\") {\n return {\n _tag: \"UpdatePost\",\n id,\n input: await decode(\n postUpdateInput,\n await json(request),\n \"Invalid post update\",\n ),\n };\n }\n if (id && request.method === \"DELETE\") return { _tag: \"ArchivePost\", id };\n throw new ApiPostNotFound({ message: \"API route not found\" });\n}\n\nexport * as PrivateApiTransport from \"./transport.ts\";\n","import {\n api,\n type PostCreateEncodedInput,\n type PostCreateInput,\n type PostStatus,\n type PostUpdateInput,\n type PublicBlog,\n type PublicAuthor,\n type PublicCategory,\n type PublicPost,\n type PublicPostPage,\n type PublicPostResult,\n publicPostPage,\n publicPostResult,\n} from \"@prosewire/contract\";\nimport { Effect, Schema } from \"effect\";\nimport {\n FetchHttpClient,\n HttpClient,\n HttpClientRequest,\n} from \"effect/unstable/http\";\nimport { HttpApiClient } from \"effect/unstable/httpapi\";\n\nexport interface ProsewireClientOptions {\n /** Base URL of a Prosewire deployment, e.g. https://blog.example.com. */\n baseUrl: string;\n /** Private API key. Public rendered/raw endpoints do not need one. */\n apiKey?: string;\n fetch?: typeof fetch;\n}\n\nexport interface PrivatePostListInput {\n readonly blog?: string;\n readonly search?: string;\n readonly status?: PostStatus;\n readonly page?: number;\n readonly pageSize?: number;\n}\n\nfunction normalizedCreateInput(input: PostCreateEncodedInput): PostCreateInput {\n return {\n ...input,\n contentMarkdown: input.contentMarkdown ?? \"\",\n status: input.status ?? \"draft\",\n locale: input.locale ?? \"en\",\n featured: input.featured ?? false,\n categoryIds: input.categoryIds ?? [],\n };\n}\n\nexport function createEffectClient(options: ProsewireClientOptions) {\n const baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n const generated = Effect.runSync(\n HttpApiClient.make(api, {\n baseUrl,\n transformClient: options.apiKey\n ? HttpClient.mapRequest(\n HttpClientRequest.bearerToken(options.apiKey),\n )\n : undefined,\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n );\n const provideFetch = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n effect.pipe(\n Effect.provideService(\n FetchHttpClient.Fetch,\n options.fetch ?? globalThis.fetch,\n ),\n );\n\n return {\n health: () => provideFetch(generated.health.check()),\n blogs: {\n list: () => provideFetch(generated.blogs.list()),\n },\n posts: {\n list: (input: PrivatePostListInput = {}) =>\n provideFetch(generated.posts.list({ query: input })),\n get: (input: { readonly params: { readonly id: string } }) =>\n provideFetch(generated.posts.get(input)),\n create: (input: PostCreateEncodedInput) =>\n provideFetch(\n generated.posts.create({ payload: normalizedCreateInput(input) }),\n ),\n update: (input: {\n readonly params: { readonly id: string };\n readonly body: PostUpdateInput;\n }) =>\n provideFetch(\n generated.posts.update({\n params: input.params,\n payload: input.body,\n }),\n ),\n archive: (input: { readonly params: { readonly id: string } }) =>\n provideFetch(generated.posts.archive(input)),\n },\n };\n}\n\nexport type EffectClient = ReturnType<typeof createEffectClient>;\n\nexport function createClient(options: ProsewireClientOptions) {\n const client = createEffectClient(options);\n return {\n health: () => Effect.runPromise(client.health()),\n blogs: {\n list: () => Effect.runPromise(client.blogs.list()),\n },\n posts: {\n list: (input: PrivatePostListInput = {}) =>\n Effect.runPromise(client.posts.list(input)),\n get: (input: { readonly params: { readonly id: string } }) =>\n Effect.runPromise(client.posts.get(input)),\n create: (input: PostCreateEncodedInput) =>\n Effect.runPromise(client.posts.create(input)),\n update: (input: {\n readonly params: { readonly id: string };\n readonly body: PostUpdateInput;\n }) => Effect.runPromise(client.posts.update(input)),\n archive: (input: { readonly params: { readonly id: string } }) =>\n Effect.runPromise(client.posts.archive(input)),\n },\n };\n}\n\nexport type Client = ReturnType<typeof createClient>;\n\nexport type {\n PublicAuthor,\n PublicBlog,\n PublicCategory,\n PublicPost,\n PublicPostPage,\n PublicPostResult,\n};\n\nexport interface PublicListInput {\n search?: string;\n category?: string;\n page?: number;\n pageSize?: number;\n /** @deprecated Use pageSize. */\n limit?: number;\n}\n\nexport interface PublicContentClient {\n listPosts(input?: PublicListInput): Promise<PublicPostPage>;\n getPost(slug: string): Promise<PublicPostResult>;\n getRendered(path?: string): Promise<string>;\n}\n\nasync function decodeResponse<S extends Schema.ConstraintDecoder<unknown>>(\n schema: S,\n response: Response,\n): Promise<S[\"Type\"]> {\n return Schema.decodeUnknownPromise(schema)(await response.json());\n}\n\nexport function createPublicClient(\n options: Pick<ProsewireClientOptions, \"baseUrl\" | \"fetch\"> & { blog: string },\n): PublicContentClient {\n const request = options.fetch ?? fetch;\n const base = options.baseUrl.replace(/\\/$/, \"\");\n const blog = encodeURIComponent(options.blog);\n return {\n async listPosts(input = {}) {\n const query = new URLSearchParams();\n if (input.search) query.set(\"search\", input.search);\n if (input.category) query.set(\"category\", input.category);\n if (input.page) query.set(\"page\", String(input.page));\n if (input.pageSize) query.set(\"pageSize\", String(input.pageSize));\n if (input.limit) query.set(\"limit\", String(input.limit));\n const suffix = query.size ? `?${query.toString()}` : \"\";\n const response = await request(`${base}/api/public/${blog}/posts${suffix}`);\n if (!response.ok) throw new Error(`Prosewire request failed (${String(response.status)})`);\n return decodeResponse(publicPostPage, response);\n },\n async getPost(slug) {\n const response = await request(`${base}/api/public/${blog}/posts/${encodeURIComponent(slug)}`);\n if (!response.ok) throw new Error(`Prosewire request failed (${String(response.status)})`);\n return decodeResponse(publicPostResult, response);\n },\n async getRendered(path = \"\") {\n const encodedPath = path.replace(/^\\//, \"\").split(\"/\").filter(Boolean).map(encodeURIComponent).join(\"/\");\n const response = await request(`${base}/api/rendered/${blog}/${encodedPath}`);\n if (!response.ok) throw new Error(`Prosewire request failed (${String(response.status)})`);\n return response.text();\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../contract/src/import.ts","../../contract/src/schemas.ts","../../contract/src/router.ts","../../contract/src/transport.ts","../src/index.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\n/** Imports use a streaming body rather than the buffered JSON HttpApi adapter. */\nexport const portableImportPath = \"/api/v1/import\";\nexport const portableImportReport = Schema.Struct({\n mode: Schema.Literals([\"preview\", \"apply\"]),\n fingerprint: Schema.String,\n preserveStates: Schema.Boolean,\n counts: Schema.Record(Schema.String, Schema.Int),\n alreadyImported: Schema.Boolean,\n});\nexport type PortableImportReport = typeof portableImportReport.Type;\n\nexport class ApiImportRejected extends Schema.TaggedError<ApiImportRejected>()(\n \"ApiImportRejected\",\n { item: Schema.String, message: Schema.String },\n { httpApiStatus: 400 },\n) {}\nexport class ApiImportConflict extends Schema.TaggedError<ApiImportConflict>()(\n \"ApiImportConflict\",\n { item: Schema.String, message: Schema.String },\n { httpApiStatus: 409 },\n) {}\n","import { Effect, Schema } from \"effect\";\n\nconst withDefault = <S extends Schema.Constraint>(\n schema: S,\n value: S[\"Encoded\"],\n) => Schema.withDecodingDefaultKey(Effect.succeed(value))(schema);\n\nconst uuid = Schema.String.check(Schema.isUUID());\nexport const isoDateTime = Schema.String.check(\n Schema.isPattern(\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-](?:[01]\\d|2[0-3]):[0-5]\\d)$/,\n ),\n Schema.makeFilter(\n (value) => {\n const [year, month, day, hour, minute, second] = value\n .slice(0, 19)\n .split(/[-T:]/)\n .map(Number);\n if (\n year === undefined ||\n month === undefined ||\n day === undefined ||\n hour === undefined ||\n minute === undefined ||\n second === undefined\n )\n return false;\n const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);\n const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n return (\n month >= 1 &&\n month <= 12 &&\n day >= 1 &&\n day <= (days[month - 1] ?? 0) &&\n hour < 24 &&\n minute < 60 &&\n second < 60\n );\n },\n { expected: \"a valid ISO calendar date and time\" },\n ),\n);\nconst url = Schema.String.check(\n Schema.isPattern(/^[a-z][a-z\\d+.-]*:\\/\\/\\S+$/i),\n);\nconst nullable = <S extends Schema.Top>(schema: S) => Schema.NullOr(schema);\n\nexport const postStatus = Schema.Literals([\n \"draft\",\n \"scheduled\",\n \"published\",\n \"archived\",\n]);\n\nexport const authorOutput = Schema.Struct({\n id: uuid,\n name: Schema.String,\n slug: Schema.String,\n bio: nullable(Schema.String),\n avatarUrl: nullable(Schema.String),\n jobTitle: nullable(Schema.String),\n credentials: nullable(Schema.String),\n});\n\nexport const categoryOutput = Schema.Struct({\n id: uuid,\n name: Schema.String,\n slug: Schema.String,\n description: nullable(Schema.String),\n});\n\nexport const postOutput = Schema.Struct({\n id: uuid,\n blogId: uuid,\n title: Schema.String,\n slug: Schema.String,\n excerpt: Schema.String,\n contentMarkdown: Schema.String,\n contentHtml: Schema.String,\n coverImageAssetId: nullable(uuid),\n coverImageUrl: nullable(Schema.String),\n coverImageAlt: nullable(Schema.String),\n status: postStatus,\n locale: Schema.String,\n featured: Schema.Boolean,\n seoTitle: nullable(Schema.String),\n seoDescription: nullable(Schema.String),\n focusKeyword: nullable(Schema.String),\n canonicalUrl: nullable(Schema.String),\n publishedAt: nullable(isoDateTime),\n scheduledAt: nullable(isoDateTime),\n createdAt: isoDateTime,\n updatedAt: isoDateTime,\n author: authorOutput,\n categories: Schema.Array(categoryOutput),\n});\n\nexport const postRevisionSnapshot = Schema.Struct({\n authorId: uuid,\n title: Schema.String,\n slug: Schema.String,\n excerpt: Schema.String,\n contentMarkdown: Schema.String,\n coverImageAssetId: Schema.optionalKey(nullable(uuid)),\n coverImageUrl: nullable(Schema.String),\n coverImageAlt: nullable(Schema.String),\n status: postStatus,\n locale: Schema.String,\n featured: Schema.Boolean,\n seoTitle: nullable(Schema.String),\n seoDescription: nullable(Schema.String),\n focusKeyword: nullable(Schema.String),\n canonicalUrl: nullable(Schema.String),\n scheduledAt: nullable(isoDateTime),\n publishedAt: nullable(isoDateTime),\n archivedAt: nullable(isoDateTime),\n categoryIds: nullable(Schema.Array(uuid)),\n});\n\nexport const postRevisionOutput = Schema.Struct({\n id: uuid,\n postId: uuid,\n editorId: nullable(Schema.String),\n version: Schema.Int,\n snapshot: postRevisionSnapshot,\n createdAt: isoDateTime,\n});\n\nconst authorId = uuid;\nconst title = Schema.Trim.pipe(\n Schema.check(Schema.isMinLength(1), Schema.isMaxLength(180)),\n);\nconst slug = Schema.Trim.pipe(\n Schema.check(\n Schema.isMinLength(1),\n Schema.isMaxLength(120),\n Schema.isPattern(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),\n ),\n);\nconst excerpt = Schema.String.check(Schema.isMaxLength(500));\nconst contentMarkdown = Schema.String;\nconst coverImageAssetId = nullable(uuid);\nconst coverImageUrl = nullable(url);\nconst coverImageAlt = nullable(Schema.String.check(Schema.isMaxLength(180)));\nconst locale = Schema.String.check(\n Schema.isMinLength(2),\n Schema.isMaxLength(10),\n);\nconst featured = Schema.Boolean;\nconst seoTitle = nullable(Schema.String.check(Schema.isMaxLength(70)));\nconst seoDescription = nullable(Schema.String.check(Schema.isMaxLength(180)));\nconst focusKeyword = nullable(Schema.String.check(Schema.isMaxLength(120)));\nconst canonicalUrl = nullable(url);\nconst scheduledAt = nullable(isoDateTime);\nconst categoryIds = Schema.Array(uuid);\n\n// Shared by transports and application commands. Dates remain transport-specific.\nexport const postMutationFields = {\n title,\n slug,\n excerpt,\n contentMarkdown,\n coverImageUrl,\n coverImageAlt,\n locale,\n featured,\n seoTitle,\n seoDescription,\n focusKeyword,\n canonicalUrl,\n};\n\nexport const postCreateInput = Schema.Struct({\n blogId: uuid,\n authorId,\n title,\n slug,\n excerpt: Schema.optionalKey(excerpt),\n contentMarkdown: withDefault(contentMarkdown, \"\"),\n coverImageAssetId: Schema.optionalKey(coverImageAssetId),\n coverImageUrl: Schema.optionalKey(coverImageUrl),\n coverImageAlt: Schema.optionalKey(coverImageAlt),\n status: withDefault(postStatus, \"draft\"),\n locale: Schema.optionalKey(locale),\n featured: withDefault(featured, false),\n seoTitle: Schema.optionalKey(seoTitle),\n seoDescription: Schema.optionalKey(seoDescription),\n focusKeyword: Schema.optionalKey(focusKeyword),\n canonicalUrl: Schema.optionalKey(canonicalUrl),\n scheduledAt: Schema.optionalKey(scheduledAt),\n categoryIds: withDefault(categoryIds, []),\n});\n\nexport const postUpdateInput = Schema.Struct({\n authorId: Schema.optionalKey(authorId),\n title: Schema.optionalKey(title),\n slug: Schema.optionalKey(slug),\n excerpt: Schema.optionalKey(excerpt),\n contentMarkdown: Schema.optionalKey(contentMarkdown),\n coverImageAssetId: Schema.optionalKey(coverImageAssetId),\n coverImageUrl: Schema.optionalKey(coverImageUrl),\n coverImageAlt: Schema.optionalKey(coverImageAlt),\n status: Schema.optionalKey(postStatus),\n locale: Schema.optionalKey(locale),\n featured: Schema.optionalKey(featured),\n seoTitle: Schema.optionalKey(seoTitle),\n seoDescription: Schema.optionalKey(seoDescription),\n focusKeyword: Schema.optionalKey(focusKeyword),\n canonicalUrl: Schema.optionalKey(canonicalUrl),\n scheduledAt: Schema.optionalKey(scheduledAt),\n categoryIds: Schema.optionalKey(categoryIds),\n});\n\nexport const blogOutput = Schema.Struct({\n id: uuid,\n name: Schema.String,\n slug: Schema.String,\n description: Schema.String,\n locale: Schema.String,\n locales: Schema.Array(Schema.String),\n accentColor: Schema.String,\n customCss: Schema.String,\n publicUrl: nullable(Schema.String),\n createdAt: isoDateTime,\n updatedAt: isoDateTime,\n});\n\nexport const publicBlogOutput = Schema.Struct({\n id: uuid,\n name: Schema.String,\n slug: Schema.String,\n description: Schema.String,\n locale: Schema.String,\n accentColor: Schema.String,\n publicUrl: nullable(Schema.String),\n createdAt: isoDateTime,\n updatedAt: isoDateTime,\n});\n\nexport const publicPostOutput = Schema.Struct({\n id: uuid,\n slug: Schema.String,\n title: Schema.String,\n excerpt: Schema.String,\n contentMarkdown: Schema.String,\n contentHtml: Schema.String,\n coverImageUrl: nullable(Schema.String),\n coverImageAlt: nullable(Schema.String),\n status: postStatus,\n locale: Schema.String,\n featured: Schema.Boolean,\n publishedAt: nullable(isoDateTime),\n updatedAt: isoDateTime,\n readingMinutes: Schema.Finite,\n seoTitle: nullable(Schema.String),\n seoDescription: nullable(Schema.String),\n canonicalUrl: nullable(Schema.String),\n author: authorOutput,\n categories: Schema.Array(categoryOutput),\n});\n\nexport const publicPostPage = Schema.Struct({\n blog: publicBlogOutput,\n posts: Schema.Array(publicPostOutput),\n categories: Schema.Array(categoryOutput),\n pagination: Schema.Struct({\n page: Schema.Int,\n pageSize: Schema.Int,\n hasMore: Schema.Boolean,\n }),\n});\n\nexport const publicPostResult = Schema.Struct({\n blog: publicBlogOutput,\n post: publicPostOutput,\n});\n\nexport const publicRedirectOutput = Schema.Struct({\n fromPath: Schema.String,\n toPath: Schema.String,\n statusCode: Schema.Literals([301, 302, 307, 308]),\n});\n\nexport const paginatedPosts = Schema.Struct({\n items: Schema.Array(postOutput),\n total: Schema.Int,\n page: Schema.Int,\n pageSize: Schema.Int,\n});\n\nexport const mediaAssetStatus = Schema.Literals([\n \"pending\",\n \"processing\",\n \"ready\",\n \"failed\",\n \"deleted\",\n]);\n\nexport const mediaVariantOutput = Schema.Struct({\n kind: Schema.Literals([\"original\", \"large\", \"thumbnail\"]),\n url,\n mimeType: Schema.String,\n byteSize: Schema.Int,\n width: Schema.Int,\n height: Schema.Int,\n checksumSha256: Schema.String,\n});\n\nexport const mediaReferenceOutput = Schema.Struct({\n postId: uuid,\n title: Schema.String,\n slug: Schema.String,\n});\n\nexport const mediaAssetOutput = Schema.Struct({\n id: uuid,\n blogId: uuid,\n filename: Schema.String,\n mimeType: Schema.String,\n byteSize: Schema.Int,\n storageBytes: Schema.Int,\n width: nullable(Schema.Int),\n height: nullable(Schema.Int),\n checksumSha256: nullable(Schema.String),\n status: mediaAssetStatus,\n url: nullable(url),\n variants: Schema.Array(mediaVariantOutput),\n references: Schema.Array(mediaReferenceOutput),\n uploadedAt: nullable(isoDateTime),\n createdAt: isoDateTime,\n updatedAt: isoDateTime,\n});\n\nexport const mediaUsageOutput = Schema.Struct({\n usedBytes: Schema.Int,\n quotaBytes: Schema.Int,\n remainingBytes: Schema.Int,\n});\n\nexport const mediaListOutput = Schema.Struct({\n items: Schema.Array(mediaAssetOutput),\n usage: mediaUsageOutput,\n configured: Schema.Boolean,\n maxUploadBytes: Schema.Int,\n});\n\nexport const mediaStartUploadInput = Schema.Struct({\n blogId: uuid,\n filename: Schema.String.check(Schema.isMinLength(1), Schema.isMaxLength(255)),\n mimeType: Schema.String,\n byteSize: Schema.Int.check(Schema.isGreaterThan(0)),\n});\n\nexport const mediaUploadReservationOutput = Schema.Struct({\n asset: mediaAssetOutput,\n upload: Schema.Struct({\n url,\n method: Schema.Literal(\"PUT\"),\n headers: Schema.Record(Schema.String, Schema.String),\n expiresAt: isoDateTime,\n }),\n usage: mediaUsageOutput,\n});\n\nexport type PostStatus = typeof postStatus.Type;\nexport type Post = typeof postOutput.Type;\nexport type PostRevision = typeof postRevisionOutput.Type;\nexport type PostRevisionSnapshot = typeof postRevisionSnapshot.Type;\nexport type Blog = typeof blogOutput.Type;\nexport type PublicBlog = typeof publicBlogOutput.Type;\nexport type PublicAuthor = typeof authorOutput.Type;\nexport type PublicCategory = typeof categoryOutput.Type;\nexport type PublicPost = typeof publicPostOutput.Type;\nexport type PublicPostPage = typeof publicPostPage.Type;\nexport type PublicPostResult = typeof publicPostResult.Type;\nexport type PublicRedirect = typeof publicRedirectOutput.Type;\nexport type PostCreateInput = typeof postCreateInput.Type;\nexport type PostCreateEncodedInput = typeof postCreateInput.Encoded;\nexport type PostUpdateInput = typeof postUpdateInput.Type;\nexport type PostUpdateEncodedInput = typeof postUpdateInput.Encoded;\nexport type PaginatedPosts = typeof paginatedPosts.Type;\nexport type MediaAssetStatus = typeof mediaAssetStatus.Type;\nexport type MediaVariant = typeof mediaVariantOutput.Type;\nexport type MediaReference = typeof mediaReferenceOutput.Type;\nexport type MediaAsset = typeof mediaAssetOutput.Type;\nexport type MediaUsage = typeof mediaUsageOutput.Type;\nexport type MediaList = typeof mediaListOutput.Type;\nexport type MediaStartUploadInput = typeof mediaStartUploadInput.Type;\nexport type MediaUploadReservation = typeof mediaUploadReservationOutput.Type;\n","import { Schema } from \"effect\";\nimport {\n HttpApi,\n HttpApiEndpoint,\n HttpApiGroup,\n HttpApiSchema,\n OpenApi,\n} from \"effect/unstable/httpapi\";\nimport {\n blogOutput,\n mediaAssetOutput,\n mediaListOutput,\n mediaStartUploadInput,\n mediaUploadReservationOutput,\n paginatedPosts,\n postCreateInput,\n postOutput,\n postRevisionOutput,\n postStatus,\n postUpdateInput,\n} from \"./schemas.ts\";\n\nexport const apiErrorStatusByTag = {\n ApiInputRejected: 400,\n ApiPostConflict: 409,\n ApiAuthenticationFailed: 401,\n ApiAccessDenied: 403,\n ApiPostNotFound: 404,\n ApiRevisionNotFound: 404,\n ApiMediaNotFound: 404,\n ApiMediaConflict: 409,\n ApiMediaTooLarge: 413,\n ApiMediaUnavailable: 503,\n ApiUnavailable: 500,\n} as const;\n\nexport const privateApiPaths = {\n prefix: \"/api/v1\",\n health: \"/health\",\n blogs: \"/blogs\",\n posts: \"/posts\",\n media: \"/media\",\n} as const;\n\nexport class ApiPostConflict extends Schema.TaggedError<ApiPostConflict>()(\n \"ApiPostConflict\",\n { message: Schema.String },\n { httpApiStatus: apiErrorStatusByTag.ApiPostConflict },\n) {}\n\nexport class ApiInputRejected extends Schema.TaggedError<ApiInputRejected>()(\n \"ApiInputRejected\",\n { message: Schema.String },\n { httpApiStatus: apiErrorStatusByTag.ApiInputRejected },\n) {}\n\nexport class ApiAuthenticationFailed extends Schema.TaggedError<ApiAuthenticationFailed>()(\n \"ApiAuthenticationFailed\",\n { message: Schema.String },\n { httpApiStatus: apiErrorStatusByTag.ApiAuthenticationFailed },\n) {}\n\nexport class ApiAccessDenied extends Schema.TaggedError<ApiAccessDenied>()(\n \"ApiAccessDenied\",\n { message: Schema.String },\n { httpApiStatus: apiErrorStatusByTag.ApiAccessDenied },\n) {}\n\nexport class ApiPostNotFound extends Schema.TaggedError<ApiPostNotFound>()(\n \"ApiPostNotFound\",\n { message: Schema.String },\n { httpApiStatus: apiErrorStatusByTag.ApiPostNotFound },\n) {}\n\nexport class ApiRevisionNotFound extends Schema.TaggedError<ApiRevisionNotFound>()(\n \"ApiRevisionNotFound\",\n { message: Schema.String },\n { httpApiStatus: apiErrorStatusByTag.ApiRevisionNotFound },\n) {}\n\nexport class ApiMediaNotFound extends Schema.TaggedError<ApiMediaNotFound>()(\n \"ApiMediaNotFound\",\n { message: Schema.String },\n { httpApiStatus: apiErrorStatusByTag.ApiMediaNotFound },\n) {}\n\nexport class ApiMediaConflict extends Schema.TaggedError<ApiMediaConflict>()(\n \"ApiMediaConflict\",\n { message: Schema.String },\n { httpApiStatus: apiErrorStatusByTag.ApiMediaConflict },\n) {}\n\nexport class ApiMediaTooLarge extends Schema.TaggedError<ApiMediaTooLarge>()(\n \"ApiMediaTooLarge\",\n { message: Schema.String },\n { httpApiStatus: apiErrorStatusByTag.ApiMediaTooLarge },\n) {}\n\nexport class ApiMediaUnavailable extends Schema.TaggedError<ApiMediaUnavailable>()(\n \"ApiMediaUnavailable\",\n { message: Schema.String },\n { httpApiStatus: apiErrorStatusByTag.ApiMediaUnavailable },\n) {}\n\nexport class ApiUnavailable extends Schema.TaggedError<ApiUnavailable>()(\n \"ApiUnavailable\",\n { message: Schema.String },\n { httpApiStatus: apiErrorStatusByTag.ApiUnavailable },\n) {}\n\nexport const apiErrors = [\n ApiPostConflict,\n ApiInputRejected,\n ApiAuthenticationFailed,\n ApiAccessDenied,\n ApiPostNotFound,\n ApiRevisionNotFound,\n ApiMediaNotFound,\n ApiMediaConflict,\n ApiMediaTooLarge,\n ApiMediaUnavailable,\n ApiUnavailable,\n] as const;\n\nexport const privateApiPostId = Schema.String.check(Schema.isUUID());\nexport const privateApiRevisionId = Schema.String.check(Schema.isUUID());\nexport const privateApiMediaId = Schema.String.check(Schema.isUUID());\nexport const privateApiPageNumber = Schema.FiniteFromString.pipe(\n Schema.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(1)),\n);\nexport const privateApiPageSize = Schema.FiniteFromString.pipe(\n Schema.check(\n Schema.isInt(),\n Schema.isGreaterThanOrEqualTo(1),\n Schema.isLessThanOrEqualTo(100),\n ),\n);\nexport const privateApiPostListQueryFields = {\n blog: Schema.optionalKey(Schema.String),\n search: Schema.optionalKey(Schema.String),\n status: Schema.optionalKey(postStatus),\n page: Schema.optionalKey(privateApiPageNumber),\n pageSize: Schema.optionalKey(privateApiPageSize),\n} as const;\nexport const privateApiPostListQuery = Schema.Struct(\n privateApiPostListQueryFields,\n);\n\nconst health = HttpApiGroup.make(\"health\").add(\n HttpApiEndpoint.get(\"check\", privateApiPaths.health, {\n success: Schema.Struct({\n status: Schema.Literal(\"ok\"),\n version: Schema.String,\n }),\n error: ApiUnavailable,\n }).annotate(OpenApi.Summary, \"Database readiness probe\"),\n);\n\nconst blogs = HttpApiGroup.make(\"blogs\").add(\n HttpApiEndpoint.get(\"list\", privateApiPaths.blogs, {\n success: Schema.Array(blogOutput),\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"List blogs\"),\n);\n\nconst posts = HttpApiGroup.make(\"posts\")\n .add(\n HttpApiEndpoint.get(\"list\", privateApiPaths.posts, {\n query: privateApiPostListQueryFields,\n success: paginatedPosts,\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"List posts\"),\n )\n .add(\n HttpApiEndpoint.get(\"get\", `${privateApiPaths.posts}/:id`, {\n params: { id: privateApiPostId },\n success: postOutput,\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"Get a post\"),\n )\n .add(\n HttpApiEndpoint.post(\"create\", privateApiPaths.posts, {\n payload: postCreateInput,\n success: postOutput.pipe(HttpApiSchema.status(200)),\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"Create a post\"),\n )\n .add(\n HttpApiEndpoint.patch(\"update\", `${privateApiPaths.posts}/:id`, {\n params: { id: privateApiPostId },\n payload: postUpdateInput,\n success: postOutput,\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"Update a post\"),\n )\n .add(\n HttpApiEndpoint.delete(\"archive\", `${privateApiPaths.posts}/:id`, {\n params: { id: privateApiPostId },\n success: Schema.Struct({ ok: Schema.Literal(true) }),\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"Archive a post\"),\n )\n .add(\n HttpApiEndpoint.get(\n \"listRevisions\",\n `${privateApiPaths.posts}/:id/revisions`,\n {\n params: { id: privateApiPostId },\n success: Schema.Array(postRevisionOutput),\n error: apiErrors,\n },\n ).annotate(OpenApi.Summary, \"List post revisions\"),\n )\n .add(\n HttpApiEndpoint.post(\n \"restoreRevision\",\n `${privateApiPaths.posts}/:id/revisions/:revisionId/restore`,\n {\n params: {\n id: privateApiPostId,\n revisionId: privateApiRevisionId,\n },\n success: postOutput,\n error: apiErrors,\n },\n ).annotate(OpenApi.Summary, \"Restore a post revision\"),\n );\n\nconst media = HttpApiGroup.make(\"media\")\n .add(\n HttpApiEndpoint.get(\"list\", privateApiPaths.media, {\n success: mediaListOutput,\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"List media assets and storage usage\"),\n )\n .add(\n HttpApiEndpoint.get(\"get\", `${privateApiPaths.media}/:id`, {\n params: { id: privateApiMediaId },\n success: mediaAssetOutput,\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"Get a media asset\"),\n )\n .add(\n HttpApiEndpoint.post(\"startUpload\", `${privateApiPaths.media}/uploads`, {\n payload: mediaStartUploadInput,\n success: mediaUploadReservationOutput.pipe(HttpApiSchema.status(201)),\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"Reserve storage and sign a direct upload\"),\n )\n .add(\n HttpApiEndpoint.post(\n \"completeUpload\",\n `${privateApiPaths.media}/:id/complete`,\n {\n params: { id: privateApiMediaId },\n success: mediaAssetOutput,\n error: apiErrors,\n },\n ).annotate(OpenApi.Summary, \"Validate and process an uploaded image\"),\n )\n .add(\n HttpApiEndpoint.delete(\"delete\", `${privateApiPaths.media}/:id`, {\n params: { id: privateApiMediaId },\n success: Schema.Struct({ ok: Schema.Literal(true) }),\n error: apiErrors,\n }).annotate(OpenApi.Summary, \"Delete an unreferenced media asset\"),\n );\n\nexport const api = HttpApi.make(\"ProsewireApi\")\n .add(health, blogs, posts, media)\n .prefix(privateApiPaths.prefix)\n .annotate(OpenApi.Title, \"Prosewire private API\")\n .annotate(OpenApi.Version, \"1.0.0\");\n\n/** @deprecated Use `api`. Kept as a source-compatible migration alias. */\nexport const contract = api;\nexport type Contract = typeof api;\n","import { Schema } from \"effect\";\nimport {\n ApiInputRejected,\n ApiMediaNotFound,\n ApiPostNotFound,\n privateApiMediaId,\n privateApiPaths,\n privateApiPostId,\n privateApiPostListQuery,\n privateApiRevisionId,\n} from \"./router.ts\";\nimport {\n type MediaStartUploadInput,\n mediaStartUploadInput,\n type PostCreateInput,\n type PostStatus,\n type PostUpdateInput,\n postCreateInput,\n postUpdateInput,\n} from \"./schemas.ts\";\n\nconst path = (route: string) => `${privateApiPaths.prefix}${route}`;\nconst healthPath = path(privateApiPaths.health);\nconst blogsPath = path(privateApiPaths.blogs);\nconst postsPath = path(privateApiPaths.posts);\nconst mediaPath = path(privateApiPaths.media);\n\nexport interface PostListRequest {\n readonly blog?: string | undefined;\n readonly search?: string | undefined;\n readonly status?: PostStatus | undefined;\n readonly page: number;\n readonly pageSize: number;\n}\n\nexport type PrivateApiRequest =\n | { readonly _tag: \"Health\" }\n | { readonly _tag: \"ListBlogs\" }\n | { readonly _tag: \"ListPosts\"; readonly input: PostListRequest }\n | { readonly _tag: \"GetPost\"; readonly id: string }\n | { readonly _tag: \"ListPostRevisions\"; readonly id: string }\n | { readonly _tag: \"CreatePost\"; readonly input: PostCreateInput }\n | {\n readonly _tag: \"UpdatePost\";\n readonly id: string;\n readonly input: PostUpdateInput;\n }\n | { readonly _tag: \"ArchivePost\"; readonly id: string }\n | {\n readonly _tag: \"RestorePostRevision\";\n readonly id: string;\n readonly revisionId: string;\n }\n | { readonly _tag: \"ListMedia\" }\n | { readonly _tag: \"GetMedia\"; readonly id: string }\n | {\n readonly _tag: \"StartMediaUpload\";\n readonly input: MediaStartUploadInput;\n }\n | { readonly _tag: \"CompleteMediaUpload\"; readonly id: string }\n | { readonly _tag: \"DeleteMedia\"; readonly id: string };\n\nasync function decode<S extends Schema.ConstraintDecoder<unknown>>(\n schema: S,\n value: unknown,\n message: string,\n): Promise<S[\"Type\"]> {\n try {\n return await Schema.decodeUnknownPromise(schema)(value);\n } catch {\n throw new ApiInputRejected({ message });\n }\n}\n\nasync function json(request: Request): Promise<unknown> {\n try {\n return await request.json();\n } catch {\n throw new ApiInputRejected({ message: \"Invalid JSON request body\" });\n }\n}\n\nasync function identifier(pathname: string): Promise<string | undefined> {\n const prefix = `${postsPath}/`;\n if (!pathname.startsWith(prefix)) return undefined;\n const encoded = pathname.slice(prefix.length);\n if (!encoded || encoded.includes(\"/\")) return undefined;\n let value: string;\n try {\n value = decodeURIComponent(encoded);\n } catch {\n throw new ApiInputRejected({ message: \"Invalid post id\" });\n }\n return decode(privateApiPostId, value, \"Invalid post id\");\n}\n\nasync function revisionRoute(pathname: string): Promise<\n | { readonly _tag: \"List\"; readonly id: string }\n | {\n readonly _tag: \"Restore\";\n readonly id: string;\n readonly revisionId: string;\n }\n | undefined\n> {\n const prefix = `${postsPath}/`;\n if (!pathname.startsWith(prefix)) return undefined;\n const segments = pathname.slice(prefix.length).split(\"/\");\n const isList = segments.length === 2 && segments[1] === \"revisions\";\n const isRestore =\n segments.length === 4 &&\n segments[1] === \"revisions\" &&\n segments[3] === \"restore\";\n if (!isList && !isRestore) return undefined;\n let id: string;\n try {\n id = decodeURIComponent(segments[0] ?? \"\");\n } catch {\n throw new ApiInputRejected({ message: \"Invalid post id\" });\n }\n const decodedId = await decode(privateApiPostId, id, \"Invalid post id\");\n if (isList) return { _tag: \"List\", id: decodedId };\n let revisionId: string;\n try {\n revisionId = decodeURIComponent(segments[2] ?? \"\");\n } catch {\n throw new ApiInputRejected({ message: \"Invalid revision id\" });\n }\n return {\n _tag: \"Restore\",\n id: decodedId,\n revisionId: await decode(\n privateApiRevisionId,\n revisionId,\n \"Invalid revision id\",\n ),\n };\n}\n\nasync function mediaIdentifier(pathname: string): Promise<\n | {\n readonly id: string;\n readonly action: \"get\" | \"complete\";\n }\n | undefined\n> {\n const prefix = `${mediaPath}/`;\n if (!pathname.startsWith(prefix)) return undefined;\n const segments = pathname.slice(prefix.length).split(\"/\");\n if (segments.length < 1 || segments.length > 2 || !segments[0]) {\n return undefined;\n }\n const action =\n segments.length === 1\n ? \"get\"\n : segments[1] === \"complete\"\n ? \"complete\"\n : undefined;\n if (!action) return undefined;\n let id: string;\n try {\n id = decodeURIComponent(segments[0]);\n } catch {\n throw new ApiInputRejected({ message: \"Invalid media asset id\" });\n }\n return {\n id: await decode(privateApiMediaId, id, \"Invalid media asset id\"),\n action,\n };\n}\n\nexport async function decodePrivateApiRequest(\n request: Request,\n): Promise<PrivateApiRequest> {\n const { pathname, searchParams } = new URL(request.url);\n if (request.method === \"GET\" && pathname === healthPath) {\n return { _tag: \"Health\" };\n }\n if (request.method === \"GET\" && pathname === blogsPath) {\n return { _tag: \"ListBlogs\" };\n }\n if (request.method === \"GET\" && pathname === mediaPath) {\n return { _tag: \"ListMedia\" };\n }\n if (request.method === \"POST\" && pathname === `${mediaPath}/uploads`) {\n return {\n _tag: \"StartMediaUpload\",\n input: await decode(\n mediaStartUploadInput,\n await json(request),\n \"Invalid media upload\",\n ),\n };\n }\n const media = await mediaIdentifier(pathname);\n if (media?.action === \"get\" && request.method === \"GET\") {\n return { _tag: \"GetMedia\", id: media.id };\n }\n if (media?.action === \"complete\" && request.method === \"POST\") {\n return { _tag: \"CompleteMediaUpload\", id: media.id };\n }\n if (media?.action === \"get\" && request.method === \"DELETE\") {\n return { _tag: \"DeleteMedia\", id: media.id };\n }\n if (request.method === \"GET\" && pathname === postsPath) {\n const query = await decode(\n privateApiPostListQuery,\n Object.fromEntries(searchParams),\n \"Invalid post list query\",\n );\n return {\n _tag: \"ListPosts\",\n input: {\n ...query,\n page: query.page ?? 1,\n pageSize: query.pageSize ?? 20,\n },\n };\n }\n\n const revision = await revisionRoute(pathname);\n if (revision?._tag === \"List\" && request.method === \"GET\") {\n return { _tag: \"ListPostRevisions\", id: revision.id };\n }\n if (revision?._tag === \"Restore\" && request.method === \"POST\") {\n return {\n _tag: \"RestorePostRevision\",\n id: revision.id,\n revisionId: revision.revisionId,\n };\n }\n\n const id = await identifier(pathname);\n if (id && request.method === \"GET\") return { _tag: \"GetPost\", id };\n if (pathname === postsPath && request.method === \"POST\") {\n return {\n _tag: \"CreatePost\",\n input: await decode(\n postCreateInput,\n await json(request),\n \"Invalid post input\",\n ),\n };\n }\n if (id && request.method === \"PATCH\") {\n return {\n _tag: \"UpdatePost\",\n id,\n input: await decode(\n postUpdateInput,\n await json(request),\n \"Invalid post update\",\n ),\n };\n }\n if (id && request.method === \"DELETE\") return { _tag: \"ArchivePost\", id };\n if (pathname.startsWith(mediaPath)) {\n throw new ApiMediaNotFound({ message: \"Media API route not found\" });\n }\n throw new ApiPostNotFound({ message: \"API route not found\" });\n}\n\nexport * as PrivateApiTransport from \"./transport.ts\";\n","import {\n api,\n type MediaAsset,\n type MediaList,\n type MediaStartUploadInput,\n type MediaUploadReservation,\n type MediaUsage,\n type MediaVariant,\n type PortableImportReport,\n type PostCreateEncodedInput,\n type PostCreateInput,\n type PostRevision,\n type PostStatus,\n type PostUpdateInput,\n type PublicAuthor,\n type PublicBlog,\n type PublicCategory,\n type PublicPost,\n type PublicPostPage,\n type PublicPostResult,\n type PublicRedirect,\n portableImportPath,\n portableImportReport,\n publicPostPage,\n publicPostResult,\n publicRedirectOutput,\n} from \"@prosewire/contract\";\nimport { Effect, Schema } from \"effect\";\nimport {\n FetchHttpClient,\n HttpClient,\n HttpClientRequest,\n} from \"effect/unstable/http\";\nimport { HttpApiClient } from \"effect/unstable/httpapi\";\n\nexport interface ProsewireClientOptions {\n /** Base URL of a Prosewire deployment, e.g. https://blog.example.com. */\n baseUrl: string;\n /** Private API key. Public rendered/raw endpoints do not need one. */\n apiKey?: string;\n fetch?: typeof fetch;\n}\n\nexport interface PrivatePostListInput {\n /** Assert that the API key belongs to this publication slug or UUID. */\n readonly blog?: string;\n readonly search?: string;\n readonly status?: PostStatus;\n readonly page?: number;\n readonly pageSize?: number;\n}\n\nexport interface PortableImportInput {\n readonly body: ReadableStream<Uint8Array>;\n readonly contentType: \"application/json\" | \"application/zip\";\n readonly mode?: \"preview\" | \"apply\";\n /** Restore published/scheduled/archive states. Otherwise all posts arrive as drafts. */\n readonly preserveStates?: boolean;\n}\n\nexport class ProsewireImportError extends Schema.TaggedError<ProsewireImportError>()(\n \"ProsewireImportError\",\n { status: Schema.Int, item: Schema.String, reason: Schema.String },\n) {\n override get message() {\n return `${this.item}: ${this.reason}`;\n }\n}\n\nfunction normalizedCreateInput(input: PostCreateEncodedInput): PostCreateInput {\n return {\n ...input,\n contentMarkdown: input.contentMarkdown ?? \"\",\n status: input.status ?? \"draft\",\n featured: input.featured ?? false,\n categoryIds: input.categoryIds ?? [],\n };\n}\n\nexport function createEffectClient(options: ProsewireClientOptions) {\n const baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n const generated = Effect.runSync(\n HttpApiClient.make(api, {\n baseUrl,\n transformClient: options.apiKey\n ? HttpClient.mapRequest(HttpClientRequest.bearerToken(options.apiKey))\n : undefined,\n }).pipe(Effect.provide(FetchHttpClient.layer)),\n );\n const provideFetch = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n effect.pipe(\n Effect.provideService(\n FetchHttpClient.Fetch,\n options.fetch ?? globalThis.fetch,\n ),\n );\n\n return {\n health: () => provideFetch(generated.health.check()),\n imports: {\n run: (input: PortableImportInput) =>\n Effect.tryPromise({\n try: async (signal) => {\n const query = new URLSearchParams({\n mode: input.mode ?? \"preview\",\n preserveStates: String(input.preserveStates ?? false),\n });\n const response = await (options.fetch ?? globalThis.fetch)(\n `${baseUrl}${portableImportPath}?${query}`,\n {\n method: \"POST\",\n headers: {\n \"content-type\": input.contentType,\n ...(options.apiKey\n ? { authorization: `Bearer ${options.apiKey}` }\n : {}),\n },\n body: input.body,\n duplex: \"half\",\n signal,\n } as RequestInit & { duplex: \"half\" },\n );\n const body: unknown = await response.json();\n if (!response.ok) {\n const failure = Schema.decodeUnknownSync(\n Schema.Struct({\n item: Schema.optionalKey(Schema.String),\n message: Schema.String,\n }),\n )(body);\n throw new ProsewireImportError({\n status: response.status,\n item: failure.item ?? \"request\",\n reason: failure.message,\n });\n }\n return Schema.decodeUnknownPromise(portableImportReport)(body);\n },\n catch: (cause) =>\n cause instanceof ProsewireImportError\n ? cause\n : new ProsewireImportError({\n status: 0,\n item: \"request\",\n reason:\n cause instanceof Error\n ? cause.message\n : \"Publication import failed\",\n }),\n }),\n },\n blogs: {\n list: () => provideFetch(generated.blogs.list()),\n },\n posts: {\n list: (input: PrivatePostListInput = {}) =>\n provideFetch(generated.posts.list({ query: input })),\n get: (input: { readonly params: { readonly id: string } }) =>\n provideFetch(generated.posts.get(input)),\n revisions: (input: { readonly params: { readonly id: string } }) =>\n provideFetch(generated.posts.listRevisions(input)),\n create: (input: PostCreateEncodedInput) =>\n provideFetch(\n generated.posts.create({ payload: normalizedCreateInput(input) }),\n ),\n update: (input: {\n readonly params: { readonly id: string };\n readonly body: PostUpdateInput;\n }) =>\n provideFetch(\n generated.posts.update({\n params: input.params,\n payload: input.body,\n }),\n ),\n archive: (input: { readonly params: { readonly id: string } }) =>\n provideFetch(generated.posts.archive(input)),\n restore: (input: {\n readonly params: {\n readonly id: string;\n readonly revisionId: string;\n };\n }) => provideFetch(generated.posts.restoreRevision(input)),\n },\n media: {\n list: () => provideFetch(generated.media.list()),\n get: (input: { readonly params: { readonly id: string } }) =>\n provideFetch(generated.media.get(input)),\n startUpload: (input: MediaStartUploadInput) =>\n provideFetch(generated.media.startUpload({ payload: input })),\n completeUpload: (input: { readonly params: { readonly id: string } }) =>\n provideFetch(generated.media.completeUpload(input)),\n delete: (input: { readonly params: { readonly id: string } }) =>\n provideFetch(generated.media.delete(input)),\n },\n };\n}\n\nexport type EffectClient = ReturnType<typeof createEffectClient>;\n\nexport function createClient(options: ProsewireClientOptions) {\n const client = createEffectClient(options);\n return {\n health: () => Effect.runPromise(client.health()),\n imports: {\n run: (input: PortableImportInput) =>\n Effect.runPromise(client.imports.run(input)),\n },\n blogs: {\n list: () => Effect.runPromise(client.blogs.list()),\n },\n posts: {\n list: (input: PrivatePostListInput = {}) =>\n Effect.runPromise(client.posts.list(input)),\n get: (input: { readonly params: { readonly id: string } }) =>\n Effect.runPromise(client.posts.get(input)),\n revisions: (input: { readonly params: { readonly id: string } }) =>\n Effect.runPromise(client.posts.revisions(input)),\n create: (input: PostCreateEncodedInput) =>\n Effect.runPromise(client.posts.create(input)),\n update: (input: {\n readonly params: { readonly id: string };\n readonly body: PostUpdateInput;\n }) => Effect.runPromise(client.posts.update(input)),\n archive: (input: { readonly params: { readonly id: string } }) =>\n Effect.runPromise(client.posts.archive(input)),\n restore: (input: {\n readonly params: {\n readonly id: string;\n readonly revisionId: string;\n };\n }) => Effect.runPromise(client.posts.restore(input)),\n },\n media: {\n list: () => Effect.runPromise(client.media.list()),\n get: (input: { readonly params: { readonly id: string } }) =>\n Effect.runPromise(client.media.get(input)),\n startUpload: (input: MediaStartUploadInput) =>\n Effect.runPromise(client.media.startUpload(input)),\n completeUpload: (input: { readonly params: { readonly id: string } }) =>\n Effect.runPromise(client.media.completeUpload(input)),\n delete: (input: { readonly params: { readonly id: string } }) =>\n Effect.runPromise(client.media.delete(input)),\n },\n };\n}\n\nexport type Client = ReturnType<typeof createClient>;\n\nexport type {\n MediaAsset,\n MediaList,\n MediaStartUploadInput,\n MediaUploadReservation,\n MediaUsage,\n MediaVariant,\n PortableImportReport,\n PostRevision,\n PublicAuthor,\n PublicBlog,\n PublicCategory,\n PublicPost,\n PublicPostPage,\n PublicPostResult,\n PublicRedirect,\n};\n\nexport interface PublicListInput {\n search?: string;\n category?: string;\n page?: number;\n pageSize?: number;\n /** @deprecated Use pageSize. */\n limit?: number;\n}\n\nexport interface PublicContentClient {\n listPosts(input?: PublicListInput): Promise<PublicPostPage>;\n listAllPosts(\n input?: Omit<PublicListInput, \"page\" | \"pageSize\" | \"limit\">,\n ): Promise<ReadonlyArray<PublicPost>>;\n getPost(slug: string): Promise<PublicPostResult>;\n resolvePost(slug: string): Promise<PublicPostResolution>;\n listRedirects(): Promise<ReadonlyArray<PublicRedirect>>;\n getRendered(path?: string): Promise<string>;\n}\n\nexport type PublicPostResolution =\n | ({ status: \"found\" } & PublicPostResult)\n | ({ status: \"redirect\"; slug: string } & PublicPostResult)\n | { status: \"not-found\" };\n\nexport class ProsewireRequestError extends Error {\n readonly status: number;\n readonly url: string;\n\n constructor(response: Response) {\n super(`Prosewire request failed (${String(response.status)})`);\n this.name = \"ProsewireRequestError\";\n this.status = response.status;\n this.url = response.url;\n }\n}\n\nasync function decodeResponse<S extends Schema.ConstraintDecoder<unknown>>(\n schema: S,\n response: Response,\n): Promise<S[\"Type\"]> {\n return Schema.decodeUnknownPromise(schema)(await response.json());\n}\n\nexport function createPublicClient(\n options: Pick<ProsewireClientOptions, \"baseUrl\" | \"fetch\"> & { blog: string },\n): PublicContentClient {\n const request = options.fetch ?? fetch;\n const base = options.baseUrl.replace(/\\/$/, \"\");\n const blog = encodeURIComponent(options.blog);\n const postUrl = (slug: string) =>\n `${base}/api/public/${blog}/posts/${encodeURIComponent(slug)}`;\n const listPosts = async (input: PublicListInput = {}) => {\n const query = new URLSearchParams();\n if (input.search) query.set(\"search\", input.search);\n if (input.category) query.set(\"category\", input.category);\n if (input.page) query.set(\"page\", String(input.page));\n if (input.pageSize) query.set(\"pageSize\", String(input.pageSize));\n if (input.limit) query.set(\"limit\", String(input.limit));\n const suffix = query.size ? `?${query.toString()}` : \"\";\n const response = await request(`${base}/api/public/${blog}/posts${suffix}`);\n if (!response.ok) throw new ProsewireRequestError(response);\n return decodeResponse(publicPostPage, response);\n };\n const resolvePost = async (slug: string): Promise<PublicPostResolution> => {\n const response = await request(postUrl(slug));\n if (response.status === 404) return { status: \"not-found\" };\n if (!response.ok) throw new ProsewireRequestError(response);\n const result = await decodeResponse(publicPostResult, response);\n return result.post.slug === slug\n ? { status: \"found\", ...result }\n : { status: \"redirect\", slug: result.post.slug, ...result };\n };\n return {\n listPosts,\n async listAllPosts(input = {}) {\n const posts: PublicPost[] = [];\n let page = 1;\n while (true) {\n const result = await listPosts({ ...input, page, pageSize: 100 });\n posts.push(...result.posts);\n if (!result.pagination.hasMore) return posts;\n page += 1;\n }\n },\n async getPost(slug) {\n const result = await resolvePost(slug);\n if (result.status === \"not-found\") {\n throw new ProsewireRequestError(new Response(null, { status: 404 }));\n }\n return { blog: result.blog, post: result.post };\n },\n resolvePost,\n async listRedirects() {\n const response = await request(`${base}/api/public/${blog}/redirects`);\n if (!response.ok) throw new ProsewireRequestError(response);\n return Schema.decodeUnknownPromise(Schema.Array(publicRedirectOutput))(\n await response.json(),\n );\n },\n async getRendered(path = \"\") {\n const encodedPath = path\n .replace(/^\\//, \"\")\n .split(\"/\")\n .filter(Boolean)\n .map(encodeURIComponent)\n .join(\"/\");\n const response = await request(\n `${base}/api/rendered/${blog}/${encodedPath}`,\n );\n if (!response.ok) throw new ProsewireRequestError(response);\n return response.text();\n },\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prosewire/sdk",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "description": "Typed client for the Prosewire content API.",
@@ -30,6 +30,11 @@
30
30
  "types": "./dist/index.d.mts",
31
31
  "import": "./dist/index.mjs",
32
32
  "default": "./dist/index.mjs"
33
+ },
34
+ "./import-node": {
35
+ "types": "./dist/import-node.d.mts",
36
+ "import": "./dist/import-node.mjs",
37
+ "default": "./dist/import-node.mjs"
33
38
  }
34
39
  },
35
40
  "files": [
@@ -42,17 +47,22 @@
42
47
  "provenance": true
43
48
  },
44
49
  "dependencies": {
45
- "effect": "4.0.0-rc.110"
50
+ "effect": "4.0.0-rc.115",
51
+ "fflate": "^0.8.3"
46
52
  },
47
53
  "devDependencies": {
48
- "@types/node": "^26.2.0",
49
- "tsdown": "^0.22.0",
54
+ "@types/node": "^26.6.1",
55
+ "tsdown": "^0.23.0",
50
56
  "typescript": "npm:@typescript/typescript6@^6.0.2",
51
- "vitest": "^4.1.11",
57
+ "vitest": "^5.0.1",
52
58
  "@prosewire/contract": "0.0.0",
53
59
  "@prosewire/config": "0.0.0"
54
60
  },
55
61
  "tsdown": {
62
+ "entry": [
63
+ "src/index.ts",
64
+ "src/import-node.ts"
65
+ ],
56
66
  "dts": {
57
67
  "eager": true
58
68
  },
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../contract/src/router.ts","../../contract/src/schemas.ts","../src/index.ts"],"mappings":";;;;;;cAiBa,yBAAyB;;;;cAMzB,gCAAgC;;;;cAMhC,wBAAwB;;;;cAMxB,wBAAwB;;;;cAMxB,uBAAuB;;;cCzBvB,YAAU,OAAA;cAOV,cAAY,OAAA;;;;;;;;;cAUZ,gBAAc,OAAA;;;;;;cAiEd,iBAAe,OAAA;;;;;;;;;;;;;;;;;;;cAoBf,iBAAe,OAAA;;;;;;;;;;;;;;;;;;cAgCf,kBAAgB,OAAA;;;;;;;;;;;cAYhB,kBAAgB,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAsBhB,gBAAc,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAWd,kBAAgB,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAYjB,oBAAoB,WAAW;KAG/B,oBAAoB,iBAAiB;KACrC,sBAAsB,aAAa;KACnC,wBAAwB,eAAe;KACvC,oBAAoB,iBAAiB;KACrC,wBAAwB,eAAe;KACvC,0BAA0B,iBAAiB;KAE3C,gCAAgC,gBAAgB;KAChD,yBAAyB,gBAAgB;;;UCnMpC;;EAEf;;EAEA;EACA,eAAe;;UAGA;WACN;WACA;WACA,SAAS;WACT;WACA;;iBAcK,mBAAmB,SAAS;;;;;;;;;;;;;;;;;;;;IA0BxB,OAAA,QAAA,yBAAoB,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAErB,MAAA;eAAW;iBAAmB;;UAAc,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAEzC,SAAA,OAAA,2BAAsB,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAItB,SAAA;eACL;iBAAmB;;eACnB,MAAM;UAChB,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAOgB,UAAA;eAAW;iBAAmB;;UAAc,OAAA;;;;;KAMvD,eAAe,kBAAkB;iBAE7B,aAAa,SAAS;;;;;;;;;;;;;;;;;;;;IAQlB,OAAA,QAAA,yBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAErB,MAAA;eAAW;iBAAmB;;UAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAEzC,SAAA,OAAA,2BAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAEtB,SAAA;eACL;iBAAmB;;eACnB,MAAM;UAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IACgB,UAAA;eAAW;iBAAmB;;UAAc;;;;;KAMvD,SAAS,kBAAkB;UAWtB;EACf;EACA;EACA;EACA;;EAEA;;UAGe;EACf,UAAU,QAAQ,kBAAkB,QAAQ;EAC5C,QAAQ,eAAe,QAAQ;EAC/B,YAAY,gBAAgB;;iBAUd,mBACd,SAAS,KAAK;EAAiD;IAC9D"}