emdash 0.17.0 → 0.17.1
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/{apply-CgamLmed.mjs → apply-CuuZG6op.mjs} +4 -4
- package/dist/{apply-CgamLmed.mjs.map → apply-CuuZG6op.mjs.map} +1 -1
- package/dist/astro/index.mjs +10 -1
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware.mjs +6 -6
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/index.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +3 -3
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +2 -2
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +3 -3
- package/dist/astro/routes/api/admin/plugins/updates.mjs +2 -2
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +2 -2
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +2 -2
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +1 -1
- package/dist/astro/routes/api/import/wordpress/execute.mjs +1 -1
- package/dist/astro/routes/api/manifest.mjs +1 -1
- package/dist/astro/routes/api/mcp.mjs +6 -6
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +2 -2
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +2 -2
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +2 -2
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +2 -2
- package/dist/astro/routes/api/schema/collections/index.mjs +2 -2
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +2 -2
- package/dist/astro/routes/api/schema/orphans/index.mjs +2 -2
- package/dist/astro/routes/api/setup/dev-bypass.mjs +1 -1
- package/dist/astro/routes/api/setup/index.mjs +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +2 -2
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +2 -2
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +2 -2
- package/dist/astro/routes/api/taxonomies/index.mjs +2 -2
- package/dist/cli/index.mjs +113 -11
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.mjs +4 -4
- package/dist/{query-CuvjwhrE.mjs → query-Bt52mHXp.mjs} +9 -8
- package/dist/query-Bt52mHXp.mjs.map +1 -0
- package/dist/seed/index.mjs +1 -1
- package/dist/{taxonomies-CgpzAU6F.mjs → taxonomies-ByLlXrv5.mjs} +2 -2
- package/dist/{taxonomies-CgpzAU6F.mjs.map → taxonomies-ByLlXrv5.mjs.map} +1 -1
- package/dist/{taxonomies-D72gTOg_.mjs → taxonomies-CbO6v7EE.mjs} +2 -2
- package/dist/{taxonomies-D72gTOg_.mjs.map → taxonomies-CbO6v7EE.mjs.map} +1 -1
- package/dist/version-CWbvq9LG.mjs +7 -0
- package/dist/{version-FGcv0ooe.mjs.map → version-CWbvq9LG.mjs.map} +1 -1
- package/package.json +6 -6
- package/src/astro/integration/vite-config.ts +16 -0
- package/src/cli/commands/export-seed.ts +174 -12
- package/src/query.ts +7 -7
- package/dist/query-CuvjwhrE.mjs.map +0 -1
- package/dist/version-FGcv0ooe.mjs +0 -7
package/dist/cli/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { i as __exportAll, r as runMigrations, t as getMigrationStatus } from "../runner-eAgyIkeg.mjs";
|
|
3
3
|
import { t as EmDashDatabaseError } from "../errors-9P_FDrJ_.mjs";
|
|
4
|
+
import { t as validateIdentifier } from "../validate-VPnKoIzW.mjs";
|
|
4
5
|
import { c as listTablesLike } from "../dialect-helpers-BKCvISIQ.mjs";
|
|
5
6
|
import { r as isI18nEnabled } from "../config-CVssduLe.mjs";
|
|
6
7
|
import { n as slugify } from "../slugify-Cjh1ssOZ.mjs";
|
|
@@ -13,7 +14,8 @@ import { t as OptionsRepository } from "../options-BL4X94qY.mjs";
|
|
|
13
14
|
import "../redirect-BZUJltlj.mjs";
|
|
14
15
|
import "../request-cache-BYMs-BGX.mjs";
|
|
15
16
|
import "../byline-registry-CxK5g559.mjs";
|
|
16
|
-
import "../byline-BrIVWLm-.mjs";
|
|
17
|
+
import { t as BylineRepository } from "../byline-BrIVWLm-.mjs";
|
|
18
|
+
import { n as isMissingTableError } from "../db-errors-CtzxKBxe.mjs";
|
|
17
19
|
import "../fts-manager-DmUAk-kQ.mjs";
|
|
18
20
|
import { n as SchemaRegistry } from "../registry-Dn6gsx3L.mjs";
|
|
19
21
|
import { kyselyLogOption } from "../database/instrumentation.mjs";
|
|
@@ -24,7 +26,7 @@ import { n as isDeprecatedCapability, t as CAPABILITY_RENAMES } from "../types-C
|
|
|
24
26
|
import "../ssrf-BsVGIE0Z.mjs";
|
|
25
27
|
import "../ssrf-BvgVcfNQ.mjs";
|
|
26
28
|
import { t as validateSeed } from "../validate-DactmcJG.mjs";
|
|
27
|
-
import { t as applySeed } from "../apply-
|
|
29
|
+
import { t as applySeed } from "../apply-CuuZG6op.mjs";
|
|
28
30
|
import { n as fingerprintKey, r as generateEncryptionKey, t as EmDashSecretsError } from "../secrets-YYbTgB1w.mjs";
|
|
29
31
|
import { LocalStorage } from "../storage/local.mjs";
|
|
30
32
|
import { o as convertDataForRead } from "../transport--Ck3RBin.mjs";
|
|
@@ -1248,16 +1250,97 @@ async function exportSeed(db, withContent) {
|
|
|
1248
1250
|
};
|
|
1249
1251
|
seed.settings = await exportSettings(db);
|
|
1250
1252
|
seed.collections = await exportCollections(db);
|
|
1251
|
-
|
|
1252
|
-
seed.
|
|
1253
|
+
const i18nEnabled = await detectI18nEnabled(db, seed.collections);
|
|
1254
|
+
seed.taxonomies = await exportTaxonomies(db, i18nEnabled);
|
|
1255
|
+
seed.menus = await exportMenus(db, i18nEnabled);
|
|
1253
1256
|
seed.widgetAreas = await exportWidgetAreas(db);
|
|
1257
|
+
const { bylines, groupToSeedId } = await exportBylines(db);
|
|
1258
|
+
if (bylines.length > 0) seed.bylines = bylines;
|
|
1254
1259
|
if (withContent !== void 0) {
|
|
1255
1260
|
const collections = withContent === "" || withContent === "true" ? null : withContent.split(",").map((s) => s.trim()).filter(Boolean);
|
|
1256
|
-
seed.content = await exportContent(db, seed.collections || [], collections);
|
|
1261
|
+
seed.content = await exportContent(db, seed.collections || [], collections, groupToSeedId, i18nEnabled);
|
|
1257
1262
|
}
|
|
1258
1263
|
return seed;
|
|
1259
1264
|
}
|
|
1260
1265
|
/**
|
|
1266
|
+
* Export byline profiles as root-level `bylines[]`.
|
|
1267
|
+
*
|
|
1268
|
+
* `SeedByline` has no locale axis, so locale siblings of the same byline
|
|
1269
|
+
* (sharing a `translation_group`) collapse to a single profile. The returned
|
|
1270
|
+
* `groupToSeedId` map keys on `translation_group` — the value stored in
|
|
1271
|
+
* `_emdash_content_bylines.byline_id` — so content credits can resolve to the
|
|
1272
|
+
* emitted seed id.
|
|
1273
|
+
*/
|
|
1274
|
+
async function exportBylines(db) {
|
|
1275
|
+
const bylineRepo = new BylineRepository(db);
|
|
1276
|
+
const bylines = [];
|
|
1277
|
+
const groupToSeedId = /* @__PURE__ */ new Map();
|
|
1278
|
+
const usedSeedIds = /* @__PURE__ */ new Set();
|
|
1279
|
+
let cursor;
|
|
1280
|
+
do {
|
|
1281
|
+
const result = await bylineRepo.findMany({
|
|
1282
|
+
limit: 100,
|
|
1283
|
+
cursor
|
|
1284
|
+
});
|
|
1285
|
+
for (const byline of result.items) {
|
|
1286
|
+
const group = byline.translationGroup ?? byline.id;
|
|
1287
|
+
if (groupToSeedId.has(group)) continue;
|
|
1288
|
+
let seedId = `byline:${byline.slug}`;
|
|
1289
|
+
if (usedSeedIds.has(seedId)) seedId = `byline:${byline.slug}:${group}`;
|
|
1290
|
+
usedSeedIds.add(seedId);
|
|
1291
|
+
groupToSeedId.set(group, seedId);
|
|
1292
|
+
bylines.push({
|
|
1293
|
+
id: seedId,
|
|
1294
|
+
slug: byline.slug,
|
|
1295
|
+
displayName: byline.displayName,
|
|
1296
|
+
bio: byline.bio || void 0,
|
|
1297
|
+
websiteUrl: byline.websiteUrl || void 0,
|
|
1298
|
+
isGuest: byline.isGuest || void 0
|
|
1299
|
+
});
|
|
1300
|
+
}
|
|
1301
|
+
cursor = result.nextCursor;
|
|
1302
|
+
} while (cursor);
|
|
1303
|
+
return {
|
|
1304
|
+
bylines,
|
|
1305
|
+
groupToSeedId
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
/**
|
|
1309
|
+
* Determine whether the export should emit locale-suffixed seed ids.
|
|
1310
|
+
*
|
|
1311
|
+
* The runtime initializes the i18n config in middleware, but the CLI never does,
|
|
1312
|
+
* so `isI18nEnabled()` is always false under `emdash export-seed` (#1330). When
|
|
1313
|
+
* the flag is unset, fall back to the data: a project is multi-locale when its
|
|
1314
|
+
* i18n-aware tables hold rows in more than one distinct locale. `locale` is
|
|
1315
|
+
* NOT NULL (defaulting to the site's default locale), so a per-row presence
|
|
1316
|
+
* check is not enough — only the *count* of distinct locales distinguishes a
|
|
1317
|
+
* genuinely single-locale project from a multi-locale one. This keeps
|
|
1318
|
+
* single-locale exports on bare ids and gives multi-locale exports the
|
|
1319
|
+
* per-locale suffix they need to avoid duplicate seed ids.
|
|
1320
|
+
*/
|
|
1321
|
+
async function detectI18nEnabled(db, collections) {
|
|
1322
|
+
if (isI18nEnabled()) return true;
|
|
1323
|
+
const locales = /* @__PURE__ */ new Set();
|
|
1324
|
+
const collectDistinctLocales = async (tableRef) => {
|
|
1325
|
+
const result = await sql`
|
|
1326
|
+
SELECT DISTINCT locale FROM ${tableRef}
|
|
1327
|
+
`.execute(db);
|
|
1328
|
+
for (const row of result.rows) if (row.locale) locales.add(row.locale);
|
|
1329
|
+
return locales.size > 1;
|
|
1330
|
+
};
|
|
1331
|
+
if (await collectDistinctLocales(sql.ref("_emdash_taxonomy_defs"))) return true;
|
|
1332
|
+
if (await collectDistinctLocales(sql.ref("_emdash_menus"))) return true;
|
|
1333
|
+
for (const collection of collections) {
|
|
1334
|
+
validateIdentifier(collection.slug, "collection slug");
|
|
1335
|
+
try {
|
|
1336
|
+
if (await collectDistinctLocales(sql.ref(`ec_${collection.slug}`))) return true;
|
|
1337
|
+
} catch (error) {
|
|
1338
|
+
if (!isMissingTableError(error)) throw error;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
return false;
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1261
1344
|
* Export site settings
|
|
1262
1345
|
*/
|
|
1263
1346
|
async function exportSettings(db) {
|
|
@@ -1306,8 +1389,7 @@ async function exportCollections(db) {
|
|
|
1306
1389
|
/**
|
|
1307
1390
|
* Export taxonomy definitions and terms
|
|
1308
1391
|
*/
|
|
1309
|
-
async function exportTaxonomies(db) {
|
|
1310
|
-
const i18nEnabled = isI18nEnabled();
|
|
1392
|
+
async function exportTaxonomies(db, i18nEnabled) {
|
|
1311
1393
|
const defs = await db.selectFrom("_emdash_taxonomy_defs").selectAll().orderBy(["name", "locale"]).execute();
|
|
1312
1394
|
const result = [];
|
|
1313
1395
|
const termRepo = new TaxonomyRepository(db);
|
|
@@ -1364,8 +1446,7 @@ async function exportTaxonomies(db) {
|
|
|
1364
1446
|
/**
|
|
1365
1447
|
* Export menus with their items
|
|
1366
1448
|
*/
|
|
1367
|
-
async function exportMenus(db) {
|
|
1368
|
-
const i18nEnabled = isI18nEnabled();
|
|
1449
|
+
async function exportMenus(db, i18nEnabled) {
|
|
1369
1450
|
const menus = await db.selectFrom("_emdash_menus").selectAll().orderBy(["name", "locale"]).execute();
|
|
1370
1451
|
const result = [];
|
|
1371
1452
|
const groupToSeedId = /* @__PURE__ */ new Map();
|
|
@@ -1487,7 +1568,7 @@ async function exportWidgetAreas(db) {
|
|
|
1487
1568
|
/**
|
|
1488
1569
|
* Export content from collections
|
|
1489
1570
|
*/
|
|
1490
|
-
async function exportContent(db, collections, includeCollections) {
|
|
1571
|
+
async function exportContent(db, collections, includeCollections, bylineGroupToSeedId, i18nEnabled) {
|
|
1491
1572
|
const content = {};
|
|
1492
1573
|
const contentRepo = new ContentRepository(db);
|
|
1493
1574
|
const taxonomyRepo = new TaxonomyRepository(db);
|
|
@@ -1510,7 +1591,6 @@ async function exportContent(db, collections, includeCollections) {
|
|
|
1510
1591
|
cursor = result.nextCursor;
|
|
1511
1592
|
} while (cursor);
|
|
1512
1593
|
} catch {}
|
|
1513
|
-
const i18nEnabled = isI18nEnabled();
|
|
1514
1594
|
for (const collection of collections) {
|
|
1515
1595
|
if (includeCollections && !includeCollections.includes(collection.slug)) continue;
|
|
1516
1596
|
const entries = [];
|
|
@@ -1540,6 +1620,8 @@ async function exportContent(db, collections, includeCollections) {
|
|
|
1540
1620
|
}
|
|
1541
1621
|
const taxonomies = await getTaxonomyAssignments(taxonomyRepo, collection.slug, item.id);
|
|
1542
1622
|
if (Object.keys(taxonomies).length > 0) entry.taxonomies = taxonomies;
|
|
1623
|
+
const bylines = await getBylineCredits(db, collection.slug, item.id, bylineGroupToSeedId);
|
|
1624
|
+
if (bylines.length > 0) entry.bylines = bylines;
|
|
1543
1625
|
entries.push(entry);
|
|
1544
1626
|
}
|
|
1545
1627
|
cursor = result.nextCursor;
|
|
@@ -1587,6 +1669,26 @@ function processDataForExport(data, fields, mediaMap) {
|
|
|
1587
1669
|
return result;
|
|
1588
1670
|
}
|
|
1589
1671
|
/**
|
|
1672
|
+
* Get ordered byline credits for a content entry as `SeedBylineCredit[]`.
|
|
1673
|
+
*
|
|
1674
|
+
* The `_emdash_content_bylines.byline_id` column stores the credited byline's
|
|
1675
|
+
* `translation_group`, so it maps straight through `groupToSeedId`. Credits
|
|
1676
|
+
* whose group wasn't emitted in the root `bylines[]` are skipped (defensive;
|
|
1677
|
+
* shouldn't happen for a consistent DB).
|
|
1678
|
+
*/
|
|
1679
|
+
async function getBylineCredits(db, collection, entryId, groupToSeedId) {
|
|
1680
|
+
const rows = await db.selectFrom("_emdash_content_bylines").select(["byline_id", "role_label"]).where("collection_slug", "=", collection).where("content_id", "=", entryId).orderBy("sort_order", "asc").execute();
|
|
1681
|
+
const credits = [];
|
|
1682
|
+
for (const row of rows) {
|
|
1683
|
+
const seedId = groupToSeedId.get(row.byline_id);
|
|
1684
|
+
if (!seedId) continue;
|
|
1685
|
+
const credit = { byline: seedId };
|
|
1686
|
+
if (row.role_label) credit.roleLabel = row.role_label;
|
|
1687
|
+
credits.push(credit);
|
|
1688
|
+
}
|
|
1689
|
+
return credits;
|
|
1690
|
+
}
|
|
1691
|
+
/**
|
|
1590
1692
|
* Get taxonomy term assignments for a content entry
|
|
1591
1693
|
*/
|
|
1592
1694
|
async function getTaxonomyAssignments(taxonomyRepo, collection, entryId) {
|