@aotter/mantle-runtime 0.1.0-alpha.1 → 0.1.0-alpha.3
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/dist/domain/model/SeoMeta.d.ts +1 -1
- package/dist/domain/model/SeoMeta.d.ts.map +1 -1
- package/dist/domain/model/TemplateRegistry.d.ts +3 -4
- package/dist/domain/model/TemplateRegistry.d.ts.map +1 -1
- package/dist/domain/model/TemplateRegistry.js.map +1 -1
- package/dist/domain/port/AssetServer.d.ts +1 -1
- package/dist/domain/port/DatabaseDriver.d.ts +1 -1
- package/dist/domain/port/EntryReader.d.ts +1 -1
- package/dist/domain/port/EntryReader.d.ts.map +1 -1
- package/dist/domain/port/EntryRepository.d.ts +19 -4
- package/dist/domain/port/EntryRepository.d.ts.map +1 -1
- package/dist/domain/port/IdGenerator.d.ts +2 -2
- package/dist/domain/port/SiteConfigRepository.d.ts +2 -2
- package/dist/domain/service/HtmlRenderer.d.ts +2 -0
- package/dist/domain/service/HtmlRenderer.d.ts.map +1 -1
- package/dist/domain/service/HtmlRenderer.js +2 -2
- package/dist/domain/service/HtmlRenderer.js.map +1 -1
- package/dist/domain/service/MarkdownSerializer.d.ts +6 -9
- package/dist/domain/service/MarkdownSerializer.d.ts.map +1 -1
- package/dist/domain/service/MarkdownSerializer.js +77 -32
- package/dist/domain/service/MarkdownSerializer.js.map +1 -1
- package/dist/domain/service/SeoMetaComposer.d.ts +13 -0
- package/dist/domain/service/SeoMetaComposer.d.ts.map +1 -1
- package/dist/domain/service/SeoMetaComposer.js +58 -9
- package/dist/domain/service/SeoMetaComposer.js.map +1 -1
- package/dist/domain/service/SitemapSerializer.d.ts +1 -1
- package/dist/domain/service/SitemapSerializer.d.ts.map +1 -1
- package/dist/domain/service/SitemapSerializer.js +1 -1
- package/dist/domain/service/SitemapSerializer.js.map +1 -1
- package/dist/domain/service/TriggerIndex.d.ts +2 -3
- package/dist/domain/service/TriggerIndex.d.ts.map +1 -1
- package/dist/domain/service/TriggerIndex.js +2 -3
- package/dist/domain/service/TriggerIndex.js.map +1 -1
- package/dist/domain/service/ViewParamCoercer.d.ts +1 -1
- package/dist/domain/service/ViewParamCoercer.js +1 -1
- package/dist/domain/service/ViewSqlCompiler.d.ts.map +1 -1
- package/dist/domain/service/ViewSqlCompiler.js +15 -23
- package/dist/domain/service/ViewSqlCompiler.js.map +1 -1
- package/dist/domain/service/io/EntryDeleteGuard.js +1 -1
- package/dist/domain/service/io/EntryDeleteGuard.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/boot/canonicalMigrations.d.ts.map +1 -1
- package/dist/infrastructure/boot/canonicalMigrations.js +1 -26
- package/dist/infrastructure/boot/canonicalMigrations.js.map +1 -1
- package/dist/infrastructure/mcp/McpJsonRpcDispatcher.d.ts +5 -21
- package/dist/infrastructure/mcp/McpJsonRpcDispatcher.d.ts.map +1 -1
- package/dist/infrastructure/mcp/McpJsonRpcDispatcher.js +24 -31
- 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 +13 -9
- package/dist/infrastructure/mcp/McpToolCatalog.js.map +1 -1
- package/dist/infrastructure/mcp/index.d.ts +1 -1
- package/dist/infrastructure/mcp/index.d.ts.map +1 -1
- package/dist/infrastructure/mcp/index.js.map +1 -1
- package/dist/infrastructure/persistence/DatabaseEntryRepository.d.ts +3 -7
- package/dist/infrastructure/persistence/DatabaseEntryRepository.d.ts.map +1 -1
- package/dist/infrastructure/persistence/DatabaseEntryRepository.js +74 -35
- package/dist/infrastructure/persistence/DatabaseEntryRepository.js.map +1 -1
- package/dist/infrastructure/persistence/DatabaseSiteConfigRepository.d.ts.map +1 -1
- package/dist/infrastructure/persistence/DatabaseSiteConfigRepository.js +20 -26
- package/dist/infrastructure/persistence/DatabaseSiteConfigRepository.js.map +1 -1
- package/dist/infrastructure/persistence/Pagination.d.ts +3 -0
- package/dist/infrastructure/persistence/Pagination.d.ts.map +1 -1
- package/dist/infrastructure/persistence/Pagination.js +28 -0
- package/dist/infrastructure/persistence/Pagination.js.map +1 -1
- package/dist/runtime.d.ts +4 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +38 -3
- package/dist/runtime.js.map +1 -1
- package/dist/usecase/boot/ValidateBootUseCase.d.ts +5 -1
- package/dist/usecase/boot/ValidateBootUseCase.d.ts.map +1 -1
- package/dist/usecase/boot/ValidateBootUseCase.js +31 -11
- package/dist/usecase/boot/ValidateBootUseCase.js.map +1 -1
- package/dist/usecase/content/ArchiveUseCase.d.ts +1 -1
- package/dist/usecase/content/ArchiveUseCase.js +1 -1
- package/dist/usecase/content/CreateDraftUseCase.d.ts +1 -1
- package/dist/usecase/content/CreateDraftUseCase.js +5 -5
- package/dist/usecase/content/CreateDraftUseCase.js.map +1 -1
- package/dist/usecase/content/DeleteEntryUseCase.d.ts +3 -5
- package/dist/usecase/content/DeleteEntryUseCase.d.ts.map +1 -1
- package/dist/usecase/content/DeleteEntryUseCase.js +3 -5
- package/dist/usecase/content/DeleteEntryUseCase.js.map +1 -1
- package/dist/usecase/content/ListEntriesUseCase.d.ts.map +1 -1
- package/dist/usecase/content/ListEntriesUseCase.js +30 -3
- package/dist/usecase/content/ListEntriesUseCase.js.map +1 -1
- package/dist/usecase/content/RequestPublishUseCase.d.ts +2 -10
- package/dist/usecase/content/RequestPublishUseCase.d.ts.map +1 -1
- package/dist/usecase/content/RequestPublishUseCase.js +3 -21
- package/dist/usecase/content/RequestPublishUseCase.js.map +1 -1
- package/dist/usecase/content/UpdateDraftUseCase.js +4 -4
- package/dist/usecase/content/UpdateDraftUseCase.js.map +1 -1
- package/dist/usecase/content/diagnostics.d.ts +1 -0
- package/dist/usecase/content/diagnostics.d.ts.map +1 -1
- package/dist/usecase/content/diagnostics.js +10 -0
- package/dist/usecase/content/diagnostics.js.map +1 -1
- package/dist/usecase/dto/content/index.d.ts +10 -1
- package/dist/usecase/dto/content/index.d.ts.map +1 -1
- package/dist/usecase/dto/render/ComposeEntrySeoMetaRequest.d.ts +4 -0
- package/dist/usecase/dto/render/ComposeEntrySeoMetaRequest.d.ts.map +1 -1
- package/dist/usecase/dto/render/ComposeLlmsTxtRequest.d.ts +6 -1
- package/dist/usecase/dto/render/ComposeLlmsTxtRequest.d.ts.map +1 -1
- package/dist/usecase/dto/render/ComposeSitemapRequest.d.ts +4 -2
- package/dist/usecase/dto/render/ComposeSitemapRequest.d.ts.map +1 -1
- package/dist/usecase/dto/render/PreviewEntryRequest.d.ts +5 -0
- package/dist/usecase/dto/render/PreviewEntryRequest.d.ts.map +1 -1
- package/dist/usecase/dto/render/RenderEntryLiveRequest.d.ts +5 -0
- package/dist/usecase/dto/render/RenderEntryLiveRequest.d.ts.map +1 -1
- package/dist/usecase/dto/render/RenderListLiveRequest.d.ts +4 -0
- package/dist/usecase/dto/render/RenderListLiveRequest.d.ts.map +1 -1
- package/dist/usecase/procedure/InvokeBuiltinUseCase.d.ts +1 -1
- package/dist/usecase/procedure/InvokeBuiltinUseCase.js +2 -2
- package/dist/usecase/procedure/InvokeBuiltinUseCase.js.map +1 -1
- package/dist/usecase/render/ComposeEntrySeoMetaUseCase.d.ts +1 -1
- package/dist/usecase/render/ComposeEntrySeoMetaUseCase.d.ts.map +1 -1
- package/dist/usecase/render/ComposeEntrySeoMetaUseCase.js +13 -6
- package/dist/usecase/render/ComposeEntrySeoMetaUseCase.js.map +1 -1
- package/dist/usecase/render/ComposeLlmsTxtUseCase.d.ts +4 -2
- package/dist/usecase/render/ComposeLlmsTxtUseCase.d.ts.map +1 -1
- package/dist/usecase/render/ComposeLlmsTxtUseCase.js +13 -2
- package/dist/usecase/render/ComposeLlmsTxtUseCase.js.map +1 -1
- package/dist/usecase/render/ComposeSitemapUseCase.d.ts.map +1 -1
- package/dist/usecase/render/ComposeSitemapUseCase.js +13 -3
- package/dist/usecase/render/ComposeSitemapUseCase.js.map +1 -1
- package/dist/usecase/render/PreviewEntryUseCase.js +2 -2
- package/dist/usecase/render/PreviewEntryUseCase.js.map +1 -1
- package/dist/usecase/render/RenderEntryLiveUseCase.js +2 -2
- package/dist/usecase/render/RenderEntryLiveUseCase.js.map +1 -1
- package/dist/usecase/render/RenderListLiveUseCase.d.ts.map +1 -1
- package/dist/usecase/render/RenderListLiveUseCase.js +2 -1
- package/dist/usecase/render/RenderListLiveUseCase.js.map +1 -1
- package/dist/usecase/site/UpdateSiteSettingsUseCase.d.ts +3 -2
- package/dist/usecase/site/UpdateSiteSettingsUseCase.d.ts.map +1 -1
- package/dist/usecase/site/UpdateSiteSettingsUseCase.js +28 -2
- package/dist/usecase/site/UpdateSiteSettingsUseCase.js.map +1 -1
- package/dist/usecase/view/ExecuteViewUseCase.d.ts.map +1 -1
- package/dist/usecase/view/ExecuteViewUseCase.js +4 -1
- package/dist/usecase/view/ExecuteViewUseCase.js.map +1 -1
- package/package.json +2 -2
|
@@ -14,7 +14,7 @@ export interface SeoMeta {
|
|
|
14
14
|
readonly canonical: string;
|
|
15
15
|
/** Absolute URL of the markdown mirror — `<link rel="alternate"
|
|
16
16
|
* type="text/markdown">`. AEO-critical. */
|
|
17
|
-
readonly alternateMarkdown: string;
|
|
17
|
+
readonly alternateMarkdown: string | null;
|
|
18
18
|
/** One per locale this entry has a translation in, plus an
|
|
19
19
|
* `x-default` row when the site has multiple locales. */
|
|
20
20
|
readonly hreflangs: ReadonlyArray<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SeoMeta.d.ts","sourceRoot":"","sources":["../../../src/domain/model/SeoMeta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,OAAO;IACtB,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;gDAC4C;IAC5C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"SeoMeta.d.ts","sourceRoot":"","sources":["../../../src/domain/model/SeoMeta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,OAAO;IACtB,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;gDAC4C;IAC5C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C;8DAC0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtF,mDAAmD;IACnD,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,wBAAwB;IACxB,QAAQ,CAAC,EAAE,EAAE;QACX,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;QACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,0BAA0B;IAC1B,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,qBAAqB,CAAC;QACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;KAC/B,CAAC;IACF;iCAC6B;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC"}
|
|
@@ -10,10 +10,9 @@ import type { MediaAsset } from "../port/MediaStorage.js";
|
|
|
10
10
|
* their public surface (Hono + hono/jsx) call their JSX → string
|
|
11
11
|
* function before the template returns.
|
|
12
12
|
*
|
|
13
|
-
* Schemas without a registered entry/list template
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* templates).
|
|
13
|
+
* Schemas without a registered entry/list template skip HTML.
|
|
14
|
+
* Their agent mirrors are emitted only when a public path resolves
|
|
15
|
+
* and the entry has serializable content.
|
|
17
16
|
*
|
|
18
17
|
* `seo` is populated when the renderer is given a composed SeoMeta
|
|
19
18
|
* block — templates render `<SeoTags seo={seo} />` (or read fields
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateRegistry.d.ts","sourceRoot":"","sources":["../../../src/domain/model/TemplateRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D
|
|
1
|
+
{"version":3,"file":"TemplateRegistry.d.ts","sourceRoot":"","sources":["../../../src/domain/model/TemplateRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvD,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvD,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,YAAY,KAAK,MAAM,CAAC;AAC1D,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,WAAW,KAAK,MAAM,CAAC;AAExD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;IAEzD,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,GAAG,IAAI;IAIjE,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,YAAY,GAAG,IAAI;IAI/D,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI/D,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;CAG9D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateRegistry.js","sourceRoot":"","sources":["../../../src/domain/model/TemplateRegistry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TemplateRegistry.js","sourceRoot":"","sources":["../../../src/domain/model/TemplateRegistry.ts"],"names":[],"mappings":"AA4CA,MAAM,OAAO,gBAAgB;IACV,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC3C,KAAK,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEzD,qBAAqB,CAAC,UAAkB,EAAE,CAAgB;QACxD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAClC,CAAC;IAED,oBAAoB,CAAC,UAAkB,EAAE,CAAe;QACtD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAChC,CAAC;IAED,gBAAgB,CAAC,UAAkB;QACjC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACtC,CAAC;IAED,eAAe,CAAC,UAAkB;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;CACF"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* returns the response.
|
|
8
8
|
*
|
|
9
9
|
* CF adapter: wraps `env.ASSETS.fetch(req)`. Future: filesystem read,
|
|
10
|
-
* S3+CDN,
|
|
10
|
+
* S3+CDN, or another platform asset service.
|
|
11
11
|
*
|
|
12
12
|
* Returning `null` lets the runtime's HTTP layer fall back to the
|
|
13
13
|
* SPA's `index.html` catchall — the React Router routing model.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `DatabaseDriver` — runtime's adapter-agnostic interface to
|
|
3
|
-
* persistent relational state. Entries,
|
|
3
|
+
* persistent relational state. Entries, site config,
|
|
4
4
|
* auth support, and media tables declared by the canonical migrations live
|
|
5
5
|
* behind this surface; the runtime never sees `D1Database`, `Pool` (postgres),
|
|
6
6
|
* or any concrete driver.
|
|
@@ -17,7 +17,7 @@ export interface ReadEntryByDataFieldArgs {
|
|
|
17
17
|
export interface ReadEntriesByDataFieldInArgs {
|
|
18
18
|
readonly collection: string;
|
|
19
19
|
readonly field: string;
|
|
20
|
-
readonly values: readonly
|
|
20
|
+
readonly values: readonly EntryDataScalar[];
|
|
21
21
|
readonly locale?: string | null;
|
|
22
22
|
readonly status?: ContentState;
|
|
23
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntryReader.d.ts","sourceRoot":"","sources":["../../../src/domain/port/EntryReader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;CAChC;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;CAChC;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"EntryReader.d.ts","sourceRoot":"","sources":["../../../src/domain/port/EntryReader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;CAChC;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;CAChC;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;CAChC;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC5C,UAAU,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC7D,eAAe,CAAC,IAAI,EAAE,wBAAwB,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACvE,iBAAiB,CAAC,IAAI,EAAE,4BAA4B,GAAG,OAAO,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC;IACjF,aAAa,CAAC,IAAI,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC;IAC1E,mBAAmB,CAAC,IAAI,EAAE,8BAA8B,GAAG,OAAO,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC;CACtF"}
|
|
@@ -20,7 +20,6 @@ export interface EntryRepository {
|
|
|
20
20
|
get(id: string): Promise<EntryRow | null>;
|
|
21
21
|
/** Throws `EntryVersionConflict` on OCC mismatch. */
|
|
22
22
|
update(args: UpdateEntryArgs): Promise<EntryRow>;
|
|
23
|
-
/** Cascades to revisions + approvals child rows for the entry id. */
|
|
24
23
|
delete(args: DeleteEntryArgs): Promise<{
|
|
25
24
|
readonly removed: boolean;
|
|
26
25
|
}>;
|
|
@@ -106,13 +105,29 @@ export interface ListEntriesArgs {
|
|
|
106
105
|
/** Opaque continuation token from a prior `ListEntriesResult.nextCursor`.
|
|
107
106
|
* Caller must round-trip without interpreting; format is impl-defined. */
|
|
108
107
|
readonly cursor?: string;
|
|
109
|
-
/**
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
/** Fetch the page before `cursor`; default is the page after it. */
|
|
109
|
+
readonly cursorDirection?: "forward" | "backward";
|
|
110
|
+
/** Free-text filter matched against `id` and `searchFields`
|
|
111
|
+
* (substring, case-insensitive for ASCII per SQLite `LIKE`). */
|
|
112
112
|
readonly search?: string;
|
|
113
|
+
/** Trusted top-level string fields resolved from Schema.searchableFields. */
|
|
114
|
+
readonly searchFields?: readonly string[];
|
|
115
|
+
/** Trusted exact enum filter resolved from the Schema's indexed fields. */
|
|
116
|
+
readonly filter?: {
|
|
117
|
+
readonly field: string;
|
|
118
|
+
readonly value: string;
|
|
119
|
+
};
|
|
120
|
+
/** Native fields or Schema-indexed scalar data fields only. */
|
|
121
|
+
readonly sort?: EntrySort;
|
|
122
|
+
}
|
|
123
|
+
export interface EntrySort {
|
|
124
|
+
readonly field: string;
|
|
125
|
+
readonly direction: "asc" | "desc";
|
|
113
126
|
}
|
|
114
127
|
export interface ListEntriesResult {
|
|
115
128
|
readonly rows: readonly EntryRow[];
|
|
129
|
+
/** Pass back with `cursorDirection: "backward"`. */
|
|
130
|
+
readonly previousCursor?: string;
|
|
116
131
|
/** Present when there may be more rows beyond this page. Undefined
|
|
117
132
|
* signals "this is the last page". Pass back as `cursor` to
|
|
118
133
|
* continue. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntryRepository.d.ts","sourceRoot":"","sources":["../../../src/domain/port/EntryRepository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAEjE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC1C,qDAAqD;IACrD,MAAM,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjD,
|
|
1
|
+
{"version":3,"file":"EntryRepository.d.ts","sourceRoot":"","sources":["../../../src/domain/port/EntryRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `IdGenerator` — abstracted id source for
|
|
3
|
-
*
|
|
2
|
+
* `IdGenerator` — abstracted id source for entries / lifecycle events /
|
|
3
|
+
* sessions / media bearer tokens / R2
|
|
4
4
|
* object keys.
|
|
5
5
|
*
|
|
6
6
|
* # Security invariant
|
|
@@ -7,7 +7,7 @@ import type { MediaPurposePolicy, SiteConfig, SiteDefaults } from "@aotter/mantl
|
|
|
7
7
|
* `siteDefaults`, but treats keys differently depending on ownership:
|
|
8
8
|
* UI-editable keys (brand/title/description/…) seed once (INSERT …
|
|
9
9
|
* ON CONFLICT DO NOTHING) so operator edits are preserved; keys with
|
|
10
|
-
* no admin-UI edit path (`locales`, `mediaPurposes`) are synced from
|
|
10
|
+
* no admin-UI edit path (`origin`, `locales`, `mediaPurposes`) are synced from
|
|
11
11
|
* config on every boot (upsert when the value differs) since code is
|
|
12
12
|
* their only source of truth. See `DatabaseSiteConfigRepository`'s
|
|
13
13
|
* header comment for the full rationale (#441).
|
|
@@ -24,7 +24,7 @@ export interface SiteConfigRepository {
|
|
|
24
24
|
load(): Promise<SiteConfig>;
|
|
25
25
|
/** Persist the operator-owned subset exposed by the Admin settings UI.
|
|
26
26
|
* Omitted fields are unchanged; an empty string intentionally clears a
|
|
27
|
-
* value. Code-canonical locales and media purposes are never writable
|
|
27
|
+
* value. Code-canonical origin, locales, and media purposes are never writable
|
|
28
28
|
* through this path. Optional during the `CmsRuntime.db` compatibility
|
|
29
29
|
* window; canonical Mantle runtimes always provide it. */
|
|
30
30
|
updateEditable?(args: UpdateEditableSiteConfigArgs): Promise<void>;
|
|
@@ -33,4 +33,6 @@ export interface RenderListArgs {
|
|
|
33
33
|
* registered for `collection`. */
|
|
34
34
|
export declare function renderListHtml(args: RenderListArgs): string | null;
|
|
35
35
|
export declare function renderTrackingTagsHtml(site: SiteConfig): string;
|
|
36
|
+
export declare function normalizeGa4MeasurementId(value: string | undefined): string | null;
|
|
37
|
+
export declare function normalizeFacebookPixelId(value: string | undefined): string | null;
|
|
36
38
|
//# sourceMappingURL=HtmlRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HtmlRenderer.d.ts","sourceRoot":"","sources":["../../../src/domain/service/HtmlRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAW1D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC;mEAC+D;IAC/D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvD;;;+DAG2D;IAC3D,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;qDACqD;AACrD,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAepE;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvD,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;mCACmC;AACnC,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAelE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAa/D"}
|
|
1
|
+
{"version":3,"file":"HtmlRenderer.d.ts","sourceRoot":"","sources":["../../../src/domain/service/HtmlRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAW1D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC;mEAC+D;IAC/D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvD;;;+DAG2D;IAC3D,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;qDACqD;AACrD,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAepE;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvD,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;mCACmC;AACnC,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAelE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAa/D;AAYD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAGlF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAGjF"}
|
|
@@ -62,11 +62,11 @@ function injectTrackingTags(html, site) {
|
|
|
62
62
|
return html.replace(bodyOpen, (match) => `${match}${tags}`);
|
|
63
63
|
return `${tags}${html}`;
|
|
64
64
|
}
|
|
65
|
-
function normalizeGa4MeasurementId(value) {
|
|
65
|
+
export function normalizeGa4MeasurementId(value) {
|
|
66
66
|
const trimmed = value?.trim().toUpperCase() ?? "";
|
|
67
67
|
return /^G-[A-Z0-9]{4,32}$/.test(trimmed) ? trimmed : null;
|
|
68
68
|
}
|
|
69
|
-
function normalizeFacebookPixelId(value) {
|
|
69
|
+
export function normalizeFacebookPixelId(value) {
|
|
70
70
|
const trimmed = value?.trim() ?? "";
|
|
71
71
|
return /^[0-9]{5,32}$/.test(trimmed) ? trimmed : null;
|
|
72
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HtmlRenderer.js","sourceRoot":"","sources":["../../../src/domain/service/HtmlRenderer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"HtmlRenderer.js","sourceRoot":"","sources":["../../../src/domain/service/HtmlRenderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,21 +19,17 @@ import type { Entry, SiteConfig } from "@aotter/mantle-spec";
|
|
|
19
19
|
*
|
|
20
20
|
* <content>
|
|
21
21
|
*
|
|
22
|
-
* Entries without
|
|
23
|
-
* mirror — see `getMarkdownBody` below for the dual-field rule.
|
|
22
|
+
* Entries without serializable public content skip the `.md` mirror.
|
|
24
23
|
*
|
|
25
24
|
* Pure transformation — no I/O. Lives in `domain/service/`.
|
|
26
25
|
*/
|
|
27
26
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* from it) declares `body`. Both are markdown text under the hood;
|
|
31
|
-
* accept either everywhere a markdown payload is read so consumers
|
|
32
|
-
* don't have to choose. Single predicate so `serializeEntryAsMarkdown`,
|
|
33
|
-
* `serializeLlmsTxt`, and the article-signal heuristic stay in sync.
|
|
27
|
+
* `content`/`body` win, then structured sections, then a non-empty
|
|
28
|
+
* description/summary. One predicate keeps mirrors and metadata in sync.
|
|
34
29
|
*/
|
|
35
30
|
export declare function getMarkdownBody(entry: Entry): string | null;
|
|
36
31
|
export declare function hasMarkdownBody(entry: Entry): boolean;
|
|
32
|
+
export declare function getEntryDescription(entry: Entry): string | null;
|
|
37
33
|
export declare function serializeEntryAsMarkdown(entry: Entry): string | null;
|
|
38
34
|
/**
|
|
39
35
|
* Per-locale `/llms.txt` index. One section per collection, one bullet
|
|
@@ -44,5 +40,6 @@ export declare function serializeLlmsTxt(args: {
|
|
|
44
40
|
readonly site: SiteConfig;
|
|
45
41
|
readonly locale: string;
|
|
46
42
|
readonly entriesByCollection: ReadonlyMap<string, readonly Entry[]>;
|
|
47
|
-
|
|
43
|
+
readonly pathFor: (entry: Entry) => string | null;
|
|
44
|
+
}): string | null;
|
|
48
45
|
//# sourceMappingURL=MarkdownSerializer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownSerializer.d.ts","sourceRoot":"","sources":["../../../src/domain/service/MarkdownSerializer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAG7D
|
|
1
|
+
{"version":3,"file":"MarkdownSerializer.d.ts","sourceRoot":"","sources":["../../../src/domain/service/MarkdownSerializer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAG7D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAS3D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAErD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAG/D;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAuBpE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,mBAAmB,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC,CAAC;IACpE,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,GAAG,IAAI,CAAC;CACnD,GAAG,MAAM,GAAG,IAAI,CAsBhB"}
|
|
@@ -19,43 +19,48 @@ import { absoluteUrl, appendMarkdownExt } from "./AbsoluteUrl.js";
|
|
|
19
19
|
*
|
|
20
20
|
* <content>
|
|
21
21
|
*
|
|
22
|
-
* Entries without
|
|
23
|
-
* mirror — see `getMarkdownBody` below for the dual-field rule.
|
|
22
|
+
* Entries without serializable public content skip the `.md` mirror.
|
|
24
23
|
*
|
|
25
24
|
* Pure transformation — no I/O. Lives in `domain/service/`.
|
|
26
25
|
*/
|
|
27
26
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* from it) declares `body`. Both are markdown text under the hood;
|
|
31
|
-
* accept either everywhere a markdown payload is read so consumers
|
|
32
|
-
* don't have to choose. Single predicate so `serializeEntryAsMarkdown`,
|
|
33
|
-
* `serializeLlmsTxt`, and the article-signal heuristic stay in sync.
|
|
27
|
+
* `content`/`body` win, then structured sections, then a non-empty
|
|
28
|
+
* description/summary. One predicate keeps mirrors and metadata in sync.
|
|
34
29
|
*/
|
|
35
30
|
export function getMarkdownBody(entry) {
|
|
36
31
|
const data = entry.data;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
for (const key of ["content", "body"]) {
|
|
33
|
+
const value = nonEmptyString(data[key]);
|
|
34
|
+
if (value)
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
const sections = serializeSections(data["sections"]);
|
|
38
|
+
if (sections)
|
|
39
|
+
return sections;
|
|
40
|
+
return getEntryDescription(entry);
|
|
42
41
|
}
|
|
43
42
|
export function hasMarkdownBody(entry) {
|
|
44
43
|
return getMarkdownBody(entry) !== null;
|
|
45
44
|
}
|
|
45
|
+
export function getEntryDescription(entry) {
|
|
46
|
+
return nonEmptyString(entry.data["description"])
|
|
47
|
+
?? nonEmptyString(entry.data["summary"]);
|
|
48
|
+
}
|
|
46
49
|
export function serializeEntryAsMarkdown(entry) {
|
|
47
50
|
const data = entry.data;
|
|
48
51
|
const content = getMarkdownBody(entry);
|
|
49
52
|
if (content == null)
|
|
50
53
|
return null;
|
|
51
54
|
const fm = [];
|
|
52
|
-
for (const k of ["title", "
|
|
55
|
+
for (const k of ["title", "slug", "locale", "publishedAt"]) {
|
|
53
56
|
const v = k === "locale" ? entry.locale : data[k];
|
|
54
57
|
if (typeof v === "string" && v.length > 0)
|
|
55
58
|
fm.push([k, v]);
|
|
56
59
|
}
|
|
57
60
|
const title = data["title"] ?? entry.id;
|
|
58
|
-
const description =
|
|
61
|
+
const description = getEntryDescription(entry);
|
|
62
|
+
if (description)
|
|
63
|
+
fm.splice(1, 0, ["description", description]);
|
|
59
64
|
let out = "---\n";
|
|
60
65
|
for (const [k, v] of fm)
|
|
61
66
|
out += `${k}: ${yamlScalar(v)}\n`;
|
|
@@ -74,31 +79,71 @@ export function serializeEntryAsMarkdown(entry) {
|
|
|
74
79
|
* so agent consumers can rely on a stable structure.
|
|
75
80
|
*/
|
|
76
81
|
export function serializeLlmsTxt(args) {
|
|
77
|
-
const { site, locale, entriesByCollection } = args;
|
|
78
|
-
const
|
|
79
|
-
let out = `# ${site.title}\n\n`;
|
|
80
|
-
if (site.description)
|
|
81
|
-
out += `> ${site.description}\n\n`;
|
|
82
|
-
if (locale)
|
|
83
|
-
out += `Locale: ${locale}\n\n`;
|
|
82
|
+
const { site, locale, entriesByCollection, pathFor } = args;
|
|
83
|
+
const sections = [];
|
|
84
84
|
for (const [collection, entries] of entriesByCollection) {
|
|
85
|
-
|
|
86
|
-
continue;
|
|
87
|
-
out += `## ${collection}\n\n`;
|
|
85
|
+
const bullets = [];
|
|
88
86
|
for (const e of entries) {
|
|
89
87
|
if (!hasMarkdownBody(e))
|
|
90
88
|
continue;
|
|
91
89
|
const data = e.data;
|
|
92
90
|
const title = data["title"] ?? e.id;
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
|
|
91
|
+
const path = pathFor(e);
|
|
92
|
+
if (!path)
|
|
93
|
+
continue;
|
|
94
|
+
const desc = getEntryDescription(e) ?? "";
|
|
95
|
+
const url = appendMarkdownExt(absoluteUrl(site.origin, path));
|
|
96
|
+
bullets.push(desc ? `- [${title}](${url}): ${desc}` : `- [${title}](${url})`);
|
|
98
97
|
}
|
|
99
|
-
|
|
98
|
+
if (bullets.length > 0)
|
|
99
|
+
sections.push(`## ${collection}\n\n${bullets.join("\n")}`);
|
|
100
100
|
}
|
|
101
|
-
|
|
101
|
+
if (sections.length === 0)
|
|
102
|
+
return null;
|
|
103
|
+
let out = `# ${site.title}\n\n`;
|
|
104
|
+
if (site.description)
|
|
105
|
+
out += `> ${site.description}\n\n`;
|
|
106
|
+
if (locale)
|
|
107
|
+
out += `Locale: ${locale}\n\n`;
|
|
108
|
+
return `${out}${sections.join("\n\n")}\n`;
|
|
109
|
+
}
|
|
110
|
+
function serializeSections(value) {
|
|
111
|
+
if (!Array.isArray(value))
|
|
112
|
+
return null;
|
|
113
|
+
const sections = value.map(serializeSection).filter((section) => section.length > 0);
|
|
114
|
+
return sections.length > 0 ? sections.join("\n\n") : null;
|
|
115
|
+
}
|
|
116
|
+
function serializeSection(value) {
|
|
117
|
+
if (!isRecord(value))
|
|
118
|
+
return "";
|
|
119
|
+
const heading = nonEmptyString(value["title"]);
|
|
120
|
+
const lines = heading ? [`## ${heading}`] : [];
|
|
121
|
+
for (const key of ["eyebrow", "body", "description", "quote", "value"]) {
|
|
122
|
+
const text = nonEmptyString(value[key]);
|
|
123
|
+
if (text && text !== heading)
|
|
124
|
+
lines.push(text);
|
|
125
|
+
}
|
|
126
|
+
if (Array.isArray(value["items"])) {
|
|
127
|
+
for (const item of value["items"]) {
|
|
128
|
+
if (!isRecord(item))
|
|
129
|
+
continue;
|
|
130
|
+
const title = nonEmptyString(item["title"]);
|
|
131
|
+
const body = nonEmptyString(item["body"])
|
|
132
|
+
?? nonEmptyString(item["description"])
|
|
133
|
+
?? nonEmptyString(item["quote"]);
|
|
134
|
+
if (title && body)
|
|
135
|
+
lines.push(`- **${title}:** ${body}`);
|
|
136
|
+
else if (title ?? body)
|
|
137
|
+
lines.push(`- ${title ?? body}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return lines.join("\n\n");
|
|
141
|
+
}
|
|
142
|
+
function nonEmptyString(value) {
|
|
143
|
+
return typeof value === "string" && value.trim() ? value : null;
|
|
144
|
+
}
|
|
145
|
+
function isRecord(value) {
|
|
146
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
102
147
|
}
|
|
103
148
|
function yamlScalar(s) {
|
|
104
149
|
if (/^[A-Za-z0-9._/-][\w. /:-]*$/.test(s) && !/^(true|false|null|yes|no|on|off)$/i.test(s)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownSerializer.js","sourceRoot":"","sources":["../../../src/domain/service/MarkdownSerializer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAElE
|
|
1
|
+
{"version":3,"file":"MarkdownSerializer.js","sourceRoot":"","sources":["../../../src/domain/service/MarkdownSerializer.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,8 +33,21 @@ export interface ComposeEntrySeoMetaArgs {
|
|
|
33
33
|
/** og:type. Defaults to `article` when the entry has a `publishedAt`
|
|
34
34
|
* (or `updatedAt`) field, `website` otherwise. */
|
|
35
35
|
readonly type?: "article" | "website";
|
|
36
|
+
/** Public-route locale for non-localized entries mounted under a locale URL. */
|
|
37
|
+
readonly locale?: string;
|
|
36
38
|
}
|
|
37
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;
|
|
38
51
|
/**
|
|
39
52
|
* Render the SEO meta block as an HTML fragment. Templates embed this
|
|
40
53
|
* verbatim inside `<head>` via `raw(renderSeoTagsHtml(seo))`.
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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,17 +1,17 @@
|
|
|
1
1
|
import { toUrlLocale } from "@aotter/mantle-spec";
|
|
2
2
|
import { absoluteUrl, appendMarkdownExt } from "./AbsoluteUrl.js";
|
|
3
3
|
import { escapeHtml as escapeAttr } from "./HtmlEscaping.js";
|
|
4
|
-
import { hasMarkdownBody } from "./MarkdownSerializer.js";
|
|
4
|
+
import { getEntryDescription, hasMarkdownBody } from "./MarkdownSerializer.js";
|
|
5
5
|
export function composeEntrySeoMeta(args) {
|
|
6
6
|
const { entry, site, publicPath, siblings = [], type } = args;
|
|
7
7
|
const data = entry.data;
|
|
8
8
|
const canonical = absoluteUrl(site.origin, publicPath);
|
|
9
|
-
const alternateMarkdown = appendMarkdownExt(canonical);
|
|
9
|
+
const alternateMarkdown = hasMarkdownBody(entry) ? appendMarkdownExt(canonical) : null;
|
|
10
10
|
const title = stringField(data, "title") ?? site.title;
|
|
11
|
-
const description =
|
|
11
|
+
const description = getEntryDescription(entry) ?? site.description ?? null;
|
|
12
12
|
const image = stringField(data, "coverUrl") ?? stringField(data, "ogImage") ?? null;
|
|
13
13
|
const ogType = type ?? (hasArticleSignal(entry) ? "article" : "website");
|
|
14
|
-
const entryLocale = entry.locale ?? site.canonicalLocale ?? "en";
|
|
14
|
+
const entryLocale = args.locale ?? entry.locale ?? site.canonicalLocale ?? "en";
|
|
15
15
|
const hreflangs = buildHreflangs({
|
|
16
16
|
site,
|
|
17
17
|
currentLocale: entryLocale,
|
|
@@ -46,13 +46,60 @@ export function composeEntrySeoMeta(args) {
|
|
|
46
46
|
image,
|
|
47
47
|
data,
|
|
48
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,
|
|
49
98
|
}),
|
|
50
99
|
};
|
|
51
100
|
}
|
|
52
101
|
function buildHreflangs(args) {
|
|
53
102
|
const { site, currentLocale, currentPublicPath, siblings } = args;
|
|
54
|
-
if (site.locales.length <= 1)
|
|
55
|
-
return [];
|
|
56
103
|
const out = [];
|
|
57
104
|
const seen = new Set();
|
|
58
105
|
const push = (locale, path) => {
|
|
@@ -76,7 +123,7 @@ function buildHreflangs(args) {
|
|
|
76
123
|
return out;
|
|
77
124
|
}
|
|
78
125
|
function buildJsonLd(args) {
|
|
79
|
-
const { ogType, title, description, canonical, image, data, site } = args;
|
|
126
|
+
const { ogType, title, description, canonical, image, data, site, locale } = args;
|
|
80
127
|
const publishedAtMs = numericField(data, "publishedAt");
|
|
81
128
|
const updatedAtMs = numericField(data, "updatedAt");
|
|
82
129
|
const base = {
|
|
@@ -87,7 +134,7 @@ function buildJsonLd(args) {
|
|
|
87
134
|
url: canonical,
|
|
88
135
|
description: description ?? undefined,
|
|
89
136
|
image: image ?? undefined,
|
|
90
|
-
inLanguage:
|
|
137
|
+
inLanguage: locale,
|
|
91
138
|
publisher: site.title || site.brand
|
|
92
139
|
? {
|
|
93
140
|
"@type": "Organization",
|
|
@@ -122,7 +169,9 @@ function hasArticleSignal(entry) {
|
|
|
122
169
|
export function renderSeoTagsHtml(meta) {
|
|
123
170
|
const parts = [];
|
|
124
171
|
parts.push(`<link rel="canonical" href="${escapeAttr(meta.canonical)}">`);
|
|
125
|
-
|
|
172
|
+
if (meta.alternateMarkdown) {
|
|
173
|
+
parts.push(`<link rel="alternate" type="text/markdown" href="${escapeAttr(meta.alternateMarkdown)}">`);
|
|
174
|
+
}
|
|
126
175
|
for (const h of meta.hreflangs) {
|
|
127
176
|
parts.push(`<link rel="alternate" hreflang="${escapeAttr(h.locale)}" href="${escapeAttr(h.href)}">`);
|
|
128
177
|
}
|