emdash 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{adapters-DoNJiveC.d.mts → adapters-BktHA7EO.d.mts} +1 -1
- package/dist/{adapters-DoNJiveC.d.mts.map → adapters-BktHA7EO.d.mts.map} +1 -1
- package/dist/{apply-BzltprvY.mjs → apply-Ded_1vng.mjs} +167 -254
- package/dist/apply-Ded_1vng.mjs.map +1 -0
- package/dist/astro/index.d.mts +6 -6
- package/dist/astro/index.mjs +10 -2
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +5 -5
- package/dist/astro/middleware/auth.mjs +5 -5
- package/dist/astro/middleware/redirect.mjs +5 -5
- package/dist/astro/middleware/request-context.mjs +4 -4
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +94 -43
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/types.d.mts +12 -11
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/{base64-BRICGH2l.mjs → base64-MBPo9ozB.mjs} +1 -1
- package/dist/{base64-BRICGH2l.mjs.map → base64-MBPo9ozB.mjs.map} +1 -1
- package/dist/{byline-BSaNL1w7.mjs → byline-gFn1r0vA.mjs} +4 -4
- package/dist/{byline-BSaNL1w7.mjs.map → byline-gFn1r0vA.mjs.map} +1 -1
- package/dist/{bylines-CvJ3PYz2.mjs → bylines-DTFI8nDM.mjs} +5 -5
- package/dist/{bylines-CvJ3PYz2.mjs.map → bylines-DTFI8nDM.mjs.map} +1 -1
- package/dist/{cache-C6N_hhN7.mjs → cache-BAJbeoZ8.mjs} +3 -3
- package/dist/{cache-C6N_hhN7.mjs.map → cache-BAJbeoZ8.mjs.map} +1 -1
- package/dist/{chunks-NBQVDOci.mjs → chunks-BK1oZS-l.mjs} +2 -2
- package/dist/{chunks-NBQVDOci.mjs.map → chunks-BK1oZS-l.mjs.map} +1 -1
- package/dist/cli/index.mjs +342 -95
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.mjs +1 -1
- package/dist/{config-BI0V3ICQ.mjs → config-CVssduLe.mjs} +1 -1
- package/dist/{config-BI0V3ICQ.mjs.map → config-CVssduLe.mjs.map} +1 -1
- package/dist/{content-8lOYF0pr.mjs → content-CERxPUN0.mjs} +14 -3
- package/dist/content-CERxPUN0.mjs.map +1 -0
- package/dist/database/instrumentation.d.mts +6 -4
- package/dist/database/instrumentation.d.mts.map +1 -1
- package/dist/database/instrumentation.mjs +19 -7
- package/dist/database/instrumentation.mjs.map +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-WRezodiz.mjs → db-errors-B7P2pSCn.mjs} +1 -1
- package/dist/{db-errors-WRezodiz.mjs.map → db-errors-B7P2pSCn.mjs.map} +1 -1
- package/dist/{default-D8ksjWhO.mjs → default-pHuz9WF6.mjs} +1 -1
- package/dist/{default-D8ksjWhO.mjs.map → default-pHuz9WF6.mjs.map} +1 -1
- package/dist/{error-D_-tqP-I.mjs → error-DqnRMM5z.mjs} +1 -1
- package/dist/{error-D_-tqP-I.mjs.map → error-DqnRMM5z.mjs.map} +1 -1
- package/dist/{index-BFRaVcD6.d.mts → index-Cg-rC4Gj.d.mts} +110 -87
- package/dist/index-Cg-rC4Gj.d.mts.map +1 -0
- package/dist/index.d.mts +11 -11
- package/dist/index.mjs +29 -28
- package/dist/{load-DDqMMvZL.mjs → load-DR1VwFXR.mjs} +2 -2
- package/dist/{load-DDqMMvZL.mjs.map → load-DR1VwFXR.mjs.map} +1 -1
- package/dist/{loader-CKLbBnhK.mjs → loader-ou_PXAjg.mjs} +31 -6
- package/dist/loader-ou_PXAjg.mjs.map +1 -0
- package/dist/{manifest-schema-DqWNC3lM.mjs → manifest-schema-CXAbd1vH.mjs} +1 -1
- package/dist/{manifest-schema-DqWNC3lM.mjs.map → manifest-schema-CXAbd1vH.mjs.map} +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +1 -1
- package/dist/media/local-runtime.d.mts +7 -7
- package/dist/media/local-runtime.mjs +3 -3
- package/dist/{media-BW32b4gi.mjs → media-1fFhub9c.mjs} +22 -10
- package/dist/media-1fFhub9c.mjs.map +1 -0
- package/dist/{mode-ier8jbBk.mjs → mode-YhqNVef_.mjs} +1 -1
- package/dist/{mode-ier8jbBk.mjs.map → mode-YhqNVef_.mjs.map} +1 -1
- package/dist/{options-BVp3UsTS.mjs → options-nPxWnrya.mjs} +1 -1
- package/dist/{options-BVp3UsTS.mjs.map → options-nPxWnrya.mjs.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/{patterns-CrCYkMBb.mjs → patterns-DsUZ4uxI.mjs} +1 -1
- package/dist/{patterns-CrCYkMBb.mjs.map → patterns-DsUZ4uxI.mjs.map} +1 -1
- package/dist/{placeholder-BE4o_2dc.d.mts → placeholder-CDPtkelt.d.mts} +1 -1
- package/dist/{placeholder-BE4o_2dc.d.mts.map → placeholder-CDPtkelt.d.mts.map} +1 -1
- package/dist/{placeholder-CIJejMlK.mjs → placeholder-Ci0RLeCk.mjs} +1 -1
- package/dist/{placeholder-CIJejMlK.mjs.map → placeholder-Ci0RLeCk.mjs.map} +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +5 -5
- package/dist/plugins/adapt-sandbox-entry.mjs +2 -2
- package/dist/{public-url-DByxYjUw.mjs → public-url-B1AxbbbQ.mjs} +1 -1
- package/dist/{public-url-DByxYjUw.mjs.map → public-url-B1AxbbbQ.mjs.map} +1 -1
- package/dist/{query-Cg9ZKRQ0.mjs → query-8c_meo_K.mjs} +13 -13
- package/dist/{query-Cg9ZKRQ0.mjs.map → query-8c_meo_K.mjs.map} +1 -1
- package/dist/{redirect-BhUBKRc1.mjs → redirect-C5H7VGIX.mjs} +3 -3
- package/dist/{redirect-BhUBKRc1.mjs.map → redirect-C5H7VGIX.mjs.map} +1 -1
- package/dist/{registry-Dw70ChxB.mjs → registry-Do34mz_P.mjs} +7 -6
- package/dist/registry-Do34mz_P.mjs.map +1 -0
- package/dist/{request-cache-B-bmkipQ.mjs → request-cache-D4I69LeL.mjs} +6 -2
- package/dist/request-cache-D4I69LeL.mjs.map +1 -0
- package/dist/request-context.d.mts +27 -1
- package/dist/request-context.d.mts.map +1 -1
- package/dist/request-context.mjs +16 -3
- package/dist/request-context.mjs.map +1 -1
- package/dist/{runner-C7ADox5q.mjs → runner-DIcU2UCC.mjs} +465 -148
- package/dist/runner-DIcU2UCC.mjs.map +1 -0
- package/dist/{runner-Bnoj7vjK.d.mts → runner-Iu3IZSDM.d.mts} +2 -2
- package/dist/{runner-Bnoj7vjK.d.mts.map → runner-Iu3IZSDM.d.mts.map} +1 -1
- package/dist/runtime.d.mts +6 -6
- package/dist/runtime.mjs +3 -3
- package/dist/{search-dOGEccMa.mjs → search-DuWhx4NG.mjs} +322 -108
- package/dist/search-DuWhx4NG.mjs.map +1 -0
- package/dist/{secrets-CW3reAnU.mjs → secrets-CZ8rxLX3.mjs} +3 -3
- package/dist/{secrets-CW3reAnU.mjs.map → secrets-CZ8rxLX3.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +15 -14
- package/dist/seo/index.d.mts +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/taxonomies-Bw76xAxo.mjs +407 -0
- package/dist/taxonomies-Bw76xAxo.mjs.map +1 -0
- package/dist/taxonomy-D6NvlKo8.mjs +218 -0
- package/dist/taxonomy-D6NvlKo8.mjs.map +1 -0
- package/dist/{tokens-D7zMmWi2.mjs → tokens-CyRDPVW2.mjs} +2 -2
- package/dist/{tokens-D7zMmWi2.mjs.map → tokens-CyRDPVW2.mjs.map} +1 -1
- package/dist/{transaction-Cn2rjY78.mjs → transaction-D44LBXvU.mjs} +1 -1
- package/dist/{transaction-Cn2rjY78.mjs.map → transaction-D44LBXvU.mjs.map} +1 -1
- package/dist/{transport-DNEfeMaU.d.mts → transport-DX_5rpsq.d.mts} +1 -1
- package/dist/{transport-DNEfeMaU.d.mts.map → transport-DX_5rpsq.d.mts.map} +1 -1
- package/dist/{transport-BeMCmin1.mjs → transport-xpzIjCIB.mjs} +1 -1
- package/dist/{transport-BeMCmin1.mjs.map → transport-xpzIjCIB.mjs.map} +1 -1
- package/dist/{types-CIOg5AR8.mjs → types-56BKbld_.mjs} +1 -1
- package/dist/types-56BKbld_.mjs.map +1 -0
- package/dist/{types-CRxNbK-Z.mjs → types-BIgulNsW.mjs} +2 -2
- package/dist/{types-CRxNbK-Z.mjs.map → types-BIgulNsW.mjs.map} +1 -1
- package/dist/{types-CrtWgIvl.d.mts → types-BQx6ZXpR.d.mts} +10 -1
- package/dist/types-BQx6ZXpR.d.mts.map +1 -0
- package/dist/{types-CJsYGpco.d.mts → types-B_CXXnzh.d.mts} +1 -1
- package/dist/{types-CJsYGpco.d.mts.map → types-B_CXXnzh.d.mts.map} +1 -1
- package/dist/{types-M78DQ1lx.d.mts → types-C-aFbqmA.d.mts} +1 -1
- package/dist/{types-M78DQ1lx.d.mts.map → types-C-aFbqmA.d.mts.map} +1 -1
- package/dist/types-DiI8NOG_.mjs +16 -0
- package/dist/types-DiI8NOG_.mjs.map +1 -0
- package/dist/{types-BuBIptGk.d.mts → types-IN5z_S3P.d.mts} +158 -92
- package/dist/types-IN5z_S3P.d.mts.map +1 -0
- package/dist/{types-BSyXeCFW.d.mts → types-IZSZfEwv.d.mts} +4 -3
- package/dist/types-IZSZfEwv.d.mts.map +1 -0
- package/dist/{types-CDbKp7ND.mjs → types-K-EkEQCI.mjs} +1 -1
- package/dist/{types-CDbKp7ND.mjs.map → types-K-EkEQCI.mjs.map} +1 -1
- package/dist/{validate-BfQh_C_y.d.mts → validate-CO3JjFV5.d.mts} +22 -5
- package/dist/validate-CO3JjFV5.d.mts.map +1 -0
- package/dist/{validate-Baqf0slj.mjs → validate-UK4Ja1uo.mjs} +14 -10
- package/dist/validate-UK4Ja1uo.mjs.map +1 -0
- package/dist/{validation-BfEI7tNe.mjs → validation-Vc5DQkJa.mjs} +5 -5
- package/dist/{validation-BfEI7tNe.mjs.map → validation-Vc5DQkJa.mjs.map} +1 -1
- package/dist/version-Bg31I_Ff.mjs +7 -0
- package/dist/{version-DoxrVdYf.mjs.map → version-Bg31I_Ff.mjs.map} +1 -1
- package/dist/{zod-generator-CC0xNe_K.mjs → zod-generator-CHnJUP2l.mjs} +8 -3
- package/dist/zod-generator-CHnJUP2l.mjs.map +1 -0
- package/package.json +9 -8
- package/src/api/errors.ts +5 -0
- package/src/api/handlers/content.ts +20 -0
- package/src/api/handlers/dashboard.ts +29 -36
- package/src/api/handlers/media-allowlist.ts +40 -0
- package/src/api/handlers/media.ts +1 -1
- package/src/api/handlers/menus.ts +400 -89
- package/src/api/handlers/taxonomies.ts +273 -97
- package/src/api/handlers/validate-media-fields.ts +125 -0
- package/src/api/schemas/common.ts +7 -0
- package/src/api/schemas/media.ts +23 -3
- package/src/api/schemas/menus.ts +23 -0
- package/src/api/schemas/schema.ts +11 -2
- package/src/api/schemas/taxonomies.ts +39 -0
- package/src/astro/integration/routes.ts +10 -0
- package/src/astro/middleware.ts +46 -11
- package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +1 -1
- package/src/astro/routes/api/import/wordpress/rewrite-url-helpers.ts +196 -0
- package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +9 -177
- package/src/astro/routes/api/media/upload-url.ts +10 -4
- package/src/astro/routes/api/media.ts +12 -4
- package/src/astro/routes/api/menus/[name]/items.ts +16 -6
- package/src/astro/routes/api/menus/[name]/reorder.ts +8 -3
- package/src/astro/routes/api/menus/[name]/translations.ts +82 -0
- package/src/astro/routes/api/menus/[name].ts +19 -10
- package/src/astro/routes/api/menus/index.ts +9 -6
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug]/translations.ts +89 -0
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug].ts +22 -22
- package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +11 -14
- package/src/astro/routes/api/taxonomies/index.ts +9 -6
- package/src/astro/types.ts +5 -1
- package/src/auth/rate-limit.ts +3 -3
- package/src/cli/commands/bundle-utils.ts +81 -6
- package/src/cli/commands/bundle.ts +18 -15
- package/src/cli/commands/export-seed.ts +139 -24
- package/src/cli/commands/plugin-init.ts +216 -90
- package/src/database/instrumentation.ts +22 -8
- package/src/database/migrations/016_api_tokens.ts +18 -3
- package/src/database/migrations/036_i18n_menus_and_taxonomies.ts +477 -0
- package/src/database/migrations/037_credential_algorithm.ts +18 -0
- package/src/database/migrations/runner.ts +4 -0
- package/src/database/repositories/content.ts +11 -0
- package/src/database/repositories/media.ts +40 -10
- package/src/database/repositories/taxonomy.ts +193 -89
- package/src/database/types.ts +12 -3
- package/src/emdash-runtime.ts +16 -3
- package/src/fields/file.ts +7 -6
- package/src/fields/image.ts +12 -11
- package/src/fields/types.ts +3 -0
- package/src/i18n/resolve.ts +37 -0
- package/src/index.ts +1 -1
- package/src/loader.ts +49 -2
- package/src/mcp/server.ts +114 -26
- package/src/media/mime.ts +75 -0
- package/src/menus/index.ts +143 -124
- package/src/menus/types.ts +15 -1
- package/src/plugins/types.ts +81 -191
- package/src/request-cache.ts +6 -2
- package/src/request-context.ts +42 -2
- package/src/schema/registry.ts +5 -5
- package/src/schema/types.ts +3 -2
- package/src/schema/zod-generator.ts +12 -2
- package/src/seed/apply.ts +157 -54
- package/src/seed/types.ts +18 -1
- package/src/seed/validate.ts +27 -13
- package/src/taxonomies/index.ts +230 -213
- package/src/taxonomies/types.ts +10 -0
- package/dist/apply-BzltprvY.mjs.map +0 -1
- package/dist/content-8lOYF0pr.mjs.map +0 -1
- package/dist/index-BFRaVcD6.d.mts.map +0 -1
- package/dist/loader-CKLbBnhK.mjs.map +0 -1
- package/dist/media-BW32b4gi.mjs.map +0 -1
- package/dist/registry-Dw70ChxB.mjs.map +0 -1
- package/dist/request-cache-B-bmkipQ.mjs.map +0 -1
- package/dist/runner-C7ADox5q.mjs.map +0 -1
- package/dist/search-dOGEccMa.mjs.map +0 -1
- package/dist/taxonomies-ZlRtD6AG.mjs +0 -315
- package/dist/taxonomies-ZlRtD6AG.mjs.map +0 -1
- package/dist/types-4fVtCIm0.mjs +0 -68
- package/dist/types-4fVtCIm0.mjs.map +0 -1
- package/dist/types-BSyXeCFW.d.mts.map +0 -1
- package/dist/types-BuBIptGk.d.mts.map +0 -1
- package/dist/types-CIOg5AR8.mjs.map +0 -1
- package/dist/types-CrtWgIvl.d.mts.map +0 -1
- package/dist/validate-Baqf0slj.mjs.map +0 -1
- package/dist/validate-BfQh_C_y.d.mts.map +0 -1
- package/dist/version-DoxrVdYf.mjs +0 -7
- package/dist/zod-generator-CC0xNe_K.mjs.map +0 -1
|
@@ -118,4 +118,4 @@ interface PostgresConfig {
|
|
|
118
118
|
declare function postgres(config: PostgresConfig): DatabaseDescriptor;
|
|
119
119
|
//#endregion
|
|
120
120
|
export { SqliteConfig as a, sqlite as c, PostgresConfig as i, DatabaseDialectType as n, libsql as o, LibsqlConfig as r, postgres as s, DatabaseDescriptor as t };
|
|
121
|
-
//# sourceMappingURL=adapters-
|
|
121
|
+
//# sourceMappingURL=adapters-BktHA7EO.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapters-
|
|
1
|
+
{"version":3,"file":"adapters-BktHA7EO.d.mts","names":[],"sources":["../src/db/adapters.ts"],"mappings":";;AA0BA;;;;;AAKA;;;;;;;;;;;AAqBA;;;;;AAOA;;;KAjCY,mBAAA;;AAsDZ;;UAjDiB,kBAAA;EAChB,UAAA;EACA,MAAA;EACA,IAAA,EAAM,mBAAA;EA8CuC;;;AAqB9C;;;;;;;;;AAWA;;EA/DC,oBAAA;AAAA;AAAA,UAGgB,YAAA;EA8DhB;;;EA1DA,GAAA;AAAA;AAAA,UAGgB,YAAA;EA6DhB;;;EAzDA,GAAA;EAyD0B;AAa3B;;EAlEC,SAAA;AAAA;;;;;;;;;;;iBAae,MAAA,CAAO,MAAA,EAAQ,YAAA,GAAe,kBAAA;;;;;;;;;;;;;;iBAqB9B,MAAA,CAAO,MAAA,EAAQ,YAAA,GAAe,kBAAA;;;;UAW7B,cAAA;EAChB,gBAAA;EACA,IAAA;EACA,IAAA;EACA,QAAA;EACA,IAAA;EACA,QAAA;EACA,GAAA;EACA,IAAA;IAAS,GAAA;IAAc,GAAA;EAAA;AAAA;;;;;;;;;;;iBAaR,QAAA,CAAS,MAAA,EAAQ,cAAA,GAAiB,kBAAA"}
|
|
@@ -1,183 +1,20 @@
|
|
|
1
|
-
import { i as __exportAll } from "./runner-
|
|
2
|
-
import {
|
|
3
|
-
import { t as
|
|
4
|
-
import { t as
|
|
5
|
-
import { t as
|
|
6
|
-
import { t as
|
|
7
|
-
import { t as
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { n as requestCached, t as peekRequestCache } from "./request-cache-
|
|
11
|
-
import {
|
|
1
|
+
import { i as __exportAll } from "./runner-DIcU2UCC.mjs";
|
|
2
|
+
import { n as getI18nConfig } from "./config-CVssduLe.mjs";
|
|
3
|
+
import { r as RevisionRepository, t as ContentRepository } from "./content-CERxPUN0.mjs";
|
|
4
|
+
import { t as MediaRepository } from "./media-1fFhub9c.mjs";
|
|
5
|
+
import { t as TaxonomyRepository } from "./taxonomy-D6NvlKo8.mjs";
|
|
6
|
+
import { t as OptionsRepository } from "./options-nPxWnrya.mjs";
|
|
7
|
+
import { t as withTransaction } from "./transaction-D44LBXvU.mjs";
|
|
8
|
+
import { t as RedirectRepository } from "./redirect-C5H7VGIX.mjs";
|
|
9
|
+
import { t as BylineRepository } from "./byline-gFn1r0vA.mjs";
|
|
10
|
+
import { n as requestCached, t as peekRequestCache } from "./request-cache-D4I69LeL.mjs";
|
|
11
|
+
import { i as FTSManager, n as SchemaRegistry } from "./registry-Do34mz_P.mjs";
|
|
12
|
+
import { r as getDb } from "./loader-ou_PXAjg.mjs";
|
|
13
|
+
import { t as validateSeed } from "./validate-UK4Ja1uo.mjs";
|
|
12
14
|
import { ulid } from "ulidx";
|
|
13
15
|
import { imageSize } from "image-size";
|
|
14
16
|
import mime from "mime/lite";
|
|
15
17
|
|
|
16
|
-
//#region src/database/repositories/taxonomy.ts
|
|
17
|
-
/**
|
|
18
|
-
* Taxonomy repository for categories, tags, and other classification
|
|
19
|
-
*
|
|
20
|
-
* Taxonomies are hierarchical (via parentId) and can be attached to content entries.
|
|
21
|
-
*/
|
|
22
|
-
var TaxonomyRepository = class {
|
|
23
|
-
constructor(db) {
|
|
24
|
-
this.db = db;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Create a new taxonomy term
|
|
28
|
-
*/
|
|
29
|
-
async create(input) {
|
|
30
|
-
const id = ulid();
|
|
31
|
-
const parentId = input.parentId === void 0 || input.parentId === "" ? null : input.parentId;
|
|
32
|
-
const row = {
|
|
33
|
-
id,
|
|
34
|
-
name: input.name,
|
|
35
|
-
slug: input.slug,
|
|
36
|
-
label: input.label,
|
|
37
|
-
parent_id: parentId,
|
|
38
|
-
data: input.data ? JSON.stringify(input.data) : null
|
|
39
|
-
};
|
|
40
|
-
await this.db.insertInto("taxonomies").values(row).execute();
|
|
41
|
-
const taxonomy = await this.findById(id);
|
|
42
|
-
if (!taxonomy) throw new Error("Failed to create taxonomy");
|
|
43
|
-
return taxonomy;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Find taxonomy by ID
|
|
47
|
-
*/
|
|
48
|
-
async findById(id) {
|
|
49
|
-
const row = await this.db.selectFrom("taxonomies").selectAll().where("id", "=", id).executeTakeFirst();
|
|
50
|
-
return row ? this.rowToTaxonomy(row) : null;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Find taxonomy by name and slug (unique constraint)
|
|
54
|
-
*/
|
|
55
|
-
async findBySlug(name, slug) {
|
|
56
|
-
const row = await this.db.selectFrom("taxonomies").selectAll().where("name", "=", name).where("slug", "=", slug).executeTakeFirst();
|
|
57
|
-
return row ? this.rowToTaxonomy(row) : null;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Get all terms for a taxonomy (e.g., all categories)
|
|
61
|
-
*/
|
|
62
|
-
async findByName(name, options = {}) {
|
|
63
|
-
let query = this.db.selectFrom("taxonomies").selectAll().where("name", "=", name).orderBy("label", "asc").orderBy("id", "asc");
|
|
64
|
-
if (options.parentId !== void 0) if (options.parentId === null) query = query.where("parent_id", "is", null);
|
|
65
|
-
else query = query.where("parent_id", "=", options.parentId);
|
|
66
|
-
return (await query.execute()).map((row) => this.rowToTaxonomy(row));
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Get children of a taxonomy term
|
|
70
|
-
*/
|
|
71
|
-
async findChildren(parentId) {
|
|
72
|
-
return (await this.db.selectFrom("taxonomies").selectAll().where("parent_id", "=", parentId).orderBy("label", "asc").orderBy("id", "asc").execute()).map((row) => this.rowToTaxonomy(row));
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Update a taxonomy term
|
|
76
|
-
*/
|
|
77
|
-
async update(id, input) {
|
|
78
|
-
if (!await this.findById(id)) return null;
|
|
79
|
-
const updates = {};
|
|
80
|
-
if (input.slug !== void 0) updates.slug = input.slug;
|
|
81
|
-
if (input.label !== void 0) updates.label = input.label;
|
|
82
|
-
if (input.parentId !== void 0) updates.parent_id = input.parentId === "" ? null : input.parentId;
|
|
83
|
-
if (input.data !== void 0) updates.data = JSON.stringify(input.data);
|
|
84
|
-
if (Object.keys(updates).length > 0) await this.db.updateTable("taxonomies").set(updates).where("id", "=", id).execute();
|
|
85
|
-
return this.findById(id);
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Delete a taxonomy term
|
|
89
|
-
*/
|
|
90
|
-
async delete(id) {
|
|
91
|
-
await this.db.deleteFrom("content_taxonomies").where("taxonomy_id", "=", id).execute();
|
|
92
|
-
return ((await this.db.deleteFrom("taxonomies").where("id", "=", id).executeTakeFirst()).numDeletedRows ?? 0) > 0;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Attach a taxonomy term to a content entry
|
|
96
|
-
*/
|
|
97
|
-
async attachToEntry(collection, entryId, taxonomyId) {
|
|
98
|
-
const row = {
|
|
99
|
-
collection,
|
|
100
|
-
entry_id: entryId,
|
|
101
|
-
taxonomy_id: taxonomyId
|
|
102
|
-
};
|
|
103
|
-
await this.db.insertInto("content_taxonomies").values(row).onConflict((oc) => oc.doNothing()).execute();
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Detach a taxonomy term from a content entry
|
|
107
|
-
*/
|
|
108
|
-
async detachFromEntry(collection, entryId, taxonomyId) {
|
|
109
|
-
await this.db.deleteFrom("content_taxonomies").where("collection", "=", collection).where("entry_id", "=", entryId).where("taxonomy_id", "=", taxonomyId).execute();
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Get all taxonomy terms for a content entry
|
|
113
|
-
*/
|
|
114
|
-
async getTermsForEntry(collection, entryId, taxonomyName) {
|
|
115
|
-
let query = this.db.selectFrom("content_taxonomies").innerJoin("taxonomies", "taxonomies.id", "content_taxonomies.taxonomy_id").selectAll("taxonomies").where("content_taxonomies.collection", "=", collection).where("content_taxonomies.entry_id", "=", entryId);
|
|
116
|
-
if (taxonomyName) query = query.where("taxonomies.name", "=", taxonomyName);
|
|
117
|
-
return (await query.execute()).map((row) => this.rowToTaxonomy(row));
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Set all taxonomy terms for a content entry (replaces existing)
|
|
121
|
-
* Uses batch operations to avoid N+1 queries.
|
|
122
|
-
*/
|
|
123
|
-
async setTermsForEntry(collection, entryId, taxonomyName, taxonomyIds) {
|
|
124
|
-
const current = await this.getTermsForEntry(collection, entryId, taxonomyName);
|
|
125
|
-
const currentIds = new Set(current.map((t) => t.id));
|
|
126
|
-
const newIds = new Set(taxonomyIds);
|
|
127
|
-
const toRemove = current.filter((t) => !newIds.has(t.id)).map((t) => t.id);
|
|
128
|
-
if (toRemove.length > 0) await this.db.deleteFrom("content_taxonomies").where("collection", "=", collection).where("entry_id", "=", entryId).where("taxonomy_id", "in", toRemove).execute();
|
|
129
|
-
const toAdd = taxonomyIds.filter((id) => !currentIds.has(id));
|
|
130
|
-
if (toAdd.length > 0) await this.db.insertInto("content_taxonomies").values(toAdd.map((taxonomy_id) => ({
|
|
131
|
-
collection,
|
|
132
|
-
entry_id: entryId,
|
|
133
|
-
taxonomy_id
|
|
134
|
-
}))).onConflict((oc) => oc.doNothing()).execute();
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Remove all taxonomy associations for an entry (use when entry is deleted)
|
|
138
|
-
*/
|
|
139
|
-
async clearEntryTerms(collection, entryId) {
|
|
140
|
-
const result = await this.db.deleteFrom("content_taxonomies").where("collection", "=", collection).where("entry_id", "=", entryId).executeTakeFirst();
|
|
141
|
-
return Number(result.numDeletedRows ?? 0);
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Count entries that have a specific taxonomy term
|
|
145
|
-
*/
|
|
146
|
-
async countEntriesWithTerm(taxonomyId) {
|
|
147
|
-
const result = await this.db.selectFrom("content_taxonomies").select((eb) => eb.fn.count("entry_id").as("count")).where("taxonomy_id", "=", taxonomyId).executeTakeFirst();
|
|
148
|
-
return Number(result?.count || 0);
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Batch count entries for multiple taxonomy term IDs.
|
|
152
|
-
* Chunks the query at SQL_BATCH_SIZE to stay below D1's bind-parameter limit.
|
|
153
|
-
* Returns a Map from term ID to count.
|
|
154
|
-
*/
|
|
155
|
-
async countEntriesForTerms(termIds) {
|
|
156
|
-
if (termIds.length === 0) return /* @__PURE__ */ new Map();
|
|
157
|
-
const { chunks, SQL_BATCH_SIZE } = await import("./chunks-NBQVDOci.mjs").then((n) => n.r);
|
|
158
|
-
const counts = /* @__PURE__ */ new Map();
|
|
159
|
-
for (const chunk of chunks(termIds, SQL_BATCH_SIZE)) {
|
|
160
|
-
const rows = await this.db.selectFrom("content_taxonomies").select(["taxonomy_id", (eb) => eb.fn.count("entry_id").as("count")]).where("taxonomy_id", "in", chunk).groupBy("taxonomy_id").execute();
|
|
161
|
-
for (const row of rows) counts.set(row.taxonomy_id, Number(row.count || 0));
|
|
162
|
-
}
|
|
163
|
-
return counts;
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Convert database row to Taxonomy object
|
|
167
|
-
*/
|
|
168
|
-
rowToTaxonomy(row) {
|
|
169
|
-
return {
|
|
170
|
-
id: row.id,
|
|
171
|
-
name: row.name,
|
|
172
|
-
slug: row.slug,
|
|
173
|
-
label: row.label,
|
|
174
|
-
parentId: row.parent_id,
|
|
175
|
-
data: row.data ? JSON.parse(row.data) : null
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
//#endregion
|
|
181
18
|
//#region src/settings/index.ts
|
|
182
19
|
/** Prefix for site settings in the options table */
|
|
183
20
|
const SETTINGS_PREFIX = "site:";
|
|
@@ -895,49 +732,78 @@ async function applySeed(db, seed, options = {}) {
|
|
|
895
732
|
}
|
|
896
733
|
}
|
|
897
734
|
}
|
|
898
|
-
if (seed.taxonomies)
|
|
899
|
-
const
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
735
|
+
if (seed.taxonomies) {
|
|
736
|
+
const defSeedIdMap = /* @__PURE__ */ new Map();
|
|
737
|
+
const termSeedIdMap = /* @__PURE__ */ new Map();
|
|
738
|
+
const fallbackLocale = getI18nConfig()?.defaultLocale ?? "en";
|
|
739
|
+
for (const taxonomy of seed.taxonomies) {
|
|
740
|
+
const defLocale = taxonomy.locale ?? fallbackLocale;
|
|
741
|
+
const existingDef = await db.selectFrom("_emdash_taxonomy_defs").selectAll().where("name", "=", taxonomy.name).where("locale", "=", defLocale).executeTakeFirst();
|
|
742
|
+
let defId;
|
|
743
|
+
let defTranslationGroup;
|
|
744
|
+
if (existingDef) {
|
|
745
|
+
defId = existingDef.id;
|
|
746
|
+
defTranslationGroup = existingDef.translation_group ?? existingDef.id;
|
|
747
|
+
if (onConflict === "error") throw new Error(`Conflict: taxonomy "${taxonomy.name}" (${defLocale}) already exists`);
|
|
748
|
+
if (onConflict === "update") await db.updateTable("_emdash_taxonomy_defs").set({
|
|
749
|
+
label: taxonomy.label,
|
|
750
|
+
label_singular: taxonomy.labelSingular ?? null,
|
|
751
|
+
hierarchical: taxonomy.hierarchical ? 1 : 0,
|
|
752
|
+
collections: JSON.stringify(taxonomy.collections)
|
|
753
|
+
}).where("id", "=", existingDef.id).execute();
|
|
754
|
+
} else {
|
|
755
|
+
defId = ulid();
|
|
756
|
+
defTranslationGroup = defId;
|
|
757
|
+
if (taxonomy.translationOf) {
|
|
758
|
+
const source = defSeedIdMap.get(taxonomy.translationOf);
|
|
759
|
+
if (source) defTranslationGroup = source.translationGroup;
|
|
760
|
+
else console.warn(`taxonomy "${taxonomy.name}" (${defLocale}): translationOf "${taxonomy.translationOf}" not found yet; minting a fresh group.`);
|
|
761
|
+
}
|
|
762
|
+
await db.insertInto("_emdash_taxonomy_defs").values({
|
|
763
|
+
id: defId,
|
|
764
|
+
name: taxonomy.name,
|
|
765
|
+
label: taxonomy.label,
|
|
766
|
+
label_singular: taxonomy.labelSingular ?? null,
|
|
767
|
+
hierarchical: taxonomy.hierarchical ? 1 : 0,
|
|
768
|
+
collections: JSON.stringify(taxonomy.collections),
|
|
769
|
+
locale: defLocale,
|
|
770
|
+
translation_group: defTranslationGroup
|
|
771
|
+
}).execute();
|
|
772
|
+
result.taxonomies.created++;
|
|
773
|
+
}
|
|
774
|
+
if (taxonomy.id) defSeedIdMap.set(taxonomy.id, {
|
|
775
|
+
id: defId,
|
|
776
|
+
translationGroup: defTranslationGroup
|
|
777
|
+
});
|
|
778
|
+
if (taxonomy.terms && taxonomy.terms.length > 0) {
|
|
779
|
+
const termRepo = new TaxonomyRepository(db);
|
|
780
|
+
if (taxonomy.hierarchical) await applyHierarchicalTerms(termRepo, taxonomy.name, defLocale, taxonomy.terms, termSeedIdMap, result, onConflict);
|
|
781
|
+
else for (const term of taxonomy.terms) {
|
|
782
|
+
const termLocale = term.locale ?? defLocale;
|
|
783
|
+
const existing = await termRepo.findBySlug(taxonomy.name, term.slug, termLocale);
|
|
784
|
+
if (existing) {
|
|
785
|
+
if (onConflict === "error") throw new Error(`Conflict: taxonomy term "${term.slug}" in "${taxonomy.name}" (${termLocale}) already exists`);
|
|
786
|
+
if (onConflict === "update") {
|
|
787
|
+
await termRepo.update(existing.id, {
|
|
788
|
+
label: term.label,
|
|
789
|
+
data: term.description ? { description: term.description } : {}
|
|
790
|
+
});
|
|
791
|
+
result.taxonomies.terms++;
|
|
792
|
+
}
|
|
793
|
+
if (term.id) termSeedIdMap.set(term.id, existing.id);
|
|
794
|
+
} else {
|
|
795
|
+
const translationOf = term.translationOf ? termSeedIdMap.get(term.translationOf) : void 0;
|
|
796
|
+
const created = await termRepo.create({
|
|
797
|
+
name: taxonomy.name,
|
|
798
|
+
slug: term.slug,
|
|
928
799
|
label: term.label,
|
|
929
|
-
data: term.description ? { description: term.description } :
|
|
800
|
+
data: term.description ? { description: term.description } : void 0,
|
|
801
|
+
locale: termLocale,
|
|
802
|
+
translationOf
|
|
930
803
|
});
|
|
804
|
+
if (term.id) termSeedIdMap.set(term.id, created.id);
|
|
931
805
|
result.taxonomies.terms++;
|
|
932
806
|
}
|
|
933
|
-
} else {
|
|
934
|
-
await termRepo.create({
|
|
935
|
-
name: taxonomy.name,
|
|
936
|
-
slug: term.slug,
|
|
937
|
-
label: term.label,
|
|
938
|
-
data: term.description ? { description: term.description } : void 0
|
|
939
|
-
});
|
|
940
|
-
result.taxonomies.terms++;
|
|
941
807
|
}
|
|
942
808
|
}
|
|
943
809
|
}
|
|
@@ -1040,25 +906,45 @@ async function applySeed(db, seed, options = {}) {
|
|
|
1040
906
|
result.content.created++;
|
|
1041
907
|
}
|
|
1042
908
|
}
|
|
1043
|
-
if (seed.menus)
|
|
1044
|
-
const
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
menuId
|
|
1051
|
-
|
|
909
|
+
if (seed.menus) {
|
|
910
|
+
const menuSeedIdMap = /* @__PURE__ */ new Map();
|
|
911
|
+
const itemSeedIdMap = /* @__PURE__ */ new Map();
|
|
912
|
+
const fallbackLocale = getI18nConfig()?.defaultLocale ?? "en";
|
|
913
|
+
for (const menu of seed.menus) {
|
|
914
|
+
const locale = menu.locale ?? fallbackLocale;
|
|
915
|
+
const existingMenu = await db.selectFrom("_emdash_menus").selectAll().where("name", "=", menu.name).where("locale", "=", locale).executeTakeFirst();
|
|
916
|
+
let menuId;
|
|
917
|
+
let translationGroup;
|
|
918
|
+
if (existingMenu) {
|
|
919
|
+
menuId = existingMenu.id;
|
|
920
|
+
translationGroup = existingMenu.translation_group ?? existingMenu.id;
|
|
921
|
+
await db.deleteFrom("_emdash_menu_items").where("menu_id", "=", menuId).execute();
|
|
922
|
+
} else {
|
|
923
|
+
menuId = ulid();
|
|
924
|
+
translationGroup = menuId;
|
|
925
|
+
if (menu.translationOf) {
|
|
926
|
+
const source = menuSeedIdMap.get(menu.translationOf);
|
|
927
|
+
if (source) translationGroup = source.translationGroup;
|
|
928
|
+
else console.warn(`menu "${menu.name}" (${locale}): translationOf "${menu.translationOf}" not found yet; minting a fresh group.`);
|
|
929
|
+
}
|
|
930
|
+
await db.insertInto("_emdash_menus").values({
|
|
931
|
+
id: menuId,
|
|
932
|
+
name: menu.name,
|
|
933
|
+
label: menu.label,
|
|
934
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
935
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
936
|
+
locale,
|
|
937
|
+
translation_group: translationGroup
|
|
938
|
+
}).execute();
|
|
939
|
+
result.menus.created++;
|
|
940
|
+
}
|
|
941
|
+
if (menu.id) menuSeedIdMap.set(menu.id, {
|
|
1052
942
|
id: menuId,
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
}).execute();
|
|
1058
|
-
result.menus.created++;
|
|
943
|
+
translationGroup
|
|
944
|
+
});
|
|
945
|
+
const itemCount = await applyMenuItems(db, menuId, locale, menu.items, null, 0, seedIdMap, itemSeedIdMap);
|
|
946
|
+
result.menus.items += itemCount;
|
|
1059
947
|
}
|
|
1060
|
-
const itemCount = await applyMenuItems(db, menuId, menu.items, null, 0, seedIdMap);
|
|
1061
|
-
result.menus.items += itemCount;
|
|
1062
948
|
}
|
|
1063
949
|
if (seed.redirects) {
|
|
1064
950
|
const redirectRepo = new RedirectRepository(db);
|
|
@@ -1157,9 +1043,9 @@ async function applySeed(db, seed, options = {}) {
|
|
|
1157
1043
|
}
|
|
1158
1044
|
}
|
|
1159
1045
|
}
|
|
1160
|
-
const { invalidateBylineCache } = await import("./bylines-
|
|
1161
|
-
const { invalidateRedirectCache } = await import("./cache-
|
|
1162
|
-
const { invalidateUrlPatternCache } = await import("./query-
|
|
1046
|
+
const { invalidateBylineCache } = await import("./bylines-DTFI8nDM.mjs").then((n) => n.t);
|
|
1047
|
+
const { invalidateRedirectCache } = await import("./cache-BAJbeoZ8.mjs").then((n) => n.t);
|
|
1048
|
+
const { invalidateUrlPatternCache } = await import("./query-8c_meo_K.mjs").then((n) => n.o);
|
|
1163
1049
|
invalidateBylineCache();
|
|
1164
1050
|
invalidateRedirectCache();
|
|
1165
1051
|
invalidateUrlPatternCache();
|
|
@@ -1168,17 +1054,22 @@ async function applySeed(db, seed, options = {}) {
|
|
|
1168
1054
|
/**
|
|
1169
1055
|
* Apply hierarchical taxonomy terms (parents before children)
|
|
1170
1056
|
*/
|
|
1171
|
-
async function applyHierarchicalTerms(termRepo, taxonomyName, terms, result, onConflict = "skip") {
|
|
1057
|
+
async function applyHierarchicalTerms(termRepo, taxonomyName, defLocale, terms, termSeedIdMap, result, onConflict = "skip") {
|
|
1172
1058
|
const slugToId = /* @__PURE__ */ new Map();
|
|
1173
1059
|
let remaining = [...terms];
|
|
1174
1060
|
let maxPasses = 10;
|
|
1175
1061
|
while (remaining.length > 0 && maxPasses > 0) {
|
|
1176
1062
|
const processedThisPass = [];
|
|
1177
|
-
for (const term of remaining)
|
|
1178
|
-
const
|
|
1179
|
-
const
|
|
1063
|
+
for (const term of remaining) {
|
|
1064
|
+
const termLocale = term.locale ?? defLocale;
|
|
1065
|
+
const parentReady = !term.parent || slugToId.has(`${termLocale}::${term.parent}`);
|
|
1066
|
+
const translationReady = !term.translationOf || termSeedIdMap.has(term.translationOf);
|
|
1067
|
+
if (!parentReady || !translationReady) continue;
|
|
1068
|
+
const parentId = term.parent ? slugToId.get(`${termLocale}::${term.parent}`) : void 0;
|
|
1069
|
+
const translationOf = term.translationOf ? termSeedIdMap.get(term.translationOf) : void 0;
|
|
1070
|
+
const existing = await termRepo.findBySlug(taxonomyName, term.slug, termLocale);
|
|
1180
1071
|
if (existing) {
|
|
1181
|
-
if (onConflict === "error") throw new Error(`Conflict: taxonomy term "${term.slug}" in "${taxonomyName}" already exists`);
|
|
1072
|
+
if (onConflict === "error") throw new Error(`Conflict: taxonomy term "${term.slug}" in "${taxonomyName}" (${termLocale}) already exists`);
|
|
1182
1073
|
if (onConflict === "update") {
|
|
1183
1074
|
await termRepo.update(existing.id, {
|
|
1184
1075
|
label: term.label,
|
|
@@ -1187,24 +1078,28 @@ async function applyHierarchicalTerms(termRepo, taxonomyName, terms, result, onC
|
|
|
1187
1078
|
});
|
|
1188
1079
|
result.taxonomies.terms++;
|
|
1189
1080
|
}
|
|
1190
|
-
slugToId.set(term.slug
|
|
1081
|
+
slugToId.set(`${termLocale}::${term.slug}`, existing.id);
|
|
1082
|
+
if (term.id) termSeedIdMap.set(term.id, existing.id);
|
|
1191
1083
|
} else {
|
|
1192
1084
|
const created = await termRepo.create({
|
|
1193
1085
|
name: taxonomyName,
|
|
1194
1086
|
slug: term.slug,
|
|
1195
1087
|
label: term.label,
|
|
1196
1088
|
parentId,
|
|
1197
|
-
data: term.description ? { description: term.description } : void 0
|
|
1089
|
+
data: term.description ? { description: term.description } : void 0,
|
|
1090
|
+
locale: termLocale,
|
|
1091
|
+
translationOf
|
|
1198
1092
|
});
|
|
1199
|
-
slugToId.set(term.slug
|
|
1093
|
+
slugToId.set(`${termLocale}::${term.slug}`, created.id);
|
|
1094
|
+
if (term.id) termSeedIdMap.set(term.id, created.id);
|
|
1200
1095
|
result.taxonomies.terms++;
|
|
1201
1096
|
}
|
|
1202
|
-
processedThisPass.push(term.slug);
|
|
1097
|
+
processedThisPass.push(term.slug + "::" + termLocale);
|
|
1203
1098
|
}
|
|
1204
|
-
remaining = remaining.filter((t) => !processedThisPass.includes(t.slug));
|
|
1099
|
+
remaining = remaining.filter((t) => !processedThisPass.includes(t.slug + "::" + (t.locale ?? defLocale)));
|
|
1205
1100
|
maxPasses--;
|
|
1206
1101
|
}
|
|
1207
|
-
if (remaining.length > 0) console.warn(`Could not process ${remaining.length} terms due to missing parents`);
|
|
1102
|
+
if (remaining.length > 0) console.warn(`Could not process ${remaining.length} terms due to missing parents/translations`);
|
|
1208
1103
|
}
|
|
1209
1104
|
/**
|
|
1210
1105
|
* Apply byline credits to a content entry.
|
|
@@ -1234,7 +1129,7 @@ async function applyContentTaxonomies(db, collectionSlug, contentId, entry, isUp
|
|
|
1234
1129
|
if (isUpdate) await db.deleteFrom("content_taxonomies").where("collection", "=", collectionSlug).where("entry_id", "=", contentId).execute();
|
|
1235
1130
|
if (!entry.taxonomies) {
|
|
1236
1131
|
if (isUpdate) {
|
|
1237
|
-
const { invalidateTermCache } = await import("./taxonomies-
|
|
1132
|
+
const { invalidateTermCache } = await import("./taxonomies-Bw76xAxo.mjs").then((n) => n.u);
|
|
1238
1133
|
invalidateTermCache();
|
|
1239
1134
|
}
|
|
1240
1135
|
return;
|
|
@@ -1246,17 +1141,23 @@ async function applyContentTaxonomies(db, collectionSlug, contentId, entry, isUp
|
|
|
1246
1141
|
if (term) await termRepo.attachToEntry(collectionSlug, contentId, term.id);
|
|
1247
1142
|
}
|
|
1248
1143
|
}
|
|
1249
|
-
const { invalidateTermCache } = await import("./taxonomies-
|
|
1144
|
+
const { invalidateTermCache } = await import("./taxonomies-Bw76xAxo.mjs").then((n) => n.u);
|
|
1250
1145
|
invalidateTermCache();
|
|
1251
1146
|
}
|
|
1252
1147
|
/**
|
|
1253
|
-
* Apply menu items recursively
|
|
1148
|
+
* Apply menu items recursively.
|
|
1149
|
+
*
|
|
1150
|
+
* When a `SeedMenuItem` carries `id`/`translationOf`, the import resolves the
|
|
1151
|
+
* source item's `translation_group` so cross-locale "same nav entry" links
|
|
1152
|
+
* survive export → apply. Items without `translationOf` get a fresh group
|
|
1153
|
+
* (= their own id).
|
|
1254
1154
|
*/
|
|
1255
|
-
async function applyMenuItems(db, menuId, items, parentId, startOrder, seedIdMap) {
|
|
1155
|
+
async function applyMenuItems(db, menuId, locale, items, parentId, startOrder, seedIdMap, itemSeedIdMap) {
|
|
1256
1156
|
let count = 0;
|
|
1257
1157
|
let order = startOrder;
|
|
1258
1158
|
for (const item of items) {
|
|
1259
1159
|
const itemId = ulid();
|
|
1160
|
+
const itemLocale = item.locale ?? locale;
|
|
1260
1161
|
let referenceId = null;
|
|
1261
1162
|
let referenceCollection = null;
|
|
1262
1163
|
if (item.type === "page" || item.type === "post") {
|
|
@@ -1265,6 +1166,12 @@ async function applyMenuItems(db, menuId, items, parentId, startOrder, seedIdMap
|
|
|
1265
1166
|
referenceCollection = item.collection || `${item.type}s`;
|
|
1266
1167
|
}
|
|
1267
1168
|
}
|
|
1169
|
+
let translationGroup = itemId;
|
|
1170
|
+
if (item.translationOf) {
|
|
1171
|
+
const source = itemSeedIdMap.get(item.translationOf);
|
|
1172
|
+
if (source) translationGroup = source.translationGroup;
|
|
1173
|
+
else console.warn(`menu item "${item.label ?? item.url ?? item.ref ?? "(unlabeled)"}" (${itemLocale}): translationOf "${item.translationOf}" not found yet; minting a fresh group.`);
|
|
1174
|
+
}
|
|
1268
1175
|
await db.insertInto("_emdash_menu_items").values({
|
|
1269
1176
|
id: itemId,
|
|
1270
1177
|
menu_id: menuId,
|
|
@@ -1278,12 +1185,18 @@ async function applyMenuItems(db, menuId, items, parentId, startOrder, seedIdMap
|
|
|
1278
1185
|
title_attr: item.titleAttr ?? null,
|
|
1279
1186
|
target: item.target ?? null,
|
|
1280
1187
|
css_classes: item.cssClasses ?? null,
|
|
1281
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1188
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1189
|
+
locale: itemLocale,
|
|
1190
|
+
translation_group: translationGroup
|
|
1282
1191
|
}).execute();
|
|
1192
|
+
if (item.id) itemSeedIdMap.set(item.id, {
|
|
1193
|
+
id: itemId,
|
|
1194
|
+
translationGroup
|
|
1195
|
+
});
|
|
1283
1196
|
count++;
|
|
1284
1197
|
order++;
|
|
1285
1198
|
if (item.children && item.children.length > 0) {
|
|
1286
|
-
const childCount = await applyMenuItems(db, menuId, item.children, itemId, 0, seedIdMap);
|
|
1199
|
+
const childCount = await applyMenuItems(db, menuId, itemLocale, item.children, itemId, 0, seedIdMap, itemSeedIdMap);
|
|
1287
1200
|
count += childCount;
|
|
1288
1201
|
}
|
|
1289
1202
|
}
|
|
@@ -1474,5 +1387,5 @@ function getImageDimensions(buffer) {
|
|
|
1474
1387
|
}
|
|
1475
1388
|
|
|
1476
1389
|
//#endregion
|
|
1477
|
-
export { ssrfSafeFetch as a, getPluginSetting as c, getSiteSettings as d, setSiteSettings as f, resolveAndValidateExternalUrl as i, getPluginSettings as l, apply_exports as n, stripCredentialHeaders as o,
|
|
1478
|
-
//# sourceMappingURL=apply-
|
|
1390
|
+
export { ssrfSafeFetch as a, getPluginSetting as c, getSiteSettings as d, setSiteSettings as f, resolveAndValidateExternalUrl as i, getPluginSettings as l, apply_exports as n, stripCredentialHeaders as o, SsrfError as r, validateExternalUrl as s, applySeed as t, getSiteSetting as u };
|
|
1391
|
+
//# sourceMappingURL=apply-Ded_1vng.mjs.map
|