@bobbykim/manguito-cms-cli 0.5.0 → 0.6.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.
|
@@ -49,7 +49,7 @@ var init_esm_shims = __esm({
|
|
|
49
49
|
}
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
// ../api/dist/chunk-
|
|
52
|
+
// ../api/dist/chunk-D5AO4BTL.mjs
|
|
53
53
|
init_esm_shims();
|
|
54
54
|
import crypto from "crypto";
|
|
55
55
|
|
|
@@ -1212,7 +1212,87 @@ Subquery.prototype.getSQL = function() {
|
|
|
1212
1212
|
return new SQL([this]);
|
|
1213
1213
|
};
|
|
1214
1214
|
|
|
1215
|
-
// ../api/dist/chunk-
|
|
1215
|
+
// ../api/dist/chunk-D5AO4BTL.mjs
|
|
1216
|
+
function isColumnBacked(field) {
|
|
1217
|
+
const col = field.db_column;
|
|
1218
|
+
if (col === null) return false;
|
|
1219
|
+
if (col.column_name === "") return false;
|
|
1220
|
+
if (col.junction) return false;
|
|
1221
|
+
return true;
|
|
1222
|
+
}
|
|
1223
|
+
function buildFieldKeyMap(pairs, allLabels, droppedKeys) {
|
|
1224
|
+
const labelToColumn = /* @__PURE__ */ new Map();
|
|
1225
|
+
const columnToLabel = /* @__PURE__ */ new Map();
|
|
1226
|
+
for (const { label, column } of pairs) {
|
|
1227
|
+
labelToColumn.set(label, column);
|
|
1228
|
+
columnToLabel.set(column, label);
|
|
1229
|
+
}
|
|
1230
|
+
for (const label of allLabels) {
|
|
1231
|
+
const columnOwner = columnToLabel.get(label);
|
|
1232
|
+
if (columnOwner !== void 0 && columnOwner !== label) {
|
|
1233
|
+
throw new Error(
|
|
1234
|
+
`Fatal: field key map failed to build \u2014 field label "${label}" collides with the storage column of field "${columnOwner}". A field label may not reuse another field's column name. Rename the field, then run \`manguito validate\` to check your schema.`
|
|
1235
|
+
);
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
for (const label of labelToColumn.keys()) {
|
|
1239
|
+
if (droppedKeys.has(label)) labelToColumn.delete(label);
|
|
1240
|
+
}
|
|
1241
|
+
for (const column of columnToLabel.keys()) {
|
|
1242
|
+
if (droppedKeys.has(column)) columnToLabel.delete(column);
|
|
1243
|
+
}
|
|
1244
|
+
const diverges = [...labelToColumn].some(([label, column]) => label !== column);
|
|
1245
|
+
function remap(input, lookup) {
|
|
1246
|
+
const out = {};
|
|
1247
|
+
for (const key of Object.keys(input)) {
|
|
1248
|
+
if (droppedKeys.has(key)) continue;
|
|
1249
|
+
out[lookup.get(key) ?? key] = input[key];
|
|
1250
|
+
}
|
|
1251
|
+
return out;
|
|
1252
|
+
}
|
|
1253
|
+
return {
|
|
1254
|
+
toStorage: (input) => remap(input, labelToColumn),
|
|
1255
|
+
toLabels: (row) => remap(row, columnToLabel),
|
|
1256
|
+
columnFor: (label) => labelToColumn.get(label),
|
|
1257
|
+
labelFor: (column) => columnToLabel.get(column),
|
|
1258
|
+
labels: [...labelToColumn.keys()],
|
|
1259
|
+
diverges
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
function createFieldKeyMap(fields) {
|
|
1263
|
+
const droppedKeys = /* @__PURE__ */ new Set();
|
|
1264
|
+
const pairs = [];
|
|
1265
|
+
for (const f of fields) {
|
|
1266
|
+
if (!isColumnBacked(f)) continue;
|
|
1267
|
+
pairs.push({ label: f.name, column: f.db_column.column_name });
|
|
1268
|
+
if (f.removed === true) {
|
|
1269
|
+
droppedKeys.add(f.name);
|
|
1270
|
+
droppedKeys.add(f.db_column.column_name);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
return buildFieldKeyMap(
|
|
1274
|
+
pairs,
|
|
1275
|
+
fields.map((f) => f.name),
|
|
1276
|
+
droppedKeys
|
|
1277
|
+
);
|
|
1278
|
+
}
|
|
1279
|
+
function createFieldKeyMapFromProjection(projectionType, allFields) {
|
|
1280
|
+
const pairs = projectionType.fields.map((f) => ({ label: f.exposed_as, column: f.column_name }));
|
|
1281
|
+
const projected = new Set(pairs.map((p) => p.label));
|
|
1282
|
+
const dropped = /* @__PURE__ */ new Set();
|
|
1283
|
+
for (const f of allFields) {
|
|
1284
|
+
if (!isColumnBacked(f)) continue;
|
|
1285
|
+
dropped.add(f.name);
|
|
1286
|
+
dropped.add(f.db_column.column_name);
|
|
1287
|
+
}
|
|
1288
|
+
for (const p of pairs) dropped.delete(p.column);
|
|
1289
|
+
for (const label of projected) dropped.delete(label);
|
|
1290
|
+
return buildFieldKeyMap(
|
|
1291
|
+
pairs,
|
|
1292
|
+
allFields.map((f) => f.name),
|
|
1293
|
+
dropped
|
|
1294
|
+
);
|
|
1295
|
+
}
|
|
1216
1296
|
function quoteIdent(name) {
|
|
1217
1297
|
if (!/^[a-z][a-z0-9_-]*$/.test(name)) throw new Error(`Unsafe identifier: ${name}`);
|
|
1218
1298
|
return `"${name}"`;
|
|
@@ -1506,58 +1586,6 @@ async function resolveRelationBareIds(db, rows, fieldName, rel) {
|
|
|
1506
1586
|
}
|
|
1507
1587
|
}
|
|
1508
1588
|
}
|
|
1509
|
-
function isColumnBacked(field) {
|
|
1510
|
-
const col = field.db_column;
|
|
1511
|
-
if (col === null) return false;
|
|
1512
|
-
if (col.column_name === "") return false;
|
|
1513
|
-
if (col.junction) return false;
|
|
1514
|
-
return true;
|
|
1515
|
-
}
|
|
1516
|
-
function createFieldKeyMap(fields) {
|
|
1517
|
-
const labelToColumn = /* @__PURE__ */ new Map();
|
|
1518
|
-
const columnToLabel = /* @__PURE__ */ new Map();
|
|
1519
|
-
const droppedKeys = /* @__PURE__ */ new Set();
|
|
1520
|
-
for (const f of fields) {
|
|
1521
|
-
if (!isColumnBacked(f)) continue;
|
|
1522
|
-
columnToLabel.set(f.db_column.column_name, f.name);
|
|
1523
|
-
if (f.removed === true) {
|
|
1524
|
-
droppedKeys.add(f.name);
|
|
1525
|
-
droppedKeys.add(f.db_column.column_name);
|
|
1526
|
-
continue;
|
|
1527
|
-
}
|
|
1528
|
-
labelToColumn.set(f.name, f.db_column.column_name);
|
|
1529
|
-
}
|
|
1530
|
-
for (const f of fields) {
|
|
1531
|
-
const columnOwner = columnToLabel.get(f.name);
|
|
1532
|
-
if (columnOwner !== void 0 && columnOwner !== f.name) {
|
|
1533
|
-
throw new Error(
|
|
1534
|
-
`Fatal: field key map failed to build \u2014 field label "${f.name}" collides with the storage column of field "${columnOwner}". A field label may not reuse another field's column name. Rename the field, then run \`manguito validate\` to check your schema.`
|
|
1535
|
-
);
|
|
1536
|
-
}
|
|
1537
|
-
}
|
|
1538
|
-
for (const f of fields) {
|
|
1539
|
-
if (isColumnBacked(f) && f.removed === true) {
|
|
1540
|
-
columnToLabel.delete(f.db_column.column_name);
|
|
1541
|
-
}
|
|
1542
|
-
}
|
|
1543
|
-
const diverges = [...labelToColumn].some(([label, column]) => label !== column);
|
|
1544
|
-
function remap(input, lookup) {
|
|
1545
|
-
const out = {};
|
|
1546
|
-
for (const key of Object.keys(input)) {
|
|
1547
|
-
if (droppedKeys.has(key)) continue;
|
|
1548
|
-
out[lookup.get(key) ?? key] = input[key];
|
|
1549
|
-
}
|
|
1550
|
-
return out;
|
|
1551
|
-
}
|
|
1552
|
-
return {
|
|
1553
|
-
toStorage: (input) => remap(input, labelToColumn),
|
|
1554
|
-
toLabels: (row) => remap(row, columnToLabel),
|
|
1555
|
-
columnFor: (label) => labelToColumn.get(label),
|
|
1556
|
-
labelFor: (column) => columnToLabel.get(column),
|
|
1557
|
-
labels: [...labelToColumn.keys()],
|
|
1558
|
-
diverges
|
|
1559
|
-
};
|
|
1560
|
-
}
|
|
1561
1589
|
|
|
1562
1590
|
export {
|
|
1563
1591
|
__require,
|
|
@@ -1590,12 +1618,13 @@ export {
|
|
|
1590
1618
|
Placeholder,
|
|
1591
1619
|
fillPlaceholders,
|
|
1592
1620
|
View,
|
|
1621
|
+
isColumnBacked,
|
|
1622
|
+
createFieldKeyMap,
|
|
1623
|
+
createFieldKeyMapFromProjection,
|
|
1593
1624
|
persistParagraphField,
|
|
1594
1625
|
deleteParagraphField,
|
|
1595
1626
|
persistJunctionField,
|
|
1596
1627
|
buildRelationsMap,
|
|
1597
1628
|
resolveRelationField,
|
|
1598
|
-
resolveRelationBareIds
|
|
1599
|
-
isColumnBacked,
|
|
1600
|
-
createFieldKeyMap
|
|
1629
|
+
resolveRelationBareIds
|
|
1601
1630
|
};
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
init_esm_shims,
|
|
12
12
|
isColumnBacked,
|
|
13
13
|
resolveRelationField
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-STFSR5LP.js";
|
|
15
15
|
|
|
16
16
|
// ../../node_modules/.pnpm/@whatwg-node+fetch@0.10.13/node_modules/@whatwg-node/fetch/dist/shouldSkipPonyfill.js
|
|
17
17
|
var require_shouldSkipPonyfill = __commonJS({
|
|
@@ -10786,10 +10786,10 @@ var require_parser = __commonJS({
|
|
|
10786
10786
|
}
|
|
10787
10787
|
});
|
|
10788
10788
|
|
|
10789
|
-
// ../api/dist/handler-
|
|
10789
|
+
// ../api/dist/handler-X7JDHJAL.mjs
|
|
10790
10790
|
init_esm_shims();
|
|
10791
10791
|
|
|
10792
|
-
// ../api/dist/chunk-
|
|
10792
|
+
// ../api/dist/chunk-ARZXLNZS.mjs
|
|
10793
10793
|
init_esm_shims();
|
|
10794
10794
|
|
|
10795
10795
|
// ../../node_modules/.pnpm/graphql-yoga@5.21.2_graphql@16.14.2/node_modules/graphql-yoga/esm/index.js
|
|
@@ -30122,7 +30122,7 @@ function createYoga(options) {
|
|
|
30122
30122
|
});
|
|
30123
30123
|
}
|
|
30124
30124
|
|
|
30125
|
-
// ../api/dist/chunk-
|
|
30125
|
+
// ../api/dist/chunk-ARZXLNZS.mjs
|
|
30126
30126
|
var import_dataloader = __toESM(require_dataloader(), 1);
|
|
30127
30127
|
|
|
30128
30128
|
// ../../node_modules/.pnpm/@escape.tech+graphql-armor@3.2.0_@envelop+core@5.5.1_@escape.tech+graphql-armor-types@0.7.0/node_modules/@escape.tech/graphql-armor/dist/graphql-armor.esm.js
|
|
@@ -30880,7 +30880,7 @@ var EnvelopArmor = class {
|
|
|
30880
30880
|
}
|
|
30881
30881
|
};
|
|
30882
30882
|
|
|
30883
|
-
// ../api/dist/chunk-
|
|
30883
|
+
// ../api/dist/chunk-ARZXLNZS.mjs
|
|
30884
30884
|
var DateTimeScalar = new GraphQLScalarType({
|
|
30885
30885
|
name: "DateTime",
|
|
30886
30886
|
description: "ISO-8601 date-time string",
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
__toESM,
|
|
23
23
|
buildRelationsMap,
|
|
24
24
|
createFieldKeyMap,
|
|
25
|
+
createFieldKeyMapFromProjection,
|
|
25
26
|
deleteParagraphField,
|
|
26
27
|
entityKind,
|
|
27
28
|
fillPlaceholders,
|
|
@@ -38,7 +39,7 @@ import {
|
|
|
38
39
|
resolveRelationField,
|
|
39
40
|
sql,
|
|
40
41
|
tracer
|
|
41
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-STFSR5LP.js";
|
|
42
43
|
|
|
43
44
|
// ../../node_modules/.pnpm/yaml@2.9.0/node_modules/yaml/dist/nodes/identity.js
|
|
44
45
|
var require_identity = __commonJS({
|
|
@@ -14469,7 +14470,7 @@ import { Command } from "commander";
|
|
|
14469
14470
|
// src/commands/build.ts
|
|
14470
14471
|
init_esm_shims();
|
|
14471
14472
|
import { mkdirSync, statSync as statSync2, existsSync as existsSync3, readdirSync as readdirSync3, writeFileSync } from "fs";
|
|
14472
|
-
import { resolve as
|
|
14473
|
+
import { resolve as resolve4, join as join9, dirname } from "path";
|
|
14473
14474
|
import { createRequire } from "module";
|
|
14474
14475
|
import { build as viteBuild } from "vite";
|
|
14475
14476
|
import { build as tsupBuild } from "tsup";
|
|
@@ -34195,7 +34196,7 @@ var PgSelectQueryBuilderBase = class extends TypedQueryBuilder {
|
|
|
34195
34196
|
const baseTableName = this.tableName;
|
|
34196
34197
|
const tableName = getTableLikeName(table);
|
|
34197
34198
|
for (const item of extractUsedTable(table)) this.usedTables.add(item);
|
|
34198
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
34199
|
+
if (typeof tableName === "string" && this.config.joins?.some((join15) => join15.alias === tableName)) {
|
|
34199
34200
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
34200
34201
|
}
|
|
34201
34202
|
if (!this.isPartialSelect) {
|
|
@@ -35419,7 +35420,7 @@ var PgUpdateBase = class extends QueryPromise {
|
|
|
35419
35420
|
createJoin(joinType) {
|
|
35420
35421
|
return (table, on) => {
|
|
35421
35422
|
const tableName = getTableLikeName(table);
|
|
35422
|
-
if (typeof tableName === "string" && this.config.joins.some((
|
|
35423
|
+
if (typeof tableName === "string" && this.config.joins.some((join15) => join15.alias === tableName)) {
|
|
35423
35424
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
35424
35425
|
}
|
|
35425
35426
|
if (typeof on === "function") {
|
|
@@ -35515,10 +35516,10 @@ var PgUpdateBase = class extends QueryPromise {
|
|
|
35515
35516
|
const fromFields = this.getTableLikeFields(this.config.from);
|
|
35516
35517
|
fields[tableName] = fromFields;
|
|
35517
35518
|
}
|
|
35518
|
-
for (const
|
|
35519
|
-
const tableName2 = getTableLikeName(
|
|
35520
|
-
if (typeof tableName2 === "string" && !is(
|
|
35521
|
-
const fromFields = this.getTableLikeFields(
|
|
35519
|
+
for (const join15 of this.config.joins) {
|
|
35520
|
+
const tableName2 = getTableLikeName(join15.table);
|
|
35521
|
+
if (typeof tableName2 === "string" && !is(join15.table, SQL)) {
|
|
35522
|
+
const fromFields = this.getTableLikeFields(join15.table);
|
|
35522
35523
|
fields[tableName2] = fromFields;
|
|
35523
35524
|
}
|
|
35524
35525
|
}
|
|
@@ -43617,6 +43618,7 @@ async function generateServerEntries(options, targetDir) {
|
|
|
43617
43618
|
function appSetup() {
|
|
43618
43619
|
return `import config from '../../manguito.config.js'
|
|
43619
43620
|
import { schemaRegistry } from './schema-registry.js'
|
|
43621
|
+
import { versionModel } from './version-model.js'
|
|
43620
43622
|
import { programmaticResolvers } from './programmatic-registry.js'
|
|
43621
43623
|
import { createCmsApp } from '@bobbykim/manguito-cms-api'
|
|
43622
43624
|
import { createPostgresAdapter } from '@bobbykim/manguito-cms-db'
|
|
@@ -43627,6 +43629,7 @@ await dbAdapter.connect()
|
|
|
43627
43629
|
const { app } = createCmsApp({
|
|
43628
43630
|
name: config.name,
|
|
43629
43631
|
registry: schemaRegistry,
|
|
43632
|
+
versions: versionModel,
|
|
43630
43633
|
db: dbAdapter.getDb(),
|
|
43631
43634
|
storage: config.storage,
|
|
43632
43635
|
prefix: config.api.prefix,
|
|
@@ -43820,6 +43823,25 @@ ${entries},
|
|
|
43820
43823
|
await writeFile5(join7(targetDir, "programmatic-registry.ts"), body, "utf8");
|
|
43821
43824
|
}
|
|
43822
43825
|
|
|
43826
|
+
// src/codegen/version-model.ts
|
|
43827
|
+
init_esm_shims();
|
|
43828
|
+
import { writeFile as writeFile6 } from "fs/promises";
|
|
43829
|
+
import { join as join8 } from "path";
|
|
43830
|
+
function reduceVersionModel(model) {
|
|
43831
|
+
return { current: model.current, live: model.live, projections: model.projections };
|
|
43832
|
+
}
|
|
43833
|
+
async function generateVersionModel(model, targetDir) {
|
|
43834
|
+
const reduced = reduceVersionModel(model);
|
|
43835
|
+
const content = [
|
|
43836
|
+
"// GENERATED by manguito build \u2014 do not edit.",
|
|
43837
|
+
"import type { BakedVersionModel } from '@bobbykim/manguito-cms-api'",
|
|
43838
|
+
"",
|
|
43839
|
+
`export const versionModel: BakedVersionModel = ${JSON.stringify(reduced, null, 2)}`,
|
|
43840
|
+
""
|
|
43841
|
+
].join("\n");
|
|
43842
|
+
await writeFile6(join8(targetDir, "version-model.ts"), content, "utf8");
|
|
43843
|
+
}
|
|
43844
|
+
|
|
43823
43845
|
// src/utils/config.ts
|
|
43824
43846
|
init_esm_shims();
|
|
43825
43847
|
import { existsSync } from "fs";
|
|
@@ -43910,6 +43932,16 @@ function isValidConfig(value) {
|
|
|
43910
43932
|
return value !== null && typeof value === "object" && "db" in value && "storage" in value && "server" in value && "api" in value && "admin" in value;
|
|
43911
43933
|
}
|
|
43912
43934
|
|
|
43935
|
+
// src/utils/schema-config.ts
|
|
43936
|
+
init_esm_shims();
|
|
43937
|
+
import { resolve as resolve3 } from "path";
|
|
43938
|
+
function resolveSchemaConfig(cwd, config3) {
|
|
43939
|
+
return {
|
|
43940
|
+
base_path: resolve3(cwd, config3.schema.base_path),
|
|
43941
|
+
folders: config3.schema.folders
|
|
43942
|
+
};
|
|
43943
|
+
}
|
|
43944
|
+
|
|
43913
43945
|
// src/utils/env.ts
|
|
43914
43946
|
init_esm_shims();
|
|
43915
43947
|
import { existsSync as existsSync2 } from "fs";
|
|
@@ -43951,7 +43983,7 @@ async function runBuild(options, deps) {
|
|
|
43951
43983
|
}
|
|
43952
43984
|
}
|
|
43953
43985
|
}
|
|
43954
|
-
const rolesPath =
|
|
43986
|
+
const rolesPath = resolve4(cwd, config3.schema.base_path, "roles.json");
|
|
43955
43987
|
const rolesLoadResult = loadSchemaFile(rolesPath);
|
|
43956
43988
|
let parsedRoles = null;
|
|
43957
43989
|
if (!rolesLoadResult.ok) {
|
|
@@ -43964,7 +43996,7 @@ async function runBuild(options, deps) {
|
|
|
43964
43996
|
parsedRoles = rolesParseResult.value;
|
|
43965
43997
|
}
|
|
43966
43998
|
}
|
|
43967
|
-
const routesPath =
|
|
43999
|
+
const routesPath = resolve4(cwd, config3.schema.base_path, "routes.json");
|
|
43968
44000
|
const routesLoadResult = loadSchemaFile(routesPath);
|
|
43969
44001
|
let parsedRoutesDef = null;
|
|
43970
44002
|
if (!routesLoadResult.ok) {
|
|
@@ -43995,13 +44027,26 @@ async function runBuild(options, deps) {
|
|
|
43995
44027
|
printSuccess(
|
|
43996
44028
|
`Schemas parsed (${contentCount} content types, ${paragraphCount} paragraph types, ${taxonomyCount} taxonomy types${enumPart})`
|
|
43997
44029
|
);
|
|
43998
|
-
const generatedDir =
|
|
44030
|
+
const generatedDir = resolve4(cwd, "dist/generated");
|
|
43999
44031
|
mkdirSync(generatedDir, { recursive: true });
|
|
44000
|
-
writeFileSync(
|
|
44032
|
+
writeFileSync(join9(generatedDir, "schema.ts"), generateSchemaFile(registry2), "utf8");
|
|
44001
44033
|
await generateSchemaRegistry(registry2, generatedDir);
|
|
44002
44034
|
await generateRoutes2(registry2, generatedDir);
|
|
44003
|
-
await generateForms(registry2,
|
|
44004
|
-
const
|
|
44035
|
+
await generateForms(registry2, join9(generatedDir, "forms"));
|
|
44036
|
+
const schema = resolveSchemaConfig(cwd, config3);
|
|
44037
|
+
const snapshots = loadVersionSnapshots(schema, registry2);
|
|
44038
|
+
if (!snapshots.ok) {
|
|
44039
|
+
printValidationErrors(snapshots.errors, "Snapshot errors", "manguito build");
|
|
44040
|
+
process.exit(1);
|
|
44041
|
+
}
|
|
44042
|
+
const versionModel = computeVersionModel({ current: registry2, snapshots: snapshots.value });
|
|
44043
|
+
if (!versionModel.ok) {
|
|
44044
|
+
printValidationErrors(versionModel.errors, "Version model errors", "manguito build");
|
|
44045
|
+
process.exit(1);
|
|
44046
|
+
}
|
|
44047
|
+
await generateVersionModel(versionModel.value, generatedDir);
|
|
44048
|
+
printSuccess(`Version model baked (live: ${versionModel.value.live.join(", ")})`);
|
|
44049
|
+
const programmaticDir = resolve4(cwd, config3.programmatic.dir);
|
|
44005
44050
|
const resolverFiles = existsSync3(programmaticDir) ? walkFiles(programmaticDir).filter((f) => /\.(ts|mjs|js)$/.test(f)) : [];
|
|
44006
44051
|
await generateProgrammaticRegistry(resolverFiles, generatedDir);
|
|
44007
44052
|
await generateServerEntries(
|
|
@@ -44014,7 +44059,7 @@ async function runBuild(options, deps) {
|
|
|
44014
44059
|
root: resolveAdminRoot(cwd),
|
|
44015
44060
|
base: config3.admin.prefix + "/",
|
|
44016
44061
|
build: {
|
|
44017
|
-
outDir:
|
|
44062
|
+
outDir: resolve4(cwd, "dist/admin"),
|
|
44018
44063
|
emptyOutDir: true
|
|
44019
44064
|
},
|
|
44020
44065
|
define: {
|
|
@@ -44034,12 +44079,12 @@ async function runBuild(options, deps) {
|
|
|
44034
44079
|
try {
|
|
44035
44080
|
await tsupBuild({
|
|
44036
44081
|
entry: {
|
|
44037
|
-
server:
|
|
44038
|
-
handler:
|
|
44039
|
-
vercel:
|
|
44082
|
+
server: resolve4(cwd, "dist/generated/server.ts"),
|
|
44083
|
+
handler: resolve4(cwd, "dist/generated/handler.ts"),
|
|
44084
|
+
vercel: resolve4(cwd, "dist/generated/vercel.ts")
|
|
44040
44085
|
},
|
|
44041
44086
|
format: ["esm"],
|
|
44042
|
-
outDir:
|
|
44087
|
+
outDir: resolve4(cwd, "dist"),
|
|
44043
44088
|
dts: false,
|
|
44044
44089
|
silent: true,
|
|
44045
44090
|
// hono/aws-lambda and hono/vercel are optional peer deps — mark external
|
|
@@ -44057,24 +44102,24 @@ async function runBuild(options, deps) {
|
|
|
44057
44102
|
process.stdout.write("\nBuild complete \u2192 dist/\n");
|
|
44058
44103
|
}
|
|
44059
44104
|
async function needsRebuild(cwd) {
|
|
44060
|
-
const sentinel =
|
|
44105
|
+
const sentinel = resolve4(cwd, "dist/generated/schema.ts");
|
|
44061
44106
|
if (!existsSync3(sentinel)) return true;
|
|
44062
44107
|
const sentinelMtime = statSync2(sentinel).mtimeMs;
|
|
44063
|
-
const schemasDir =
|
|
44108
|
+
const schemasDir = resolve4(cwd, "schemas");
|
|
44064
44109
|
if (!existsSync3(schemasDir)) return false;
|
|
44065
44110
|
return walkFiles(schemasDir).some(
|
|
44066
44111
|
(file2) => statSync2(file2).mtimeMs > sentinelMtime
|
|
44067
44112
|
);
|
|
44068
44113
|
}
|
|
44069
44114
|
function resolveAdminRoot(cwd) {
|
|
44070
|
-
const cwdRequire = createRequire(
|
|
44115
|
+
const cwdRequire = createRequire(join9(cwd, "package.json"));
|
|
44071
44116
|
const adminPkgJson = cwdRequire.resolve("@bobbykim/manguito-cms-admin/package.json");
|
|
44072
44117
|
return dirname(adminPkgJson);
|
|
44073
44118
|
}
|
|
44074
44119
|
function walkFiles(dir) {
|
|
44075
44120
|
const files = [];
|
|
44076
44121
|
for (const entry of readdirSync3(dir, { withFileTypes: true })) {
|
|
44077
|
-
const full =
|
|
44122
|
+
const full = join9(dir, entry.name);
|
|
44078
44123
|
if (entry.isDirectory()) {
|
|
44079
44124
|
files.push(...walkFiles(full));
|
|
44080
44125
|
} else {
|
|
@@ -44088,8 +44133,8 @@ function walkFiles(dir) {
|
|
|
44088
44133
|
init_esm_shims();
|
|
44089
44134
|
import { createServer as createHttpServer } from "http";
|
|
44090
44135
|
import { existsSync as existsSync5 } from "fs";
|
|
44091
|
-
import { resolve as
|
|
44092
|
-
import { mkdir as mkdir2, writeFile as
|
|
44136
|
+
import { resolve as resolve7, join as join13, dirname as dirname2, extname as extname4 } from "path";
|
|
44137
|
+
import { mkdir as mkdir2, writeFile as writeFile9, watch, readFile } from "fs/promises";
|
|
44093
44138
|
import { createRequire as createRequire2 } from "module";
|
|
44094
44139
|
import { createServer as createViteServer, searchForWorkspaceRoot } from "vite";
|
|
44095
44140
|
|
|
@@ -47009,15 +47054,20 @@ function normalizePrefix(prefix) {
|
|
|
47009
47054
|
}
|
|
47010
47055
|
function createPublicPaths(prefix) {
|
|
47011
47056
|
return {
|
|
47012
|
-
collection: (basePath) => `${prefix}/${basePath}`,
|
|
47013
|
-
item: (basePath) => `${prefix}/${basePath}/:slug`,
|
|
47014
|
-
taxonomyCollection: (typeName) => `${prefix}/taxonomy/${typeName}`,
|
|
47015
|
-
taxonomyItem: (typeName) => `${prefix}/taxonomy/${typeName}/:id`,
|
|
47016
47057
|
mediaCollection: () => `${prefix}/media`,
|
|
47017
47058
|
mediaItem: () => `${prefix}/media/:id`,
|
|
47018
47059
|
openapi: () => `${prefix}/openapi.json`
|
|
47019
47060
|
};
|
|
47020
47061
|
}
|
|
47062
|
+
function createVersionedPaths(prefix, version3) {
|
|
47063
|
+
const root = version3 === null ? prefix : `${prefix}/${version3}`;
|
|
47064
|
+
return {
|
|
47065
|
+
collection: (basePath) => `${root}/${basePath}`,
|
|
47066
|
+
item: (basePath) => `${root}/${basePath}/:slug`,
|
|
47067
|
+
taxonomyCollection: (typeName) => `${root}/taxonomy/${typeName}`,
|
|
47068
|
+
taxonomyItem: (typeName) => `${root}/taxonomy/${typeName}/:id`
|
|
47069
|
+
};
|
|
47070
|
+
}
|
|
47021
47071
|
function createCorsMiddleware(corsConfig) {
|
|
47022
47072
|
const allowList = Array.isArray(corsConfig.origin) ? corsConfig.origin : [corsConfig.origin];
|
|
47023
47073
|
const wildcard = allowList.includes("*");
|
|
@@ -47579,7 +47629,7 @@ function nestedTargets(fields) {
|
|
|
47579
47629
|
}
|
|
47580
47630
|
return out;
|
|
47581
47631
|
}
|
|
47582
|
-
function buildProjectors(registry2, fieldKeyMaps) {
|
|
47632
|
+
function buildProjectors(registry2, fieldKeyMaps, fallbacks) {
|
|
47583
47633
|
const projectors = {};
|
|
47584
47634
|
const sources = [
|
|
47585
47635
|
registry2.content_types,
|
|
@@ -47590,7 +47640,14 @@ function buildProjectors(registry2, fieldKeyMaps) {
|
|
|
47590
47640
|
for (const [typeName, type] of Object.entries(source)) {
|
|
47591
47641
|
const map2 = fieldKeyMaps[typeName];
|
|
47592
47642
|
if (!map2) continue;
|
|
47593
|
-
|
|
47643
|
+
const typeFallbacks = fallbacks?.[typeName];
|
|
47644
|
+
projectors[typeName] = {
|
|
47645
|
+
map: map2,
|
|
47646
|
+
nested: nestedTargets(type.fields),
|
|
47647
|
+
// Spread rather than assign: with exactOptionalPropertyTypes, an optional
|
|
47648
|
+
// property may be ABSENT but not present-and-undefined.
|
|
47649
|
+
...typeFallbacks !== void 0 && { fallbacks: typeFallbacks }
|
|
47650
|
+
};
|
|
47594
47651
|
}
|
|
47595
47652
|
}
|
|
47596
47653
|
return projectors;
|
|
@@ -47599,6 +47656,11 @@ function projectRow(row, typeName, projectors) {
|
|
|
47599
47656
|
const p2 = projectors[typeName];
|
|
47600
47657
|
if (!p2) return row;
|
|
47601
47658
|
const out = p2.map.toLabels(row);
|
|
47659
|
+
if (p2.fallbacks !== void 0) {
|
|
47660
|
+
for (const [label, value] of Object.entries(p2.fallbacks)) {
|
|
47661
|
+
if (out[label] === null || out[label] === void 0) out[label] = value;
|
|
47662
|
+
}
|
|
47663
|
+
}
|
|
47602
47664
|
for (const { label, target } of p2.nested) {
|
|
47603
47665
|
const v2 = out[label];
|
|
47604
47666
|
if (v2 === null || v2 === void 0) continue;
|
|
@@ -47688,13 +47750,24 @@ function registerPublicContentRoutes(app, registry2, repos, projectors, paths, l
|
|
|
47688
47750
|
const basePath = contentType.default_base_path;
|
|
47689
47751
|
const repo = repos[typeName];
|
|
47690
47752
|
if (!repo) continue;
|
|
47691
|
-
const
|
|
47692
|
-
|
|
47693
|
-
)
|
|
47753
|
+
const fieldKeys = projectors[typeName].map;
|
|
47754
|
+
const relationFieldNames = /* @__PURE__ */ new Set();
|
|
47755
|
+
for (const f of contentType.fields) {
|
|
47756
|
+
if (!RELATION_FIELD_TYPES.has(f.field_type)) continue;
|
|
47757
|
+
if (isColumnBacked(f)) {
|
|
47758
|
+
const label = fieldKeys.labelFor(f.db_column.column_name);
|
|
47759
|
+
if (label !== void 0) relationFieldNames.add(label);
|
|
47760
|
+
} else {
|
|
47761
|
+
relationFieldNames.add(f.name);
|
|
47762
|
+
}
|
|
47763
|
+
}
|
|
47694
47764
|
const filterableFieldNames = /* @__PURE__ */ new Set([
|
|
47695
|
-
...
|
|
47765
|
+
...fieldKeys.labels,
|
|
47696
47766
|
...contentType.system_fields.map((f) => f.name)
|
|
47697
47767
|
]);
|
|
47768
|
+
const sortableFieldNames = new Set(
|
|
47769
|
+
[...SORTABLE_FIELDS].filter((f) => filterableFieldNames.has(f))
|
|
47770
|
+
);
|
|
47698
47771
|
if (contentType.only_one) {
|
|
47699
47772
|
app.get(paths.collection(basePath), async (c) => {
|
|
47700
47773
|
const result = await repo.findMany({ published_only: true, page: 1, per_page: 1 });
|
|
@@ -47710,8 +47783,6 @@ function registerPublicContentRoutes(app, registry2, repos, projectors, paths, l
|
|
|
47710
47783
|
});
|
|
47711
47784
|
} else {
|
|
47712
47785
|
registerListRoute(paths.collection(basePath), async (c) => {
|
|
47713
|
-
const projector = projectors[typeName];
|
|
47714
|
-
const fieldKeys = projector.map;
|
|
47715
47786
|
const pagination = parsePagination(c.req.query("page"), c.req.query("per_page"));
|
|
47716
47787
|
if (!pagination.ok) {
|
|
47717
47788
|
return c.json(
|
|
@@ -47726,13 +47797,13 @@ function registerPublicContentRoutes(app, registry2, repos, projectors, paths, l
|
|
|
47726
47797
|
);
|
|
47727
47798
|
}
|
|
47728
47799
|
const sortBy = c.req.query("sort_by") ?? "created_at";
|
|
47729
|
-
if (!
|
|
47800
|
+
if (!sortableFieldNames.has(sortBy)) {
|
|
47730
47801
|
return c.json(
|
|
47731
47802
|
{
|
|
47732
47803
|
ok: false,
|
|
47733
47804
|
error: {
|
|
47734
47805
|
code: "INVALID_SORT_FIELD",
|
|
47735
|
-
message: `'${sortBy}' is not sortable. Allowed:
|
|
47806
|
+
message: `'${sortBy}' is not sortable. Allowed: ${[...sortableFieldNames].join(", ")}`
|
|
47736
47807
|
}
|
|
47737
47808
|
},
|
|
47738
47809
|
400
|
|
@@ -47779,7 +47850,7 @@ function registerPublicContentRoutes(app, registry2, repos, projectors, paths, l
|
|
|
47779
47850
|
);
|
|
47780
47851
|
}
|
|
47781
47852
|
}
|
|
47782
|
-
const sortColumn = fieldKeys.columnFor(sortBy)
|
|
47853
|
+
const sortColumn = fieldKeys.labels.includes(sortBy) ? fieldKeys.columnFor(sortBy) : sortBy;
|
|
47783
47854
|
const result = await repo.findMany({
|
|
47784
47855
|
published_only: true,
|
|
47785
47856
|
page: pagination.page,
|
|
@@ -49631,7 +49702,7 @@ function registerUserRoutes(app, db, requirePermission, requireHierarchy) {
|
|
|
49631
49702
|
}
|
|
49632
49703
|
var API_VERSION = (() => {
|
|
49633
49704
|
try {
|
|
49634
|
-
return "0.
|
|
49705
|
+
return "0.5.0";
|
|
49635
49706
|
} catch {
|
|
49636
49707
|
return "0.0.0";
|
|
49637
49708
|
}
|
|
@@ -50020,6 +50091,90 @@ function createMediaRepository(db) {
|
|
|
50020
50091
|
}
|
|
50021
50092
|
};
|
|
50022
50093
|
}
|
|
50094
|
+
var VERSION_SEGMENT = /^v\d+$/;
|
|
50095
|
+
function versionNumber2(version3) {
|
|
50096
|
+
return Number.parseInt(version3.slice(1), 10);
|
|
50097
|
+
}
|
|
50098
|
+
function classifyVersion(segment, model) {
|
|
50099
|
+
if (!VERSION_SEGMENT.test(segment)) return "not-a-version";
|
|
50100
|
+
if (model.live.includes(segment)) return "live";
|
|
50101
|
+
return versionNumber2(segment) < versionNumber2(model.current) ? "retired" : "unknown";
|
|
50102
|
+
}
|
|
50103
|
+
function fallbacksFor(projection) {
|
|
50104
|
+
const out = {};
|
|
50105
|
+
for (const [typeName, type] of Object.entries(projection.types)) {
|
|
50106
|
+
const perLabel = {};
|
|
50107
|
+
for (const f of type.fields) {
|
|
50108
|
+
if (f.fallback !== void 0) perLabel[f.exposed_as] = f.fallback;
|
|
50109
|
+
}
|
|
50110
|
+
if (Object.keys(perLabel).length > 0) out[typeName] = perLabel;
|
|
50111
|
+
}
|
|
50112
|
+
return out;
|
|
50113
|
+
}
|
|
50114
|
+
function buildVersionSurface(input2) {
|
|
50115
|
+
const { version: version3, projectionVersion, prefix, registry: registry2, model, makeRepo } = input2;
|
|
50116
|
+
const paths = createVersionedPaths(prefix, version3);
|
|
50117
|
+
const projection = model.projections[projectionVersion];
|
|
50118
|
+
const fieldKeyMaps = {};
|
|
50119
|
+
const sources = [
|
|
50120
|
+
registry2.content_types,
|
|
50121
|
+
registry2.taxonomy_types,
|
|
50122
|
+
registry2.paragraph_types
|
|
50123
|
+
];
|
|
50124
|
+
for (const source of sources) {
|
|
50125
|
+
for (const [typeName, type] of Object.entries(source)) {
|
|
50126
|
+
const projectionType = projection?.types[typeName];
|
|
50127
|
+
fieldKeyMaps[typeName] = projectionType ? createFieldKeyMapFromProjection(projectionType, type.fields) : createFieldKeyMap(type.fields);
|
|
50128
|
+
}
|
|
50129
|
+
}
|
|
50130
|
+
const fallbacks = projection ? fallbacksFor(projection) : void 0;
|
|
50131
|
+
const projectors = buildProjectors(registry2, fieldKeyMaps, fallbacks);
|
|
50132
|
+
const sortableColumnsFor = (typeName) => {
|
|
50133
|
+
const map2 = fieldKeyMaps[typeName];
|
|
50134
|
+
const type = registry2.content_types[typeName] ?? registry2.taxonomy_types[typeName];
|
|
50135
|
+
const systemFieldNames = new Set((type?.system_fields ?? []).map((f) => f.name));
|
|
50136
|
+
const out = /* @__PURE__ */ new Set();
|
|
50137
|
+
for (const label of SORTABLE_FIELDS) {
|
|
50138
|
+
const column = map2.columnFor(label);
|
|
50139
|
+
if (column !== void 0) out.add(column);
|
|
50140
|
+
else if (systemFieldNames.has(label)) out.add(label);
|
|
50141
|
+
}
|
|
50142
|
+
return out;
|
|
50143
|
+
};
|
|
50144
|
+
const repos = {};
|
|
50145
|
+
for (const [typeName, ct2] of Object.entries(registry2.content_types)) {
|
|
50146
|
+
repos[typeName] = makeRepo(typeName, ct2.db.table_name, sortableColumnsFor(typeName));
|
|
50147
|
+
}
|
|
50148
|
+
for (const [typeName, tt2] of Object.entries(registry2.taxonomy_types)) {
|
|
50149
|
+
repos[typeName] = makeRepo(typeName, tt2.db.table_name, sortableColumnsFor(typeName));
|
|
50150
|
+
}
|
|
50151
|
+
return { paths, fieldKeyMaps, projectors, repos };
|
|
50152
|
+
}
|
|
50153
|
+
function deprecationHeaders(input2) {
|
|
50154
|
+
const { requested, model, successor } = input2;
|
|
50155
|
+
const link = `<${successor}>; rel="successor-version"`;
|
|
50156
|
+
if (requested === null) {
|
|
50157
|
+
if (model.live.length <= 1) return null;
|
|
50158
|
+
return {
|
|
50159
|
+
Deprecation: "true",
|
|
50160
|
+
Link: link,
|
|
50161
|
+
Warning: `299 - "Unversioned path resolves to the latest version (${model.current}) and will change when a new version is cut. Pin a version."`
|
|
50162
|
+
};
|
|
50163
|
+
}
|
|
50164
|
+
if (requested === model.current) return null;
|
|
50165
|
+
return { Deprecation: "true", Link: link };
|
|
50166
|
+
}
|
|
50167
|
+
function versionRoutePaths(registry2, paths) {
|
|
50168
|
+
const out = [paths.collection("content"), paths.collection("taxonomy")];
|
|
50169
|
+
for (const ct2 of Object.values(registry2.content_types)) {
|
|
50170
|
+
out.push(paths.collection(ct2.default_base_path));
|
|
50171
|
+
if (!ct2.only_one) out.push(paths.item(ct2.default_base_path));
|
|
50172
|
+
}
|
|
50173
|
+
for (const tt2 of Object.values(registry2.taxonomy_types)) {
|
|
50174
|
+
out.push(paths.taxonomyCollection(tt2.name), paths.taxonomyItem(tt2.name));
|
|
50175
|
+
}
|
|
50176
|
+
return out;
|
|
50177
|
+
}
|
|
50023
50178
|
var MISSING_STORAGE_ERROR = `\u2717 api.storage is required but not configured.
|
|
50024
50179
|
Add a storage adapter to your manguito.config.ts:
|
|
50025
50180
|
|
|
@@ -50035,6 +50190,7 @@ function createCmsApp(options) {
|
|
|
50035
50190
|
}
|
|
50036
50191
|
const prefix = normalizePrefix(options.prefix);
|
|
50037
50192
|
const publicPaths = createPublicPaths(prefix);
|
|
50193
|
+
const versionedPaths = createVersionedPaths(prefix, null);
|
|
50038
50194
|
const { storage, registry: registry2, db, rateLimit, media, cors } = options;
|
|
50039
50195
|
const cmsName = options.name ?? "Manguito CMS";
|
|
50040
50196
|
const maxFileSize = media?.max_file_size;
|
|
@@ -50083,9 +50239,18 @@ function createCmsApp(options) {
|
|
|
50083
50239
|
])
|
|
50084
50240
|
]);
|
|
50085
50241
|
const projectors = buildProjectors(registry2, fieldKeyMaps);
|
|
50086
|
-
const sortableColumnsFor = (typeName) =>
|
|
50087
|
-
|
|
50088
|
-
|
|
50242
|
+
const sortableColumnsFor = (typeName) => {
|
|
50243
|
+
const map2 = fieldKeyMaps[typeName];
|
|
50244
|
+
const type = registry2.content_types[typeName] ?? registry2.taxonomy_types[typeName];
|
|
50245
|
+
const systemFieldNames = new Set((type?.system_fields ?? []).map((f) => f.name));
|
|
50246
|
+
const out = /* @__PURE__ */ new Set();
|
|
50247
|
+
for (const label of SORTABLE_FIELDS) {
|
|
50248
|
+
const column = map2.columnFor(label);
|
|
50249
|
+
if (column !== void 0) out.add(column);
|
|
50250
|
+
else if (systemFieldNames.has(label)) out.add(label);
|
|
50251
|
+
}
|
|
50252
|
+
return out;
|
|
50253
|
+
};
|
|
50089
50254
|
const contentRepos = Object.fromEntries(
|
|
50090
50255
|
Object.entries(registry2.content_types).map(([typeName, ct2]) => [
|
|
50091
50256
|
typeName,
|
|
@@ -50104,27 +50269,14 @@ function createCmsApp(options) {
|
|
|
50104
50269
|
);
|
|
50105
50270
|
const repos = { ...contentRepos, ...taxonomyRepos };
|
|
50106
50271
|
const mediaRepo = createMediaRepository(db);
|
|
50107
|
-
const
|
|
50108
|
-
|
|
50109
|
-
|
|
50110
|
-
|
|
50111
|
-
|
|
50112
|
-
|
|
50113
|
-
|
|
50114
|
-
|
|
50115
|
-
])
|
|
50116
|
-
);
|
|
50117
|
-
const publicTaxonomyRepos = Object.fromEntries(
|
|
50118
|
-
Object.entries(registry2.taxonomy_types).map(([typeName, tt2]) => [
|
|
50119
|
-
typeName,
|
|
50120
|
-
createDrizzleContentRepository(db, tt2.db.table_name, {
|
|
50121
|
-
relations: buildRelationsMap(tt2.fields, registry2),
|
|
50122
|
-
publishedRelations: true,
|
|
50123
|
-
sortableColumns: sortableColumnsFor(typeName)
|
|
50124
|
-
})
|
|
50125
|
-
])
|
|
50126
|
-
);
|
|
50127
|
-
const publicRepos = { ...publicContentRepos, ...publicTaxonomyRepos };
|
|
50272
|
+
const makeRepo = (typeName, tableName, sortableColumns) => {
|
|
50273
|
+
const type = registry2.content_types[typeName] ?? registry2.taxonomy_types[typeName];
|
|
50274
|
+
return createDrizzleContentRepository(db, tableName, {
|
|
50275
|
+
relations: buildRelationsMap(type.fields, registry2),
|
|
50276
|
+
publishedRelations: true,
|
|
50277
|
+
sortableColumns
|
|
50278
|
+
});
|
|
50279
|
+
};
|
|
50128
50280
|
const graphqlRepos = Object.fromEntries([
|
|
50129
50281
|
...Object.entries(registry2.content_types).map(([typeName, ct2]) => [
|
|
50130
50282
|
typeName,
|
|
@@ -50147,17 +50299,17 @@ function createCmsApp(options) {
|
|
|
50147
50299
|
for (const ct2 of Object.values(registry2.content_types)) {
|
|
50148
50300
|
const base = ct2.default_base_path;
|
|
50149
50301
|
if (ct2.only_one) {
|
|
50150
|
-
paths[
|
|
50302
|
+
paths[versionedPaths.collection(base)] = { get: { summary: `Get ${ct2.label}`, tags: [ct2.label] } };
|
|
50151
50303
|
} else {
|
|
50152
|
-
paths[
|
|
50153
|
-
paths[
|
|
50304
|
+
paths[versionedPaths.collection(base)] = { get: { summary: `List published ${ct2.label}`, tags: [ct2.label] } };
|
|
50305
|
+
paths[versionedPaths.item(base).replace(":slug", "{slug}")] = {
|
|
50154
50306
|
get: { summary: `Get ${ct2.label} by slug`, tags: [ct2.label] }
|
|
50155
50307
|
};
|
|
50156
50308
|
}
|
|
50157
50309
|
}
|
|
50158
50310
|
for (const tt2 of Object.values(registry2.taxonomy_types)) {
|
|
50159
|
-
paths[
|
|
50160
|
-
paths[
|
|
50311
|
+
paths[versionedPaths.taxonomyCollection(tt2.name)] = { get: { summary: `List published ${tt2.label}`, tags: [tt2.label] } };
|
|
50312
|
+
paths[versionedPaths.taxonomyItem(tt2.name).replace(":id", "{id}")] = {
|
|
50161
50313
|
get: { summary: `Get ${tt2.label} by id`, tags: [tt2.label] }
|
|
50162
50314
|
};
|
|
50163
50315
|
}
|
|
@@ -50177,13 +50329,68 @@ function createCmsApp(options) {
|
|
|
50177
50329
|
paths: {}
|
|
50178
50330
|
})
|
|
50179
50331
|
);
|
|
50180
|
-
|
|
50332
|
+
const model = options.versions ?? {
|
|
50333
|
+
current: "v1",
|
|
50334
|
+
live: ["v1"],
|
|
50335
|
+
projections: {}
|
|
50336
|
+
};
|
|
50337
|
+
const passes = [
|
|
50338
|
+
...options.versions !== void 0 ? model.live.map((v2) => ({ version: v2, projectionVersion: v2 })) : [],
|
|
50339
|
+
{ version: null, projectionVersion: model.current }
|
|
50340
|
+
];
|
|
50341
|
+
for (const pass of passes) {
|
|
50342
|
+
const surface = buildVersionSurface({ ...pass, prefix, registry: registry2, model, makeRepo });
|
|
50343
|
+
const headers = deprecationHeaders({
|
|
50344
|
+
requested: pass.version,
|
|
50345
|
+
model,
|
|
50346
|
+
// The version root, with no trailing slash — never
|
|
50347
|
+
// createVersionedPaths(prefix, model.current).collection(''), which
|
|
50348
|
+
// would yield `${prefix}/${model.current}/` in every Link header.
|
|
50349
|
+
successor: `${prefix}/${model.current}`
|
|
50350
|
+
});
|
|
50351
|
+
if (headers !== null) {
|
|
50352
|
+
const attachDeprecationHeaders = async (c, next) => {
|
|
50353
|
+
await next();
|
|
50354
|
+
for (const [key, value] of Object.entries(headers)) c.res.headers.set(key, value);
|
|
50355
|
+
};
|
|
50356
|
+
for (const path7 of versionRoutePaths(registry2, surface.paths)) {
|
|
50357
|
+
app.use(path7, attachDeprecationHeaders);
|
|
50358
|
+
}
|
|
50359
|
+
}
|
|
50360
|
+
registerPublicContentRoutes(app, registry2, surface.repos, surface.projectors, surface.paths, listRateLimit, programmaticResolver);
|
|
50361
|
+
}
|
|
50362
|
+
if (options.versions !== void 0) {
|
|
50363
|
+
app.all(`${prefix}/:version/*`, async (c, next) => {
|
|
50364
|
+
const kind = classifyVersion(c.req.param("version"), model);
|
|
50365
|
+
if (kind === "not-a-version" || kind === "live") return next();
|
|
50366
|
+
const live = model.live.join(", ");
|
|
50367
|
+
return kind === "retired" ? c.json(
|
|
50368
|
+
{
|
|
50369
|
+
ok: false,
|
|
50370
|
+
error: {
|
|
50371
|
+
code: "VERSION_RETIRED",
|
|
50372
|
+
message: `Version ${c.req.param("version")} is no longer served. Live versions: ${live}.`
|
|
50373
|
+
}
|
|
50374
|
+
},
|
|
50375
|
+
410
|
|
50376
|
+
) : c.json(
|
|
50377
|
+
{
|
|
50378
|
+
ok: false,
|
|
50379
|
+
error: {
|
|
50380
|
+
code: "VERSION_NOT_FOUND",
|
|
50381
|
+
message: `No version ${c.req.param("version")} is served. Live versions: ${live}.`
|
|
50382
|
+
}
|
|
50383
|
+
},
|
|
50384
|
+
404
|
|
50385
|
+
);
|
|
50386
|
+
});
|
|
50387
|
+
}
|
|
50181
50388
|
registerPublicMediaRoutes(app, mediaRepo, publicPaths, listRateLimit);
|
|
50182
50389
|
if (options.graphql?.enabled) {
|
|
50183
50390
|
const gqlOptions = options.graphql;
|
|
50184
50391
|
let gqlHandler = null;
|
|
50185
50392
|
let initError = null;
|
|
50186
|
-
const ready = import("./handler-
|
|
50393
|
+
const ready = import("./handler-X7JDHJAL-JEAY3P6W.js").then(({ createGraphQLHandler }) => {
|
|
50187
50394
|
gqlHandler = createGraphQLHandler(registry2, graphqlRepos, fieldKeyMaps, programmaticResolver, db, gqlOptions);
|
|
50188
50395
|
}).catch((err) => {
|
|
50189
50396
|
initError = err;
|
|
@@ -50231,12 +50438,12 @@ function createCmsApp(options) {
|
|
|
50231
50438
|
|
|
50232
50439
|
// src/codegen/drizzle-config.ts
|
|
50233
50440
|
init_esm_shims();
|
|
50234
|
-
import { writeFile as
|
|
50235
|
-
import { join as
|
|
50441
|
+
import { writeFile as writeFile7 } from "fs/promises";
|
|
50442
|
+
import { join as join10, relative as relative2, resolve as resolve5 } from "path";
|
|
50236
50443
|
async function generateDrizzleConfig(config3, targetDir) {
|
|
50237
50444
|
const migrationsFolder = config3.migrations?.folder ?? "./migrations";
|
|
50238
50445
|
const migrationsTable = config3.migrations?.table ?? "__manguito_migrations";
|
|
50239
|
-
const outPath = relative2(
|
|
50446
|
+
const outPath = relative2(resolve5(targetDir), resolve5(migrationsFolder)).replace(/\\/g, "/");
|
|
50240
50447
|
const content = [
|
|
50241
50448
|
`import { defineConfig } from 'drizzle-kit'`,
|
|
50242
50449
|
``,
|
|
@@ -50254,13 +50461,13 @@ async function generateDrizzleConfig(config3, targetDir) {
|
|
|
50254
50461
|
` tablesFilter: ['!${migrationsTable}'],`,
|
|
50255
50462
|
`})`
|
|
50256
50463
|
].join("\n");
|
|
50257
|
-
await
|
|
50464
|
+
await writeFile7(join10(targetDir, "drizzle.config.ts"), content, "utf8");
|
|
50258
50465
|
}
|
|
50259
50466
|
|
|
50260
50467
|
// src/codegen/nav.ts
|
|
50261
50468
|
init_esm_shims();
|
|
50262
|
-
import { writeFile as
|
|
50263
|
-
import { join as
|
|
50469
|
+
import { writeFile as writeFile8 } from "fs/promises";
|
|
50470
|
+
import { join as join11 } from "path";
|
|
50264
50471
|
function schemaBasePath(name) {
|
|
50265
50472
|
const segment = name.includes("--") ? name.slice(name.indexOf("--") + 2) : name;
|
|
50266
50473
|
return segment.replace(/_/g, "-");
|
|
@@ -50278,7 +50485,7 @@ async function generateNav(registry2, targetDir) {
|
|
|
50278
50485
|
})).sort((a2, b2) => a2.label.localeCompare(b2.label));
|
|
50279
50486
|
const content = `export const nav = ${JSON.stringify({ contentTypes, taxonomyTypes }, null, 2)}
|
|
50280
50487
|
`;
|
|
50281
|
-
await
|
|
50488
|
+
await writeFile8(join11(targetDir, "nav.ts"), content, "utf8");
|
|
50282
50489
|
}
|
|
50283
50490
|
|
|
50284
50491
|
// src/commands/dev-routing.ts
|
|
@@ -50323,7 +50530,7 @@ function createPromptAdapter() {
|
|
|
50323
50530
|
init_esm_shims();
|
|
50324
50531
|
import { existsSync as existsSync4 } from "fs";
|
|
50325
50532
|
import { readdir } from "fs/promises";
|
|
50326
|
-
import { resolve as
|
|
50533
|
+
import { resolve as resolve6, join as join12, extname as extname3 } from "path";
|
|
50327
50534
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
50328
50535
|
var RESOLVER_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".mjs", ".js"]);
|
|
50329
50536
|
function isProgrammaticFieldDefinition(v2) {
|
|
@@ -50332,7 +50539,7 @@ function isProgrammaticFieldDefinition(v2) {
|
|
|
50332
50539
|
async function walkTsFiles(dir) {
|
|
50333
50540
|
const out = [];
|
|
50334
50541
|
for (const entry of await readdir(dir, { withFileTypes: true })) {
|
|
50335
|
-
const full =
|
|
50542
|
+
const full = join12(dir, entry.name);
|
|
50336
50543
|
if (entry.isDirectory()) {
|
|
50337
50544
|
out.push(...await walkTsFiles(full));
|
|
50338
50545
|
} else if (RESOLVER_EXTENSIONS.has(extname3(entry.name))) {
|
|
@@ -50342,7 +50549,7 @@ async function walkTsFiles(dir) {
|
|
|
50342
50549
|
return out;
|
|
50343
50550
|
}
|
|
50344
50551
|
async function loadProgrammaticResolvers(cwd, dir) {
|
|
50345
|
-
const abs =
|
|
50552
|
+
const abs = resolve6(cwd, dir);
|
|
50346
50553
|
const map2 = /* @__PURE__ */ new Map();
|
|
50347
50554
|
if (!existsSync4(abs)) return map2;
|
|
50348
50555
|
for (const file2 of (await walkTsFiles(abs)).sort()) {
|
|
@@ -50389,13 +50596,13 @@ async function runDev(options, deps) {
|
|
|
50389
50596
|
printSuccess("Config loaded");
|
|
50390
50597
|
const db = await connectDb(config3);
|
|
50391
50598
|
printSuccess("Database connected");
|
|
50392
|
-
const manguitoDir =
|
|
50599
|
+
const manguitoDir = resolve7(cwd, ".manguito");
|
|
50393
50600
|
await mkdir2(manguitoDir, { recursive: true });
|
|
50394
|
-
const drizzleConfigPath =
|
|
50601
|
+
const drizzleConfigPath = resolve7(manguitoDir, "drizzle.config.ts");
|
|
50395
50602
|
const needsSeed = !await db.tableExists("users");
|
|
50396
50603
|
const bootstrapRegistry = await parseAllSchemas(cwd, config3);
|
|
50397
50604
|
await generateDrizzleConfig(config3, manguitoDir);
|
|
50398
|
-
await
|
|
50605
|
+
await writeFile9(join13(manguitoDir, "schema.ts"), generateSchemaFile(bootstrapRegistry), "utf8");
|
|
50399
50606
|
await runDevMigration(drizzleConfigPath);
|
|
50400
50607
|
printSuccess(needsSeed ? "Schema tables created" : "Schema tables up to date");
|
|
50401
50608
|
if (needsSeed) {
|
|
@@ -50441,8 +50648,20 @@ async function runDev(options, deps) {
|
|
|
50441
50648
|
);
|
|
50442
50649
|
await generateSchemaRegistry(registry2, manguitoDir);
|
|
50443
50650
|
await generateRoutes2(registry2, manguitoDir);
|
|
50444
|
-
await generateForms(registry2,
|
|
50651
|
+
await generateForms(registry2, join13(manguitoDir, "forms"));
|
|
50445
50652
|
await generateNav(registry2, manguitoDir);
|
|
50653
|
+
const schemaConfig = resolveSchemaConfig(cwd, config3);
|
|
50654
|
+
const snapshotsResult = loadVersionSnapshots(schemaConfig, registry2);
|
|
50655
|
+
if (!snapshotsResult.ok) {
|
|
50656
|
+
printValidationErrors(snapshotsResult.errors, "Version snapshot errors", "manguito version:diff");
|
|
50657
|
+
process.exit(1);
|
|
50658
|
+
}
|
|
50659
|
+
const versionModelResult = computeVersionModel({ current: registry2, snapshots: snapshotsResult.value });
|
|
50660
|
+
if (!versionModelResult.ok) {
|
|
50661
|
+
printValidationErrors(versionModelResult.errors, "Version model errors", "manguito version:diff");
|
|
50662
|
+
process.exit(1);
|
|
50663
|
+
}
|
|
50664
|
+
const versionModel = reduceVersionModel(versionModelResult.value);
|
|
50446
50665
|
const resolverMap = await loadProgrammaticResolvers(cwd, config3.programmatic.dir);
|
|
50447
50666
|
const adapter = createCmsApp({
|
|
50448
50667
|
name: config3.name,
|
|
@@ -50450,6 +50669,7 @@ async function runDev(options, deps) {
|
|
|
50450
50669
|
db: db.getDb(),
|
|
50451
50670
|
storage: config3.storage,
|
|
50452
50671
|
resolvers: resolverMap,
|
|
50672
|
+
versions: versionModel,
|
|
50453
50673
|
...config3.api.prefix ? { prefix: config3.api.prefix } : {},
|
|
50454
50674
|
...config3.api.media?.max_file_size ? { media: { max_file_size: config3.api.media.max_file_size } } : {},
|
|
50455
50675
|
...config3.api.rateLimit ? { rateLimit: config3.api.rateLimit } : {},
|
|
@@ -50482,8 +50702,8 @@ async function runDev(options, deps) {
|
|
|
50482
50702
|
}
|
|
50483
50703
|
if (url2.startsWith("/uploads/")) {
|
|
50484
50704
|
const relativePath = (url2.slice("/uploads/".length).split("?")[0] ?? "").replace(/\.\./g, "");
|
|
50485
|
-
const uploadsDir =
|
|
50486
|
-
const filePath =
|
|
50705
|
+
const uploadsDir = resolve7(cwd, "uploads");
|
|
50706
|
+
const filePath = resolve7(uploadsDir, relativePath);
|
|
50487
50707
|
if (!filePath.startsWith(uploadsDir + "/") && filePath !== uploadsDir) {
|
|
50488
50708
|
res.statusCode = 403;
|
|
50489
50709
|
res.end("Forbidden");
|
|
@@ -50524,7 +50744,7 @@ async function runDev(options, deps) {
|
|
|
50524
50744
|
printSuccess(`Dev server running at http://localhost:${port}`);
|
|
50525
50745
|
printSuccess(`Admin panel at http://localhost:${port}${config3.admin.prefix}`);
|
|
50526
50746
|
});
|
|
50527
|
-
const schemasDir =
|
|
50747
|
+
const schemasDir = resolve7(cwd, config3.schema.base_path);
|
|
50528
50748
|
const watcher = watch(schemasDir, { recursive: true });
|
|
50529
50749
|
void (async () => {
|
|
50530
50750
|
for await (const event of watcher) {
|
|
@@ -50543,7 +50763,7 @@ async function runDev(options, deps) {
|
|
|
50543
50763
|
}
|
|
50544
50764
|
}
|
|
50545
50765
|
})();
|
|
50546
|
-
const programmaticDir =
|
|
50766
|
+
const programmaticDir = resolve7(cwd, config3.programmatic.dir);
|
|
50547
50767
|
if (existsSync5(programmaticDir)) {
|
|
50548
50768
|
const progWatcher = watch(programmaticDir, { recursive: true });
|
|
50549
50769
|
void (async () => {
|
|
@@ -50575,11 +50795,25 @@ async function onSchemaFileChange(args) {
|
|
|
50575
50795
|
return;
|
|
50576
50796
|
}
|
|
50577
50797
|
await generateDrizzleConfig(config3, manguitoDir);
|
|
50578
|
-
await
|
|
50798
|
+
await writeFile9(join13(manguitoDir, "schema.ts"), generateSchemaFile(registry2), "utf8");
|
|
50579
50799
|
await generateSchemaRegistry(registry2, manguitoDir);
|
|
50580
50800
|
await generateRoutes2(registry2, manguitoDir);
|
|
50581
|
-
await generateForms(registry2,
|
|
50801
|
+
await generateForms(registry2, join13(manguitoDir, "forms"));
|
|
50582
50802
|
await generateNav(registry2, manguitoDir);
|
|
50803
|
+
const schemaConfig = resolveSchemaConfig(cwd, config3);
|
|
50804
|
+
const snapshotsResult = loadVersionSnapshots(schemaConfig, registry2);
|
|
50805
|
+
if (!snapshotsResult.ok) {
|
|
50806
|
+
printValidationErrors(snapshotsResult.errors, "Version snapshot errors", "manguito version:diff");
|
|
50807
|
+
process.stderr.write("\u26A0 Changes not applied.\n");
|
|
50808
|
+
return;
|
|
50809
|
+
}
|
|
50810
|
+
const versionModelResult = computeVersionModel({ current: registry2, snapshots: snapshotsResult.value });
|
|
50811
|
+
if (!versionModelResult.ok) {
|
|
50812
|
+
printValidationErrors(versionModelResult.errors, "Version model errors", "manguito version:diff");
|
|
50813
|
+
process.stderr.write("\u26A0 Changes not applied.\n");
|
|
50814
|
+
return;
|
|
50815
|
+
}
|
|
50816
|
+
const versionModel = reduceVersionModel(versionModelResult.value);
|
|
50583
50817
|
try {
|
|
50584
50818
|
await runDevMigration(drizzleConfigPath);
|
|
50585
50819
|
} catch (err) {
|
|
@@ -50594,6 +50828,7 @@ async function onSchemaFileChange(args) {
|
|
|
50594
50828
|
db: db.getDb(),
|
|
50595
50829
|
storage: config3.storage,
|
|
50596
50830
|
resolvers: resolverMap,
|
|
50831
|
+
versions: versionModel,
|
|
50597
50832
|
...config3.api.prefix ? { prefix: config3.api.prefix } : {},
|
|
50598
50833
|
...config3.api.media?.max_file_size ? { media: { max_file_size: config3.api.media.max_file_size } } : {},
|
|
50599
50834
|
...config3.api.rateLimit ? { rateLimit: config3.api.rateLimit } : {},
|
|
@@ -50618,7 +50853,7 @@ async function parseAllSchemas(cwd, config3) {
|
|
|
50618
50853
|
}
|
|
50619
50854
|
parsedSchemas.push(parseResult.schema);
|
|
50620
50855
|
}
|
|
50621
|
-
const rolesPath =
|
|
50856
|
+
const rolesPath = resolve7(cwd, config3.schema.base_path, "roles.json");
|
|
50622
50857
|
const rolesLoad = loadSchemaFile(rolesPath);
|
|
50623
50858
|
if (!rolesLoad.ok) {
|
|
50624
50859
|
printGuidedError("Could not read roles.json.");
|
|
@@ -50629,7 +50864,7 @@ async function parseAllSchemas(cwd, config3) {
|
|
|
50629
50864
|
printGuidedError("roles.json parse errors \u2014 run `manguito validate` for details.");
|
|
50630
50865
|
process.exit(1);
|
|
50631
50866
|
}
|
|
50632
|
-
const routesPath =
|
|
50867
|
+
const routesPath = resolve7(cwd, config3.schema.base_path, "routes.json");
|
|
50633
50868
|
const routesLoad = loadSchemaFile(routesPath);
|
|
50634
50869
|
if (!routesLoad.ok) {
|
|
50635
50870
|
printGuidedError("Could not read routes.json.");
|
|
@@ -50643,7 +50878,7 @@ async function parseAllSchemas(cwd, config3) {
|
|
|
50643
50878
|
return buildSchemaRegistry(parsedSchemas, routesResult.value, rolesResult.value);
|
|
50644
50879
|
}
|
|
50645
50880
|
function resolveAdminRoot2(cwd) {
|
|
50646
|
-
const cwdRequire = createRequire2(
|
|
50881
|
+
const cwdRequire = createRequire2(join13(cwd, "package.json"));
|
|
50647
50882
|
const adminPkgJson = cwdRequire.resolve("@bobbykim/manguito-cms-admin/package.json");
|
|
50648
50883
|
return dirname2(adminPkgJson);
|
|
50649
50884
|
}
|
|
@@ -50689,7 +50924,7 @@ async function bridgeToHono(req, res, honoFetch) {
|
|
|
50689
50924
|
|
|
50690
50925
|
// src/commands/start.ts
|
|
50691
50926
|
init_esm_shims();
|
|
50692
|
-
import { resolve as
|
|
50927
|
+
import { resolve as resolve8 } from "path";
|
|
50693
50928
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
50694
50929
|
function registerStart(program2) {
|
|
50695
50930
|
program2.command("start").description("Start the production server from dist/").option("--env <path>", "path to .env file to load").action(async (options) => {
|
|
@@ -50702,7 +50937,7 @@ async function runStart(options, deps) {
|
|
|
50702
50937
|
const config3 = await resolveConfig(cwd);
|
|
50703
50938
|
const db = await connectDb(config3);
|
|
50704
50939
|
const migrationsTable = config3.migrations?.table ?? "__manguito_migrations";
|
|
50705
|
-
const migrationsFolder = config3.migrations?.folder ?
|
|
50940
|
+
const migrationsFolder = config3.migrations?.folder ? resolve8(cwd, config3.migrations.folder) : resolve8(cwd, "./migrations");
|
|
50706
50941
|
const trackingTableExists = await db.tableExists(migrationsTable);
|
|
50707
50942
|
if (!trackingTableExists) {
|
|
50708
50943
|
printGuidedError(
|
|
@@ -50737,7 +50972,7 @@ async function runStart(options, deps) {
|
|
|
50737
50972
|
} else {
|
|
50738
50973
|
allErrors.push(...walkResult.errors);
|
|
50739
50974
|
}
|
|
50740
|
-
const rolesPath =
|
|
50975
|
+
const rolesPath = resolve8(cwd, config3.schema.base_path, "roles.json");
|
|
50741
50976
|
const rolesLoad = loadSchemaFile(rolesPath);
|
|
50742
50977
|
let parsedRoles = null;
|
|
50743
50978
|
if (rolesLoad.ok) {
|
|
@@ -50750,7 +50985,7 @@ async function runStart(options, deps) {
|
|
|
50750
50985
|
} else {
|
|
50751
50986
|
allErrors.push(...rolesLoad.errors);
|
|
50752
50987
|
}
|
|
50753
|
-
const routesPath =
|
|
50988
|
+
const routesPath = resolve8(cwd, config3.schema.base_path, "routes.json");
|
|
50754
50989
|
const routesLoad = loadSchemaFile(routesPath);
|
|
50755
50990
|
let parsedRoutes = null;
|
|
50756
50991
|
if (routesLoad.ok) {
|
|
@@ -50772,7 +51007,7 @@ async function runStart(options, deps) {
|
|
|
50772
51007
|
}
|
|
50773
51008
|
const registry2 = buildSchemaRegistry(parsedSchemas, parsedRoutes, parsedRoles);
|
|
50774
51009
|
await seedSystemTables(db.getDb(), registry2);
|
|
50775
|
-
const serverUrl = pathToFileURL3(
|
|
51010
|
+
const serverUrl = pathToFileURL3(resolve8(cwd, "dist/server.js")).href;
|
|
50776
51011
|
await (deps.loadServer ? deps.loadServer(serverUrl) : import(serverUrl));
|
|
50777
51012
|
const port = Number(process.env["PORT"] ?? 3e3);
|
|
50778
51013
|
printSuccess(`Server running at http://localhost:${port}`);
|
|
@@ -50781,7 +51016,7 @@ async function runStart(options, deps) {
|
|
|
50781
51016
|
|
|
50782
51017
|
// src/commands/migrate.ts
|
|
50783
51018
|
init_esm_shims();
|
|
50784
|
-
import { resolve as
|
|
51019
|
+
import { resolve as resolve9, join as join14 } from "path";
|
|
50785
51020
|
import { readFile as readFile2 } from "fs/promises";
|
|
50786
51021
|
function registerMigrate(program2) {
|
|
50787
51022
|
program2.command("migrate").description("Apply pending database migrations").option("--env <path>", "path to .env file to load").option("--status", "show migration state without applying").option("--dry-run", "preview migrations without writing").option("--force", "skip destructive-change confirmation prompt").action(async (options) => {
|
|
@@ -50799,8 +51034,8 @@ function buildDeps(options, cwd) {
|
|
|
50799
51034
|
buildRunner: async () => runBuild(options.env ? { env: options.env } : {}, { cwd }),
|
|
50800
51035
|
needsRebuild: () => needsRebuild(cwd),
|
|
50801
51036
|
db: createPostgresAdapter(),
|
|
50802
|
-
migrationsFolder:
|
|
50803
|
-
configPath:
|
|
51037
|
+
migrationsFolder: resolve9(cwd, "./migrations"),
|
|
51038
|
+
configPath: resolve9(cwd, "dist/generated/drizzle.config.ts"),
|
|
50804
51039
|
prompt: createPromptAdapter()
|
|
50805
51040
|
};
|
|
50806
51041
|
}
|
|
@@ -50815,7 +51050,7 @@ async function runMigrate(options, deps) {
|
|
|
50815
51050
|
}
|
|
50816
51051
|
const config4 = await resolveConfig(process.cwd());
|
|
50817
51052
|
const migrationsTable2 = config4.migrations?.table ?? "__manguito_migrations";
|
|
50818
|
-
const migrationsFolder2 = config4.migrations?.folder ?
|
|
51053
|
+
const migrationsFolder2 = config4.migrations?.folder ? resolve9(process.cwd(), config4.migrations.folder) : deps.migrationsFolder;
|
|
50819
51054
|
const status = await getMigrationStatus(deps.db.getDb(), { migrationsTable: migrationsTable2, migrationsFolder: migrationsFolder2 });
|
|
50820
51055
|
if (status.applied.length === 0 && status.pending.length === 0) {
|
|
50821
51056
|
process.stdout.write(
|
|
@@ -50847,7 +51082,7 @@ async function runMigrate(options, deps) {
|
|
|
50847
51082
|
loadEnvFile(options.env);
|
|
50848
51083
|
const cwd = process.cwd();
|
|
50849
51084
|
const config3 = await resolveConfig(cwd);
|
|
50850
|
-
const migrationsFolder = config3.migrations?.folder ?
|
|
51085
|
+
const migrationsFolder = config3.migrations?.folder ? resolve9(cwd, config3.migrations.folder) : deps.migrationsFolder;
|
|
50851
51086
|
const migrationsTable = config3.migrations?.table ?? "__manguito_migrations";
|
|
50852
51087
|
try {
|
|
50853
51088
|
await deps.db.connect();
|
|
@@ -50867,10 +51102,10 @@ async function runMigrate(options, deps) {
|
|
|
50867
51102
|
}
|
|
50868
51103
|
}
|
|
50869
51104
|
printSuccess("Build complete");
|
|
50870
|
-
const generatedDir =
|
|
51105
|
+
const generatedDir = resolve9(cwd, "dist/generated");
|
|
50871
51106
|
await generateDrizzleConfig(config3, generatedDir);
|
|
50872
51107
|
const newFileNames = await generateMigration(deps.configPath, migrationsFolder);
|
|
50873
|
-
const newFilePaths = newFileNames.map((f) =>
|
|
51108
|
+
const newFilePaths = newFileNames.map((f) => join14(migrationsFolder, f));
|
|
50874
51109
|
printSuccess(
|
|
50875
51110
|
newFileNames.length === 0 ? "No new migration files generated" : `Generated ${newFileNames.length} migration file${newFileNames.length !== 1 ? "s" : ""}: ${newFileNames.join(", ")}`
|
|
50876
51111
|
);
|
|
@@ -50940,7 +51175,7 @@ async function runMigrate(options, deps) {
|
|
|
50940
51175
|
} else {
|
|
50941
51176
|
allErrors.push(...walkResult.errors);
|
|
50942
51177
|
}
|
|
50943
|
-
const rolesPath =
|
|
51178
|
+
const rolesPath = resolve9(cwd, config3.schema.base_path, "roles.json");
|
|
50944
51179
|
const rolesLoad = loadSchemaFile(rolesPath);
|
|
50945
51180
|
let parsedRoles = null;
|
|
50946
51181
|
if (rolesLoad.ok) {
|
|
@@ -50953,7 +51188,7 @@ async function runMigrate(options, deps) {
|
|
|
50953
51188
|
} else {
|
|
50954
51189
|
allErrors.push(...rolesLoad.errors);
|
|
50955
51190
|
}
|
|
50956
|
-
const routesPath =
|
|
51191
|
+
const routesPath = resolve9(cwd, config3.schema.base_path, "routes.json");
|
|
50957
51192
|
const routesLoad = loadSchemaFile(routesPath);
|
|
50958
51193
|
let parsedRoutes = null;
|
|
50959
51194
|
if (routesLoad.ok) {
|
|
@@ -50985,7 +51220,7 @@ async function runMigrate(options, deps) {
|
|
|
50985
51220
|
|
|
50986
51221
|
// src/commands/validate.ts
|
|
50987
51222
|
init_esm_shims();
|
|
50988
|
-
import { resolve as
|
|
51223
|
+
import { resolve as resolve10 } from "path";
|
|
50989
51224
|
function registerValidate(program2) {
|
|
50990
51225
|
program2.command("validate").description("Parse and validate all schemas, config, roles, and routes").option("--env <path>", "path to .env file to load").action(async (options) => {
|
|
50991
51226
|
await runValidate(options, { cwd: process.cwd() });
|
|
@@ -51010,7 +51245,7 @@ async function runValidate(options, deps) {
|
|
|
51010
51245
|
}
|
|
51011
51246
|
}
|
|
51012
51247
|
}
|
|
51013
|
-
const rolesPath =
|
|
51248
|
+
const rolesPath = resolve10(cwd, config3.schema.base_path, "roles.json");
|
|
51014
51249
|
const rolesLoadResult = loadSchemaFile(rolesPath);
|
|
51015
51250
|
let parsedRoles = null;
|
|
51016
51251
|
if (!rolesLoadResult.ok) {
|
|
@@ -51023,7 +51258,7 @@ async function runValidate(options, deps) {
|
|
|
51023
51258
|
parsedRoles = rolesParseResult.value;
|
|
51024
51259
|
}
|
|
51025
51260
|
}
|
|
51026
|
-
const routesPath =
|
|
51261
|
+
const routesPath = resolve10(cwd, config3.schema.base_path, "routes.json");
|
|
51027
51262
|
const routesLoadResult = loadSchemaFile(routesPath);
|
|
51028
51263
|
let parsedRoutesDef = null;
|
|
51029
51264
|
if (!routesLoadResult.ok) {
|
|
@@ -51306,18 +51541,6 @@ import path6 from "path";
|
|
|
51306
51541
|
// src/utils/registry.ts
|
|
51307
51542
|
init_esm_shims();
|
|
51308
51543
|
import { resolve as resolve11 } from "path";
|
|
51309
|
-
|
|
51310
|
-
// src/utils/schema-config.ts
|
|
51311
|
-
init_esm_shims();
|
|
51312
|
-
import { resolve as resolve10 } from "path";
|
|
51313
|
-
function resolveSchemaConfig(cwd, config3) {
|
|
51314
|
-
return {
|
|
51315
|
-
base_path: resolve10(cwd, config3.schema.base_path),
|
|
51316
|
-
folders: config3.schema.folders
|
|
51317
|
-
};
|
|
51318
|
-
}
|
|
51319
|
-
|
|
51320
|
-
// src/utils/registry.ts
|
|
51321
51544
|
function loadWorkingRegistry(cwd, config3, command) {
|
|
51322
51545
|
const schema = resolveSchemaConfig(cwd, config3);
|
|
51323
51546
|
const allErrors = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobbykim/manguito-cms-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Bobby Kim <bobby.sihun.kim@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/bobbykim89/manguito-cms",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"tsup": "^8.5.1",
|
|
30
30
|
"typescript": "^6.0.3",
|
|
31
31
|
"vite": "^8.1.3",
|
|
32
|
-
"@bobbykim/manguito-cms-api": "0.4.3",
|
|
33
|
-
"@bobbykim/manguito-cms-core": "0.5.0",
|
|
34
32
|
"@bobbykim/manguito-cms-admin": "0.4.2",
|
|
35
|
-
"@bobbykim/manguito-cms-
|
|
33
|
+
"@bobbykim/manguito-cms-core": "0.5.0",
|
|
34
|
+
"@bobbykim/manguito-cms-db": "0.1.5",
|
|
35
|
+
"@bobbykim/manguito-cms-api": "0.5.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^25.9.5",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"build": "tsup",
|
|
44
44
|
"dev": "tsup --watch",
|
|
45
45
|
"test": "dotenv -e .env.test -- vitest run",
|
|
46
|
-
"lint": "eslint src"
|
|
46
|
+
"lint": "eslint src",
|
|
47
|
+
"typecheck": "tsc --noEmit"
|
|
47
48
|
}
|
|
48
49
|
}
|