@aotter/mantle-runtime 0.1.0-alpha.7 → 0.1.0-alpha.8
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 +37 -4
- package/dist/MantleRuntime.d.ts +96 -0
- package/dist/MantleRuntime.d.ts.map +1 -0
- package/dist/MantleRuntime.js +197 -0
- package/dist/MantleRuntime.js.map +1 -0
- package/dist/domain/model/HandlerContext.d.ts +3 -4
- package/dist/domain/model/HandlerContext.d.ts.map +1 -1
- package/dist/domain/model/PreparedMantleRevision.d.ts +14 -0
- package/dist/domain/model/PreparedMantleRevision.d.ts.map +1 -0
- package/dist/domain/model/PreparedMantleRevision.js +8 -0
- package/dist/domain/model/PreparedMantleRevision.js.map +1 -0
- package/dist/domain/model/index.d.ts +1 -2
- package/dist/domain/model/index.d.ts.map +1 -1
- package/dist/domain/model/index.js +0 -1
- package/dist/domain/model/index.js.map +1 -1
- package/dist/domain/port/Clock.d.ts +1 -2
- package/dist/domain/port/Clock.d.ts.map +1 -1
- package/dist/domain/port/Clock.js.map +1 -1
- package/dist/domain/port/DatabaseDriver.d.ts +13 -21
- package/dist/domain/port/DatabaseDriver.d.ts.map +1 -1
- package/dist/domain/port/HandlerRegistry.d.ts +1 -1
- package/dist/domain/port/IdGenerator.d.ts +1 -2
- package/dist/domain/port/IdGenerator.d.ts.map +1 -1
- package/dist/domain/port/IdGenerator.js.map +1 -1
- package/dist/domain/port/MantleStorageAdapter.d.ts +23 -0
- package/dist/domain/port/MantleStorageAdapter.d.ts.map +1 -0
- package/dist/domain/port/MantleStorageAdapter.js +2 -0
- package/dist/domain/port/MantleStorageAdapter.js.map +1 -0
- package/dist/domain/port/SiteConfigRepository.d.ts +10 -8
- package/dist/domain/port/SiteConfigRepository.d.ts.map +1 -1
- package/dist/domain/port/ViewQueryExecutor.d.ts +29 -0
- package/dist/domain/port/ViewQueryExecutor.d.ts.map +1 -0
- package/dist/domain/port/ViewQueryExecutor.js +2 -0
- package/dist/domain/port/ViewQueryExecutor.js.map +1 -0
- package/dist/domain/port/index.d.ts +5 -2
- package/dist/domain/port/index.d.ts.map +1 -1
- package/dist/domain/port/index.js.map +1 -1
- package/dist/domain/service/RuntimePlanCompiler.d.ts +89 -0
- package/dist/domain/service/RuntimePlanCompiler.d.ts.map +1 -0
- package/dist/domain/service/RuntimePlanCompiler.js +230 -0
- package/dist/domain/service/RuntimePlanCompiler.js.map +1 -0
- package/dist/domain/service/TriggerIndex.d.ts +3 -0
- package/dist/domain/service/TriggerIndex.d.ts.map +1 -1
- package/dist/domain/service/TriggerIndex.js +14 -1
- package/dist/domain/service/TriggerIndex.js.map +1 -1
- package/dist/domain/service/index.d.ts +1 -9
- package/dist/domain/service/index.d.ts.map +1 -1
- package/dist/domain/service/index.js +1 -9
- package/dist/domain/service/index.js.map +1 -1
- package/dist/domain/service/io/EntryWriteGuard.d.ts +2 -2
- package/dist/domain/service/io/EntryWriteGuard.d.ts.map +1 -1
- package/dist/domain/service/io/EntryWriteGuard.js +1 -3
- package/dist/domain/service/io/EntryWriteGuard.js.map +1 -1
- package/dist/index.d.ts +15 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -11
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/boot/SqliteMigrationRunner.d.ts +10 -0
- package/dist/infrastructure/boot/SqliteMigrationRunner.d.ts.map +1 -0
- package/dist/infrastructure/boot/SqliteMigrationRunner.js +41 -0
- package/dist/infrastructure/boot/SqliteMigrationRunner.js.map +1 -0
- package/dist/infrastructure/boot/bootState.d.ts +2 -4
- package/dist/infrastructure/boot/bootState.d.ts.map +1 -1
- package/dist/infrastructure/boot/bootState.js +1 -1
- package/dist/infrastructure/boot/bootState.js.map +1 -1
- package/dist/infrastructure/boot/canonicalMigrations.d.ts.map +1 -1
- package/dist/infrastructure/boot/canonicalMigrations.js +124 -60
- package/dist/infrastructure/boot/canonicalMigrations.js.map +1 -1
- package/dist/infrastructure/boot/index.d.ts +1 -0
- package/dist/infrastructure/boot/index.d.ts.map +1 -1
- package/dist/infrastructure/boot/index.js +1 -0
- package/dist/infrastructure/boot/index.js.map +1 -1
- package/dist/infrastructure/http/createMantleRequestHandler.d.ts +12 -0
- package/dist/infrastructure/http/createMantleRequestHandler.d.ts.map +1 -0
- package/dist/infrastructure/http/createMantleRequestHandler.js +127 -0
- package/dist/infrastructure/http/createMantleRequestHandler.js.map +1 -0
- package/dist/infrastructure/mcp/McpJsonRpcDispatcher.d.ts +2 -2
- package/dist/infrastructure/mcp/McpJsonRpcDispatcher.d.ts.map +1 -1
- package/dist/infrastructure/mcp/McpJsonRpcDispatcher.js +1 -1
- package/dist/infrastructure/mcp/McpJsonRpcDispatcher.js.map +1 -1
- package/dist/infrastructure/mcp/McpToolCatalog.d.ts.map +1 -1
- package/dist/infrastructure/mcp/McpToolCatalog.js +6 -7
- package/dist/infrastructure/mcp/McpToolCatalog.js.map +1 -1
- package/dist/infrastructure/persistence/DatabaseEntryRepository.d.ts +1 -1
- package/dist/infrastructure/persistence/DatabaseEntryRepository.d.ts.map +1 -1
- package/dist/infrastructure/persistence/DatabaseEntryRepository.js +1 -1
- package/dist/infrastructure/persistence/DatabaseEntryRepository.js.map +1 -1
- package/dist/infrastructure/persistence/DatabaseSiteConfigRepository.js +3 -3
- package/dist/infrastructure/storage/SqliteMantleStorageAdapter.d.ts +22 -0
- package/dist/infrastructure/storage/SqliteMantleStorageAdapter.d.ts.map +1 -0
- package/dist/infrastructure/storage/SqliteMantleStorageAdapter.js +86 -0
- package/dist/infrastructure/storage/SqliteMantleStorageAdapter.js.map +1 -0
- package/dist/{domain/service/ViewSqlCompiler.d.ts → infrastructure/storage/SqliteViewCompiler.d.ts} +9 -20
- package/dist/infrastructure/storage/SqliteViewCompiler.d.ts.map +1 -0
- package/dist/infrastructure/storage/SqliteViewCompiler.js +307 -0
- package/dist/infrastructure/storage/SqliteViewCompiler.js.map +1 -0
- package/dist/infrastructure/testing/IndexCoverageHarness.d.ts +2 -2
- package/dist/infrastructure/testing/IndexCoverageHarness.d.ts.map +1 -1
- package/dist/infrastructure/testing/IndexCoverageHarness.js +4 -4
- package/dist/infrastructure/testing/IndexCoverageHarness.js.map +1 -1
- package/dist/usecase/boot/ValidateBootUseCase.d.ts +15 -38
- package/dist/usecase/boot/ValidateBootUseCase.d.ts.map +1 -1
- package/dist/usecase/boot/ValidateBootUseCase.js +79 -274
- package/dist/usecase/boot/ValidateBootUseCase.js.map +1 -1
- package/dist/usecase/boot/index.d.ts +1 -1
- package/dist/usecase/boot/index.d.ts.map +1 -1
- package/dist/usecase/boot/index.js +1 -1
- package/dist/usecase/boot/index.js.map +1 -1
- package/dist/usecase/content/CreateDraftUseCase.d.ts +2 -2
- package/dist/usecase/content/CreateDraftUseCase.d.ts.map +1 -1
- package/dist/usecase/content/CreateDraftUseCase.js.map +1 -1
- package/dist/usecase/content/RequestPublishUseCase.d.ts +2 -2
- package/dist/usecase/content/RequestPublishUseCase.d.ts.map +1 -1
- package/dist/usecase/content/RequestPublishUseCase.js.map +1 -1
- package/dist/usecase/content/UpdateDraftUseCase.d.ts +2 -2
- package/dist/usecase/content/UpdateDraftUseCase.d.ts.map +1 -1
- package/dist/usecase/content/UpdateDraftUseCase.js.map +1 -1
- package/dist/usecase/dto/index.d.ts +0 -1
- package/dist/usecase/dto/index.d.ts.map +1 -1
- package/dist/usecase/dto/index.js +0 -1
- package/dist/usecase/dto/index.js.map +1 -1
- package/dist/usecase/dto/view/ExecuteViewRequest.d.ts +2 -2
- package/dist/usecase/dto/view/ExecuteViewRequest.d.ts.map +1 -1
- package/dist/usecase/index.d.ts +0 -1
- package/dist/usecase/index.d.ts.map +1 -1
- package/dist/usecase/index.js +0 -1
- package/dist/usecase/index.js.map +1 -1
- package/dist/usecase/media/diagnostics.js +1 -1
- package/dist/usecase/procedure/InvokeBuiltinUseCase.d.ts +2 -2
- package/dist/usecase/procedure/InvokeBuiltinUseCase.d.ts.map +1 -1
- package/dist/usecase/procedure/InvokeBuiltinUseCase.js.map +1 -1
- package/dist/usecase/site/UpdateSiteSettingsUseCase.d.ts.map +1 -1
- package/dist/usecase/site/UpdateSiteSettingsUseCase.js +8 -1
- package/dist/usecase/site/UpdateSiteSettingsUseCase.js.map +1 -1
- package/dist/usecase/view/ExecuteViewUseCase.d.ts +8 -16
- package/dist/usecase/view/ExecuteViewUseCase.d.ts.map +1 -1
- package/dist/usecase/view/ExecuteViewUseCase.js +19 -95
- package/dist/usecase/view/ExecuteViewUseCase.js.map +1 -1
- package/dist/usecase/view/index.d.ts +2 -1
- package/dist/usecase/view/index.d.ts.map +1 -1
- package/dist/usecase/view/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/domain/model/SeoMeta.d.ts +0 -47
- package/dist/domain/model/SeoMeta.d.ts.map +0 -1
- package/dist/domain/model/SeoMeta.js +0 -2
- package/dist/domain/model/SeoMeta.js.map +0 -1
- package/dist/domain/model/TemplateRegistry.d.ts +0 -49
- package/dist/domain/model/TemplateRegistry.d.ts.map +0 -1
- package/dist/domain/model/TemplateRegistry.js +0 -17
- package/dist/domain/model/TemplateRegistry.js.map +0 -1
- package/dist/domain/port/AssetServer.d.ts +0 -22
- package/dist/domain/port/AssetServer.d.ts.map +0 -1
- package/dist/domain/port/AssetServer.js +0 -2
- package/dist/domain/port/AssetServer.js.map +0 -1
- package/dist/domain/service/AbsoluteUrl.d.ts +0 -6
- package/dist/domain/service/AbsoluteUrl.d.ts.map +0 -1
- package/dist/domain/service/AbsoluteUrl.js +0 -33
- package/dist/domain/service/AbsoluteUrl.js.map +0 -1
- package/dist/domain/service/HtmlEscaping.d.ts +0 -2
- package/dist/domain/service/HtmlEscaping.d.ts.map +0 -1
- package/dist/domain/service/HtmlEscaping.js +0 -9
- package/dist/domain/service/HtmlEscaping.js.map +0 -1
- package/dist/domain/service/HtmlRenderer.d.ts +0 -38
- package/dist/domain/service/HtmlRenderer.d.ts.map +0 -1
- package/dist/domain/service/HtmlRenderer.js +0 -73
- package/dist/domain/service/HtmlRenderer.js.map +0 -1
- package/dist/domain/service/MarkdownSerializer.d.ts +0 -45
- package/dist/domain/service/MarkdownSerializer.d.ts.map +0 -1
- package/dist/domain/service/MarkdownSerializer.js +0 -154
- package/dist/domain/service/MarkdownSerializer.js.map +0 -1
- package/dist/domain/service/McpToolNaming.d.ts +0 -31
- package/dist/domain/service/McpToolNaming.d.ts.map +0 -1
- package/dist/domain/service/McpToolNaming.js +0 -48
- package/dist/domain/service/McpToolNaming.js.map +0 -1
- package/dist/domain/service/PreviewBanner.d.ts +0 -10
- package/dist/domain/service/PreviewBanner.d.ts.map +0 -1
- package/dist/domain/service/PreviewBanner.js +0 -30
- package/dist/domain/service/PreviewBanner.js.map +0 -1
- package/dist/domain/service/PublicPathResolver.d.ts +0 -46
- package/dist/domain/service/PublicPathResolver.d.ts.map +0 -1
- package/dist/domain/service/PublicPathResolver.js +0 -36
- package/dist/domain/service/PublicPathResolver.js.map +0 -1
- package/dist/domain/service/SeoMetaComposer.d.ts +0 -60
- package/dist/domain/service/SeoMetaComposer.d.ts.map +0 -1
- package/dist/domain/service/SeoMetaComposer.js +0 -213
- package/dist/domain/service/SeoMetaComposer.js.map +0 -1
- package/dist/domain/service/SitemapSerializer.d.ts +0 -19
- package/dist/domain/service/SitemapSerializer.d.ts.map +0 -1
- package/dist/domain/service/SitemapSerializer.js +0 -27
- package/dist/domain/service/SitemapSerializer.js.map +0 -1
- package/dist/domain/service/ViewSqlCompiler.d.ts.map +0 -1
- package/dist/domain/service/ViewSqlCompiler.js +0 -244
- package/dist/domain/service/ViewSqlCompiler.js.map +0 -1
- package/dist/domain/service/io/MediaAssetReferences.d.ts +0 -13
- package/dist/domain/service/io/MediaAssetReferences.d.ts.map +0 -1
- package/dist/domain/service/io/MediaAssetReferences.js +0 -48
- package/dist/domain/service/io/MediaAssetReferences.js.map +0 -1
- package/dist/runtime.d.ts +0 -145
- package/dist/runtime.d.ts.map +0 -1
- package/dist/runtime.js +0 -224
- package/dist/runtime.js.map +0 -1
- package/dist/usecase/dto/render/ComposeEntrySeoMetaRequest.d.ts +0 -18
- package/dist/usecase/dto/render/ComposeEntrySeoMetaRequest.d.ts.map +0 -1
- package/dist/usecase/dto/render/ComposeEntrySeoMetaRequest.js +0 -2
- package/dist/usecase/dto/render/ComposeEntrySeoMetaRequest.js.map +0 -1
- package/dist/usecase/dto/render/ComposeLlmsTxtRequest.d.ts +0 -13
- package/dist/usecase/dto/render/ComposeLlmsTxtRequest.d.ts.map +0 -1
- package/dist/usecase/dto/render/ComposeLlmsTxtRequest.js +0 -2
- package/dist/usecase/dto/render/ComposeLlmsTxtRequest.js.map +0 -1
- package/dist/usecase/dto/render/ComposeSitemapRequest.d.ts +0 -13
- package/dist/usecase/dto/render/ComposeSitemapRequest.d.ts.map +0 -1
- package/dist/usecase/dto/render/ComposeSitemapRequest.js +0 -2
- package/dist/usecase/dto/render/ComposeSitemapRequest.js.map +0 -1
- package/dist/usecase/dto/render/PreviewEntryRequest.d.ts +0 -18
- package/dist/usecase/dto/render/PreviewEntryRequest.d.ts.map +0 -1
- package/dist/usecase/dto/render/PreviewEntryRequest.js +0 -2
- package/dist/usecase/dto/render/PreviewEntryRequest.js.map +0 -1
- package/dist/usecase/dto/render/RenderEntryLiveRequest.d.ts +0 -19
- package/dist/usecase/dto/render/RenderEntryLiveRequest.d.ts.map +0 -1
- package/dist/usecase/dto/render/RenderEntryLiveRequest.js +0 -2
- package/dist/usecase/dto/render/RenderEntryLiveRequest.js.map +0 -1
- package/dist/usecase/dto/render/RenderListLiveRequest.d.ts +0 -15
- package/dist/usecase/dto/render/RenderListLiveRequest.d.ts.map +0 -1
- package/dist/usecase/dto/render/RenderListLiveRequest.js +0 -2
- package/dist/usecase/dto/render/RenderListLiveRequest.js.map +0 -1
- package/dist/usecase/dto/render/index.d.ts +0 -7
- package/dist/usecase/dto/render/index.d.ts.map +0 -1
- package/dist/usecase/dto/render/index.js +0 -7
- package/dist/usecase/dto/render/index.js.map +0 -1
- package/dist/usecase/render/ComposeEntrySeoMetaUseCase.d.ts +0 -28
- package/dist/usecase/render/ComposeEntrySeoMetaUseCase.d.ts.map +0 -1
- package/dist/usecase/render/ComposeEntrySeoMetaUseCase.js +0 -66
- package/dist/usecase/render/ComposeEntrySeoMetaUseCase.js.map +0 -1
- package/dist/usecase/render/ComposeLlmsTxtUseCase.d.ts +0 -18
- package/dist/usecase/render/ComposeLlmsTxtUseCase.d.ts.map +0 -1
- package/dist/usecase/render/ComposeLlmsTxtUseCase.js +0 -47
- package/dist/usecase/render/ComposeLlmsTxtUseCase.js.map +0 -1
- package/dist/usecase/render/ComposeSitemapUseCase.d.ts +0 -15
- package/dist/usecase/render/ComposeSitemapUseCase.d.ts.map +0 -1
- package/dist/usecase/render/ComposeSitemapUseCase.js +0 -38
- package/dist/usecase/render/ComposeSitemapUseCase.js.map +0 -1
- package/dist/usecase/render/PreviewEntryUseCase.d.ts +0 -28
- package/dist/usecase/render/PreviewEntryUseCase.d.ts.map +0 -1
- package/dist/usecase/render/PreviewEntryUseCase.js +0 -72
- package/dist/usecase/render/PreviewEntryUseCase.js.map +0 -1
- package/dist/usecase/render/RenderEntryLiveUseCase.d.ts +0 -36
- package/dist/usecase/render/RenderEntryLiveUseCase.d.ts.map +0 -1
- package/dist/usecase/render/RenderEntryLiveUseCase.js +0 -62
- package/dist/usecase/render/RenderEntryLiveUseCase.js.map +0 -1
- package/dist/usecase/render/RenderListLiveUseCase.d.ts +0 -25
- package/dist/usecase/render/RenderListLiveUseCase.d.ts.map +0 -1
- package/dist/usecase/render/RenderListLiveUseCase.js +0 -46
- package/dist/usecase/render/RenderListLiveUseCase.js.map +0 -1
- package/dist/usecase/render/index.d.ts +0 -7
- package/dist/usecase/render/index.d.ts.map +0 -1
- package/dist/usecase/render/index.js +0 -7
- package/dist/usecase/render/index.js.map +0 -1
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { type Entry, type SiteConfig } from "@aotter/mantle-spec";
|
|
2
|
-
import type { SeoMeta } from "../model/SeoMeta.js";
|
|
3
|
-
/**
|
|
4
|
-
* Pure composer for SEO + AEO meta blocks emitted on every public
|
|
5
|
-
* entry page. Carries the conventions a consumer otherwise re-invents
|
|
6
|
-
* — canonical, hreflang siblings, the `.md` mirror alternate that
|
|
7
|
-
* lets LLM crawlers grab clean markdown, og: + twitter card, JSON-LD
|
|
8
|
-
* structured data.
|
|
9
|
-
*
|
|
10
|
-
* The composer is pure — no I/O, no DB. The caller resolves the
|
|
11
|
-
* sibling translations (for hreflang) and passes them in. See
|
|
12
|
-
* `ComposeEntrySeoMetaUseCase` for the wired version that does the
|
|
13
|
-
* sibling-read.
|
|
14
|
-
*
|
|
15
|
-
* The shape of the result lives in `domain/model/SeoMeta` so
|
|
16
|
-
* `TemplateRegistry`'s `EntryContext.seo` can reference it without
|
|
17
|
-
* pulling service code into model.
|
|
18
|
-
*/
|
|
19
|
-
export type { SeoMeta } from "../model/SeoMeta.js";
|
|
20
|
-
export interface SiblingTranslation {
|
|
21
|
-
readonly locale: string;
|
|
22
|
-
readonly publicPath: string;
|
|
23
|
-
}
|
|
24
|
-
export interface ComposeEntrySeoMetaArgs {
|
|
25
|
-
readonly entry: Entry;
|
|
26
|
-
readonly site: SiteConfig;
|
|
27
|
-
/** The current entry's public path (already includes locale prefix).
|
|
28
|
-
* Composer prepends `site.origin` to absolutize. */
|
|
29
|
-
readonly publicPath: string;
|
|
30
|
-
/** Optional sibling translations for hreflang. The current entry's
|
|
31
|
-
* locale entry is added by the composer if not already present. */
|
|
32
|
-
readonly siblings?: ReadonlyArray<SiblingTranslation>;
|
|
33
|
-
/** og:type. Defaults to `article` when the entry has a `publishedAt`
|
|
34
|
-
* (or `updatedAt`) field, `website` otherwise. */
|
|
35
|
-
readonly type?: "article" | "website";
|
|
36
|
-
/** Public-route locale for non-localized entries mounted under a locale URL. */
|
|
37
|
-
readonly locale?: string;
|
|
38
|
-
}
|
|
39
|
-
export declare function composeEntrySeoMeta(args: ComposeEntrySeoMetaArgs): SeoMeta;
|
|
40
|
-
export interface ComposePageSeoMetaArgs {
|
|
41
|
-
readonly site: SiteConfig;
|
|
42
|
-
readonly locale: string;
|
|
43
|
-
readonly publicPath: string;
|
|
44
|
-
readonly title?: string;
|
|
45
|
-
readonly description?: string | null;
|
|
46
|
-
readonly markdown: boolean;
|
|
47
|
-
readonly pathForLocale: (locale: string) => string;
|
|
48
|
-
}
|
|
49
|
-
/** SEO for public home/list pages that are not represented by one Entry. */
|
|
50
|
-
export declare function composePageSeoMeta(args: ComposePageSeoMetaArgs): SeoMeta;
|
|
51
|
-
/**
|
|
52
|
-
* Render the SEO meta block as an HTML fragment. Templates embed this
|
|
53
|
-
* verbatim inside `<head>` via `raw(renderSeoTagsHtml(seo))`.
|
|
54
|
-
*
|
|
55
|
-
* Order matters slightly for crawlers — canonical first, alternates
|
|
56
|
-
* (markdown then hreflang) before og:/twitter so the discoverability
|
|
57
|
-
* bones land before the rich-preview block.
|
|
58
|
-
*/
|
|
59
|
-
export declare function renderSeoTagsHtml(meta: SeoMeta): string;
|
|
60
|
-
//# sourceMappingURL=SeoMetaComposer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SeoMetaComposer.d.ts","sourceRoot":"","sources":["../../../src/domain/service/SeoMetaComposer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAKnD;;;;;;;;;;;;;;;GAeG;AACH,YAAY,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B;yDACqD;IACrD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;wEACoE;IACpE,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACtD;uDACmD;IACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IACtC,gFAAgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,OAAO,CAkD1E;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;CACpD;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAiDxE;AAmFD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAgDvD"}
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import { toUrlLocale } from "@aotter/mantle-spec";
|
|
2
|
-
import { absoluteUrl, appendMarkdownExt } from "./AbsoluteUrl.js";
|
|
3
|
-
import { escapeHtml as escapeAttr } from "./HtmlEscaping.js";
|
|
4
|
-
import { getEntryDescription, hasMarkdownBody } from "./MarkdownSerializer.js";
|
|
5
|
-
export function composeEntrySeoMeta(args) {
|
|
6
|
-
const { entry, site, publicPath, siblings = [], type } = args;
|
|
7
|
-
const data = entry.data;
|
|
8
|
-
const canonical = absoluteUrl(site.origin, publicPath);
|
|
9
|
-
const alternateMarkdown = hasMarkdownBody(entry) ? appendMarkdownExt(canonical) : null;
|
|
10
|
-
const title = stringField(data, "title") ?? site.title;
|
|
11
|
-
const description = getEntryDescription(entry) ?? site.description ?? null;
|
|
12
|
-
const image = stringField(data, "coverUrl") ?? stringField(data, "ogImage") ?? null;
|
|
13
|
-
const ogType = type ?? (hasArticleSignal(entry) ? "article" : "website");
|
|
14
|
-
const entryLocale = args.locale ?? entry.locale ?? site.canonicalLocale ?? "en";
|
|
15
|
-
const hreflangs = buildHreflangs({
|
|
16
|
-
site,
|
|
17
|
-
currentLocale: entryLocale,
|
|
18
|
-
currentPublicPath: publicPath,
|
|
19
|
-
siblings,
|
|
20
|
-
});
|
|
21
|
-
return {
|
|
22
|
-
canonical,
|
|
23
|
-
alternateMarkdown,
|
|
24
|
-
hreflangs,
|
|
25
|
-
description: description ?? null,
|
|
26
|
-
og: {
|
|
27
|
-
type: ogType,
|
|
28
|
-
url: canonical,
|
|
29
|
-
title,
|
|
30
|
-
siteName: site.title || site.brand,
|
|
31
|
-
description: description ?? null,
|
|
32
|
-
image,
|
|
33
|
-
locale: entryLocale,
|
|
34
|
-
},
|
|
35
|
-
twitter: {
|
|
36
|
-
card: image ? "summary_large_image" : "summary",
|
|
37
|
-
title,
|
|
38
|
-
description: description ?? null,
|
|
39
|
-
image,
|
|
40
|
-
},
|
|
41
|
-
jsonLd: buildJsonLd({
|
|
42
|
-
ogType,
|
|
43
|
-
title,
|
|
44
|
-
description,
|
|
45
|
-
canonical,
|
|
46
|
-
image,
|
|
47
|
-
data,
|
|
48
|
-
site,
|
|
49
|
-
locale: entryLocale,
|
|
50
|
-
}),
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
/** SEO for public home/list pages that are not represented by one Entry. */
|
|
54
|
-
export function composePageSeoMeta(args) {
|
|
55
|
-
const { site, locale, publicPath, pathForLocale } = args;
|
|
56
|
-
const canonical = absoluteUrl(site.origin, publicPath);
|
|
57
|
-
const title = args.title ?? site.title;
|
|
58
|
-
const description = args.description ?? site.description ?? null;
|
|
59
|
-
const hreflangs = [
|
|
60
|
-
...site.locales.map((candidate) => ({
|
|
61
|
-
locale: candidate,
|
|
62
|
-
href: absoluteUrl(site.origin, pathForLocale(candidate)),
|
|
63
|
-
})),
|
|
64
|
-
{
|
|
65
|
-
locale: "x-default",
|
|
66
|
-
href: absoluteUrl(site.origin, pathForLocale(site.canonicalLocale ?? site.locales[0] ?? locale)),
|
|
67
|
-
},
|
|
68
|
-
];
|
|
69
|
-
return {
|
|
70
|
-
canonical,
|
|
71
|
-
alternateMarkdown: args.markdown ? appendMarkdownExt(canonical) : null,
|
|
72
|
-
hreflangs,
|
|
73
|
-
description,
|
|
74
|
-
og: {
|
|
75
|
-
type: "website",
|
|
76
|
-
url: canonical,
|
|
77
|
-
title,
|
|
78
|
-
siteName: site.title || site.brand,
|
|
79
|
-
description,
|
|
80
|
-
image: null,
|
|
81
|
-
locale,
|
|
82
|
-
},
|
|
83
|
-
twitter: {
|
|
84
|
-
card: "summary",
|
|
85
|
-
title,
|
|
86
|
-
description,
|
|
87
|
-
image: null,
|
|
88
|
-
},
|
|
89
|
-
jsonLd: buildJsonLd({
|
|
90
|
-
ogType: "website",
|
|
91
|
-
title,
|
|
92
|
-
description,
|
|
93
|
-
canonical,
|
|
94
|
-
image: null,
|
|
95
|
-
data: {},
|
|
96
|
-
site,
|
|
97
|
-
locale,
|
|
98
|
-
}),
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
function buildHreflangs(args) {
|
|
102
|
-
const { site, currentLocale, currentPublicPath, siblings } = args;
|
|
103
|
-
const out = [];
|
|
104
|
-
const seen = new Set();
|
|
105
|
-
const push = (locale, path) => {
|
|
106
|
-
const key = locale.toLowerCase();
|
|
107
|
-
if (seen.has(key))
|
|
108
|
-
return;
|
|
109
|
-
seen.add(key);
|
|
110
|
-
out.push({ locale, href: absoluteUrl(site.origin, path) });
|
|
111
|
-
};
|
|
112
|
-
push(currentLocale, currentPublicPath);
|
|
113
|
-
for (const s of siblings)
|
|
114
|
-
push(s.locale, s.publicPath);
|
|
115
|
-
// x-default points at the canonical-locale variant when known,
|
|
116
|
-
// falling back to the current entry's URL otherwise. Search engines
|
|
117
|
-
// expect this row alongside the per-locale ones.
|
|
118
|
-
const canonicalSibling = siblings.find((s) => site.canonicalLocale && s.locale.toLowerCase() === site.canonicalLocale.toLowerCase());
|
|
119
|
-
out.push({
|
|
120
|
-
locale: "x-default",
|
|
121
|
-
href: absoluteUrl(site.origin, canonicalSibling?.publicPath ?? currentPublicPath),
|
|
122
|
-
});
|
|
123
|
-
return out;
|
|
124
|
-
}
|
|
125
|
-
function buildJsonLd(args) {
|
|
126
|
-
const { ogType, title, description, canonical, image, data, site, locale } = args;
|
|
127
|
-
const publishedAtMs = numericField(data, "publishedAt");
|
|
128
|
-
const updatedAtMs = numericField(data, "updatedAt");
|
|
129
|
-
const base = {
|
|
130
|
-
"@context": "https://schema.org",
|
|
131
|
-
"@type": ogType === "article" ? "Article" : "WebPage",
|
|
132
|
-
headline: title,
|
|
133
|
-
name: title,
|
|
134
|
-
url: canonical,
|
|
135
|
-
description: description ?? undefined,
|
|
136
|
-
image: image ?? undefined,
|
|
137
|
-
inLanguage: locale,
|
|
138
|
-
publisher: site.title || site.brand
|
|
139
|
-
? {
|
|
140
|
-
"@type": "Organization",
|
|
141
|
-
name: site.title || site.brand,
|
|
142
|
-
}
|
|
143
|
-
: undefined,
|
|
144
|
-
datePublished: publishedAtMs ? new Date(publishedAtMs).toISOString() : undefined,
|
|
145
|
-
dateModified: updatedAtMs ? new Date(updatedAtMs).toISOString() : undefined,
|
|
146
|
-
};
|
|
147
|
-
// Drop undefined keys so JSON.stringify produces a clean object.
|
|
148
|
-
return Object.fromEntries(Object.entries(base).filter(([, v]) => v !== undefined));
|
|
149
|
-
}
|
|
150
|
-
function stringField(data, key) {
|
|
151
|
-
const v = data[key];
|
|
152
|
-
return typeof v === "string" && v.length > 0 ? v : null;
|
|
153
|
-
}
|
|
154
|
-
function numericField(data, key) {
|
|
155
|
-
const v = data[key];
|
|
156
|
-
return typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
157
|
-
}
|
|
158
|
-
function hasArticleSignal(entry) {
|
|
159
|
-
return typeof entry.data["publishedAt"] === "number" || hasMarkdownBody(entry);
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Render the SEO meta block as an HTML fragment. Templates embed this
|
|
163
|
-
* verbatim inside `<head>` via `raw(renderSeoTagsHtml(seo))`.
|
|
164
|
-
*
|
|
165
|
-
* Order matters slightly for crawlers — canonical first, alternates
|
|
166
|
-
* (markdown then hreflang) before og:/twitter so the discoverability
|
|
167
|
-
* bones land before the rich-preview block.
|
|
168
|
-
*/
|
|
169
|
-
export function renderSeoTagsHtml(meta) {
|
|
170
|
-
const parts = [];
|
|
171
|
-
parts.push(`<link rel="canonical" href="${escapeAttr(meta.canonical)}">`);
|
|
172
|
-
if (meta.alternateMarkdown) {
|
|
173
|
-
parts.push(`<link rel="alternate" type="text/markdown" href="${escapeAttr(meta.alternateMarkdown)}">`);
|
|
174
|
-
}
|
|
175
|
-
for (const h of meta.hreflangs) {
|
|
176
|
-
parts.push(`<link rel="alternate" hreflang="${escapeAttr(h.locale)}" href="${escapeAttr(h.href)}">`);
|
|
177
|
-
}
|
|
178
|
-
if (meta.description) {
|
|
179
|
-
parts.push(`<meta name="description" content="${escapeAttr(meta.description)}">`);
|
|
180
|
-
}
|
|
181
|
-
parts.push(`<meta name="generator" content="mantle">`);
|
|
182
|
-
parts.push(`<meta property="og:type" content="${escapeAttr(meta.og.type)}">`);
|
|
183
|
-
parts.push(`<meta property="og:url" content="${escapeAttr(meta.og.url)}">`);
|
|
184
|
-
parts.push(`<meta property="og:title" content="${escapeAttr(meta.og.title)}">`);
|
|
185
|
-
if (meta.og.siteName) {
|
|
186
|
-
parts.push(`<meta property="og:site_name" content="${escapeAttr(meta.og.siteName)}">`);
|
|
187
|
-
}
|
|
188
|
-
if (meta.og.description) {
|
|
189
|
-
parts.push(`<meta property="og:description" content="${escapeAttr(meta.og.description)}">`);
|
|
190
|
-
}
|
|
191
|
-
if (meta.og.image) {
|
|
192
|
-
parts.push(`<meta property="og:image" content="${escapeAttr(meta.og.image)}">`);
|
|
193
|
-
}
|
|
194
|
-
parts.push(`<meta property="og:locale" content="${escapeAttr(toUrlLocale(meta.og.locale))}">`);
|
|
195
|
-
parts.push(`<meta name="twitter:card" content="${escapeAttr(meta.twitter.card)}">`);
|
|
196
|
-
parts.push(`<meta name="twitter:title" content="${escapeAttr(meta.twitter.title)}">`);
|
|
197
|
-
if (meta.twitter.description) {
|
|
198
|
-
parts.push(`<meta name="twitter:description" content="${escapeAttr(meta.twitter.description)}">`);
|
|
199
|
-
}
|
|
200
|
-
if (meta.twitter.image) {
|
|
201
|
-
parts.push(`<meta name="twitter:image" content="${escapeAttr(meta.twitter.image)}">`);
|
|
202
|
-
}
|
|
203
|
-
if (meta.jsonLd) {
|
|
204
|
-
parts.push(`<script type="application/ld+json">${escapeJsonLd(meta.jsonLd)}</script>`);
|
|
205
|
-
}
|
|
206
|
-
return parts.join("\n");
|
|
207
|
-
}
|
|
208
|
-
function escapeJsonLd(obj) {
|
|
209
|
-
// `</script>` inside JSON-LD is the only nested-script pitfall;
|
|
210
|
-
// escaping the closing `</` keeps the embedded JSON strict-parseable.
|
|
211
|
-
return JSON.stringify(obj).replace(/<\//g, "<\\/");
|
|
212
|
-
}
|
|
213
|
-
//# sourceMappingURL=SeoMetaComposer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SeoMetaComposer.js","sourceRoot":"","sources":["../../../src/domain/service/SeoMetaComposer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { Entry, SiteConfig } from "@aotter/mantle-spec";
|
|
2
|
-
/**
|
|
3
|
-
* Hreflang alternates are deferred to v0.1.x (need cross-locale entry
|
|
4
|
-
* pairing first); only minimal `loc + lastmod` shipped.
|
|
5
|
-
*
|
|
6
|
-
* Entries arrive pre-mapped from storage row to public path — the
|
|
7
|
-
* caller (`ComposeSitemapUseCase`) decides how a (collection, slug,
|
|
8
|
-
* locale) row surfaces under the consumer's routing.
|
|
9
|
-
*/
|
|
10
|
-
export interface SitemapEntry {
|
|
11
|
-
readonly entry?: Entry;
|
|
12
|
-
readonly path: string;
|
|
13
|
-
}
|
|
14
|
-
export interface SitemapInput {
|
|
15
|
-
readonly site: SiteConfig;
|
|
16
|
-
readonly entries: readonly SitemapEntry[];
|
|
17
|
-
}
|
|
18
|
-
export declare function serializeSitemap(input: SitemapInput): string;
|
|
19
|
-
//# sourceMappingURL=SitemapSerializer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SitemapSerializer.d.ts","sourceRoot":"","sources":["../../../src/domain/service/SitemapSerializer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAG7D;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;CAC3C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAgB5D"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { absoluteUrl } from "./AbsoluteUrl.js";
|
|
2
|
-
export function serializeSitemap(input) {
|
|
3
|
-
const { site, entries } = input;
|
|
4
|
-
const out = [];
|
|
5
|
-
out.push(`<?xml version="1.0" encoding="UTF-8"?>`);
|
|
6
|
-
out.push(`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">`);
|
|
7
|
-
for (const { entry, path } of entries) {
|
|
8
|
-
const loc = absoluteUrl(site.origin ?? "", path);
|
|
9
|
-
out.push(" <url>");
|
|
10
|
-
out.push(` <loc>${escapeXml(loc)}</loc>`);
|
|
11
|
-
if (entry?.updatedAt) {
|
|
12
|
-
out.push(` <lastmod>${new Date(entry.updatedAt).toISOString()}</lastmod>`);
|
|
13
|
-
}
|
|
14
|
-
out.push(" </url>");
|
|
15
|
-
}
|
|
16
|
-
out.push("</urlset>");
|
|
17
|
-
return out.join("\n") + "\n";
|
|
18
|
-
}
|
|
19
|
-
function escapeXml(s) {
|
|
20
|
-
return s
|
|
21
|
-
.replace(/&/g, "&")
|
|
22
|
-
.replace(/</g, "<")
|
|
23
|
-
.replace(/>/g, ">")
|
|
24
|
-
.replace(/"/g, """)
|
|
25
|
-
.replace(/'/g, "'");
|
|
26
|
-
}
|
|
27
|
-
//# sourceMappingURL=SitemapSerializer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SitemapSerializer.js","sourceRoot":"","sources":["../../../src/domain/service/SitemapSerializer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAoB/C,MAAM,UAAU,gBAAgB,CAAC,KAAmB;IAClD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAChC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,GAAG,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IACnD,GAAG,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;IACzE,KAAK,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;QACjD,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpB,GAAG,CAAC,IAAI,CAAC,YAAY,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,KAAK,EAAE,SAAS,EAAE,CAAC;YACrB,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAChF,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvB,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACtB,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAC/B,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,CAAC;SACL,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ViewSqlCompiler.d.ts","sourceRoot":"","sources":["../../../src/domain/service/ViewSqlCompiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAG7B;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;IAChF,wEAAwE;IACxE,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtF;AAoCD,wBAAgB,WAAW,CACzB,IAAI,EAAE,YAAY,EAClB,OAAO,GAAE,kBAAuB,EAChC,MAAM,CAAC,EAAE,cAAc,GACtB,YAAY,CA8Cd"}
|
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
import { DiagnosticError, isCtxUserRef, isParamRef, runtimeDiagnostic, schemaIndexedFieldSql, } from "@aotter/mantle-spec";
|
|
2
|
-
import { clampPage, clampShow } from "./Pagination.js";
|
|
3
|
-
// alias → SQL column. Aliases mirror RESERVED_ENTRY_COLUMNS from
|
|
4
|
-
// spec; SQL column shape (snake_case) is local to the storage layout.
|
|
5
|
-
// The compile-time check below ensures the alias set stays in sync —
|
|
6
|
-
// adding to spec without updating here is a type error.
|
|
7
|
-
const RESERVED_COLUMN = {
|
|
8
|
-
id: "id",
|
|
9
|
-
status: "status",
|
|
10
|
-
version: "version",
|
|
11
|
-
createdAt: "created_at",
|
|
12
|
-
updatedAt: "updated_at",
|
|
13
|
-
authorId: "author_id",
|
|
14
|
-
};
|
|
15
|
-
const _aliasCheck = RESERVED_COLUMN;
|
|
16
|
-
void _aliasCheck;
|
|
17
|
-
const DEFAULT_PROJECTION = Object.entries(RESERVED_COLUMN)
|
|
18
|
-
.map(([alias, col]) => (alias === col ? col : `${col} AS ${alias}`))
|
|
19
|
-
.join(", ");
|
|
20
|
-
const SQL_COMPARISON_OP = {
|
|
21
|
-
eq: "=",
|
|
22
|
-
gt: ">",
|
|
23
|
-
gte: ">=",
|
|
24
|
-
lt: "<",
|
|
25
|
-
lte: "<=",
|
|
26
|
-
};
|
|
27
|
-
export function compileView(view, options = {}, schema) {
|
|
28
|
-
if (view.spec.sql)
|
|
29
|
-
return compileSqlView(view, options);
|
|
30
|
-
const from = view.spec.from;
|
|
31
|
-
if (!from) {
|
|
32
|
-
throw new Error(`View '${view.metadata.name}' requires either spec.from or spec.sql.`);
|
|
33
|
-
}
|
|
34
|
-
if (schema && schema.metadata.name !== view.spec.from) {
|
|
35
|
-
throw new DiagnosticError(runtimeDiagnostic({
|
|
36
|
-
code: "INTERNAL_ERROR",
|
|
37
|
-
severity: "error",
|
|
38
|
-
path: "compileView/schema",
|
|
39
|
-
value: schema.metadata.name,
|
|
40
|
-
expected: `Schema '${view.spec.from}' referenced by View.spec.from`,
|
|
41
|
-
message: `View '${view.metadata.name}' cannot compile against Schema '${schema.metadata.name}'.`,
|
|
42
|
-
}));
|
|
43
|
-
}
|
|
44
|
-
const sqlParams = [from];
|
|
45
|
-
const selectExpr = buildSelect(view.spec.fields, schema);
|
|
46
|
-
const whereParts = ["collection = ?"];
|
|
47
|
-
if (view.spec.filter) {
|
|
48
|
-
const compiled = compileFilter(view.spec.filter, options.params ?? {}, options.ctxUserId, schema);
|
|
49
|
-
whereParts.push(`(${compiled.sql})`);
|
|
50
|
-
sqlParams.push(...compiled.params);
|
|
51
|
-
}
|
|
52
|
-
const listQuery = compileListQuery(options, (field) => fieldRefExpr(field, schema));
|
|
53
|
-
whereParts.push(...listQuery.conditions);
|
|
54
|
-
sqlParams.push(...listQuery.params);
|
|
55
|
-
const where = `WHERE ${whereParts.join(" AND ")}`;
|
|
56
|
-
const orderBy = buildOrderBy(view.spec.orderBy, schema);
|
|
57
|
-
const effectiveShow = clampShow(options.show, view.spec.limit);
|
|
58
|
-
const effectivePage = clampPage(options.page);
|
|
59
|
-
// Cap the offset so a huge `?page=` can't render in exponential
|
|
60
|
-
// notation (`5e+21`) or exceed SQLite's INT64 range — either makes
|
|
61
|
-
// D1 reject the literal and surfaces as a 500 instead of an empty
|
|
62
|
-
// page. MAX_SAFE_INTEGER (~9e15) stringifies as plain digits and is
|
|
63
|
-
// well under INT64 max; any page past the data just returns no rows.
|
|
64
|
-
const offset = Math.min((effectivePage - 1) * effectiveShow, Number.MAX_SAFE_INTEGER);
|
|
65
|
-
const sql = `SELECT ${selectExpr} FROM entries ${where}${orderBy} LIMIT ${effectiveShow} OFFSET ${offset}`;
|
|
66
|
-
return { sql, params: sqlParams, effectivePage, effectiveShow };
|
|
67
|
-
}
|
|
68
|
-
function compileSqlView(view, options) {
|
|
69
|
-
const params = [];
|
|
70
|
-
// ponytail: token regex is enough for agent-authored SQL; add a lexer if
|
|
71
|
-
// quoted SQL literals containing `:name` become a real manifest use case.
|
|
72
|
-
const statement = view.spec.sql.trim().replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, (_token, name) => {
|
|
73
|
-
const value = options.params?.[name];
|
|
74
|
-
if (value === undefined)
|
|
75
|
-
throw new Error(`View SQL requires param '${name}'.`);
|
|
76
|
-
params.push(value);
|
|
77
|
-
return "?";
|
|
78
|
-
});
|
|
79
|
-
const effectiveShow = clampShow(options.show, view.spec.limit);
|
|
80
|
-
const effectivePage = clampPage(options.page);
|
|
81
|
-
const offset = Math.min((effectivePage - 1) * effectiveShow, Number.MAX_SAFE_INTEGER);
|
|
82
|
-
const listQuery = compileListQuery(options, (field) => `"_mantle_view".${quoteIdent(field)}`);
|
|
83
|
-
const where = listQuery.conditions.length > 0
|
|
84
|
-
? ` WHERE ${listQuery.conditions.join(" AND ")}`
|
|
85
|
-
: "";
|
|
86
|
-
return {
|
|
87
|
-
sql: `SELECT * FROM (${statement}) AS "_mantle_view"${where} LIMIT ${effectiveShow} OFFSET ${offset}`,
|
|
88
|
-
params: [...params, ...listQuery.params],
|
|
89
|
-
effectivePage,
|
|
90
|
-
effectiveShow,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
function compileListQuery(options, fieldRef) {
|
|
94
|
-
const conditions = [];
|
|
95
|
-
const params = [];
|
|
96
|
-
const term = options.search?.term.trim();
|
|
97
|
-
if (term && options.search?.fields.length) {
|
|
98
|
-
const escaped = escapeLikeTerm(term);
|
|
99
|
-
conditions.push(`(${options.search.fields
|
|
100
|
-
.map((field) => `${fieldRef(field)} LIKE '%'||?||'%' ESCAPE '\\'`)
|
|
101
|
-
.join(" OR ")})`);
|
|
102
|
-
params.push(...options.search.fields.map(() => escaped));
|
|
103
|
-
}
|
|
104
|
-
for (const filter of options.filters ?? []) {
|
|
105
|
-
conditions.push(`CAST(${fieldRef(filter.field)} AS TEXT) = ?`);
|
|
106
|
-
params.push(filter.value);
|
|
107
|
-
}
|
|
108
|
-
return { conditions, params };
|
|
109
|
-
}
|
|
110
|
-
function escapeLikeTerm(term) {
|
|
111
|
-
return term.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
112
|
-
}
|
|
113
|
-
function buildSelect(fields, schema) {
|
|
114
|
-
if (!fields || fields.length === 0)
|
|
115
|
-
return DEFAULT_PROJECTION;
|
|
116
|
-
return fields.map((field) => fieldExpr(field, schema)).join(", ");
|
|
117
|
-
}
|
|
118
|
-
function fieldExpr(field, schema) {
|
|
119
|
-
const reserved = RESERVED_COLUMN[field];
|
|
120
|
-
const expression = fieldRefExpr(field, schema);
|
|
121
|
-
if (reserved === field)
|
|
122
|
-
return expression;
|
|
123
|
-
return `${expression} AS ${reserved ? field : quoteIdent(field)}`;
|
|
124
|
-
}
|
|
125
|
-
function fieldRefExpr(field, schema) {
|
|
126
|
-
const reserved = RESERVED_COLUMN[field];
|
|
127
|
-
if (reserved)
|
|
128
|
-
return reserved;
|
|
129
|
-
const indexed = schema ? schemaIndexedFieldSql(schema, field) : null;
|
|
130
|
-
if (indexed)
|
|
131
|
-
return indexed;
|
|
132
|
-
return `json_extract(data, ${quotedJsonPath(field)})`;
|
|
133
|
-
}
|
|
134
|
-
function compileFilter(node, paramValues, ctxUserId, schema) {
|
|
135
|
-
const comparison = getFilterComparison(node);
|
|
136
|
-
if (comparison) {
|
|
137
|
-
const value = comparison.node.value;
|
|
138
|
-
let bound;
|
|
139
|
-
if (isCtxUserRef(value)) {
|
|
140
|
-
if (!ctxUserId) {
|
|
141
|
-
throw new DiagnosticError(runtimeDiagnostic({
|
|
142
|
-
code: "UNAUTHENTICATED",
|
|
143
|
-
severity: "error",
|
|
144
|
-
path: "compileView/filter",
|
|
145
|
-
expected: "ctx.user.id for an identity-bound View filter",
|
|
146
|
-
message: "View filter requires ctx.user.id.",
|
|
147
|
-
}));
|
|
148
|
-
}
|
|
149
|
-
bound = ctxUserId;
|
|
150
|
-
}
|
|
151
|
-
else if (isParamRef(value)) {
|
|
152
|
-
const resolved = paramValues[value.$param];
|
|
153
|
-
if (resolved === undefined) {
|
|
154
|
-
throw new Error(`View filter requires param '${value.$param}'.`);
|
|
155
|
-
}
|
|
156
|
-
bound = resolved;
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
bound = value;
|
|
160
|
-
}
|
|
161
|
-
return {
|
|
162
|
-
sql: `${fieldRefExpr(comparison.node.field, schema)} ${SQL_COMPARISON_OP[comparison.op]} ?`,
|
|
163
|
-
params: [bound],
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
const op = "and" in node ? "AND" : "OR";
|
|
167
|
-
const children = "and" in node ? node.and : "or" in node ? node.or : [];
|
|
168
|
-
const compiled = children
|
|
169
|
-
.map((c) => compileFilter(c, paramValues, ctxUserId, schema));
|
|
170
|
-
return {
|
|
171
|
-
sql: compiled.map((c) => `(${c.sql})`).join(` ${op} `),
|
|
172
|
-
params: compiled.flatMap((c) => c.params),
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
function getFilterComparison(node) {
|
|
176
|
-
if ("eq" in node)
|
|
177
|
-
return { op: "eq", node: node.eq };
|
|
178
|
-
if ("gt" in node)
|
|
179
|
-
return { op: "gt", node: node.gt };
|
|
180
|
-
if ("gte" in node)
|
|
181
|
-
return { op: "gte", node: node.gte };
|
|
182
|
-
if ("lt" in node)
|
|
183
|
-
return { op: "lt", node: node.lt };
|
|
184
|
-
if ("lte" in node)
|
|
185
|
-
return { op: "lte", node: node.lte };
|
|
186
|
-
return null;
|
|
187
|
-
}
|
|
188
|
-
function buildOrderBy(orderBy, schema) {
|
|
189
|
-
if (!orderBy || orderBy.length === 0)
|
|
190
|
-
return "";
|
|
191
|
-
const parts = orderBy.map((o) => {
|
|
192
|
-
// Closed-set map, never interpolate the raw value: `direction` is
|
|
193
|
-
// only a compile-time "asc"|"desc" type, but manifests are parsed
|
|
194
|
-
// from YAML, so an out-of-enum string (e.g. `DESC LIMIT 0 --`)
|
|
195
|
-
// could otherwise reach the SQL string verbatim.
|
|
196
|
-
const dir = o.direction === "desc" ? "DESC" : "ASC";
|
|
197
|
-
return `${fieldRefExpr(o.field, schema)} ${dir}`;
|
|
198
|
-
});
|
|
199
|
-
return ` ORDER BY ${parts.join(", ")}`;
|
|
200
|
-
}
|
|
201
|
-
// Schema JSON property keys can be arbitrary strings per RFC 8259,
|
|
202
|
-
// but SQLite's JSON1 path syntax (`$."key"`) has no documented way
|
|
203
|
-
// to escape an inner `"` or `\` inside a quoted key — doubled-quote
|
|
204
|
-
// escaping is the SQLite identifier convention, NOT a JSON-path
|
|
205
|
-
// convention. So we always quote the path/alias (admitting hyphens,
|
|
206
|
-
// spaces, etc.) but refuse `"`, `\`, and `\0` in field names —
|
|
207
|
-
// those break either the JSON-path resolution or the SQL string
|
|
208
|
-
// literal. Real Schema authors don't use those characters in keys;
|
|
209
|
-
// rejecting them keeps the path always-resolvable.
|
|
210
|
-
const FORBIDDEN_FIELD_CHARS = /["\\\0]/;
|
|
211
|
-
function assertFieldNameSafe(name, callsite) {
|
|
212
|
-
if (!FORBIDDEN_FIELD_CHARS.test(name))
|
|
213
|
-
return;
|
|
214
|
-
throw new DiagnosticError(runtimeDiagnostic({
|
|
215
|
-
code: "INTERNAL_ERROR",
|
|
216
|
-
severity: "error",
|
|
217
|
-
path: `compileView/${callsite}`,
|
|
218
|
-
value: name,
|
|
219
|
-
expected: 'field name without `"`, `\\`, or NUL',
|
|
220
|
-
message: `field name '${name}' contains an unrepresentable character (\", \\, or NUL); Schema validation should have caught this.`,
|
|
221
|
-
}));
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Emit `'$."<field>"'` — a SQL string literal containing a SQLite
|
|
225
|
-
* JSON path. Doubles single quotes for the surrounding SQL literal
|
|
226
|
-
* (SQLite literal escape). Field name itself is guaranteed free of
|
|
227
|
-
* `"` / `\` / NUL by `assertFieldNameSafe`, so the inner double-
|
|
228
|
-
* quoted key needs no further escape.
|
|
229
|
-
*/
|
|
230
|
-
function quotedJsonPath(field) {
|
|
231
|
-
assertFieldNameSafe(field, "quotedJsonPath");
|
|
232
|
-
// Only `'` needs escaping for the surrounding SQL literal; field
|
|
233
|
-
// is guaranteed free of `"` / `\` / NUL.
|
|
234
|
-
return `'$."${field.replace(/'/g, "''")}"'`;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* SQLite quoted-identifier alias (`"hero-image"`). Used as the result
|
|
238
|
-
* column name so callers read the field back under its declared key.
|
|
239
|
-
*/
|
|
240
|
-
function quoteIdent(name) {
|
|
241
|
-
assertFieldNameSafe(name, "quoteIdent");
|
|
242
|
-
return `"${name}"`;
|
|
243
|
-
}
|
|
244
|
-
//# sourceMappingURL=ViewSqlCompiler.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ViewSqlCompiler.js","sourceRoot":"","sources":["../../../src/domain/service/ViewSqlCompiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { Entry } from "@aotter/mantle-spec";
|
|
2
|
-
import type { MediaAssetRepository } from "../../port/MediaAssetRepository.js";
|
|
3
|
-
import type { MediaAsset } from "../../port/MediaStorage.js";
|
|
4
|
-
/**
|
|
5
|
-
* Extract media asset references from entry data by convention.
|
|
6
|
-
* Starters use `coverAssetId`, `imageAssetId`, nested `{ assetId }`, etc.
|
|
7
|
-
* The schema-level source of truth remains `x-mantle-ref: media_assets`;
|
|
8
|
-
* this convention keeps the render path schema-agnostic until the
|
|
9
|
-
* manifest compiler exposes field metadata at runtime.
|
|
10
|
-
*/
|
|
11
|
-
export declare function collectMediaAssetIds(value: unknown): readonly string[];
|
|
12
|
-
export declare function resolveMediaAssetsForEntries(repo: MediaAssetRepository | null, entries: readonly Entry[]): Promise<ReadonlyMap<string, MediaAsset> | undefined>;
|
|
13
|
-
//# sourceMappingURL=MediaAssetReferences.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MediaAssetReferences.d.ts","sourceRoot":"","sources":["../../../../src/domain/service/io/MediaAssetReferences.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE7D;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAItE;AAED,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,oBAAoB,GAAG,IAAI,EACjC,OAAO,EAAE,SAAS,KAAK,EAAE,GACxB,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,SAAS,CAAC,CAKtD"}
|