diff options
| author | Volpeon <git@volpeon.ink> | 2026-07-26 11:57:13 +0200 |
|---|---|---|
| committer | Volpeon <git@volpeon.ink> | 2026-07-26 11:57:13 +0200 |
| commit | 5c899b4a5c2c07398151960b2b86d238b49d5bf4 (patch) | |
| tree | ccc743f27ba234a25396cb24b6124c139d13b027 /src/deps/strapi.ts | |
| parent | Use Corvos 0.1.4 (diff) | |
| download | corvos-website-5c899b4a5c2c07398151960b2b86d238b49d5bf4.tar.gz corvos-website-5c899b4a5c2c07398151960b2b86d238b49d5bf4.tar.bz2 corvos-website-5c899b4a5c2c07398151960b2b86d238b49d5bf4.zip | |
Diffstat (limited to 'src/deps/strapi.ts')
| -rw-r--r-- | src/deps/strapi.ts | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/deps/strapi.ts b/src/deps/strapi.ts new file mode 100644 index 0000000..32e49b0 --- /dev/null +++ b/src/deps/strapi.ts | |||
| @@ -0,0 +1,110 @@ | |||
| 1 | import type { Pipeline, PipelineStageError } from "corvos"; | ||
| 2 | import type { StandardSchemaV1, StandardTypedV1 } from "corvos/deps/standard_schema.ts"; | ||
| 3 | |||
| 4 | import { Page } from "corvos"; | ||
| 5 | import { replaceExtension } from "corvos/core/utils/path.ts"; | ||
| 6 | |||
| 7 | import type { Node } from "./strapi/schema.ts"; | ||
| 8 | |||
| 9 | import { blocksToTSX } from "./strapi/blocks.tsx"; | ||
| 10 | import { StrapiLoader } from "./strapi/loader.ts"; | ||
| 11 | |||
| 12 | export type { Node } from "./strapi/schema.ts"; | ||
| 13 | export { nodeSchema, fileAttributeSchema, imageAttributeSchema } from "./strapi/schema.ts"; | ||
| 14 | export { Blocks } from "./strapi/blocks.tsx"; | ||
| 15 | |||
| 16 | export interface StrapiContent<Type extends "single" | "collection" = "single" | "collection"> { | ||
| 17 | type: Type; | ||
| 18 | schema: StandardSchemaV1; | ||
| 19 | query?: Record<string, string>; | ||
| 20 | } | ||
| 21 | |||
| 22 | type ContentSingle<T extends Record<string, StrapiContent>> = { | ||
| 23 | [Key in keyof T]: T[Key]["type"] extends "single" ? Key : never; | ||
| 24 | }[keyof T]; | ||
| 25 | |||
| 26 | type ContentCollection<T extends Record<string, StrapiContent>> = { | ||
| 27 | [Key in keyof T]: T[Key]["type"] extends "collection" ? Key : never; | ||
| 28 | }[keyof T]; | ||
| 29 | |||
| 30 | export interface Options<Content extends Record<string, StrapiContent>> { | ||
| 31 | url: string; | ||
| 32 | token: string; | ||
| 33 | content: Content; | ||
| 34 | } | ||
| 35 | |||
| 36 | export function strapi<Content extends Record<string, StrapiContent>>(options: Options<Content>) { | ||
| 37 | const loader = new StrapiLoader(options.url, options.token); | ||
| 38 | |||
| 39 | function load<const Key extends ContentSingle<Content> & string>( | ||
| 40 | key: Key, | ||
| 41 | query?: Record<string, string>, | ||
| 42 | ): Promise< | ||
| 43 | { | ||
| 44 | documentId: string; | ||
| 45 | publishedAt: Date | null; | ||
| 46 | updatedAt: Date; | ||
| 47 | } & StandardTypedV1.InferOutput<Content[Key]["schema"]> | ||
| 48 | >; | ||
| 49 | function load<const Key extends ContentCollection<Content> & string>( | ||
| 50 | key: Key, | ||
| 51 | query?: Record<string, string>, | ||
| 52 | ): AsyncGenerator< | ||
| 53 | | PipelineStageError | ||
| 54 | | ({ | ||
| 55 | documentId: string; | ||
| 56 | publishedAt: Date | null; | ||
| 57 | updatedAt: Date; | ||
| 58 | } & StandardTypedV1.InferOutput<Content[Key]["schema"]>), | ||
| 59 | void, | ||
| 60 | unknown | ||
| 61 | >; | ||
| 62 | function load<const Key extends Content & string>( | ||
| 63 | key: Key, | ||
| 64 | query?: Record<string, string>, | ||
| 65 | ): | ||
| 66 | | Promise< | ||
| 67 | { | ||
| 68 | documentId: string; | ||
| 69 | publishedAt: Date | null; | ||
| 70 | updatedAt: Date; | ||
| 71 | } & StandardTypedV1.InferOutput<Content[Key]["schema"]> | ||
| 72 | > | ||
| 73 | | AsyncGenerator< | ||
| 74 | | PipelineStageError | ||
| 75 | | ({ | ||
| 76 | documentId: string; | ||
| 77 | publishedAt: Date | null; | ||
| 78 | updatedAt: Date; | ||
| 79 | } & StandardTypedV1.InferOutput<Content[Key]["schema"]>), | ||
| 80 | void, | ||
| 81 | unknown | ||
| 82 | > { | ||
| 83 | if (options.content[key]!.type === "single") { | ||
| 84 | return loader.loadSingle(key, options.content[key]!.schema, { | ||
| 85 | ...options.content[key]!.query, | ||
| 86 | ...query, | ||
| 87 | }); | ||
| 88 | } else { | ||
| 89 | return loader.loadCollection(key, options.content[key]!.schema, { | ||
| 90 | ...options.content[key]!.query, | ||
| 91 | ...query, | ||
| 92 | }); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | return <Loaders extends string, Out extends { ".strapi": [Node[], {}] }, Helpers extends {}>( | ||
| 97 | pipeline: Pipeline<Loaders, Out, Helpers>, | ||
| 98 | ) => | ||
| 99 | pipeline | ||
| 100 | .process("strapi", ".strapi", function* (page) { | ||
| 101 | yield new Page( | ||
| 102 | ".jsxelement", | ||
| 103 | blocksToTSX(page.content), | ||
| 104 | page.data as Out[".strapi"][1], | ||
| 105 | replaceExtension(page.url, ".jsx"), | ||
| 106 | page, | ||
| 107 | ); | ||
| 108 | }) | ||
| 109 | .helper("strapi", load); | ||
| 110 | } | ||
