Tonne of debugging - getting ready for the production builds
This commit is contained in:
3
api/dist/modules/pages/blocks.routes.d.ts
vendored
Normal file
3
api/dist/modules/pages/blocks.routes.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
declare const router: import("express-serve-static-core").Router;
|
||||
export { router as blocksRouter };
|
||||
//# sourceMappingURL=blocks.routes.d.ts.map
|
||||
1
api/dist/modules/pages/blocks.routes.d.ts.map
vendored
Normal file
1
api/dist/modules/pages/blocks.routes.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"blocks.routes.d.ts","sourceRoot":"","sources":["../../../src/modules/pages/blocks.routes.ts"],"names":[],"mappings":"AAUA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA4ExB,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,CAAC"}
|
||||
69
api/dist/modules/pages/blocks.routes.js
vendored
Normal file
69
api/dist/modules/pages/blocks.routes.js
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.blocksRouter = void 0;
|
||||
const express_1 = require("express");
|
||||
const client_1 = require("@prisma/client");
|
||||
const blocks_service_1 = require("./blocks.service");
|
||||
const pages_schemas_1 = require("./pages.schemas");
|
||||
const validate_1 = require("../../middleware/validate");
|
||||
const auth_middleware_1 = require("../../middleware/auth.middleware");
|
||||
const rbac_middleware_1 = require("../../middleware/rbac.middleware");
|
||||
const ADMIN_ROLES = [client_1.UserRole.SUPER_ADMIN, client_1.UserRole.INFLUENCE_ADMIN, client_1.UserRole.MAP_ADMIN];
|
||||
const router = (0, express_1.Router)();
|
||||
exports.blocksRouter = router;
|
||||
router.use(auth_middleware_1.authenticate);
|
||||
router.use((0, rbac_middleware_1.requireRole)(...ADMIN_ROLES));
|
||||
// GET /api/page-blocks — list all blocks
|
||||
router.get('/', (0, validate_1.validate)(pages_schemas_1.listPageBlocksSchema, 'query'), async (req, res, next) => {
|
||||
try {
|
||||
const blocks = await blocks_service_1.blocksService.findAll(req.query);
|
||||
res.json(blocks);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
// GET /api/page-blocks/:id — get single block
|
||||
router.get('/:id', async (req, res, next) => {
|
||||
try {
|
||||
const id = req.params.id;
|
||||
const block = await blocks_service_1.blocksService.findById(id);
|
||||
res.json(block);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
// POST /api/page-blocks — create block
|
||||
router.post('/', (0, validate_1.validate)(pages_schemas_1.createPageBlockSchema), async (req, res, next) => {
|
||||
try {
|
||||
const block = await blocks_service_1.blocksService.create(req.body);
|
||||
res.status(201).json(block);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
// PUT /api/page-blocks/:id — update block
|
||||
router.put('/:id', (0, validate_1.validate)(pages_schemas_1.updatePageBlockSchema), async (req, res, next) => {
|
||||
try {
|
||||
const id = req.params.id;
|
||||
const block = await blocks_service_1.blocksService.update(id, req.body);
|
||||
res.json(block);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
// DELETE /api/page-blocks/:id — delete block
|
||||
router.delete('/:id', async (req, res, next) => {
|
||||
try {
|
||||
const id = req.params.id;
|
||||
await blocks_service_1.blocksService.delete(id);
|
||||
res.status(204).send();
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=blocks.routes.js.map
|
||||
1
api/dist/modules/pages/blocks.routes.js.map
vendored
Normal file
1
api/dist/modules/pages/blocks.routes.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"blocks.routes.js","sourceRoot":"","sources":["../../../src/modules/pages/blocks.routes.ts"],"names":[],"mappings":";;;AAAA,qCAAkE;AAClE,2CAA0C;AAC1C,qDAAiD;AACjD,mDAAqG;AACrG,wDAAqD;AACrD,sEAAgE;AAChE,sEAA+D;AAE/D,MAAM,WAAW,GAAe,CAAC,iBAAQ,CAAC,WAAW,EAAE,iBAAQ,CAAC,eAAe,EAAE,iBAAQ,CAAC,SAAS,CAAC,CAAC;AAErG,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;AA4EL,8BAAY;AA1E/B,MAAM,CAAC,GAAG,CAAC,8BAAY,CAAC,CAAC;AACzB,MAAM,CAAC,GAAG,CAAC,IAAA,6BAAW,EAAC,GAAG,WAAW,CAAC,CAAC,CAAC;AAExC,yCAAyC;AACzC,MAAM,CAAC,GAAG,CACR,GAAG,EACH,IAAA,mBAAQ,EAAC,oCAAoB,EAAE,OAAO,CAAC,EACvC,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACxD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,8BAAa,CAAC,OAAO,CAAC,GAAG,CAAC,KAAY,CAAC,CAAC;QAC7D,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,8CAA8C;AAC9C,MAAM,CAAC,GAAG,CACR,MAAM,EACN,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACxD,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,EAAY,CAAC;QACnC,MAAM,KAAK,GAAG,MAAM,8BAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC/C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,uCAAuC;AACvC,MAAM,CAAC,IAAI,CACT,GAAG,EACH,IAAA,mBAAQ,EAAC,qCAAqB,CAAC,EAC/B,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACxD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,8BAAa,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,0CAA0C;AAC1C,MAAM,CAAC,GAAG,CACR,MAAM,EACN,IAAA,mBAAQ,EAAC,qCAAqB,CAAC,EAC/B,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACxD,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,EAAY,CAAC;QACnC,MAAM,KAAK,GAAG,MAAM,8BAAa,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,CAAC;AACH,CAAC,CACF,CAAC;AAEF,6CAA6C;AAC7C,MAAM,CAAC,MAAM,CACX,MAAM,EACN,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACxD,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,EAAY,CAAC;QACnC,MAAM,8BAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,CAAC;AACH,CAAC,CACF,CAAC"}
|
||||
54
api/dist/modules/pages/blocks.service.d.ts
vendored
Normal file
54
api/dist/modules/pages/blocks.service.d.ts
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Prisma } from '@prisma/client';
|
||||
import type { CreatePageBlockInput, UpdatePageBlockInput, ListPageBlocksInput } from './pages.schemas';
|
||||
export declare const blocksService: {
|
||||
findAll(filters: ListPageBlocksInput): Promise<{
|
||||
type: string;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
schema: Prisma.JsonValue;
|
||||
category: string | null;
|
||||
label: string;
|
||||
sortOrder: number;
|
||||
defaults: Prisma.JsonValue;
|
||||
thumbnail: string | null;
|
||||
}[]>;
|
||||
findById(id: string): Promise<{
|
||||
type: string;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
schema: Prisma.JsonValue;
|
||||
category: string | null;
|
||||
label: string;
|
||||
sortOrder: number;
|
||||
defaults: Prisma.JsonValue;
|
||||
thumbnail: string | null;
|
||||
}>;
|
||||
create(data: CreatePageBlockInput): Promise<{
|
||||
type: string;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
schema: Prisma.JsonValue;
|
||||
category: string | null;
|
||||
label: string;
|
||||
sortOrder: number;
|
||||
defaults: Prisma.JsonValue;
|
||||
thumbnail: string | null;
|
||||
}>;
|
||||
update(id: string, data: UpdatePageBlockInput): Promise<{
|
||||
type: string;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
schema: Prisma.JsonValue;
|
||||
category: string | null;
|
||||
label: string;
|
||||
sortOrder: number;
|
||||
defaults: Prisma.JsonValue;
|
||||
thumbnail: string | null;
|
||||
}>;
|
||||
delete(id: string): Promise<void>;
|
||||
};
|
||||
//# sourceMappingURL=blocks.service.d.ts.map
|
||||
1
api/dist/modules/pages/blocks.service.d.ts.map
vendored
Normal file
1
api/dist/modules/pages/blocks.service.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"blocks.service.d.ts","sourceRoot":"","sources":["../../../src/modules/pages/blocks.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAGxC,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAevG,eAAO,MAAM,aAAa;qBACD,mBAAmB;;;;;;;;;;;;iBAcvB,MAAM;;;;;;;;;;;;iBAaN,oBAAoB;;;;;;;;;;;;eAWtB,MAAM,QAAQ,oBAAoB;;;;;;;;;;;;eAsBlC,MAAM;CAQxB,CAAC"}
|
||||
76
api/dist/modules/pages/blocks.service.js
vendored
Normal file
76
api/dist/modules/pages/blocks.service.js
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.blocksService = void 0;
|
||||
const database_1 = require("../../config/database");
|
||||
const error_handler_1 = require("../../middleware/error-handler");
|
||||
const blockSelect = {
|
||||
id: true,
|
||||
type: true,
|
||||
label: true,
|
||||
schema: true,
|
||||
defaults: true,
|
||||
thumbnail: true,
|
||||
category: true,
|
||||
sortOrder: true,
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
};
|
||||
exports.blocksService = {
|
||||
async findAll(filters) {
|
||||
const where = {};
|
||||
if (filters.category) {
|
||||
where.category = filters.category;
|
||||
}
|
||||
return database_1.prisma.pageBlock.findMany({
|
||||
where,
|
||||
select: blockSelect,
|
||||
orderBy: { sortOrder: 'asc' },
|
||||
});
|
||||
},
|
||||
async findById(id) {
|
||||
const block = await database_1.prisma.pageBlock.findUnique({
|
||||
where: { id },
|
||||
select: blockSelect,
|
||||
});
|
||||
if (!block) {
|
||||
throw new error_handler_1.AppError(404, 'Page block not found', 'BLOCK_NOT_FOUND');
|
||||
}
|
||||
return block;
|
||||
},
|
||||
async create(data) {
|
||||
return database_1.prisma.pageBlock.create({
|
||||
data: {
|
||||
...data,
|
||||
schema: data.schema,
|
||||
defaults: data.defaults,
|
||||
},
|
||||
select: blockSelect,
|
||||
});
|
||||
},
|
||||
async update(id, data) {
|
||||
const existing = await database_1.prisma.pageBlock.findUnique({ where: { id } });
|
||||
if (!existing) {
|
||||
throw new error_handler_1.AppError(404, 'Page block not found', 'BLOCK_NOT_FOUND');
|
||||
}
|
||||
const updateData = { ...data };
|
||||
if (data.schema !== undefined) {
|
||||
updateData.schema = data.schema;
|
||||
}
|
||||
if (data.defaults !== undefined) {
|
||||
updateData.defaults = data.defaults;
|
||||
}
|
||||
return database_1.prisma.pageBlock.update({
|
||||
where: { id },
|
||||
data: updateData,
|
||||
select: blockSelect,
|
||||
});
|
||||
},
|
||||
async delete(id) {
|
||||
const existing = await database_1.prisma.pageBlock.findUnique({ where: { id } });
|
||||
if (!existing) {
|
||||
throw new error_handler_1.AppError(404, 'Page block not found', 'BLOCK_NOT_FOUND');
|
||||
}
|
||||
await database_1.prisma.pageBlock.delete({ where: { id } });
|
||||
},
|
||||
};
|
||||
//# sourceMappingURL=blocks.service.js.map
|
||||
1
api/dist/modules/pages/blocks.service.js.map
vendored
Normal file
1
api/dist/modules/pages/blocks.service.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"blocks.service.js","sourceRoot":"","sources":["../../../src/modules/pages/blocks.service.ts"],"names":[],"mappings":"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"}
|
||||
3
api/dist/modules/pages/pages-admin.routes.d.ts
vendored
Normal file
3
api/dist/modules/pages/pages-admin.routes.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
declare const router: import("express-serve-static-core").Router;
|
||||
export { router as pagesAdminRouter };
|
||||
//# sourceMappingURL=pages-admin.routes.d.ts.map
|
||||
1
api/dist/modules/pages/pages-admin.routes.d.ts.map
vendored
Normal file
1
api/dist/modules/pages/pages-admin.routes.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"pages-admin.routes.d.ts","sourceRoot":"","sources":["../../../src/modules/pages/pages-admin.routes.ts"],"names":[],"mappings":"AAUA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAsGxB,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,CAAC"}
|
||||
89
api/dist/modules/pages/pages-admin.routes.js
vendored
Normal file
89
api/dist/modules/pages/pages-admin.routes.js
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.pagesAdminRouter = void 0;
|
||||
const express_1 = require("express");
|
||||
const client_1 = require("@prisma/client");
|
||||
const pages_service_1 = require("./pages.service");
|
||||
const pages_schemas_1 = require("./pages.schemas");
|
||||
const validate_1 = require("../../middleware/validate");
|
||||
const auth_middleware_1 = require("../../middleware/auth.middleware");
|
||||
const rbac_middleware_1 = require("../../middleware/rbac.middleware");
|
||||
const ADMIN_ROLES = [client_1.UserRole.SUPER_ADMIN, client_1.UserRole.INFLUENCE_ADMIN, client_1.UserRole.MAP_ADMIN];
|
||||
const router = (0, express_1.Router)();
|
||||
exports.pagesAdminRouter = router;
|
||||
router.use(auth_middleware_1.authenticate);
|
||||
router.use((0, rbac_middleware_1.requireRole)(...ADMIN_ROLES));
|
||||
// POST /api/pages/sync — sync MkDocs overrides (must be before /:id routes)
|
||||
router.post('/sync', async (_req, res, next) => {
|
||||
try {
|
||||
const result = await pages_service_1.pagesService.syncOverrides();
|
||||
res.json(result);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
// POST /api/pages/validate — validate and repair MkDocs exports
|
||||
router.post('/validate', async (_req, res, next) => {
|
||||
try {
|
||||
const result = await pages_service_1.pagesService.validateExports();
|
||||
res.json(result);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
// GET /api/pages — list landing pages with pagination/filters
|
||||
router.get('/', (0, validate_1.validate)(pages_schemas_1.listLandingPagesSchema, 'query'), async (req, res, next) => {
|
||||
try {
|
||||
const result = await pages_service_1.pagesService.findAll(req.query);
|
||||
res.json(result);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
// GET /api/pages/:id — get single landing page
|
||||
router.get('/:id', async (req, res, next) => {
|
||||
try {
|
||||
const id = req.params.id;
|
||||
const page = await pages_service_1.pagesService.findById(id);
|
||||
res.json(page);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
// POST /api/pages — create landing page
|
||||
router.post('/', (0, validate_1.validate)(pages_schemas_1.createLandingPageSchema), async (req, res, next) => {
|
||||
try {
|
||||
const page = await pages_service_1.pagesService.create(req.body);
|
||||
res.status(201).json(page);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
// PUT /api/pages/:id — update landing page
|
||||
router.put('/:id', (0, validate_1.validate)(pages_schemas_1.updateLandingPageSchema), async (req, res, next) => {
|
||||
try {
|
||||
const id = req.params.id;
|
||||
const page = await pages_service_1.pagesService.update(id, req.body);
|
||||
res.json(page);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
// DELETE /api/pages/:id — delete landing page
|
||||
router.delete('/:id', async (req, res, next) => {
|
||||
try {
|
||||
const id = req.params.id;
|
||||
await pages_service_1.pagesService.delete(id);
|
||||
res.status(204).send();
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=pages-admin.routes.js.map
|
||||
1
api/dist/modules/pages/pages-admin.routes.js.map
vendored
Normal file
1
api/dist/modules/pages/pages-admin.routes.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"pages-admin.routes.js","sourceRoot":"","sources":["../../../src/modules/pages/pages-admin.routes.ts"],"names":[],"mappings":"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"}
|
||||
3
api/dist/modules/pages/pages-public.routes.d.ts
vendored
Normal file
3
api/dist/modules/pages/pages-public.routes.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
declare const router: import("express-serve-static-core").Router;
|
||||
export { router as pagesPublicRouter };
|
||||
//# sourceMappingURL=pages-public.routes.d.ts.map
|
||||
1
api/dist/modules/pages/pages-public.routes.d.ts.map
vendored
Normal file
1
api/dist/modules/pages/pages-public.routes.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"pages-public.routes.d.ts","sourceRoot":"","sources":["../../../src/modules/pages/pages-public.routes.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAgBxB,OAAO,EAAE,MAAM,IAAI,iBAAiB,EAAE,CAAC"}
|
||||
19
api/dist/modules/pages/pages-public.routes.js
vendored
Normal file
19
api/dist/modules/pages/pages-public.routes.js
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.pagesPublicRouter = void 0;
|
||||
const express_1 = require("express");
|
||||
const pages_service_1 = require("./pages.service");
|
||||
const router = (0, express_1.Router)();
|
||||
exports.pagesPublicRouter = router;
|
||||
// GET /api/pages/:slug/view — get published page by slug (public)
|
||||
router.get('/:slug/view', async (req, res, next) => {
|
||||
try {
|
||||
const slug = req.params.slug;
|
||||
const page = await pages_service_1.pagesService.findBySlugPublic(slug);
|
||||
res.json(page);
|
||||
}
|
||||
catch (err) {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=pages-public.routes.js.map
|
||||
1
api/dist/modules/pages/pages-public.routes.js.map
vendored
Normal file
1
api/dist/modules/pages/pages-public.routes.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"pages-public.routes.js","sourceRoot":"","sources":["../../../src/modules/pages/pages-public.routes.ts"],"names":[],"mappings":";;;AAAA,qCAAkE;AAClE,mDAA+C;AAE/C,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAC;AAgBL,mCAAiB;AAdpC,kEAAkE;AAClE,MAAM,CAAC,GAAG,CACR,aAAa,EACb,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACxD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAc,CAAC;QACvC,MAAM,IAAI,GAAG,MAAM,4BAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,CAAC;AACH,CAAC,CACF,CAAC"}
|
||||
186
api/dist/modules/pages/pages.schemas.d.ts
vendored
Normal file
186
api/dist/modules/pages/pages.schemas.d.ts
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
import { z } from 'zod';
|
||||
export declare const createLandingPageSchema: z.ZodObject<{
|
||||
title: z.ZodString;
|
||||
description: z.ZodOptional<z.ZodString>;
|
||||
editorMode: z.ZodDefault<z.ZodOptional<z.ZodEnum<["VISUAL", "CODE"]>>>;
|
||||
blocks: z.ZodDefault<z.ZodOptional<z.ZodAny>>;
|
||||
htmlOutput: z.ZodOptional<z.ZodString>;
|
||||
cssOutput: z.ZodOptional<z.ZodString>;
|
||||
mkdocsPath: z.ZodOptional<z.ZodString>;
|
||||
mkdocsExportMode: z.ZodDefault<z.ZodOptional<z.ZodEnum<["THEMED", "STANDALONE"]>>>;
|
||||
mkdocsHideNav: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
||||
mkdocsHideToc: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
||||
mkdocsSkipExport: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
||||
published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
||||
seoTitle: z.ZodOptional<z.ZodString>;
|
||||
seoDescription: z.ZodOptional<z.ZodString>;
|
||||
seoImage: z.ZodOptional<z.ZodString>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
title: string;
|
||||
editorMode: "VISUAL" | "CODE";
|
||||
mkdocsExportMode: "THEMED" | "STANDALONE";
|
||||
mkdocsHideNav: boolean;
|
||||
mkdocsHideToc: boolean;
|
||||
mkdocsSkipExport: boolean;
|
||||
published: boolean;
|
||||
blocks?: any;
|
||||
description?: string | undefined;
|
||||
htmlOutput?: string | undefined;
|
||||
cssOutput?: string | undefined;
|
||||
mkdocsPath?: string | undefined;
|
||||
seoTitle?: string | undefined;
|
||||
seoDescription?: string | undefined;
|
||||
seoImage?: string | undefined;
|
||||
}, {
|
||||
title: string;
|
||||
blocks?: any;
|
||||
description?: string | undefined;
|
||||
editorMode?: "VISUAL" | "CODE" | undefined;
|
||||
htmlOutput?: string | undefined;
|
||||
cssOutput?: string | undefined;
|
||||
mkdocsPath?: string | undefined;
|
||||
mkdocsExportMode?: "THEMED" | "STANDALONE" | undefined;
|
||||
mkdocsHideNav?: boolean | undefined;
|
||||
mkdocsHideToc?: boolean | undefined;
|
||||
mkdocsSkipExport?: boolean | undefined;
|
||||
published?: boolean | undefined;
|
||||
seoTitle?: string | undefined;
|
||||
seoDescription?: string | undefined;
|
||||
seoImage?: string | undefined;
|
||||
}>;
|
||||
export declare const updateLandingPageSchema: z.ZodObject<{
|
||||
title: z.ZodOptional<z.ZodString>;
|
||||
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
||||
editorMode: z.ZodOptional<z.ZodEnum<["VISUAL", "CODE"]>>;
|
||||
blocks: z.ZodOptional<z.ZodAny>;
|
||||
htmlOutput: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
||||
cssOutput: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
||||
mkdocsPath: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
||||
mkdocsExportMode: z.ZodOptional<z.ZodEnum<["THEMED", "STANDALONE"]>>;
|
||||
mkdocsHideNav: z.ZodOptional<z.ZodBoolean>;
|
||||
mkdocsHideToc: z.ZodOptional<z.ZodBoolean>;
|
||||
mkdocsSkipExport: z.ZodOptional<z.ZodBoolean>;
|
||||
published: z.ZodOptional<z.ZodBoolean>;
|
||||
seoTitle: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
||||
seoDescription: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
||||
seoImage: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
blocks?: any;
|
||||
title?: string | undefined;
|
||||
description?: string | null | undefined;
|
||||
editorMode?: "VISUAL" | "CODE" | undefined;
|
||||
htmlOutput?: string | null | undefined;
|
||||
cssOutput?: string | null | undefined;
|
||||
mkdocsPath?: string | null | undefined;
|
||||
mkdocsExportMode?: "THEMED" | "STANDALONE" | undefined;
|
||||
mkdocsHideNav?: boolean | undefined;
|
||||
mkdocsHideToc?: boolean | undefined;
|
||||
mkdocsSkipExport?: boolean | undefined;
|
||||
published?: boolean | undefined;
|
||||
seoTitle?: string | null | undefined;
|
||||
seoDescription?: string | null | undefined;
|
||||
seoImage?: string | null | undefined;
|
||||
}, {
|
||||
blocks?: any;
|
||||
title?: string | undefined;
|
||||
description?: string | null | undefined;
|
||||
editorMode?: "VISUAL" | "CODE" | undefined;
|
||||
htmlOutput?: string | null | undefined;
|
||||
cssOutput?: string | null | undefined;
|
||||
mkdocsPath?: string | null | undefined;
|
||||
mkdocsExportMode?: "THEMED" | "STANDALONE" | undefined;
|
||||
mkdocsHideNav?: boolean | undefined;
|
||||
mkdocsHideToc?: boolean | undefined;
|
||||
mkdocsSkipExport?: boolean | undefined;
|
||||
published?: boolean | undefined;
|
||||
seoTitle?: string | null | undefined;
|
||||
seoDescription?: string | null | undefined;
|
||||
seoImage?: string | null | undefined;
|
||||
}>;
|
||||
export declare const listLandingPagesSchema: z.ZodObject<{
|
||||
page: z.ZodDefault<z.ZodNumber>;
|
||||
limit: z.ZodDefault<z.ZodNumber>;
|
||||
search: z.ZodOptional<z.ZodString>;
|
||||
published: z.ZodOptional<z.ZodEnum<["true", "false"]>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
limit: number;
|
||||
page: number;
|
||||
search?: string | undefined;
|
||||
published?: "true" | "false" | undefined;
|
||||
}, {
|
||||
search?: string | undefined;
|
||||
limit?: number | undefined;
|
||||
page?: number | undefined;
|
||||
published?: "true" | "false" | undefined;
|
||||
}>;
|
||||
export declare const createPageBlockSchema: z.ZodObject<{
|
||||
type: z.ZodString;
|
||||
label: z.ZodString;
|
||||
schema: z.ZodDefault<z.ZodOptional<z.ZodAny>>;
|
||||
defaults: z.ZodDefault<z.ZodOptional<z.ZodAny>>;
|
||||
thumbnail: z.ZodOptional<z.ZodString>;
|
||||
category: z.ZodOptional<z.ZodString>;
|
||||
sortOrder: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
type: string;
|
||||
label: string;
|
||||
sortOrder: number;
|
||||
schema?: any;
|
||||
category?: string | undefined;
|
||||
defaults?: any;
|
||||
thumbnail?: string | undefined;
|
||||
}, {
|
||||
type: string;
|
||||
label: string;
|
||||
schema?: any;
|
||||
category?: string | undefined;
|
||||
sortOrder?: number | undefined;
|
||||
defaults?: any;
|
||||
thumbnail?: string | undefined;
|
||||
}>;
|
||||
export declare const updatePageBlockSchema: z.ZodObject<{
|
||||
type: z.ZodOptional<z.ZodString>;
|
||||
label: z.ZodOptional<z.ZodString>;
|
||||
schema: z.ZodOptional<z.ZodAny>;
|
||||
defaults: z.ZodOptional<z.ZodAny>;
|
||||
thumbnail: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
||||
category: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
||||
sortOrder: z.ZodOptional<z.ZodNumber>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
type?: string | undefined;
|
||||
schema?: any;
|
||||
category?: string | null | undefined;
|
||||
label?: string | undefined;
|
||||
sortOrder?: number | undefined;
|
||||
defaults?: any;
|
||||
thumbnail?: string | null | undefined;
|
||||
}, {
|
||||
type?: string | undefined;
|
||||
schema?: any;
|
||||
category?: string | null | undefined;
|
||||
label?: string | undefined;
|
||||
sortOrder?: number | undefined;
|
||||
defaults?: any;
|
||||
thumbnail?: string | null | undefined;
|
||||
}>;
|
||||
export declare const listPageBlocksSchema: z.ZodObject<{
|
||||
category: z.ZodOptional<z.ZodString>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
category?: string | undefined;
|
||||
}, {
|
||||
category?: string | undefined;
|
||||
}>;
|
||||
export declare const pageIdSchema: z.ZodObject<{
|
||||
id: z.ZodString;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
id: string;
|
||||
}, {
|
||||
id: string;
|
||||
}>;
|
||||
export type CreateLandingPageInput = z.infer<typeof createLandingPageSchema>;
|
||||
export type UpdateLandingPageInput = z.infer<typeof updateLandingPageSchema>;
|
||||
export type ListLandingPagesInput = z.infer<typeof listLandingPagesSchema>;
|
||||
export type CreatePageBlockInput = z.infer<typeof createPageBlockSchema>;
|
||||
export type UpdatePageBlockInput = z.infer<typeof updatePageBlockSchema>;
|
||||
export type ListPageBlocksInput = z.infer<typeof listPageBlocksSchema>;
|
||||
//# sourceMappingURL=pages.schemas.d.ts.map
|
||||
1
api/dist/modules/pages/pages.schemas.d.ts.map
vendored
Normal file
1
api/dist/modules/pages/pages.schemas.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"pages.schemas.d.ts","sourceRoot":"","sources":["../../../src/modules/pages/pages.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBlC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBlC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;EAKjC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;EAQhC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;EAQhC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;EAE/B,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;EAEvB,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC7E,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC7E,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC3E,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACzE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACzE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
|
||||
71
api/dist/modules/pages/pages.schemas.js
vendored
Normal file
71
api/dist/modules/pages/pages.schemas.js
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.pageIdSchema = exports.listPageBlocksSchema = exports.updatePageBlockSchema = exports.createPageBlockSchema = exports.listLandingPagesSchema = exports.updateLandingPageSchema = exports.createLandingPageSchema = void 0;
|
||||
const zod_1 = require("zod");
|
||||
const editorModeEnum = zod_1.z.enum(['VISUAL', 'CODE']);
|
||||
const mkdocsExportModeEnum = zod_1.z.enum(['THEMED', 'STANDALONE']);
|
||||
exports.createLandingPageSchema = zod_1.z.object({
|
||||
title: zod_1.z.string().min(1, 'Title is required'),
|
||||
description: zod_1.z.string().optional(),
|
||||
editorMode: editorModeEnum.optional().default('VISUAL'),
|
||||
blocks: zod_1.z.any().optional().default({}),
|
||||
htmlOutput: zod_1.z.string().optional(),
|
||||
cssOutput: zod_1.z.string().optional(),
|
||||
mkdocsPath: zod_1.z.string().optional(),
|
||||
mkdocsExportMode: mkdocsExportModeEnum.optional().default('THEMED'),
|
||||
mkdocsHideNav: zod_1.z.boolean().optional().default(true),
|
||||
mkdocsHideToc: zod_1.z.boolean().optional().default(true),
|
||||
mkdocsSkipExport: zod_1.z.boolean().optional().default(false),
|
||||
published: zod_1.z.boolean().optional().default(false),
|
||||
seoTitle: zod_1.z.string().optional(),
|
||||
seoDescription: zod_1.z.string().optional(),
|
||||
seoImage: zod_1.z.string().optional(),
|
||||
});
|
||||
exports.updateLandingPageSchema = zod_1.z.object({
|
||||
title: zod_1.z.string().min(1).optional(),
|
||||
description: zod_1.z.string().nullable().optional(),
|
||||
editorMode: editorModeEnum.optional(),
|
||||
blocks: zod_1.z.any().optional(),
|
||||
htmlOutput: zod_1.z.string().nullable().optional(),
|
||||
cssOutput: zod_1.z.string().nullable().optional(),
|
||||
mkdocsPath: zod_1.z.string().nullable().optional(),
|
||||
mkdocsExportMode: mkdocsExportModeEnum.optional(),
|
||||
mkdocsHideNav: zod_1.z.boolean().optional(),
|
||||
mkdocsHideToc: zod_1.z.boolean().optional(),
|
||||
mkdocsSkipExport: zod_1.z.boolean().optional(),
|
||||
published: zod_1.z.boolean().optional(),
|
||||
seoTitle: zod_1.z.string().nullable().optional(),
|
||||
seoDescription: zod_1.z.string().nullable().optional(),
|
||||
seoImage: zod_1.z.string().nullable().optional(),
|
||||
});
|
||||
exports.listLandingPagesSchema = zod_1.z.object({
|
||||
page: zod_1.z.coerce.number().int().positive().default(1),
|
||||
limit: zod_1.z.coerce.number().int().positive().max(100).default(20),
|
||||
search: zod_1.z.string().optional(),
|
||||
published: zod_1.z.enum(['true', 'false']).optional(),
|
||||
});
|
||||
exports.createPageBlockSchema = zod_1.z.object({
|
||||
type: zod_1.z.string().min(1, 'Type is required'),
|
||||
label: zod_1.z.string().min(1, 'Label is required'),
|
||||
schema: zod_1.z.any().optional().default({}),
|
||||
defaults: zod_1.z.any().optional().default({}),
|
||||
thumbnail: zod_1.z.string().optional(),
|
||||
category: zod_1.z.string().optional(),
|
||||
sortOrder: zod_1.z.number().int().optional().default(0),
|
||||
});
|
||||
exports.updatePageBlockSchema = zod_1.z.object({
|
||||
type: zod_1.z.string().min(1).optional(),
|
||||
label: zod_1.z.string().min(1).optional(),
|
||||
schema: zod_1.z.any().optional(),
|
||||
defaults: zod_1.z.any().optional(),
|
||||
thumbnail: zod_1.z.string().nullable().optional(),
|
||||
category: zod_1.z.string().nullable().optional(),
|
||||
sortOrder: zod_1.z.number().int().optional(),
|
||||
});
|
||||
exports.listPageBlocksSchema = zod_1.z.object({
|
||||
category: zod_1.z.string().optional(),
|
||||
});
|
||||
exports.pageIdSchema = zod_1.z.object({
|
||||
id: zod_1.z.string().min(1),
|
||||
});
|
||||
//# sourceMappingURL=pages.schemas.js.map
|
||||
1
api/dist/modules/pages/pages.schemas.js.map
vendored
Normal file
1
api/dist/modules/pages/pages.schemas.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"pages.schemas.js","sourceRoot":"","sources":["../../../src/modules/pages/pages.schemas.ts"],"names":[],"mappings":"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"}
|
||||
138
api/dist/modules/pages/pages.service.d.ts
vendored
Normal file
138
api/dist/modules/pages/pages.service.d.ts
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
import { Prisma } from '@prisma/client';
|
||||
import type { CreateLandingPageInput, UpdateLandingPageInput, ListLandingPagesInput } from './pages.schemas';
|
||||
export declare const pagesService: {
|
||||
findAll(filters: ListLandingPagesInput): Promise<{
|
||||
pages: {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
blocks: Prisma.JsonValue;
|
||||
title: string;
|
||||
description: string | null;
|
||||
slug: string;
|
||||
editorMode: import(".prisma/client").$Enums.EditorMode;
|
||||
htmlOutput: string | null;
|
||||
cssOutput: string | null;
|
||||
mkdocsPath: string | null;
|
||||
mkdocsExportMode: import(".prisma/client").$Enums.MkdocsExportMode;
|
||||
mkdocsHideNav: boolean;
|
||||
mkdocsHideToc: boolean;
|
||||
mkdocsSkipExport: boolean;
|
||||
published: boolean;
|
||||
seoTitle: string | null;
|
||||
seoDescription: string | null;
|
||||
seoImage: string | null;
|
||||
mkdocsStubPath: string | null;
|
||||
}[];
|
||||
pagination: {
|
||||
page: number;
|
||||
limit: number;
|
||||
total: number;
|
||||
totalPages: number;
|
||||
};
|
||||
}>;
|
||||
findById(id: string): Promise<{
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
blocks: Prisma.JsonValue;
|
||||
title: string;
|
||||
description: string | null;
|
||||
slug: string;
|
||||
editorMode: import(".prisma/client").$Enums.EditorMode;
|
||||
htmlOutput: string | null;
|
||||
cssOutput: string | null;
|
||||
mkdocsPath: string | null;
|
||||
mkdocsExportMode: import(".prisma/client").$Enums.MkdocsExportMode;
|
||||
mkdocsHideNav: boolean;
|
||||
mkdocsHideToc: boolean;
|
||||
mkdocsSkipExport: boolean;
|
||||
published: boolean;
|
||||
seoTitle: string | null;
|
||||
seoDescription: string | null;
|
||||
seoImage: string | null;
|
||||
mkdocsStubPath: string | null;
|
||||
}>;
|
||||
findBySlugPublic(slug: string): Promise<{
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
blocks: Prisma.JsonValue;
|
||||
title: string;
|
||||
description: string | null;
|
||||
slug: string;
|
||||
editorMode: import(".prisma/client").$Enums.EditorMode;
|
||||
htmlOutput: string | null;
|
||||
cssOutput: string | null;
|
||||
mkdocsPath: string | null;
|
||||
mkdocsExportMode: import(".prisma/client").$Enums.MkdocsExportMode;
|
||||
mkdocsHideNav: boolean;
|
||||
mkdocsHideToc: boolean;
|
||||
mkdocsSkipExport: boolean;
|
||||
published: boolean;
|
||||
seoTitle: string | null;
|
||||
seoDescription: string | null;
|
||||
seoImage: string | null;
|
||||
mkdocsStubPath: string | null;
|
||||
}>;
|
||||
create(data: CreateLandingPageInput): Promise<{
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
blocks: Prisma.JsonValue;
|
||||
title: string;
|
||||
description: string | null;
|
||||
slug: string;
|
||||
editorMode: import(".prisma/client").$Enums.EditorMode;
|
||||
htmlOutput: string | null;
|
||||
cssOutput: string | null;
|
||||
mkdocsPath: string | null;
|
||||
mkdocsExportMode: import(".prisma/client").$Enums.MkdocsExportMode;
|
||||
mkdocsHideNav: boolean;
|
||||
mkdocsHideToc: boolean;
|
||||
mkdocsSkipExport: boolean;
|
||||
published: boolean;
|
||||
seoTitle: string | null;
|
||||
seoDescription: string | null;
|
||||
seoImage: string | null;
|
||||
mkdocsStubPath: string | null;
|
||||
}>;
|
||||
update(id: string, data: UpdateLandingPageInput): Promise<{
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
blocks: Prisma.JsonValue;
|
||||
title: string;
|
||||
description: string | null;
|
||||
slug: string;
|
||||
editorMode: import(".prisma/client").$Enums.EditorMode;
|
||||
htmlOutput: string | null;
|
||||
cssOutput: string | null;
|
||||
mkdocsPath: string | null;
|
||||
mkdocsExportMode: import(".prisma/client").$Enums.MkdocsExportMode;
|
||||
mkdocsHideNav: boolean;
|
||||
mkdocsHideToc: boolean;
|
||||
mkdocsSkipExport: boolean;
|
||||
published: boolean;
|
||||
seoTitle: string | null;
|
||||
seoDescription: string | null;
|
||||
seoImage: string | null;
|
||||
mkdocsStubPath: string | null;
|
||||
}>;
|
||||
delete(id: string): Promise<void>;
|
||||
syncOverrides(): Promise<{
|
||||
imported: number;
|
||||
updated: number;
|
||||
stubs: number;
|
||||
}>;
|
||||
validateExports(): Promise<{
|
||||
validated: number;
|
||||
repaired: number;
|
||||
errors: Array<{
|
||||
pageId: string;
|
||||
slug: string;
|
||||
error: string;
|
||||
}>;
|
||||
}>;
|
||||
};
|
||||
//# sourceMappingURL=pages.service.d.ts.map
|
||||
1
api/dist/modules/pages/pages.service.d.ts.map
vendored
Normal file
1
api/dist/modules/pages/pages.service.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"pages.service.d.ts","sourceRoot":"","sources":["../../../src/modules/pages/pages.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAOtE,OAAO,KAAK,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA4Q7G,eAAO,MAAM,YAAY;qBACA,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuCzB,MAAM;;;;;;;;;;;;;;;;;;;;;;2BAaI,MAAM;;;;;;;;;;;;;;;;;;;;;;iBAahB,sBAAsB;;;;;;;;;;;;;;;;;;;;;;eAqBxB,MAAM,QAAQ,sBAAsB;;;;;;;;;;;;;;;;;;;;;;eA2EpC,MAAM;qBAcA,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;uBAmG3D,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,KAAK,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CAqF1I,CAAC"}
|
||||
554
api/dist/modules/pages/pages.service.js
vendored
Normal file
554
api/dist/modules/pages/pages.service.js
vendored
Normal file
@@ -0,0 +1,554 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.pagesService = void 0;
|
||||
const promises_1 = __importDefault(require("fs/promises"));
|
||||
const path_1 = __importDefault(require("path"));
|
||||
const database_1 = require("../../config/database");
|
||||
const env_1 = require("../../config/env");
|
||||
const error_handler_1 = require("../../middleware/error-handler");
|
||||
const logger_1 = require("../../utils/logger");
|
||||
const landingPageSelect = {
|
||||
id: true,
|
||||
slug: true,
|
||||
title: true,
|
||||
description: true,
|
||||
editorMode: true,
|
||||
blocks: true,
|
||||
htmlOutput: true,
|
||||
cssOutput: true,
|
||||
mkdocsPath: true,
|
||||
mkdocsStubPath: true,
|
||||
mkdocsExportMode: true,
|
||||
mkdocsHideNav: true,
|
||||
mkdocsHideToc: true,
|
||||
mkdocsSkipExport: true,
|
||||
published: true,
|
||||
seoTitle: true,
|
||||
seoDescription: true,
|
||||
seoImage: true,
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
};
|
||||
function generateSlug(title) {
|
||||
return title
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '')
|
||||
.slice(0, 80);
|
||||
}
|
||||
async function resolveSlugCollision(slug, excludeId) {
|
||||
let candidate = slug;
|
||||
let suffix = 2;
|
||||
while (true) {
|
||||
const existing = await database_1.prisma.landingPage.findUnique({
|
||||
where: { slug: candidate },
|
||||
select: { id: true },
|
||||
});
|
||||
if (!existing || (excludeId && existing.id === excludeId)) {
|
||||
return candidate;
|
||||
}
|
||||
candidate = `${slug}-${suffix}`;
|
||||
suffix++;
|
||||
}
|
||||
}
|
||||
const MKDOCS_OVERRIDES = path_1.default.join(env_1.env.MKDOCS_DOCS_PATH, 'overrides');
|
||||
const MKDOCS_DOCS_ROOT = env_1.env.MKDOCS_DOCS_PATH;
|
||||
function validateMkdocsPath(mkdocsPath) {
|
||||
// Check for null bytes
|
||||
if (mkdocsPath.includes('\0')) {
|
||||
throw new error_handler_1.AppError(400, 'Invalid path: null byte detected', 'INVALID_MKDOCS_PATH');
|
||||
}
|
||||
// Normalize and check for traversal
|
||||
const normalized = path_1.default.normalize(mkdocsPath);
|
||||
if (normalized.includes('..') || path_1.default.isAbsolute(normalized)) {
|
||||
throw new error_handler_1.AppError(400, 'Path traversal not allowed', 'INVALID_MKDOCS_PATH');
|
||||
}
|
||||
// Check for encoded traversal sequences
|
||||
if (mkdocsPath.includes('%2e') || mkdocsPath.includes('%2E')) {
|
||||
throw new error_handler_1.AppError(400, 'Encoded path traversal not allowed', 'INVALID_MKDOCS_PATH');
|
||||
}
|
||||
if (!mkdocsPath.endsWith('.html')) {
|
||||
throw new error_handler_1.AppError(400, 'Path must end with .html', 'INVALID_MKDOCS_PATH');
|
||||
}
|
||||
}
|
||||
function validateStubPath(stubPath) {
|
||||
// Check for null bytes
|
||||
if (stubPath.includes('\0')) {
|
||||
throw new error_handler_1.AppError(400, 'Invalid path: null byte detected', 'INVALID_STUB_PATH');
|
||||
}
|
||||
// Normalize and check for traversal
|
||||
const normalized = path_1.default.normalize(stubPath);
|
||||
if (normalized.includes('..') || path_1.default.isAbsolute(normalized)) {
|
||||
throw new error_handler_1.AppError(400, 'Path traversal not allowed', 'INVALID_STUB_PATH');
|
||||
}
|
||||
// Check for encoded traversal sequences
|
||||
if (stubPath.includes('%2e') || stubPath.includes('%2E')) {
|
||||
throw new error_handler_1.AppError(400, 'Encoded path traversal not allowed', 'INVALID_STUB_PATH');
|
||||
}
|
||||
}
|
||||
function wrapInMaterialOverride(html, css) {
|
||||
const styleBlock = css ? `<style>\n${css}\n</style>` : '';
|
||||
return `{% extends "main.html" %}
|
||||
{% block content %}
|
||||
${styleBlock}
|
||||
${html}
|
||||
{% endblock %}
|
||||
`;
|
||||
}
|
||||
function wrapInStandaloneDocument(html, css, title, description) {
|
||||
const metaDesc = description ? `\n <meta name="description" content="${description.replace(/"/g, '"')}">` : '';
|
||||
const styleBlock = css ? `\n <style>\n${css}\n </style>` : '';
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>${title.replace(/</g, '<')}</title>${metaDesc}${styleBlock}
|
||||
</head>
|
||||
<body>
|
||||
${html}
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
}
|
||||
function deriveStubPath(overridePath) {
|
||||
return overridePath.replace(/\.html$/, '.md');
|
||||
}
|
||||
function generateMdStub(opts) {
|
||||
const hideItems = [];
|
||||
if (opts.hideNav)
|
||||
hideItems.push(' - navigation');
|
||||
if (opts.hideToc)
|
||||
hideItems.push(' - toc');
|
||||
const hideBlock = hideItems.length > 0 ? `hide:\n${hideItems.join('\n')}\n` : '';
|
||||
const descLine = opts.description ? `description: "${opts.description.replace(/"/g, '\\"')}"\n` : '';
|
||||
return `---
|
||||
template: ${opts.overrideFilename}
|
||||
${hideBlock}title: "${opts.title.replace(/"/g, '\\"')}"
|
||||
${descLine}---
|
||||
`;
|
||||
}
|
||||
async function writeStubFile(stubPath, content) {
|
||||
try {
|
||||
validateStubPath(stubPath);
|
||||
const filePath = path_1.default.join(MKDOCS_DOCS_ROOT, stubPath);
|
||||
await promises_1.default.mkdir(path_1.default.dirname(filePath), { recursive: true });
|
||||
await promises_1.default.writeFile(filePath, content, 'utf-8');
|
||||
logger_1.logger.info(`Wrote MkDocs stub: ${stubPath}`);
|
||||
}
|
||||
catch (err) {
|
||||
if (err instanceof error_handler_1.AppError)
|
||||
throw err;
|
||||
logger_1.logger.warn(`Failed to write stub: ${stubPath}`, err);
|
||||
}
|
||||
}
|
||||
async function removeStubFile(stubPath) {
|
||||
try {
|
||||
const filePath = path_1.default.join(MKDOCS_DOCS_ROOT, stubPath);
|
||||
await promises_1.default.unlink(filePath);
|
||||
logger_1.logger.info(`Removed MkDocs stub: ${stubPath}`);
|
||||
}
|
||||
catch {
|
||||
// File may not exist — ignore
|
||||
}
|
||||
}
|
||||
async function exportToMkDocs(opts) {
|
||||
const { mkdocsPath, html, css, editorMode, exportMode, title, seoTitle, seoDescription, hideNav, hideToc } = opts;
|
||||
try {
|
||||
validateMkdocsPath(mkdocsPath);
|
||||
// Write the override template
|
||||
const filePath = path_1.default.join(MKDOCS_OVERRIDES, mkdocsPath);
|
||||
await promises_1.default.mkdir(path_1.default.dirname(filePath), { recursive: true });
|
||||
let content;
|
||||
if (editorMode === 'CODE') {
|
||||
content = html;
|
||||
}
|
||||
else if (exportMode === 'STANDALONE') {
|
||||
content = wrapInStandaloneDocument(html, css, seoTitle || title, seoDescription);
|
||||
}
|
||||
else {
|
||||
content = wrapInMaterialOverride(html, css);
|
||||
}
|
||||
await promises_1.default.writeFile(filePath, content, 'utf-8');
|
||||
logger_1.logger.info(`Exported landing page to MkDocs: ${mkdocsPath} (${editorMode}/${exportMode})`);
|
||||
// Write the .md stub
|
||||
const stubPath = deriveStubPath(mkdocsPath);
|
||||
const stubContent = generateMdStub({
|
||||
overrideFilename: mkdocsPath,
|
||||
title: seoTitle || title,
|
||||
description: seoDescription,
|
||||
hideNav,
|
||||
hideToc,
|
||||
});
|
||||
await writeStubFile(stubPath, stubContent);
|
||||
return stubPath;
|
||||
}
|
||||
catch (err) {
|
||||
if (err instanceof error_handler_1.AppError)
|
||||
throw err;
|
||||
logger_1.logger.warn(`Failed to export to MkDocs: ${mkdocsPath}`, err);
|
||||
return deriveStubPath(mkdocsPath);
|
||||
}
|
||||
}
|
||||
async function removeFromMkDocs(mkdocsPath, stubPath) {
|
||||
try {
|
||||
const filePath = path_1.default.join(MKDOCS_OVERRIDES, mkdocsPath);
|
||||
await promises_1.default.unlink(filePath);
|
||||
logger_1.logger.info(`Removed MkDocs export: ${mkdocsPath}`);
|
||||
}
|
||||
catch {
|
||||
// File may not exist — ignore
|
||||
}
|
||||
// Also remove the stub
|
||||
const effectiveStubPath = stubPath || deriveStubPath(mkdocsPath);
|
||||
await removeStubFile(effectiveStubPath);
|
||||
}
|
||||
async function scanOverrideFiles(dir, base = '') {
|
||||
const results = [];
|
||||
try {
|
||||
const entries = await promises_1.default.readdir(dir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
const rel = base ? `${base}/${entry.name}` : entry.name;
|
||||
const full = path_1.default.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
results.push(...await scanOverrideFiles(full, rel));
|
||||
}
|
||||
else if (entry.name.endsWith('.html')) {
|
||||
results.push({ relativePath: rel, fullPath: full });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// Directory may not exist
|
||||
}
|
||||
return results;
|
||||
}
|
||||
async function stubExistsOnDisk(stubPath) {
|
||||
try {
|
||||
await promises_1.default.access(path_1.default.join(MKDOCS_DOCS_ROOT, stubPath));
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
exports.pagesService = {
|
||||
async findAll(filters) {
|
||||
const { page, limit, search, published } = filters;
|
||||
const skip = (page - 1) * limit;
|
||||
const where = {};
|
||||
if (search) {
|
||||
where.OR = [
|
||||
{ title: { contains: search, mode: 'insensitive' } },
|
||||
{ description: { contains: search, mode: 'insensitive' } },
|
||||
{ slug: { contains: search, mode: 'insensitive' } },
|
||||
];
|
||||
}
|
||||
if (published === 'true')
|
||||
where.published = true;
|
||||
else if (published === 'false')
|
||||
where.published = false;
|
||||
const [pages, total] = await Promise.all([
|
||||
database_1.prisma.landingPage.findMany({
|
||||
where,
|
||||
select: landingPageSelect,
|
||||
skip,
|
||||
take: limit,
|
||||
orderBy: { createdAt: 'desc' },
|
||||
}),
|
||||
database_1.prisma.landingPage.count({ where }),
|
||||
]);
|
||||
return {
|
||||
pages,
|
||||
pagination: {
|
||||
page,
|
||||
limit,
|
||||
total,
|
||||
totalPages: Math.ceil(total / limit),
|
||||
},
|
||||
};
|
||||
},
|
||||
async findById(id) {
|
||||
const page = await database_1.prisma.landingPage.findUnique({
|
||||
where: { id },
|
||||
select: landingPageSelect,
|
||||
});
|
||||
if (!page) {
|
||||
throw new error_handler_1.AppError(404, 'Landing page not found', 'PAGE_NOT_FOUND');
|
||||
}
|
||||
return page;
|
||||
},
|
||||
async findBySlugPublic(slug) {
|
||||
const page = await database_1.prisma.landingPage.findUnique({
|
||||
where: { slug },
|
||||
select: landingPageSelect,
|
||||
});
|
||||
if (!page || !page.published) {
|
||||
throw new error_handler_1.AppError(404, 'Page not found', 'PAGE_NOT_FOUND');
|
||||
}
|
||||
return page;
|
||||
},
|
||||
async create(data) {
|
||||
const baseSlug = generateSlug(data.title);
|
||||
const slug = await resolveSlugCollision(baseSlug);
|
||||
// Auto-generate mkdocsPath from slug if not provided
|
||||
const mkdocsPath = data.mkdocsPath ?? `${slug}.html`;
|
||||
validateMkdocsPath(mkdocsPath);
|
||||
const page = await database_1.prisma.landingPage.create({
|
||||
data: {
|
||||
...data,
|
||||
slug,
|
||||
mkdocsPath,
|
||||
blocks: data.blocks,
|
||||
},
|
||||
select: landingPageSelect,
|
||||
});
|
||||
return page;
|
||||
},
|
||||
async update(id, data) {
|
||||
const existing = await database_1.prisma.landingPage.findUnique({ where: { id } });
|
||||
if (!existing) {
|
||||
throw new error_handler_1.AppError(404, 'Landing page not found', 'PAGE_NOT_FOUND');
|
||||
}
|
||||
if (data.mkdocsPath) {
|
||||
validateMkdocsPath(data.mkdocsPath);
|
||||
}
|
||||
const updateData = { ...data };
|
||||
// Handle blocks JSON field
|
||||
if (data.blocks !== undefined) {
|
||||
updateData.blocks = data.blocks;
|
||||
}
|
||||
// Regenerate slug if title changes, and keep mkdocsPath in sync
|
||||
if (data.title && data.title !== existing.title) {
|
||||
const baseSlug = generateSlug(data.title);
|
||||
const newSlug = await resolveSlugCollision(baseSlug, id);
|
||||
updateData.slug = newSlug;
|
||||
// Update mkdocsPath if it was auto-generated (matches old slug pattern)
|
||||
const autoPath = `${existing.slug}.html`;
|
||||
if (existing.mkdocsPath === autoPath) {
|
||||
const oldMkdocsPath = existing.mkdocsPath;
|
||||
updateData.mkdocsPath = `${newSlug}.html`;
|
||||
// Clean up old override + old stub
|
||||
await removeFromMkDocs(oldMkdocsPath, existing.mkdocsStubPath);
|
||||
updateData.mkdocsStubPath = null;
|
||||
}
|
||||
}
|
||||
const page = await database_1.prisma.landingPage.update({
|
||||
where: { id },
|
||||
data: updateData,
|
||||
select: landingPageSelect,
|
||||
});
|
||||
// Handle MkDocs export/cleanup based on publish state
|
||||
if (page.published && !page.mkdocsSkipExport && page.mkdocsPath && page.htmlOutput) {
|
||||
const stubPath = await exportToMkDocs({
|
||||
mkdocsPath: page.mkdocsPath,
|
||||
html: page.htmlOutput,
|
||||
css: page.cssOutput,
|
||||
editorMode: page.editorMode,
|
||||
exportMode: page.mkdocsExportMode,
|
||||
title: page.title,
|
||||
seoTitle: page.seoTitle,
|
||||
seoDescription: page.seoDescription,
|
||||
hideNav: page.mkdocsHideNav,
|
||||
hideToc: page.mkdocsHideToc,
|
||||
});
|
||||
// Store stubPath if changed
|
||||
if (stubPath !== page.mkdocsStubPath) {
|
||||
await database_1.prisma.landingPage.update({
|
||||
where: { id },
|
||||
data: { mkdocsStubPath: stubPath },
|
||||
});
|
||||
}
|
||||
}
|
||||
else if ((!page.published || page.mkdocsSkipExport) && existing.mkdocsPath) {
|
||||
await removeFromMkDocs(existing.mkdocsPath, existing.mkdocsStubPath);
|
||||
if (existing.mkdocsStubPath) {
|
||||
await database_1.prisma.landingPage.update({
|
||||
where: { id },
|
||||
data: { mkdocsStubPath: null },
|
||||
});
|
||||
}
|
||||
}
|
||||
return page;
|
||||
},
|
||||
async delete(id) {
|
||||
const existing = await database_1.prisma.landingPage.findUnique({ where: { id } });
|
||||
if (!existing) {
|
||||
throw new error_handler_1.AppError(404, 'Landing page not found', 'PAGE_NOT_FOUND');
|
||||
}
|
||||
// Remove MkDocs export + stub if exists
|
||||
if (existing.mkdocsPath) {
|
||||
await removeFromMkDocs(existing.mkdocsPath, existing.mkdocsStubPath);
|
||||
}
|
||||
await database_1.prisma.landingPage.delete({ where: { id } });
|
||||
},
|
||||
async syncOverrides() {
|
||||
let imported = 0;
|
||||
let updated = 0;
|
||||
let stubs = 0;
|
||||
const files = await scanOverrideFiles(MKDOCS_OVERRIDES);
|
||||
if (files.length === 0) {
|
||||
logger_1.logger.info('syncOverrides: No HTML files found in overrides directory');
|
||||
}
|
||||
// Get all existing pages with mkdocsPath set
|
||||
const existingPages = await database_1.prisma.landingPage.findMany({
|
||||
where: { mkdocsPath: { not: null } },
|
||||
select: {
|
||||
id: true,
|
||||
mkdocsPath: true,
|
||||
mkdocsStubPath: true,
|
||||
mkdocsExportMode: true,
|
||||
mkdocsHideNav: true,
|
||||
mkdocsHideToc: true,
|
||||
editorMode: true,
|
||||
title: true,
|
||||
seoTitle: true,
|
||||
seoDescription: true,
|
||||
published: true,
|
||||
},
|
||||
});
|
||||
const pathMap = new Map(existingPages.map(p => [p.mkdocsPath, p]));
|
||||
for (const file of files) {
|
||||
const content = await promises_1.default.readFile(file.fullPath, 'utf-8');
|
||||
const tracked = pathMap.get(file.relativePath);
|
||||
if (!tracked) {
|
||||
// Untracked file — import as CODE page
|
||||
const title = path_1.default.basename(file.relativePath, '.html');
|
||||
const baseSlug = generateSlug(title);
|
||||
const slug = await resolveSlugCollision(baseSlug);
|
||||
await database_1.prisma.landingPage.create({
|
||||
data: {
|
||||
slug,
|
||||
title,
|
||||
editorMode: 'CODE',
|
||||
htmlOutput: content,
|
||||
mkdocsPath: file.relativePath,
|
||||
published: true,
|
||||
blocks: {},
|
||||
},
|
||||
});
|
||||
imported++;
|
||||
logger_1.logger.info(`syncOverrides: Imported ${file.relativePath} as CODE page`);
|
||||
}
|
||||
else if (tracked.editorMode === 'CODE') {
|
||||
// Tracked CODE page — update from disk (disk wins)
|
||||
await database_1.prisma.landingPage.update({
|
||||
where: { id: tracked.id },
|
||||
data: { htmlOutput: content },
|
||||
});
|
||||
updated++;
|
||||
logger_1.logger.info(`syncOverrides: Updated ${file.relativePath} from disk`);
|
||||
}
|
||||
// VISUAL pages: don't overwrite from disk (managed by GrapesJS)
|
||||
}
|
||||
// Backfill missing .md stubs for published pages with overrides
|
||||
for (const page of existingPages) {
|
||||
if (!page.published || !page.mkdocsPath)
|
||||
continue;
|
||||
const expectedStubPath = page.mkdocsStubPath || deriveStubPath(page.mkdocsPath);
|
||||
const exists = await stubExistsOnDisk(expectedStubPath);
|
||||
if (!exists) {
|
||||
const stubContent = generateMdStub({
|
||||
overrideFilename: page.mkdocsPath,
|
||||
title: page.seoTitle || page.title,
|
||||
description: page.seoDescription,
|
||||
hideNav: page.mkdocsHideNav,
|
||||
hideToc: page.mkdocsHideToc,
|
||||
});
|
||||
await writeStubFile(expectedStubPath, stubContent);
|
||||
if (page.mkdocsStubPath !== expectedStubPath) {
|
||||
await database_1.prisma.landingPage.update({
|
||||
where: { id: page.id },
|
||||
data: { mkdocsStubPath: expectedStubPath },
|
||||
});
|
||||
}
|
||||
stubs++;
|
||||
logger_1.logger.info(`syncOverrides: Created missing stub ${expectedStubPath}`);
|
||||
}
|
||||
}
|
||||
logger_1.logger.info(`syncOverrides: Imported ${imported}, updated ${updated}, stubs created ${stubs}`);
|
||||
return { imported, updated, stubs };
|
||||
},
|
||||
async validateExports() {
|
||||
let validated = 0;
|
||||
let repaired = 0;
|
||||
const errors = [];
|
||||
const pages = await database_1.prisma.landingPage.findMany({
|
||||
where: {
|
||||
published: true,
|
||||
mkdocsSkipExport: false,
|
||||
mkdocsPath: { not: null },
|
||||
htmlOutput: { not: null },
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
slug: true,
|
||||
title: true,
|
||||
mkdocsPath: true,
|
||||
mkdocsStubPath: true,
|
||||
htmlOutput: true,
|
||||
cssOutput: true,
|
||||
editorMode: true,
|
||||
mkdocsExportMode: true,
|
||||
mkdocsHideNav: true,
|
||||
mkdocsHideToc: true,
|
||||
seoTitle: true,
|
||||
seoDescription: true,
|
||||
},
|
||||
});
|
||||
logger_1.logger.info(`Validating MkDocs exports for ${pages.length} published pages`);
|
||||
for (const page of pages) {
|
||||
validated++;
|
||||
try {
|
||||
// Check override HTML exists
|
||||
const overridePath = path_1.default.join(MKDOCS_OVERRIDES, page.mkdocsPath);
|
||||
let overrideExists = false;
|
||||
try {
|
||||
await promises_1.default.access(overridePath);
|
||||
overrideExists = true;
|
||||
}
|
||||
catch {
|
||||
// File doesn't exist
|
||||
}
|
||||
// Check stub exists
|
||||
const expectedStubPath = page.mkdocsStubPath || deriveStubPath(page.mkdocsPath);
|
||||
const stubExists = await stubExistsOnDisk(expectedStubPath);
|
||||
// Repair if either missing
|
||||
if (!overrideExists || !stubExists) {
|
||||
logger_1.logger.warn(`Missing exports for ${page.slug}: override=${overrideExists}, stub=${stubExists}. Re-exporting...`);
|
||||
const stubPath = await exportToMkDocs({
|
||||
mkdocsPath: page.mkdocsPath,
|
||||
html: page.htmlOutput,
|
||||
css: page.cssOutput,
|
||||
editorMode: page.editorMode,
|
||||
exportMode: page.mkdocsExportMode,
|
||||
title: page.title,
|
||||
seoTitle: page.seoTitle,
|
||||
seoDescription: page.seoDescription,
|
||||
hideNav: page.mkdocsHideNav,
|
||||
hideToc: page.mkdocsHideToc,
|
||||
});
|
||||
if (stubPath !== page.mkdocsStubPath) {
|
||||
await database_1.prisma.landingPage.update({
|
||||
where: { id: page.id },
|
||||
data: { mkdocsStubPath: stubPath },
|
||||
});
|
||||
}
|
||||
repaired++;
|
||||
logger_1.logger.info(`✓ Repaired exports for ${page.slug}`);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
const errorMsg = err instanceof Error ? err.message : String(err);
|
||||
logger_1.logger.error(`Failed to validate/repair ${page.slug}:`, err);
|
||||
errors.push({ pageId: page.id, slug: page.slug, error: errorMsg });
|
||||
}
|
||||
}
|
||||
logger_1.logger.info(`Validation complete: ${validated} validated, ${repaired} repaired, ${errors.length} errors`);
|
||||
return { validated, repaired, errors };
|
||||
},
|
||||
};
|
||||
//# sourceMappingURL=pages.service.js.map
|
||||
1
api/dist/modules/pages/pages.service.js.map
vendored
Normal file
1
api/dist/modules/pages/pages.service.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user