@bobbykim/manguito-cms-api 0.4.0 → 0.4.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/{chunk-B5LWIR4U.mjs → chunk-S4NT6FUM.mjs} +8 -6
- package/dist/chunk-S4NT6FUM.mjs.map +1 -0
- package/dist/graphql/index.js +7 -5
- package/dist/graphql/index.js.map +1 -1
- package/dist/graphql/index.mjs +1 -1
- package/dist/{handler-TPEULQ5W.mjs → handler-7LVYEU5C.mjs} +2 -2
- package/dist/index.js +127 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +121 -45
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-B5LWIR4U.mjs.map +0 -1
- /package/dist/{handler-TPEULQ5W.mjs.map → handler-7LVYEU5C.mjs.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -500,7 +500,7 @@ var init_naming = __esm({
|
|
|
500
500
|
function buildSortFieldEnum(typeName) {
|
|
501
501
|
return new import_graphql3.GraphQLEnumType({
|
|
502
502
|
name: `${typeName}SortField`,
|
|
503
|
-
values: Object.fromEntries(SORTABLE.map((s) => [s.gql, { value: s.
|
|
503
|
+
values: Object.fromEntries(SORTABLE.map((s) => [s.gql, { value: s.value }]))
|
|
504
504
|
});
|
|
505
505
|
}
|
|
506
506
|
function comparableFilterInput(name, scalar) {
|
|
@@ -586,9 +586,9 @@ var init_filters = __esm({
|
|
|
586
586
|
values: { ASC: { value: "asc" }, DESC: { value: "desc" } }
|
|
587
587
|
});
|
|
588
588
|
SORTABLE = [
|
|
589
|
-
{ gql: "title",
|
|
590
|
-
{ gql: "createdAt",
|
|
591
|
-
{ gql: "updatedAt",
|
|
589
|
+
{ gql: "title", value: "title" },
|
|
590
|
+
{ gql: "createdAt", value: "created_at" },
|
|
591
|
+
{ gql: "updatedAt", value: "updated_at" }
|
|
592
592
|
];
|
|
593
593
|
StringFilter = equalityFilterInput("StringFilter", import_graphql3.GraphQLString);
|
|
594
594
|
BooleanFilter = new import_graphql3.GraphQLInputObjectType({
|
|
@@ -647,11 +647,13 @@ function collectionResolver(typeName, nameMap, fieldKeys) {
|
|
|
647
647
|
throw codeError2("INVALID_PAGINATION", "perPage must be between 1 and 100");
|
|
648
648
|
}
|
|
649
649
|
const repo = ctx.repos[typeName];
|
|
650
|
+
const sortBy = args.sortBy ?? "created_at";
|
|
651
|
+
const sortColumn = fieldKeys?.columnFor(sortBy) ?? sortBy;
|
|
650
652
|
const result = await repo.findMany({
|
|
651
653
|
published_only: true,
|
|
652
654
|
page,
|
|
653
655
|
per_page: perPage,
|
|
654
|
-
sort_by:
|
|
656
|
+
sort_by: sortColumn,
|
|
655
657
|
sort_order: args.sortOrder ?? "asc",
|
|
656
658
|
filters: translateFilters(args.filter, nameMap, fieldKeys?.columnFor)
|
|
657
659
|
});
|
|
@@ -1643,6 +1645,54 @@ function createProgrammaticResolver(resolvers, options) {
|
|
|
1643
1645
|
return { resolveItem, resolveList, hasSchema };
|
|
1644
1646
|
}
|
|
1645
1647
|
|
|
1648
|
+
// src/projector.ts
|
|
1649
|
+
function isPlainRow(v) {
|
|
1650
|
+
return typeof v === "object" && v !== null && !Array.isArray(v) && !(v instanceof Date);
|
|
1651
|
+
}
|
|
1652
|
+
var MEDIA_FIELD_TYPES = /* @__PURE__ */ new Set(["image", "video", "file"]);
|
|
1653
|
+
function nestedTargets(fields) {
|
|
1654
|
+
const out = [];
|
|
1655
|
+
for (const f of fields) {
|
|
1656
|
+
if (MEDIA_FIELD_TYPES.has(f.field_type)) continue;
|
|
1657
|
+
if (f.field_type !== "paragraph" && f.field_type !== "reference") continue;
|
|
1658
|
+
const ref = f.ui_component.ref;
|
|
1659
|
+
if (!ref) continue;
|
|
1660
|
+
out.push({ label: f.name, target: ref });
|
|
1661
|
+
}
|
|
1662
|
+
return out;
|
|
1663
|
+
}
|
|
1664
|
+
function buildProjectors(registry, fieldKeyMaps) {
|
|
1665
|
+
const projectors = {};
|
|
1666
|
+
const sources = [
|
|
1667
|
+
registry.content_types,
|
|
1668
|
+
registry.taxonomy_types,
|
|
1669
|
+
registry.paragraph_types
|
|
1670
|
+
];
|
|
1671
|
+
for (const source of sources) {
|
|
1672
|
+
for (const [typeName, type] of Object.entries(source)) {
|
|
1673
|
+
const map = fieldKeyMaps[typeName];
|
|
1674
|
+
if (!map) continue;
|
|
1675
|
+
projectors[typeName] = { map, nested: nestedTargets(type.fields) };
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
return projectors;
|
|
1679
|
+
}
|
|
1680
|
+
function projectRow(row, typeName, projectors) {
|
|
1681
|
+
const p = projectors[typeName];
|
|
1682
|
+
if (!p) return row;
|
|
1683
|
+
const out = p.map.toLabels(row);
|
|
1684
|
+
for (const { label, target } of p.nested) {
|
|
1685
|
+
const v = out[label];
|
|
1686
|
+
if (v === null || v === void 0) continue;
|
|
1687
|
+
if (Array.isArray(v)) {
|
|
1688
|
+
out[label] = v.map((item) => isPlainRow(item) ? projectRow(item, target, projectors) : item);
|
|
1689
|
+
} else if (isPlainRow(v)) {
|
|
1690
|
+
out[label] = projectRow(v, target, projectors);
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
return out;
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1646
1696
|
// src/routes/query-params.ts
|
|
1647
1697
|
var SORTABLE_FIELDS = /* @__PURE__ */ new Set(["title", "created_at", "updated_at"]);
|
|
1648
1698
|
var RELATION_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -1697,7 +1747,7 @@ function parseFilters(url, validFields, columnFor) {
|
|
|
1697
1747
|
function isPublished(item) {
|
|
1698
1748
|
return item["published"] === true;
|
|
1699
1749
|
}
|
|
1700
|
-
function registerPublicContentRoutes(app, registry, repos,
|
|
1750
|
+
function registerPublicContentRoutes(app, registry, repos, projectors, paths, listRateLimit, resolver) {
|
|
1701
1751
|
function registerListRoute(path, handler) {
|
|
1702
1752
|
if (listRateLimit) {
|
|
1703
1753
|
app.get(path, listRateLimit, handler);
|
|
@@ -1740,13 +1790,14 @@ function registerPublicContentRoutes(app, registry, repos, fieldKeyMaps, paths,
|
|
|
1740
1790
|
404
|
|
1741
1791
|
);
|
|
1742
1792
|
}
|
|
1743
|
-
let data =
|
|
1793
|
+
let data = projectRow(result.data[0], typeName, projectors);
|
|
1744
1794
|
if (resolver?.hasSchema(typeName)) data = await resolver.resolveItem(typeName, data);
|
|
1745
1795
|
return c.json({ ok: true, data });
|
|
1746
1796
|
});
|
|
1747
1797
|
} else {
|
|
1748
1798
|
registerListRoute(paths.collection(basePath), async (c) => {
|
|
1749
|
-
const
|
|
1799
|
+
const projector = projectors[typeName];
|
|
1800
|
+
const fieldKeys = projector.map;
|
|
1750
1801
|
const pagination = parsePagination(c.req.query("page"), c.req.query("per_page"));
|
|
1751
1802
|
if (!pagination.ok) {
|
|
1752
1803
|
return c.json(
|
|
@@ -1814,17 +1865,18 @@ function registerPublicContentRoutes(app, registry, repos, fieldKeyMaps, paths,
|
|
|
1814
1865
|
);
|
|
1815
1866
|
}
|
|
1816
1867
|
}
|
|
1868
|
+
const sortColumn = fieldKeys.columnFor(sortBy) ?? sortBy;
|
|
1817
1869
|
const result = await repo.findMany({
|
|
1818
1870
|
published_only: true,
|
|
1819
1871
|
page: pagination.page,
|
|
1820
1872
|
per_page: pagination.per_page,
|
|
1821
|
-
sort_by:
|
|
1873
|
+
sort_by: sortColumn,
|
|
1822
1874
|
sort_order: sortOrder,
|
|
1823
1875
|
filters: filtersResult.filters,
|
|
1824
1876
|
include
|
|
1825
1877
|
});
|
|
1826
1878
|
const labeled = result.data.map(
|
|
1827
|
-
(row) =>
|
|
1879
|
+
(row) => projectRow(row, typeName, projectors)
|
|
1828
1880
|
);
|
|
1829
1881
|
const data = resolver?.hasSchema(typeName) ? await resolver.resolveList(typeName, labeled) : labeled;
|
|
1830
1882
|
return c.json({ ...result, data });
|
|
@@ -1856,7 +1908,7 @@ function registerPublicContentRoutes(app, registry, repos, fieldKeyMaps, paths,
|
|
|
1856
1908
|
404
|
|
1857
1909
|
);
|
|
1858
1910
|
}
|
|
1859
|
-
let data =
|
|
1911
|
+
let data = projectRow(item, typeName, projectors);
|
|
1860
1912
|
if (resolver?.hasSchema(typeName)) data = await resolver.resolveItem(typeName, data);
|
|
1861
1913
|
return c.json({ ok: true, data });
|
|
1862
1914
|
});
|
|
@@ -1884,9 +1936,8 @@ function registerPublicContentRoutes(app, registry, repos, fieldKeyMaps, paths,
|
|
|
1884
1936
|
page: pagination.page,
|
|
1885
1937
|
per_page: pagination.per_page
|
|
1886
1938
|
});
|
|
1887
|
-
const fieldKeys = fieldKeyMaps[typeName];
|
|
1888
1939
|
const labeled = result.data.map(
|
|
1889
|
-
(row) =>
|
|
1940
|
+
(row) => projectRow(row, typeName, projectors)
|
|
1890
1941
|
);
|
|
1891
1942
|
const data = resolver?.hasSchema(typeName) ? await resolver.resolveList(typeName, labeled) : labeled;
|
|
1892
1943
|
return c.json({ ...result, data });
|
|
@@ -1903,7 +1954,7 @@ function registerPublicContentRoutes(app, registry, repos, fieldKeyMaps, paths,
|
|
|
1903
1954
|
404
|
|
1904
1955
|
);
|
|
1905
1956
|
}
|
|
1906
|
-
let data =
|
|
1957
|
+
let data = projectRow(item, typeName, projectors);
|
|
1907
1958
|
if (resolver?.hasSchema(typeName)) data = await resolver.resolveItem(typeName, data);
|
|
1908
1959
|
return c.json({ ok: true, data });
|
|
1909
1960
|
});
|
|
@@ -2119,7 +2170,7 @@ function parseListQuery(url, schemaFieldNames, relationFieldNames, columnFor) {
|
|
|
2119
2170
|
search
|
|
2120
2171
|
};
|
|
2121
2172
|
}
|
|
2122
|
-
function registerAdminContentRoutes(app, registry, repos,
|
|
2173
|
+
function registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo, requirePermission, db) {
|
|
2123
2174
|
for (const [typeName, contentType] of Object.entries(registry.content_types)) {
|
|
2124
2175
|
const basePath = `content/${typeName}`;
|
|
2125
2176
|
const repo = repos[typeName];
|
|
@@ -2131,7 +2182,8 @@ function registerAdminContentRoutes(app, registry, repos, fieldKeyMaps, mediaRep
|
|
|
2131
2182
|
const relationFieldNames = new Set(
|
|
2132
2183
|
contentType.fields.filter((f) => RELATION_FIELD_TYPES.has(f.field_type)).map((f) => f.name)
|
|
2133
2184
|
);
|
|
2134
|
-
const
|
|
2185
|
+
const projector = projectors[typeName];
|
|
2186
|
+
const fieldKeys = projector.map;
|
|
2135
2187
|
const requiredFields = contentType.fields.filter((f) => f.required);
|
|
2136
2188
|
const mediaFields = contentType.fields.filter(
|
|
2137
2189
|
(f) => f.field_type === "image" || f.field_type === "video" || f.field_type === "file"
|
|
@@ -2152,10 +2204,11 @@ function registerAdminContentRoutes(app, registry, repos, fieldKeyMaps, mediaRep
|
|
|
2152
2204
|
const publishedParam = c.req.query("published");
|
|
2153
2205
|
const extraFilters = {};
|
|
2154
2206
|
if (publishedParam === "false") extraFilters["published"] = false;
|
|
2207
|
+
const sortColumn = fieldKeys.columnFor(parsed.sortBy) ?? parsed.sortBy;
|
|
2155
2208
|
const findOpts = {
|
|
2156
2209
|
page: parsed.pagination.page,
|
|
2157
2210
|
per_page: parsed.pagination.per_page,
|
|
2158
|
-
sort_by:
|
|
2211
|
+
sort_by: sortColumn,
|
|
2159
2212
|
sort_order: parsed.sortOrder,
|
|
2160
2213
|
filters: { ...parsed.filters, ...extraFilters },
|
|
2161
2214
|
include: parsed.include
|
|
@@ -2165,7 +2218,9 @@ function registerAdminContentRoutes(app, registry, repos, fieldKeyMaps, mediaRep
|
|
|
2165
2218
|
findOpts.search = { term: parsed.search, columns: searchableColumns };
|
|
2166
2219
|
}
|
|
2167
2220
|
const result = await repo.findMany(findOpts);
|
|
2168
|
-
const data = result.data.map(
|
|
2221
|
+
const data = result.data.map(
|
|
2222
|
+
(row) => projectRow(row, typeName, projectors)
|
|
2223
|
+
);
|
|
2169
2224
|
return c.json({ ...result, data });
|
|
2170
2225
|
}
|
|
2171
2226
|
);
|
|
@@ -2201,7 +2256,7 @@ function registerAdminContentRoutes(app, registry, repos, fieldKeyMaps, mediaRep
|
|
|
2201
2256
|
}
|
|
2202
2257
|
}
|
|
2203
2258
|
}
|
|
2204
|
-
const data =
|
|
2259
|
+
const data = projectRow(item, typeName, projectors);
|
|
2205
2260
|
return c.json({ ok: true, data });
|
|
2206
2261
|
}
|
|
2207
2262
|
);
|
|
@@ -2342,7 +2397,7 @@ function registerAdminContentRoutes(app, registry, repos, fieldKeyMaps, mediaRep
|
|
|
2342
2397
|
}
|
|
2343
2398
|
}
|
|
2344
2399
|
await applyMediaReferenceDelta(mergeMediaDeltas(...mediaDeltas), mediaRepo);
|
|
2345
|
-
const data =
|
|
2400
|
+
const data = projectRow(item, typeName, projectors);
|
|
2346
2401
|
return c.json({ ok: true, data }, 201);
|
|
2347
2402
|
};
|
|
2348
2403
|
app.patch(
|
|
@@ -2463,7 +2518,7 @@ function registerAdminContentRoutes(app, registry, repos, fieldKeyMaps, mediaRep
|
|
|
2463
2518
|
}
|
|
2464
2519
|
}
|
|
2465
2520
|
await applyMediaReferenceDelta(mergeMediaDeltas(...mediaDeltas), mediaRepo);
|
|
2466
|
-
const data =
|
|
2521
|
+
const data = projectRow(updated, typeName, projectors);
|
|
2467
2522
|
return c.json({ ok: true, data });
|
|
2468
2523
|
};
|
|
2469
2524
|
if (contentType.only_one) {
|
|
@@ -2524,7 +2579,8 @@ function registerAdminContentRoutes(app, registry, repos, fieldKeyMaps, mediaRep
|
|
|
2524
2579
|
const relationFieldNames = new Set(
|
|
2525
2580
|
taxonomyType.fields.filter((f) => RELATION_FIELD_TYPES.has(f.field_type)).map((f) => f.name)
|
|
2526
2581
|
);
|
|
2527
|
-
const
|
|
2582
|
+
const projector = projectors[typeName];
|
|
2583
|
+
const fieldKeys = projector.map;
|
|
2528
2584
|
const requiredFields = taxonomyType.fields.filter((f) => f.required);
|
|
2529
2585
|
const mediaFields = taxonomyType.fields.filter(
|
|
2530
2586
|
(f) => f.field_type === "image" || f.field_type === "video" || f.field_type === "file"
|
|
@@ -2545,10 +2601,11 @@ function registerAdminContentRoutes(app, registry, repos, fieldKeyMaps, mediaRep
|
|
|
2545
2601
|
const publishedParam = c.req.query("published");
|
|
2546
2602
|
const extraFilters = {};
|
|
2547
2603
|
if (publishedParam === "false") extraFilters["published"] = false;
|
|
2604
|
+
const sortColumn = fieldKeys.columnFor(parsed.sortBy) ?? parsed.sortBy;
|
|
2548
2605
|
const findOpts = {
|
|
2549
2606
|
page: parsed.pagination.page,
|
|
2550
2607
|
per_page: parsed.pagination.per_page,
|
|
2551
|
-
sort_by:
|
|
2608
|
+
sort_by: sortColumn,
|
|
2552
2609
|
sort_order: parsed.sortOrder,
|
|
2553
2610
|
filters: { ...parsed.filters, ...extraFilters },
|
|
2554
2611
|
include: parsed.include
|
|
@@ -2558,7 +2615,9 @@ function registerAdminContentRoutes(app, registry, repos, fieldKeyMaps, mediaRep
|
|
|
2558
2615
|
findOpts.search = { term: parsed.search, columns: searchableColumns };
|
|
2559
2616
|
}
|
|
2560
2617
|
const result = await repo.findMany(findOpts);
|
|
2561
|
-
const data = result.data.map(
|
|
2618
|
+
const data = result.data.map(
|
|
2619
|
+
(row) => projectRow(row, typeName, projectors)
|
|
2620
|
+
);
|
|
2562
2621
|
return c.json({ ...result, data });
|
|
2563
2622
|
}
|
|
2564
2623
|
);
|
|
@@ -2574,7 +2633,7 @@ function registerAdminContentRoutes(app, registry, repos, fieldKeyMaps, mediaRep
|
|
|
2574
2633
|
404
|
|
2575
2634
|
);
|
|
2576
2635
|
}
|
|
2577
|
-
const data =
|
|
2636
|
+
const data = projectRow(item, typeName, projectors);
|
|
2578
2637
|
return c.json({ ok: true, data });
|
|
2579
2638
|
}
|
|
2580
2639
|
);
|
|
@@ -2627,7 +2686,7 @@ function registerAdminContentRoutes(app, registry, repos, fieldKeyMaps, mediaRep
|
|
|
2627
2686
|
}
|
|
2628
2687
|
}
|
|
2629
2688
|
await applyMediaReferenceDelta(mergeMediaDeltas(...mediaDeltas), mediaRepo);
|
|
2630
|
-
const data =
|
|
2689
|
+
const data = projectRow(item, typeName, projectors);
|
|
2631
2690
|
return c.json({ ok: true, data }, 201);
|
|
2632
2691
|
}
|
|
2633
2692
|
);
|
|
@@ -2695,7 +2754,7 @@ function registerAdminContentRoutes(app, registry, repos, fieldKeyMaps, mediaRep
|
|
|
2695
2754
|
}
|
|
2696
2755
|
}
|
|
2697
2756
|
await applyMediaReferenceDelta(mergeMediaDeltas(...mediaDeltas), mediaRepo);
|
|
2698
|
-
const data =
|
|
2757
|
+
const data = projectRow(updated, typeName, projectors);
|
|
2699
2758
|
return c.json({ ok: true, data });
|
|
2700
2759
|
}
|
|
2701
2760
|
);
|
|
@@ -3688,7 +3747,7 @@ function registerUserRoutes(app, db, requirePermission, requireHierarchy) {
|
|
|
3688
3747
|
var import_drizzle_orm6 = require("drizzle-orm");
|
|
3689
3748
|
var API_VERSION = (() => {
|
|
3690
3749
|
try {
|
|
3691
|
-
return "0.4.
|
|
3750
|
+
return "0.4.1";
|
|
3692
3751
|
} catch {
|
|
3693
3752
|
return "0.0.0";
|
|
3694
3753
|
}
|
|
@@ -3851,7 +3910,7 @@ function whereFragment(conds) {
|
|
|
3851
3910
|
return conds.length > 0 ? import_drizzle_orm8.sql` WHERE ${import_drizzle_orm8.sql.join(conds, import_drizzle_orm8.sql` AND `)}` : import_drizzle_orm8.sql``;
|
|
3852
3911
|
}
|
|
3853
3912
|
function createDrizzleContentRepository(db, tableName, options = {}) {
|
|
3854
|
-
const { relations = {}, publishedRelations = false } = options;
|
|
3913
|
+
const { relations = {}, publishedRelations = false, sortableColumns } = options;
|
|
3855
3914
|
function tableRaw() {
|
|
3856
3915
|
return import_drizzle_orm8.sql.raw(quoteIdent3(tableName));
|
|
3857
3916
|
}
|
|
@@ -3889,8 +3948,9 @@ function createDrizzleContentRepository(db, tableName, options = {}) {
|
|
|
3889
3948
|
sort_order = "asc",
|
|
3890
3949
|
search
|
|
3891
3950
|
} = opts;
|
|
3892
|
-
|
|
3893
|
-
|
|
3951
|
+
const allowed = sortableColumns ?? SORTABLE_FIELDS2;
|
|
3952
|
+
if (!allowed.has(sort_by)) {
|
|
3953
|
+
throw codeError("INVALID_SORT_FIELD", `'${sort_by}' is not sortable.`);
|
|
3894
3954
|
}
|
|
3895
3955
|
const offset = (page - 1) * per_page;
|
|
3896
3956
|
const conds = buildConditions(published_only, filters, search);
|
|
@@ -4139,16 +4199,38 @@ function createCmsApp(options) {
|
|
|
4139
4199
|
return result.rows[0]?.role ?? null;
|
|
4140
4200
|
};
|
|
4141
4201
|
const requireHierarchy = createHierarchyMiddleware(rolesRegistry, getUserRole);
|
|
4202
|
+
const fieldKeyMaps = Object.fromEntries([
|
|
4203
|
+
...Object.entries(registry.content_types).map(([typeName, ct]) => [
|
|
4204
|
+
typeName,
|
|
4205
|
+
createFieldKeyMap(ct.fields)
|
|
4206
|
+
]),
|
|
4207
|
+
...Object.entries(registry.taxonomy_types).map(([typeName, tt]) => [
|
|
4208
|
+
typeName,
|
|
4209
|
+
createFieldKeyMap(tt.fields)
|
|
4210
|
+
]),
|
|
4211
|
+
...Object.entries(registry.paragraph_types).map(([typeName, pt]) => [
|
|
4212
|
+
typeName,
|
|
4213
|
+
createFieldKeyMap(pt.fields)
|
|
4214
|
+
])
|
|
4215
|
+
]);
|
|
4216
|
+
const projectors = buildProjectors(registry, fieldKeyMaps);
|
|
4217
|
+
const sortableColumnsFor = (typeName) => new Set(
|
|
4218
|
+
[...SORTABLE_FIELDS].map((label) => fieldKeyMaps[typeName].columnFor(label) ?? label)
|
|
4219
|
+
);
|
|
4142
4220
|
const contentRepos = Object.fromEntries(
|
|
4143
4221
|
Object.entries(registry.content_types).map(([typeName, ct]) => [
|
|
4144
4222
|
typeName,
|
|
4145
|
-
createDrizzleContentRepository(db, ct.db.table_name
|
|
4223
|
+
createDrizzleContentRepository(db, ct.db.table_name, {
|
|
4224
|
+
sortableColumns: sortableColumnsFor(typeName)
|
|
4225
|
+
})
|
|
4146
4226
|
])
|
|
4147
4227
|
);
|
|
4148
4228
|
const taxonomyRepos = Object.fromEntries(
|
|
4149
4229
|
Object.entries(registry.taxonomy_types).map(([typeName, tt]) => [
|
|
4150
4230
|
typeName,
|
|
4151
|
-
createDrizzleContentRepository(db, tt.db.table_name
|
|
4231
|
+
createDrizzleContentRepository(db, tt.db.table_name, {
|
|
4232
|
+
sortableColumns: sortableColumnsFor(typeName)
|
|
4233
|
+
})
|
|
4152
4234
|
])
|
|
4153
4235
|
);
|
|
4154
4236
|
const repos = { ...contentRepos, ...taxonomyRepos };
|
|
@@ -4158,7 +4240,8 @@ function createCmsApp(options) {
|
|
|
4158
4240
|
typeName,
|
|
4159
4241
|
createDrizzleContentRepository(db, ct.db.table_name, {
|
|
4160
4242
|
relations: buildRelationsMap(ct.fields, registry),
|
|
4161
|
-
publishedRelations: true
|
|
4243
|
+
publishedRelations: true,
|
|
4244
|
+
sortableColumns: sortableColumnsFor(typeName)
|
|
4162
4245
|
})
|
|
4163
4246
|
])
|
|
4164
4247
|
);
|
|
@@ -4167,7 +4250,8 @@ function createCmsApp(options) {
|
|
|
4167
4250
|
typeName,
|
|
4168
4251
|
createDrizzleContentRepository(db, tt.db.table_name, {
|
|
4169
4252
|
relations: buildRelationsMap(tt.fields, registry),
|
|
4170
|
-
publishedRelations: true
|
|
4253
|
+
publishedRelations: true,
|
|
4254
|
+
sortableColumns: sortableColumnsFor(typeName)
|
|
4171
4255
|
})
|
|
4172
4256
|
])
|
|
4173
4257
|
);
|
|
@@ -4175,11 +4259,15 @@ function createCmsApp(options) {
|
|
|
4175
4259
|
const graphqlRepos = Object.fromEntries([
|
|
4176
4260
|
...Object.entries(registry.content_types).map(([typeName, ct]) => [
|
|
4177
4261
|
typeName,
|
|
4178
|
-
createDrizzleContentRepository(db, ct.db.table_name
|
|
4262
|
+
createDrizzleContentRepository(db, ct.db.table_name, {
|
|
4263
|
+
sortableColumns: sortableColumnsFor(typeName)
|
|
4264
|
+
})
|
|
4179
4265
|
]),
|
|
4180
4266
|
...Object.entries(registry.taxonomy_types).map(([typeName, tt]) => [
|
|
4181
4267
|
typeName,
|
|
4182
|
-
createDrizzleContentRepository(db, tt.db.table_name
|
|
4268
|
+
createDrizzleContentRepository(db, tt.db.table_name, {
|
|
4269
|
+
sortableColumns: sortableColumnsFor(typeName)
|
|
4270
|
+
})
|
|
4183
4271
|
])
|
|
4184
4272
|
]);
|
|
4185
4273
|
registerAuthRoutes(app, db);
|
|
@@ -4220,17 +4308,7 @@ function createCmsApp(options) {
|
|
|
4220
4308
|
paths: {}
|
|
4221
4309
|
})
|
|
4222
4310
|
);
|
|
4223
|
-
|
|
4224
|
-
...Object.entries(registry.content_types).map(([typeName, ct]) => [
|
|
4225
|
-
typeName,
|
|
4226
|
-
createFieldKeyMap(ct.fields)
|
|
4227
|
-
]),
|
|
4228
|
-
...Object.entries(registry.taxonomy_types).map(([typeName, tt]) => [
|
|
4229
|
-
typeName,
|
|
4230
|
-
createFieldKeyMap(tt.fields)
|
|
4231
|
-
])
|
|
4232
|
-
]);
|
|
4233
|
-
registerPublicContentRoutes(app, registry, publicRepos, fieldKeyMaps, publicPaths, listRateLimit, programmaticResolver);
|
|
4311
|
+
registerPublicContentRoutes(app, registry, publicRepos, projectors, publicPaths, listRateLimit, programmaticResolver);
|
|
4234
4312
|
registerPublicMediaRoutes(app, mediaRepo, publicPaths, listRateLimit);
|
|
4235
4313
|
if (options.graphql?.enabled) {
|
|
4236
4314
|
const gqlOptions = options.graphql;
|
|
@@ -4277,7 +4355,7 @@ function createCmsApp(options) {
|
|
|
4277
4355
|
);
|
|
4278
4356
|
registerSchemaRoute(app, registry, db);
|
|
4279
4357
|
registerUserRoutes(app, db, requirePermission, requireHierarchy);
|
|
4280
|
-
registerAdminContentRoutes(app, registry, repos,
|
|
4358
|
+
registerAdminContentRoutes(app, registry, repos, projectors, mediaRepo, requirePermission, db);
|
|
4281
4359
|
registerAdminMediaRoutes(app, mediaRepo, storage, requirePermission, maxFileSize);
|
|
4282
4360
|
return { prefix, app };
|
|
4283
4361
|
}
|