@lucidcms/core
Version:
The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.
1,841 lines (1,795 loc) • 453 kB
JavaScript
import {
build_response_default,
route_default
} from "./chunk-SX4AK7IW.js";
import {
ClientIntegrationsFormatter,
CollectionDocumentVersions,
CollectionDocumentsFormatter,
CollectionsFormatter,
EmailsFormatter,
LocalesFormatter,
MediaFormatter,
PermissionsFormatter,
RolesFormatter,
SettingsFormatter,
UsersFormatter,
choose_accept_header_format_default,
formatters_default,
generate_process_key_default,
get_unique_locale_codes_default,
merge_translation_groups_default,
should_update_translations_default
} from "./chunk-URI3PAN7.js";
import {
permissions_default,
service_wrapper_default
} from "./chunk-CGRLN764.js";
import {
constants_default,
decode_error_default,
logging_default,
lucid_api_error_default,
lucid_error_default,
permission_groups_default,
translations_default
} from "./chunk-ZMWDUGJW.js";
// src/libs/fastify/server.ts
import Fastify from "fastify";
// src/libs/fastify/plugins/lucid.ts
import fs10 from "node:fs";
import path5 from "node:path";
import fastifyCookie from "@fastify/cookie";
import cors from "@fastify/cors";
import fastifyHelmet from "@fastify/helmet";
import fastifyRateLimit from "@fastify/rate-limit";
import fastifyStatic2 from "@fastify/static";
import fastifySwagger from "@fastify/swagger";
import fastifySwaggerUi from "@fastify/swagger-ui";
import fp2 from "fastify-plugin";
// package.json
var package_default = {
name: "@lucidcms/core",
version: "0.10.2-alpha.0",
description: "The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.",
type: "module",
types: "./dist/index.d.ts",
module: "dist/index.js",
exports: {
".": {
import: "./dist/index.js",
types: "./dist/index.d.ts"
},
"./adapters": {
types: "./dist/adapters.d.ts",
default: "./dist/adapters.js"
},
"./api": {
types: "./dist/api.d.ts",
default: "./dist/api.js"
},
"./builders": {
types: "./dist/builders.d.ts",
default: "./dist/builders.js"
},
"./middleware": {
types: "./dist/middleware.d.ts",
default: "./dist/middleware.js"
},
"./types": {
types: "./dist/types.d.ts",
default: "./dist/types.js"
},
"./package.json": "./package.json"
},
scripts: {
build: "tsc && tsup",
dev: "tsup --watch",
format: "biome format ./src",
"format:fix": "biome format --write ./src",
lint: "biome lint ./src",
"lint:fix": "biome lint --apply ./src",
"clear-db:postgres": "node ./scripts/clear-db-pg.js"
},
files: ["dist", "cms", "templates", "assets"],
author: "Proto Digital",
repository: {
type: "git",
url: "git+https://github.com/ProtoDigitalUK/lucid_cms.git",
directory: "packages/core"
},
keywords: [
"CMS",
"Headless",
"Node.js",
"Typescript",
"ESM",
"Fastify",
"Postgres",
"SQLite",
"LibSQL",
"Kysely"
],
devDependencies: {
"@biomejs/biome": "^1.8.3",
"@lucidcms/admin": "*",
"@lucidcms/config": "*",
"@types/fs-extra": "^11.0.4",
"@types/jsonwebtoken": "^9.0.6",
"@types/lodash.merge": "^4.6.9",
"@types/mime-types": "^2.1.4",
"@types/mjml": "^4.7.4",
"@types/node": "^20.14.10",
"@types/node-cron": "^3.0.11",
"@types/pg": "^8.11.6",
"@types/sanitize-html": "^2.11.0",
"@types/semver": "^7.5.8",
"@types/slug": "^5.0.9",
"@types/uuid": "^10.0.0",
tsup: "^8.2.4",
typescript: "^5.5.4"
},
dependencies: {
"@fastify/cookie": "^9.3.1",
"@fastify/cors": "^9.0.1",
"@fastify/helmet": "^11.1.1",
"@fastify/rate-limit": "^9.1.0",
"@fastify/static": "^7.0.4",
"@fastify/swagger": "^8.15.0",
"@fastify/swagger-ui": "^4.1.0",
"@libsql/kysely-libsql": "^0.4.1",
"@tailwindcss/vite": "^4.0.0-beta.4",
argon2: "^0.41.1",
"better-sqlite3": "^11.5.0",
blurhash: "^2.0.5",
"date-fns": "^4.1.0",
"fast-average-color-node": "^3.1.0",
fastify: "^4.28.1",
"fastify-plugin": "^4.5.1",
"fs-extra": "^11.2.0",
handlebars: "^4.7.8",
jsonwebtoken: "^9.0.2",
kysely: "^0.27.4",
"lodash.merge": "^4.6.2",
"mime-types": "^2.1.35",
mjml: "^5.0.0-alpha.4",
"node-cron": "^3.0.3",
pg: "^8.13.1",
"sanitize-html": "^2.13.1",
semver: "^7.6.3",
sharp: "^0.33.5",
slug: "^10.0.0",
"solid-js": "^1.9.3",
tailwindcss: "^4.0.0-beta.4",
uuid: "^11.0.3",
vite: "^5.3.3",
"vite-plugin-solid": "^2.11.0",
winston: "^3.17.0",
zod: "^3.23.8",
"zod-validation-error": "^3.4.0",
"@lucidcms/admin": "0.10.2-alpha.0"
},
volta: {
node: "20.18.1"
},
license: "MIT"
};
// src/actions/register-cron-jobs.ts
import cron from "node-cron";
var registerCronJobs = async (service) => {
try {
cron.schedule(constants_default.cronSchedule, async () => {
logging_default("info", {
message: translations_default("running_cron_jobs")
});
await Promise.allSettled([
service_wrapper_default(service.services.crons.clearExpiredLocales, {
transaction: true,
logError: true,
defaultError: {
type: "cron",
name: translations_default("cron_job_error_name"),
message: translations_default("an_error_occurred_clearing_expired_locales")
}
})(service),
service_wrapper_default(service.services.crons.clearExpiredTokens, {
transaction: true,
logError: true,
defaultError: {
type: "cron",
name: translations_default("cron_job_error_name"),
message: translations_default("an_error_occurred_clearing_expired_tokens")
}
})(service),
service_wrapper_default(service.services.crons.updateMediaStorage, {
transaction: true,
logError: true,
defaultError: {
type: "cron",
name: translations_default("cron_job_error_name"),
message: translations_default("an_error_occurred_updating_media_storage")
}
})(service),
service_wrapper_default(service.services.crons.deleteExpiredMedia, {
transaction: true,
logError: true,
defaultError: {
type: "cron",
name: translations_default("cron_job_error_name"),
message: translations_default("an_error_occurred_deleting_expired_media")
}
})(service)
]);
});
} catch (error) {
logging_default("error", {
message: translations_default("cron_job_error_message")
});
}
};
var register_cron_jobs_default = registerCronJobs;
// src/actions/execute-start-tasks.ts
var executeStartTasks = async (service) => {
await service.config.db.migrateToLatest();
await Promise.all([
service_wrapper_default(service.services.start.executeSeeds, {
transaction: true,
logError: true,
defaultError: {
name: translations_default("seed_error_name")
}
})(service),
service_wrapper_default(service.services.start.syncLocales, {
transaction: true,
logError: true,
defaultError: {
name: translations_default("start_error_name"),
message: translations_default("locale_error_occured_saving_default")
}
})(service)
]);
register_cron_jobs_default(service);
};
var execute_start_tasks_default = executeStartTasks;
// src/libs/config/get-config-path.ts
import path from "node:path";
import fs from "fs-extra";
var getConfigPath = (cwd, filename) => {
let configPath = void 0;
const root = path.parse(cwd).root;
const configFileName = filename ?? "lucid.config";
const configExtensions = [".ts", ".js", ".mjs", ".mts"];
const search = (cwd2) => {
const files = fs.readdirSync(cwd2);
const configFiles = files.filter((file) => {
const { name, ext } = path.parse(file);
return name === configFileName && configExtensions.includes(ext);
});
if (configFiles.length > 0 && configFiles[0]) {
configPath = path.resolve(cwd2, configFiles[0]);
return;
}
const parent = path.resolve(cwd2, "..");
if (parent === cwd2 || parent === root) {
return;
}
search(parent);
};
search(cwd);
if (!configPath) {
throw new Error(translations_default("cannot_find_config_path"));
}
return configPath;
};
var get_config_path_default = getConfigPath;
// src/libs/config/get-config.ts
import path2 from "node:path";
import { pathToFileURL } from "node:url";
var config = void 0;
var getConfig = async (props) => {
if (props?.config) {
config = props.config;
return config;
}
if (config) {
return config;
}
const configPath = props?.givenPath ? props.givenPath : get_config_path_default(process.cwd());
const importPath = pathToFileURL(path2.resolve(configPath)).href;
const configModule = await import(
/* @vite-ignore */
importPath
);
config = configModule.default;
return config;
};
var get_config_default = getConfig;
// src/schemas/auth.ts
import z from "zod";
var auth_default = {
getCSRF: {
body: void 0,
query: void 0,
params: void 0
},
login: {
body: z.object({
usernameOrEmail: z.string(),
password: z.string()
}),
query: void 0,
params: void 0
},
token: {
body: void 0,
query: void 0,
params: void 0
},
logout: {
body: void 0,
query: void 0,
params: void 0
}
};
// src/utils/swagger/swagger-response.ts
var metaObject = {
type: "object",
properties: {
path: { type: "string" },
links: {
type: "array"
},
currentPage: { type: "number", nullable: true, example: null },
lastPage: { type: "number", nullable: true, example: null },
perPage: { type: "number", nullable: true, example: null },
total: { type: "number", nullable: true, example: null }
}
};
var paginatedMetaObject = {
type: "object",
properties: {
path: { type: "string" },
links: {
type: "array",
items: {
type: "object",
properties: {
active: { type: "boolean" },
label: { type: "string" },
url: { type: "string", nullable: true },
page: { type: "number" }
}
}
},
currentPage: {
type: "number",
nullable: true,
example: constants_default.query.page
},
lastPage: {
type: "number",
nullable: true,
example: 200 / constants_default.query.perPage
},
perPage: {
type: "number",
nullable: true,
example: constants_default.query.perPage
},
total: { type: "number", nullable: true, example: 200 }
}
};
var linksObject = {
type: "object",
properties: {
first: { type: "string", nullable: true },
last: { type: "string", nullable: true },
next: { type: "string", nullable: true },
prev: { type: "string", nullable: true }
}
};
var swaggerResponse = (params) => {
let description = translations_default("swagger_response_200");
const headers = {};
switch (params.type) {
case 200:
description = translations_default("swagger_response_200");
break;
case 201:
description = translations_default("swagger_response_201");
break;
case 204:
description = translations_default("swagger_response_204");
break;
case 400:
description = translations_default("swagger_response_400");
break;
case 401:
description = translations_default("swagger_response_401");
break;
case 403:
description = translations_default("swagger_response_403");
break;
case 404:
description = translations_default("swagger_response_404");
break;
case 500:
description = translations_default("swagger_response_500");
break;
}
const propertise = {
data: params.data,
meta: params.paginated ? paginatedMetaObject : metaObject
};
if (params.paginated) {
propertise.links = linksObject;
}
return {
description,
type: params.noPropertise === true ? "null" : "object",
properties: params.noPropertise === true ? void 0 : propertise,
headers
};
};
var swagger_response_default = swaggerResponse;
// src/utils/swagger/swagger-headers.ts
var swaggerHeaders = (headers) => {
const propertise = {};
const required = [];
if (headers.csrf !== void 0) {
propertise._csrf = {
type: "string",
description: translations_default("swagger_csrf_header_description")
};
if (headers.csrf) {
required.push("_csrf");
}
}
if (headers.contentLocale !== void 0) {
propertise["lucid-content-locale"] = {
type: "string",
description: translations_default("swagger_content_locale_header_description")
};
}
if (headers.clientKey !== void 0) {
propertise["lucid-client-key"] = {
type: "string",
description: translations_default("swagger_client_key_header_description")
};
}
if (headers.authorization !== void 0) {
propertise.Authorization = {
type: "string",
description: translations_default("swagger_authorization_header_description")
};
}
return {
type: "object",
properties: propertise,
required
};
};
var swagger_headers_default = swaggerHeaders;
// src/utils/swagger/swagger-query-string.ts
var swaggerQueryString = (config2) => {
const queryString = {
type: "object",
properties: {}
};
if (config2.include && config2.include.length > 0) {
queryString.properties.include = {
type: "string",
enum: config2.include,
description: translations_default("swagger_query_string_include_description")
};
}
if (config2.filters && config2.filters.length > 0) {
for (const filter of config2.filters) {
queryString.properties[`filter[${filter.key}]`] = {
type: "string",
enum: filter.enum,
description: translations_default("swagger_query_string_filter_description")
};
}
}
if (config2.sorts && config2.sorts.length > 0) {
queryString.properties.sort = {
type: "string",
enum: config2.sorts,
description: translations_default("swagger_query_string_sort_description")
};
}
if (config2.page) {
queryString.properties.page = {
type: "number",
description: translations_default("swagger_query_string_page_description")
};
}
if (config2.perPage) {
queryString.properties.perPage = {
type: "number",
description: translations_default("swagger_query_string_per_page_description")
};
}
return queryString;
};
var swagger_query_string_default = swaggerQueryString;
// src/controllers/auth/get-csrf.ts
var getCSRFController = async (request, reply) => {
const tokenRes = await request.server.services.auth.csrf.generateToken(
request,
reply
);
if (tokenRes.error) throw new lucid_api_error_default(tokenRes.error);
reply.status(200).send(
build_response_default(request, {
data: {
_csrf: tokenRes.data
}
})
);
};
var get_csrf_default = {
controller: getCSRFController,
zodSchema: auth_default.getCSRF,
swaggerSchema: {
description: "This route returns a CSRF token in the response body and also sets a _csrf httpOnly cookie. The client can use this token on required routes by setting a _csrf header. On required routes this header will be checked against the _csrf cookie.",
tags: ["auth"],
summary: "Returns a CSRF token",
response: {
200: swagger_response_default({
type: 200,
data: {
type: "object",
properties: {
_csrf: { type: "string" }
}
}
})
}
}
};
// src/controllers/auth/login.ts
var loginController = async (request, reply) => {
const userRes = await service_wrapper_default(request.server.services.auth.login, {
transaction: false,
defaultError: {
type: "basic",
code: "login",
name: translations_default("route_login_error_name"),
message: translations_default("route_login_error_message")
}
})(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
usernameOrEmail: request.body.usernameOrEmail,
password: request.body.password
}
);
if (userRes.error) throw new lucid_api_error_default(userRes.error);
const [refreshRes, accessRes] = await Promise.all([
request.server.services.auth.refreshToken.generateToken(
reply,
request,
userRes.data.id
),
request.server.services.auth.accessToken.generateToken(
reply,
request,
userRes.data.id
)
]);
if (refreshRes.error) throw new lucid_api_error_default(refreshRes.error);
if (accessRes.error) throw new lucid_api_error_default(accessRes.error);
reply.status(204).send();
};
var login_default = {
controller: loginController,
zodSchema: auth_default.login,
swaggerSchema: {
description: "Authenticates a user and sets a refresh and access token as httpOnly cookies.",
tags: ["auth"],
summary: "Authenticates a user and sets httpOnly cookies",
body: {
type: "object",
properties: {
usernameOrEmail: { type: "string" },
password: { type: "string" }
},
required: ["usernameOrEmail", "password"]
},
response: {
204: swagger_response_default({
type: 204,
noPropertise: true
})
},
headers: swagger_headers_default({
csrf: true
})
}
};
// src/controllers/auth/token.ts
var tokenController = async (request, reply) => {
const payloadRes = await request.server.services.auth.refreshToken.verifyToken(request, reply);
if (payloadRes.error) throw new lucid_api_error_default(payloadRes.error);
const [refreshRes, accessRes] = await Promise.all([
request.server.services.auth.refreshToken.generateToken(
reply,
request,
payloadRes.data.user_id
),
request.server.services.auth.accessToken.generateToken(
reply,
request,
payloadRes.data.user_id
)
]);
if (refreshRes.error) throw new lucid_api_error_default(refreshRes.error);
if (accessRes.error) throw new lucid_api_error_default(accessRes.error);
reply.status(204).send();
};
var token_default = {
controller: tokenController,
zodSchema: auth_default.token,
swaggerSchema: {
description: "Verifies the refresh token and issues a new access and refresh token.",
tags: ["auth"],
summary: "Issues a new access and refresh token.",
response: {
204: swagger_response_default({
type: 204,
noPropertise: true
})
},
headers: swagger_headers_default({
csrf: true
})
}
};
// src/controllers/auth/logout.ts
var logoutController = async (request, reply) => {
const [clearRefreshRes, clearAccessRes, clearCSRFRes] = await Promise.all([
request.server.services.auth.refreshToken.clearToken(request, reply),
request.server.services.auth.accessToken.clearToken(reply),
request.server.services.auth.csrf.clearToken(reply)
]);
if (clearRefreshRes.error) throw new lucid_api_error_default(clearRefreshRes.error);
if (clearAccessRes.error) throw new lucid_api_error_default(clearAccessRes.error);
if (clearCSRFRes.error) throw new lucid_api_error_default(clearCSRFRes.error);
reply.status(204).send();
};
var logout_default = {
controller: logoutController,
zodSchema: auth_default.logout,
swaggerSchema: {
description: "Logs out a user by clearing the refresh token and access token, it also clears the CSRF token",
tags: ["auth"],
summary: "Logs out a user",
response: {
204: swagger_response_default({
type: 204,
noPropertise: true
})
},
headers: swagger_headers_default({
csrf: true
})
}
};
// src/controllers/auth/index.ts
var auth_default2 = {
getCSRF: get_csrf_default,
login: login_default,
token: token_default,
logout: logout_default
};
// src/routes/v1/api/auth.routes.ts
var authRoutes = async (fastify2) => {
route_default(fastify2, {
method: "get",
url: "/csrf",
zodSchema: auth_default2.getCSRF.zodSchema,
swaggerSchema: auth_default2.getCSRF.swaggerSchema,
controller: auth_default2.getCSRF.controller
});
route_default(fastify2, {
method: "post",
url: "/token",
middleware: {
validateCSRF: true
// Does have the authenticate middleware because all it does it checks if the access token is valid
// and if it is it will return the user data, this handles authorisatio itsself via the refresh token.
},
zodSchema: auth_default2.token.zodSchema,
swaggerSchema: auth_default2.token.swaggerSchema,
controller: auth_default2.token.controller
});
route_default(fastify2, {
method: "post",
url: "/login",
middleware: {
validateCSRF: true
},
zodSchema: auth_default2.login.zodSchema,
swaggerSchema: auth_default2.login.swaggerSchema,
controller: auth_default2.login.controller
});
route_default(fastify2, {
method: "post",
url: "/logout",
middleware: {
authenticate: true,
validateCSRF: true
},
zodSchema: auth_default2.logout.zodSchema,
swaggerSchema: auth_default2.logout.swaggerSchema,
controller: auth_default2.logout.controller
});
};
var auth_routes_default = authRoutes;
// src/schemas/permissions.ts
var permissions_default2 = {
getAll: {
body: void 0,
query: void 0,
params: void 0
}
};
// src/controllers/permissions/get-all.ts
var getAllController = async (request, reply) => {
const PermissionsFormatter2 = formatters_default.get("permissions");
reply.status(200).send(
build_response_default(request, {
data: PermissionsFormatter2.formatMultiple({
permissions: permission_groups_default
})
})
);
};
var get_all_default = {
controller: getAllController,
zodSchema: permissions_default2.getAll,
swaggerSchema: {
description: "Returns a list of all permissions available for users.",
tags: ["permissions"],
summary: "Get all permissions",
response: {
200: swagger_response_default({
type: 200,
data: {
type: "array",
items: PermissionsFormatter.swagger
}
})
}
}
};
// src/controllers/permissions/index.ts
var permissions_default3 = {
getAll: get_all_default
};
// src/routes/v1/api/permissions.routes.ts
var permissionRoutes = async (fastify2) => {
route_default(fastify2, {
method: "get",
url: "",
middleware: {
authenticate: true
},
swaggerSchema: permissions_default3.getAll.swaggerSchema,
zodSchema: permissions_default3.getAll.zodSchema,
controller: permissions_default3.getAll.controller
});
};
var permissions_routes_default = permissionRoutes;
// src/schemas/roles.ts
import z3 from "zod";
// src/schemas/default-query.ts
import z2 from "zod";
var filterOperators = z2.enum(["=", "%", "like", "ilike", "in", "not in", "<>", "is not", "is", "!="]).optional();
var filterSchemas = {
single: z2.object({
value: z2.union([z2.string(), z2.number()]),
operator: filterOperators
}),
union: z2.object({
value: z2.union([
z2.string(),
z2.array(z2.string()),
z2.number(),
z2.array(z2.number())
]),
operator: filterOperators
})
};
var default_query_default = {
filter: z2.object({}).optional(),
sort: z2.array(
z2.object({
key: z2.string(),
value: z2.enum(["asc", "desc"])
})
).optional(),
include: z2.array(z2.string()).optional(),
exclude: z2.array(z2.string()).optional(),
page: z2.number(),
perPage: z2.number()
};
// src/schemas/roles.ts
var roles_default = {
createSingle: {
body: z3.object({
name: z3.string().min(2),
description: z3.string().optional(),
permissions: z3.array(z3.string())
}),
query: void 0,
params: void 0
},
updateSingle: {
body: z3.object({
name: z3.string().min(2).optional(),
description: z3.string().optional(),
permissions: z3.array(z3.string()).optional()
}),
query: void 0,
params: z3.object({
id: z3.string()
})
},
deleteSingle: {
body: void 0,
query: void 0,
params: z3.object({
id: z3.string()
})
},
getMultiple: {
body: void 0,
query: z3.object({
filter: z3.object({
name: filterSchemas.single.optional(),
roleIds: filterSchemas.union.optional()
}).optional(),
sort: z3.array(
z3.object({
key: z3.enum(["createdAt", "name"]),
value: z3.enum(["asc", "desc"])
})
).optional(),
include: z3.array(z3.enum(["permissions"])).optional(),
exclude: default_query_default.exclude,
page: default_query_default.page,
perPage: default_query_default.perPage
}),
params: void 0
},
getSingle: {
body: void 0,
query: void 0,
params: z3.object({
id: z3.string()
})
}
};
// src/controllers/roles/create-single.ts
var createSingleController = async (request, reply) => {
const roleId = await service_wrapper_default(
request.server.services.role.createSingle,
{
transaction: true,
defaultError: {
type: "basic",
name: translations_default("route_roles_create_error_name"),
message: translations_default("route_roles_create_error_message")
}
}
)(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
name: request.body.name,
description: request.body.description,
permissions: request.body.permissions
}
);
if (roleId.error) throw new lucid_api_error_default(roleId.error);
const role = await service_wrapper_default(request.server.services.role.getSingle, {
transaction: false,
defaultError: {
type: "basic",
name: translations_default("route_roles_fetch_error_name"),
message: translations_default("route_roles_fetch_error_message")
}
})(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
id: roleId.data
}
);
if (role.error) throw new lucid_api_error_default(role.error);
reply.status(200).send(
build_response_default(request, {
data: role.data
})
);
};
var create_single_default = {
controller: createSingleController,
zodSchema: roles_default.createSingle,
swaggerSchema: {
description: "Create a single role with the given name and permission groups.",
tags: ["roles"],
summary: "Create a single role",
response: {
200: swagger_response_default({
type: 200,
data: RolesFormatter.swagger
})
},
body: {
type: "object",
properties: {
name: {
type: "string"
},
description: {
type: "string"
},
permissions: {
type: "array",
items: {
type: "string"
}
}
},
required: ["name", "permissions"]
},
headers: swagger_headers_default({
csrf: true
})
}
};
// src/controllers/roles/get-single.ts
var getSingleController = async (request, reply) => {
const role = await service_wrapper_default(request.server.services.role.getSingle, {
transaction: false,
defaultError: {
type: "basic",
name: translations_default("route_roles_fetch_error_name"),
message: translations_default("route_roles_fetch_error_message")
}
})(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
id: Number.parseInt(request.params.id, 10)
}
);
if (role.error) throw new lucid_api_error_default(role.error);
reply.status(200).send(
build_response_default(request, {
data: role.data
})
);
};
var get_single_default = {
controller: getSingleController,
zodSchema: roles_default.getSingle,
swaggerSchema: {
description: "Returns a single role based on the id URL paramater.",
tags: ["roles"],
summary: "Get a single role",
response: {
200: swagger_response_default({
type: 200,
data: RolesFormatter.swagger
})
}
}
};
// src/controllers/roles/get-multiple.ts
var getMultipleController = async (request, reply) => {
const role = await service_wrapper_default(request.server.services.role.getMultiple, {
transaction: false,
defaultError: {
type: "basic",
name: translations_default("route_roles_fetch_error_name"),
message: translations_default("route_roles_fetch_error_message")
}
})(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
query: request.query
}
);
if (role.error) throw new lucid_api_error_default(role.error);
reply.status(200).send(
build_response_default(request, {
data: role.data.data,
pagination: {
count: role.data.count,
page: request.query.page,
perPage: request.query.perPage
}
})
);
};
var get_multiple_default = {
controller: getMultipleController,
zodSchema: roles_default.getMultiple,
swaggerSchema: {
description: "Returns multiple roles based on the query parameters.",
tags: ["roles"],
summary: "Get multiple roles",
response: {
200: swagger_response_default({
type: 200,
data: {
type: "array",
items: RolesFormatter.swagger
},
paginated: true
})
},
querystring: swagger_query_string_default({
include: ["permissions"],
filters: [
{
key: "name"
},
{
key: "roleIds"
}
],
sorts: ["name", "createdAt"],
page: true,
perPage: true
})
}
};
// src/controllers/roles/delete-single.ts
var deleteSingleController = async (request, reply) => {
const deleteSingle7 = await service_wrapper_default(
request.server.services.role.deleteSingle,
{
transaction: true,
defaultError: {
type: "basic",
name: translations_default("route_roles_delete_error_name"),
message: translations_default("route_roles_delete_error_message")
}
}
)(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
id: Number.parseInt(request.params.id)
}
);
if (deleteSingle7.error) throw new lucid_api_error_default(deleteSingle7.error);
reply.status(204).send();
};
var delete_single_default = {
controller: deleteSingleController,
zodSchema: roles_default.deleteSingle,
swaggerSchema: {
description: "Delete a single role based on the given role id.",
tags: ["roles"],
summary: "Delete a single role",
response: {
204: swagger_response_default({
type: 204,
noPropertise: true
})
},
headers: swagger_headers_default({
csrf: true
})
}
};
// src/controllers/roles/update-single.ts
var updateSingleController = async (request, reply) => {
const updateSingel = await service_wrapper_default(
request.server.services.role.updateSingle,
{
transaction: true,
defaultError: {
type: "basic",
name: translations_default("route_roles_update_error_name"),
message: translations_default("route_roles_update_error_message")
}
}
)(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
id: Number.parseInt(request.params.id),
name: request.body.name,
description: request.body.description,
permissions: request.body.permissions
}
);
if (updateSingel.error) throw new lucid_api_error_default(updateSingel.error);
reply.status(204).send();
};
var update_single_default = {
controller: updateSingleController,
zodSchema: roles_default.updateSingle,
swaggerSchema: {
description: "Update a single role with the given name and permission groups.",
tags: ["roles"],
summary: "Update a single role",
response: {
204: swagger_response_default({
type: 204,
noPropertise: true
})
},
body: {
type: "object",
properties: {
name: {
type: "string"
},
description: {
type: "string"
},
permissions: {
type: "array",
items: {
type: "string"
}
}
}
},
headers: swagger_headers_default({
csrf: true
})
}
};
// src/controllers/roles/index.ts
var roles_default2 = {
createSingle: create_single_default,
getSingle: get_single_default,
getMultiple: get_multiple_default,
deleteSingle: delete_single_default,
updateSingle: update_single_default
};
// src/routes/v1/api/roles.routes.ts
var roleRoutes = async (fastify2) => {
route_default(fastify2, {
method: "post",
url: "",
middleware: {
authenticate: true,
validateCSRF: true
},
permissions: ["create_role"],
swaggerSchema: roles_default2.createSingle.swaggerSchema,
zodSchema: roles_default2.createSingle.zodSchema,
controller: roles_default2.createSingle.controller
});
route_default(fastify2, {
method: "get",
url: "/:id",
middleware: {
authenticate: true
},
swaggerSchema: roles_default2.getSingle.swaggerSchema,
zodSchema: roles_default2.getSingle.zodSchema,
controller: roles_default2.getSingle.controller
});
route_default(fastify2, {
method: "get",
url: "",
middleware: {
authenticate: true
},
swaggerSchema: roles_default2.getMultiple.swaggerSchema,
zodSchema: roles_default2.getMultiple.zodSchema,
controller: roles_default2.getMultiple.controller
});
route_default(fastify2, {
method: "delete",
url: "/:id",
middleware: {
authenticate: true,
validateCSRF: true
},
permissions: ["delete_role"],
swaggerSchema: roles_default2.deleteSingle.swaggerSchema,
zodSchema: roles_default2.deleteSingle.zodSchema,
controller: roles_default2.deleteSingle.controller
});
route_default(fastify2, {
method: "patch",
url: "/:id",
permissions: ["update_role"],
middleware: {
authenticate: true,
validateCSRF: true
},
swaggerSchema: roles_default2.updateSingle.swaggerSchema,
zodSchema: roles_default2.updateSingle.zodSchema,
controller: roles_default2.updateSingle.controller
});
};
var roles_routes_default = roleRoutes;
// src/schemas/account.ts
import z4 from "zod";
var account_default = {
getMe: {
body: void 0,
query: void 0,
params: void 0
},
updateMe: {
body: z4.object({
firstName: z4.string().optional(),
lastName: z4.string().optional(),
username: z4.string().min(3).optional(),
email: z4.string().email().optional(),
currentPassword: z4.string().optional(),
newPassword: z4.string().min(8).max(128).optional(),
passwordConfirmation: z4.string().min(8).max(128).optional()
}),
query: void 0,
params: void 0
},
sendResetPassword: {
body: z4.object({
email: z4.string().email()
}),
query: void 0,
params: void 0
},
verifyResetPassword: {
body: void 0,
query: void 0,
params: z4.object({
token: z4.string()
})
},
resetPassword: {
body: z4.object({
password: z4.string().min(8).max(128),
passwordConfirmation: z4.string().min(8).max(128)
}).refine((data) => data.password === data.passwordConfirmation, {
message: translations_default("please_ensure_passwords_match"),
path: ["passwordConfirmation"]
}),
query: void 0,
params: z4.object({
token: z4.string()
})
}
};
// src/controllers/account/update-me.ts
var updateMeController = async (request, reply) => {
const updateMe2 = await service_wrapper_default(
request.server.services.account.updateMe,
{
transaction: true,
defaultError: {
type: "basic",
name: translations_default("route_user_me_update_error_name"),
message: translations_default("route_user_me_update_error_message")
}
}
)(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
auth: request.auth,
firstName: request.body.firstName,
lastName: request.body.lastName,
username: request.body.username,
email: request.body.email,
currentPassword: request.body.currentPassword,
newPassword: request.body.newPassword,
passwordConfirmation: request.body.passwordConfirmation
}
);
if (updateMe2.error) throw new lucid_api_error_default(updateMe2.error);
reply.status(204).send();
};
var update_me_default = {
controller: updateMeController,
zodSchema: account_default.updateMe,
swaggerSchema: {
description: "Used to update the current authenticated users information",
tags: ["account"],
summary: "Update the authenticated user",
response: {
204: swagger_response_default({
type: 204,
noPropertise: true
})
},
body: {
type: "object",
properties: {
firstName: {
type: "string"
},
lastName: {
type: "string"
},
username: {
type: "string"
},
email: {
type: "string"
},
roleIds: {
type: "array",
items: {
type: "number"
}
}
}
},
headers: swagger_headers_default({
csrf: true
})
}
};
// src/controllers/account/get-me.ts
var getMeController = async (request, reply) => {
const user = await service_wrapper_default(request.server.services.user.getSingle, {
transaction: false,
defaultError: {
type: "basic",
name: translations_default("route_user_fetch_error_name"),
message: translations_default("route_user_fetch_error_message")
}
})(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
userId: request.auth.id
}
);
if (user.error) throw new lucid_api_error_default(user.error);
reply.status(200).send(
build_response_default(request, {
data: user.data
})
);
};
var get_me_default = {
controller: getMeController,
zodSchema: account_default.getMe,
swaggerSchema: {
description: "Returns user data based on the authenticated user",
tags: ["account"],
summary: "Returns user data based on the authenticated user",
response: {
200: swagger_response_default({
type: 200,
data: UsersFormatter.swagger
})
}
}
};
// src/controllers/account/send-reset-password.ts
var sendResetPasswordController = async (request, reply) => {
const resetPassword2 = await service_wrapper_default(
request.server.services.account.sendResetPassword,
{
transaction: true,
defaultError: {
type: "basic",
name: translations_default("route_send_password_reset_error_name"),
message: translations_default("route_send_password_reset_error_message")
}
}
)(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
email: request.body.email
}
);
if (resetPassword2.error) throw new lucid_api_error_default(resetPassword2.error);
reply.status(200).send(
build_response_default(request, {
data: resetPassword2.data
})
);
};
var send_reset_password_default = {
controller: sendResetPasswordController,
zodSchema: account_default.sendResetPassword,
swaggerSchema: {
description: "Sends a reset password email to the given users email",
tags: ["account"],
summary: "Send reset password email",
response: {
200: swagger_response_default({
type: 200,
data: {
type: "object",
properties: {
message: { type: "string" }
}
}
})
},
headers: swagger_headers_default({
csrf: true
})
}
};
// src/controllers/account/verify-reset-password.ts
var verifyResetPasswordController = async (request, reply) => {
const token = await service_wrapper_default(
request.server.services.user.token.getSingle,
{
transaction: false,
defaultError: {
type: "basic",
name: translations_default("route_verify_password_reset_error_name"),
message: translations_default("route_verify_password_reset_error_message")
}
}
)(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
tokenType: "password_reset",
token: request.params.token
}
);
if (token.error) throw new lucid_api_error_default(token.error);
reply.status(204).send();
};
var verify_reset_password_default = {
controller: verifyResetPasswordController,
zodSchema: account_default.verifyResetPassword,
swaggerSchema: {
description: "Verifies the password reset token is valid",
tags: ["account"],
summary: "Verify reset token",
response: {
204: swagger_response_default({
type: 204,
noPropertise: true
})
}
}
};
// src/controllers/account/reset-password.ts
var resetPasswordController = async (request, reply) => {
const resetPassword2 = await service_wrapper_default(
request.server.services.account.resetPassword,
{
transaction: true,
defaultError: {
type: "basic",
name: translations_default("route_reset_password_error_name"),
message: translations_default("route_reset_password_error_message")
}
}
)(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
token: request.params.token,
password: request.body.password
}
);
if (resetPassword2.error) throw new lucid_api_error_default(resetPassword2.error);
reply.status(204).send();
};
var reset_password_default = {
controller: resetPasswordController,
zodSchema: account_default.resetPassword,
swaggerSchema: {
description: "Resets the password for the user if the token is valid",
tags: ["account"],
summary: "Resets users password",
response: {
204: swagger_response_default({
type: 204,
noPropertise: true
})
},
headers: swagger_headers_default({
csrf: true
})
}
};
// src/controllers/account/index.ts
var account_default2 = {
updateMe: update_me_default,
getMe: get_me_default,
sendResetPassword: send_reset_password_default,
verifyResetPassword: verify_reset_password_default,
resetPassword: reset_password_default
};
// src/routes/v1/api/account.routes.ts
var accountRoutes = async (fastify2) => {
route_default(fastify2, {
method: "get",
url: "",
middleware: {
authenticate: true
},
zodSchema: account_default2.getMe.zodSchema,
swaggerSchema: account_default2.getMe.swaggerSchema,
controller: account_default2.getMe.controller
});
route_default(fastify2, {
method: "patch",
url: "",
middleware: {
authenticate: true,
validateCSRF: true
},
swaggerSchema: account_default2.updateMe.swaggerSchema,
zodSchema: account_default2.updateMe.zodSchema,
controller: account_default2.updateMe.controller
});
route_default(fastify2, {
method: "post",
url: "/reset-password",
middleware: {
validateCSRF: true
},
swaggerSchema: account_default2.sendResetPassword.swaggerSchema,
zodSchema: account_default2.sendResetPassword.zodSchema,
controller: account_default2.sendResetPassword.controller
});
route_default(fastify2, {
method: "get",
url: "/reset-password/:token",
swaggerSchema: account_default2.verifyResetPassword.swaggerSchema,
zodSchema: account_default2.verifyResetPassword.zodSchema,
controller: account_default2.verifyResetPassword.controller
});
route_default(fastify2, {
method: "patch",
url: "/reset-password/:token",
middleware: {
validateCSRF: true
},
swaggerSchema: account_default2.resetPassword.swaggerSchema,
zodSchema: account_default2.resetPassword.zodSchema,
controller: account_default2.resetPassword.controller
});
};
var account_routes_default = accountRoutes;
// src/schemas/locales.ts
import z5 from "zod";
var stringTranslations = z5.union([
z5.string(),
z5.record(z5.enum(constants_default.locales), z5.string())
]);
var locales_default = {
getSingle: {
query: void 0,
params: z5.object({
code: z5.string().min(2)
}),
body: void 0
},
getAll: {
query: void 0,
params: void 0,
body: void 0
},
client: {
getAll: {
query: void 0,
params: void 0,
body: void 0
}
}
};
// src/controllers/locales/client/get-all.ts
var getAllController2 = async (request, reply) => {
const locales = await service_wrapper_default(request.server.services.locale.getAll, {
transaction: false,
defaultError: {
type: "basic",
name: translations_default("route_locale_fetch_error_name"),
message: translations_default("route_locale_fetch_error_message")
}
})({
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
});
if (locales.error) throw new lucid_api_error_default(locales.error);
reply.status(200).send(
build_response_default(request, {
data: locales.data
})
);
};
var get_all_default2 = {
controller: getAllController2,
zodSchema: locales_default.client.getAll,
swaggerSchema: {
description: "Returns all enabled locales via the client integration.",
tags: ["client-integrations", "locales"],
summary: "Get all locales",
response: {
200: swagger_response_default({
type: 200,
data: {
type: "array",
items: LocalesFormatter.swagger
},
paginated: true
})
},
querystring: swagger_query_string_default({
sorts: ["code", "createdAt", "updatedAt"],
page: true,
perPage: true
})
}
};
// src/controllers/locales/client/index.ts
var client_default = {
getAll: get_all_default2
};
// src/controllers/locales/get-single.ts
var getSingleController2 = async (request, reply) => {
const localeRes = await service_wrapper_default(
request.server.services.locale.getSingle,
{
transaction: false,
defaultError: {
type: "basic",
name: translations_default("route_locale_fetch_error_name"),
message: translations_default("route_locale_fetch_error_message")
}
}
)(
{
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
},
{
code: request.params.code
}
);
if (localeRes.error) throw new lucid_api_error_default(localeRes.error);
reply.status(200).send(
build_response_default(request, {
data: localeRes.data
})
);
};
var get_single_default2 = {
controller: getSingleController2,
zodSchema: locales_default.getSingle,
swaggerSchema: {
description: "Returns a single locale based on the code URL parameter.",
tags: ["locales"],
summary: "Get a single locale",
response: {
200: swagger_response_default({
type: 200,
data: LocalesFormatter.swagger
})
}
}
};
// src/controllers/locales/get-all.ts
var getAllController3 = async (request, reply) => {
const locales = await service_wrapper_default(request.server.services.locale.getAll, {
transaction: false,
defaultError: {
type: "basic",
name: translations_default("route_locale_fetch_error_name"),
message: translations_default("route_locale_fetch_error_message")
}
})({
db: request.server.config.db.client,
config: request.server.config,
services: request.server.services
});
if (locales.error) throw new lucid_api_error_default(locales.error);
reply.status(200).send(
build_response_default(request, {
data: locales.data
})
);
};
var get_all_default3 = {
controller: getAllController3,
zodSchema: locales_default.getAll,
swaggerSchema: {
description: "Returns all locale.",
tags: ["locales"],
summary: "Get all locales",
response: {
200: swagger_response_default({
type: 200,
data: {
type: "array",
items: LocalesFormatter.swagger
},
paginated: true
})
},
querystring: swagger_query_string_default({
sorts: ["code", "createdAt", "updatedAt"],
page: true,
perPage: true
})
}
};
// src/controllers/locales/index.ts
var locales_default2 = {
client: client_default,
getSingle: get_single_default2,
getAll: get_all_default3
};
// src/routes/v1/api/locales.routes.ts
var localeRoutes = async (fastify2) => {
route_default(fastify2, {
method: "get",
url: "/:code",
middleware: {
authenticate: true
},
swaggerSchema: locales_default2.getSingle.swaggerSchema,
zodSchema: locales_default2.getSingle.zodSchema,
controller: locales_default2.getSingle.controller
});
route_default(fastify2, {
method: "get",
url: "",
middleware: {
authenticate: true
},
swaggerSchema: locales_default2.getAll.swaggerSchema,
zodSchema: locales_default2.getAll.zodSchema,
controller: locales_default2.g