@gzl10/nexus-backend 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-error-CKbYJQ9V.d.ts +136 -0
- package/dist/cli.js +521 -282
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +3 -135
- package/dist/index.js +632 -147
- package/dist/index.js.map +1 -1
- package/dist/main.js +632 -147
- package/dist/main.js.map +1 -1
- package/dist/migration-helpers/index.d.ts +63 -0
- package/dist/migration-helpers/index.js +12116 -0
- package/dist/migration-helpers/index.js.map +1 -0
- package/dist/testing/index.d.ts +81 -0
- package/dist/testing/index.js +1675 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +17 -3
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var init_package = __esm({
|
|
|
14
14
|
"package.json"() {
|
|
15
15
|
package_default = {
|
|
16
16
|
name: "@gzl10/nexus-backend",
|
|
17
|
-
version: "0.
|
|
17
|
+
version: "0.19.0",
|
|
18
18
|
description: "Backend as a Service (BaaS) with Express 5, Knex and CASL",
|
|
19
19
|
type: "module",
|
|
20
20
|
main: "./dist/index.js",
|
|
@@ -26,6 +26,14 @@ var init_package = __esm({
|
|
|
26
26
|
".": {
|
|
27
27
|
import: "./dist/index.js",
|
|
28
28
|
types: "./dist/index.d.ts"
|
|
29
|
+
},
|
|
30
|
+
"./testing": {
|
|
31
|
+
import: "./dist/testing/index.js",
|
|
32
|
+
types: "./dist/testing/index.d.ts"
|
|
33
|
+
},
|
|
34
|
+
"./migrations": {
|
|
35
|
+
import: "./dist/migration-helpers/index.js",
|
|
36
|
+
types: "./dist/migration-helpers/index.d.ts"
|
|
29
37
|
}
|
|
30
38
|
},
|
|
31
39
|
files: [
|
|
@@ -131,9 +139,11 @@ var init_package = __esm({
|
|
|
131
139
|
"@types/cookie-parser": "^1.4.10",
|
|
132
140
|
"@types/cors": "^2.8.19",
|
|
133
141
|
"@types/express": "^5.0.6",
|
|
142
|
+
"@types/express-serve-static-core": "^5.1.1",
|
|
134
143
|
"@types/jsonwebtoken": "^9.0.10",
|
|
135
144
|
"@types/multer": "^2.1.0",
|
|
136
145
|
"@types/nodemailer": "^7.0.11",
|
|
146
|
+
"@types/qs": "^6.15.0",
|
|
137
147
|
"@types/supertest": "^6.0.3",
|
|
138
148
|
"pino-pretty": "^13.1.3",
|
|
139
149
|
"socket.io-client": "^4.8.3",
|
|
@@ -142,11 +152,15 @@ var init_package = __esm({
|
|
|
142
152
|
vite: "^8.0.3"
|
|
143
153
|
},
|
|
144
154
|
peerDependencies: {
|
|
145
|
-
vite: ">=6.0.0"
|
|
155
|
+
vite: ">=6.0.0",
|
|
156
|
+
vitest: ">=3.0.0"
|
|
146
157
|
},
|
|
147
158
|
peerDependenciesMeta: {
|
|
148
159
|
vite: {
|
|
149
160
|
optional: true
|
|
161
|
+
},
|
|
162
|
+
vitest: {
|
|
163
|
+
optional: true
|
|
150
164
|
}
|
|
151
165
|
},
|
|
152
166
|
publishConfig: {
|
|
@@ -1048,6 +1062,14 @@ async function isWorkspacePackage(name) {
|
|
|
1048
1062
|
}
|
|
1049
1063
|
}
|
|
1050
1064
|
async function installPlugin(name, opts) {
|
|
1065
|
+
const projectPath2 = opts?.projectPath ?? process.cwd();
|
|
1066
|
+
const pkgPath = join2(projectPath2, "package.json");
|
|
1067
|
+
if (existsSync2(pkgPath)) {
|
|
1068
|
+
const pkg3 = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
1069
|
+
if (pkg3.name === "@gzl10/nexus-backend") {
|
|
1070
|
+
throw new Error("Cannot install plugins inside @gzl10/nexus-backend. Run this command from a Nexus project directory.");
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1051
1073
|
const isWorkspace = await isWorkspacePackage(name);
|
|
1052
1074
|
let pkg2;
|
|
1053
1075
|
if (opts?.version) {
|
|
@@ -1064,11 +1086,28 @@ async function installPlugin(name, opts) {
|
|
|
1064
1086
|
plugins[name] = { enabled: true };
|
|
1065
1087
|
writePluginsFile(plugins, filePath);
|
|
1066
1088
|
}
|
|
1089
|
+
function isPackageInstalled(name, projectPath2) {
|
|
1090
|
+
const base = projectPath2 || process.cwd();
|
|
1091
|
+
const pkgPath = join2(base, "package.json");
|
|
1092
|
+
try {
|
|
1093
|
+
const pkg2 = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
1094
|
+
return !!(pkg2.dependencies?.[name] || pkg2.devDependencies?.[name]);
|
|
1095
|
+
} catch {
|
|
1096
|
+
return false;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1067
1099
|
async function uninstallPlugin(name, projectPath2) {
|
|
1068
|
-
await execAsync(`pnpm remove ${name}`);
|
|
1069
1100
|
const filePath = getPluginsFilePath(projectPath2);
|
|
1070
1101
|
const plugins = readPluginsFile(filePath);
|
|
1071
|
-
|
|
1102
|
+
const isRegistered = name in plugins;
|
|
1103
|
+
const isInstalled = isPackageInstalled(name, projectPath2);
|
|
1104
|
+
if (!isRegistered && !isInstalled) {
|
|
1105
|
+
throw new Error(`Plugin ${shortPluginName(name)} is not installed`);
|
|
1106
|
+
}
|
|
1107
|
+
if (isInstalled) {
|
|
1108
|
+
await execAsync(`pnpm remove ${name}`);
|
|
1109
|
+
}
|
|
1110
|
+
if (isRegistered) {
|
|
1072
1111
|
delete plugins[name];
|
|
1073
1112
|
writePluginsFile(plugins, filePath);
|
|
1074
1113
|
}
|
|
@@ -2068,6 +2107,7 @@ var init_definitions = __esm({
|
|
|
2068
2107
|
};
|
|
2069
2108
|
mastersEntity = {
|
|
2070
2109
|
table: "masters",
|
|
2110
|
+
seedable: true,
|
|
2071
2111
|
routePrefix: "/",
|
|
2072
2112
|
label: { en: "Master", es: "Maestro" },
|
|
2073
2113
|
labelPlural: { en: "Masters", es: "Maestros" },
|
|
@@ -2099,14 +2139,15 @@ var init_definitions = __esm({
|
|
|
2099
2139
|
meta: { sortable: true, searchable: true }
|
|
2100
2140
|
}),
|
|
2101
2141
|
label: useLocalizedField({ label: { en: "Name", es: "Nombre" } }),
|
|
2102
|
-
order: orderField,
|
|
2142
|
+
order: { ...orderField, meta: { ...orderField.meta, showInDisplay: false } },
|
|
2103
2143
|
is_active: isActiveField,
|
|
2104
2144
|
metadata: useJsonField({
|
|
2105
2145
|
label: { en: "Metadata", es: "Metadatos" },
|
|
2106
2146
|
hint: {
|
|
2107
2147
|
en: "Type-specific fields (symbol, flag, etc.)",
|
|
2108
2148
|
es: "Campos espec\xEDficos del tipo"
|
|
2109
|
-
}
|
|
2149
|
+
},
|
|
2150
|
+
meta: { showInDisplay: false }
|
|
2110
2151
|
})
|
|
2111
2152
|
},
|
|
2112
2153
|
hooks: () => ({
|
|
@@ -2115,6 +2156,12 @@ var init_definitions = __esm({
|
|
|
2115
2156
|
data["id"] = `${data["type"]}:${data["code"]}`;
|
|
2116
2157
|
}
|
|
2117
2158
|
return data;
|
|
2159
|
+
},
|
|
2160
|
+
beforeUpdate: async (_id, data) => {
|
|
2161
|
+
if ("type" in data || "code" in data) {
|
|
2162
|
+
throw new Error("Cannot update type or code of a master record. Delete and recreate instead.");
|
|
2163
|
+
}
|
|
2164
|
+
return data;
|
|
2118
2165
|
}
|
|
2119
2166
|
}),
|
|
2120
2167
|
defaultSort: { field: "order", order: "asc" },
|
|
@@ -2166,7 +2213,7 @@ function createMasterRegistry() {
|
|
|
2166
2213
|
await ctx.db.knex("masters").insert(row).onConflict(["type", "code"]).merge();
|
|
2167
2214
|
}
|
|
2168
2215
|
} else {
|
|
2169
|
-
await ctx.db.knex("masters").insert(rows);
|
|
2216
|
+
await ctx.db.knex("masters").insert(rows).onConflict(["type", "code"]).ignore();
|
|
2170
2217
|
}
|
|
2171
2218
|
}
|
|
2172
2219
|
},
|
|
@@ -8599,15 +8646,12 @@ var init_document_types = __esm({
|
|
|
8599
8646
|
}
|
|
8600
8647
|
});
|
|
8601
8648
|
|
|
8602
|
-
// src/modules/masters/
|
|
8603
|
-
var
|
|
8604
|
-
var
|
|
8605
|
-
"src/modules/masters/
|
|
8649
|
+
// src/modules/masters/constants.ts
|
|
8650
|
+
var DEFAULT_MASTER_TYPES, PREDEFINED_MASTERS;
|
|
8651
|
+
var init_constants = __esm({
|
|
8652
|
+
"src/modules/masters/constants.ts"() {
|
|
8606
8653
|
"use strict";
|
|
8607
|
-
|
|
8608
|
-
init_registry2();
|
|
8609
|
-
init_definitions();
|
|
8610
|
-
init_registry2();
|
|
8654
|
+
DEFAULT_MASTER_TYPES = ["languages", "timezones"];
|
|
8611
8655
|
PREDEFINED_MASTERS = {
|
|
8612
8656
|
currencies: () => Promise.resolve().then(() => (init_currencies(), currencies_exports)).then((m2) => m2.default),
|
|
8613
8657
|
languages: () => Promise.resolve().then(() => (init_languages(), languages_exports)).then((m2) => m2.default),
|
|
@@ -8624,15 +8668,137 @@ var init_masters = __esm({
|
|
|
8624
8668
|
"phone-prefixes": () => Promise.resolve().then(() => (init_phone_prefixes(), phone_prefixes_exports)).then((m2) => m2.default),
|
|
8625
8669
|
"document-types": () => Promise.resolve().then(() => (init_document_types(), document_types_exports)).then((m2) => m2.default)
|
|
8626
8670
|
};
|
|
8671
|
+
}
|
|
8672
|
+
});
|
|
8673
|
+
|
|
8674
|
+
// src/modules/masters/actions/install-type.ts
|
|
8675
|
+
import { useSelectField as useSelectField2 } from "@gzl10/nexus-sdk/fields";
|
|
8676
|
+
var installTypeAction;
|
|
8677
|
+
var init_install_type = __esm({
|
|
8678
|
+
"src/modules/masters/actions/install-type.ts"() {
|
|
8679
|
+
"use strict";
|
|
8680
|
+
init_constants();
|
|
8681
|
+
installTypeAction = {
|
|
8682
|
+
key: "install-type",
|
|
8683
|
+
scope: "module",
|
|
8684
|
+
label: { en: "Install Master Type", es: "Instalar Tipo de Maestro" },
|
|
8685
|
+
icon: "mdi:database-plus",
|
|
8686
|
+
variant: "primary",
|
|
8687
|
+
output: {},
|
|
8688
|
+
input: {
|
|
8689
|
+
type: useSelectField2({
|
|
8690
|
+
label: { en: "Master Type", es: "Tipo de Maestro" },
|
|
8691
|
+
required: true,
|
|
8692
|
+
options: Object.keys(PREDEFINED_MASTERS).filter((t) => !DEFAULT_MASTER_TYPES.includes(t)).map((t) => ({
|
|
8693
|
+
value: t,
|
|
8694
|
+
label: t.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())
|
|
8695
|
+
}))
|
|
8696
|
+
})
|
|
8697
|
+
},
|
|
8698
|
+
handler: async (ctx, input) => {
|
|
8699
|
+
if (process.env["NODE_ENV"] === "production") {
|
|
8700
|
+
throw new ctx.core.errors.ForbiddenError("Master type management is only available in development");
|
|
8701
|
+
}
|
|
8702
|
+
const { type: type2 } = input;
|
|
8703
|
+
const loader = PREDEFINED_MASTERS[type2];
|
|
8704
|
+
if (!loader) {
|
|
8705
|
+
throw new ctx.core.errors.AppError(`Unknown predefined master type: ${type2}`, 400);
|
|
8706
|
+
}
|
|
8707
|
+
const existing = await ctx.db.knex("masters").where({ type: type2 }).first();
|
|
8708
|
+
if (existing) {
|
|
8709
|
+
throw new ctx.core.errors.ConflictError(`Master type "${type2}" is already installed`);
|
|
8710
|
+
}
|
|
8711
|
+
const entries = await loader();
|
|
8712
|
+
const rows = entries.map((entry, i) => ({
|
|
8713
|
+
id: `${type2}:${entry.code}`,
|
|
8714
|
+
type: type2,
|
|
8715
|
+
code: entry.code,
|
|
8716
|
+
label: JSON.stringify(typeof entry.label === "string" ? { en: entry.label } : entry.label),
|
|
8717
|
+
order: entry.order ?? i,
|
|
8718
|
+
is_active: entry.is_active ?? true,
|
|
8719
|
+
metadata: entry.metadata ? JSON.stringify(entry.metadata) : null
|
|
8720
|
+
}));
|
|
8721
|
+
await ctx.db.knex("masters").insert(rows).onConflict(["type", "code"]).ignore();
|
|
8722
|
+
return { installed: type2, count: rows.length };
|
|
8723
|
+
}
|
|
8724
|
+
};
|
|
8725
|
+
}
|
|
8726
|
+
});
|
|
8727
|
+
|
|
8728
|
+
// src/modules/masters/actions/uninstall-type.ts
|
|
8729
|
+
import { useTextField as useTextField3 } from "@gzl10/nexus-sdk/fields";
|
|
8730
|
+
var uninstallTypeAction;
|
|
8731
|
+
var init_uninstall_type = __esm({
|
|
8732
|
+
"src/modules/masters/actions/uninstall-type.ts"() {
|
|
8733
|
+
"use strict";
|
|
8734
|
+
init_constants();
|
|
8735
|
+
uninstallTypeAction = {
|
|
8736
|
+
key: "uninstall-type",
|
|
8737
|
+
scope: "module",
|
|
8738
|
+
label: { en: "Uninstall Master Type", es: "Desinstalar Tipo de Maestro" },
|
|
8739
|
+
icon: "mdi:database-minus",
|
|
8740
|
+
variant: "danger",
|
|
8741
|
+
output: {},
|
|
8742
|
+
confirm: {
|
|
8743
|
+
type: "simple",
|
|
8744
|
+
title: { en: "Uninstall Master Type", es: "Desinstalar Tipo de Maestro" },
|
|
8745
|
+
message: {
|
|
8746
|
+
en: "This will delete ALL records of the selected type. This action cannot be undone.",
|
|
8747
|
+
es: "Esto eliminar\xE1 TODOS los registros del tipo seleccionado. Esta acci\xF3n no se puede deshacer."
|
|
8748
|
+
}
|
|
8749
|
+
},
|
|
8750
|
+
input: {
|
|
8751
|
+
type: useTextField3({
|
|
8752
|
+
label: { en: "Type slug to uninstall", es: "Slug del tipo a desinstalar" },
|
|
8753
|
+
required: true,
|
|
8754
|
+
hint: {
|
|
8755
|
+
en: 'Enter the master type slug (e.g., "currencies", "countries")',
|
|
8756
|
+
es: 'Introduce el slug del tipo (ej: "currencies", "countries")'
|
|
8757
|
+
}
|
|
8758
|
+
})
|
|
8759
|
+
},
|
|
8760
|
+
handler: async (ctx, input) => {
|
|
8761
|
+
if (process.env["NODE_ENV"] === "production") {
|
|
8762
|
+
throw new ctx.core.errors.ForbiddenError("Master type management is only available in development");
|
|
8763
|
+
}
|
|
8764
|
+
const { type: type2 } = input;
|
|
8765
|
+
if (DEFAULT_MASTER_TYPES.includes(type2)) {
|
|
8766
|
+
throw new ctx.core.errors.AppError(`Cannot uninstall default master type "${type2}" (required by core)`, 400);
|
|
8767
|
+
}
|
|
8768
|
+
const existing = await ctx.db.knex("masters").where({ type: type2 }).first();
|
|
8769
|
+
if (!existing) {
|
|
8770
|
+
throw new ctx.core.errors.NotFoundError(`Master type "${type2}" is not installed`);
|
|
8771
|
+
}
|
|
8772
|
+
const deleted = await ctx.db.knex("masters").where({ type: type2 }).del();
|
|
8773
|
+
return { uninstalled: type2, count: deleted };
|
|
8774
|
+
}
|
|
8775
|
+
};
|
|
8776
|
+
}
|
|
8777
|
+
});
|
|
8778
|
+
|
|
8779
|
+
// src/modules/masters/index.ts
|
|
8780
|
+
var mastersModule;
|
|
8781
|
+
var init_masters = __esm({
|
|
8782
|
+
"src/modules/masters/index.ts"() {
|
|
8783
|
+
"use strict";
|
|
8784
|
+
init_definitions();
|
|
8785
|
+
init_registry2();
|
|
8786
|
+
init_constants();
|
|
8787
|
+
init_install_type();
|
|
8788
|
+
init_uninstall_type();
|
|
8789
|
+
init_definitions();
|
|
8790
|
+
init_registry2();
|
|
8791
|
+
init_constants();
|
|
8627
8792
|
mastersModule = {
|
|
8628
8793
|
name: "masters",
|
|
8629
8794
|
type: "core",
|
|
8630
|
-
label: { en: "
|
|
8795
|
+
label: { en: "Masters", es: "Maestros" },
|
|
8631
8796
|
icon: "mdi:database-outline",
|
|
8632
8797
|
description: { en: "Reference data catalogs", es: "Cat\xE1logos de datos de referencia" },
|
|
8633
|
-
category: "
|
|
8798
|
+
category: "settings",
|
|
8634
8799
|
routePrefix: "/masters",
|
|
8635
8800
|
definitions: [mastersEntity],
|
|
8801
|
+
actions: [installTypeAction, uninstallTypeAction],
|
|
8636
8802
|
init: (ctx) => {
|
|
8637
8803
|
if (!ctx.services.has("masters")) {
|
|
8638
8804
|
ctx.services.register("masters", createMasterRegistry());
|
|
@@ -8643,13 +8809,14 @@ var init_masters = __esm({
|
|
|
8643
8809
|
ctx.services.register("masters", createMasterRegistry());
|
|
8644
8810
|
}
|
|
8645
8811
|
const registry2 = ctx.services.get("masters");
|
|
8646
|
-
const
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
|
|
8650
|
-
|
|
8651
|
-
|
|
8652
|
-
|
|
8812
|
+
const existing = await ctx.db.knex("masters").first();
|
|
8813
|
+
if (!existing) {
|
|
8814
|
+
for (const type2 of DEFAULT_MASTER_TYPES) {
|
|
8815
|
+
const loader = PREDEFINED_MASTERS[type2];
|
|
8816
|
+
if (!loader) continue;
|
|
8817
|
+
const entries = await loader();
|
|
8818
|
+
registry2.register(type2, entries, { seed: "if-empty" });
|
|
8819
|
+
}
|
|
8653
8820
|
}
|
|
8654
8821
|
await registry2.seed(ctx);
|
|
8655
8822
|
}
|
|
@@ -8913,6 +9080,7 @@ function toPageDTO(page) {
|
|
|
8913
9080
|
dataSource: page.dataSource,
|
|
8914
9081
|
widgets: page.widgets,
|
|
8915
9082
|
component: page.component,
|
|
9083
|
+
contentEndpoint: page.contentEndpoint,
|
|
8916
9084
|
meta: page.meta,
|
|
8917
9085
|
layout: page.layout
|
|
8918
9086
|
};
|
|
@@ -9176,7 +9344,7 @@ var init_system_routes = __esm({
|
|
|
9176
9344
|
|
|
9177
9345
|
// src/modules/system/system.entity.ts
|
|
9178
9346
|
import * as os from "os";
|
|
9179
|
-
import { useIconField, useTextField as
|
|
9347
|
+
import { useIconField, useTextField as useTextField4, useSelectField as useSelectField3, useNumberField as useNumberField2, useCheckboxField, useTagsField, useNameField, useDescriptionField } from "@gzl10/nexus-sdk/fields";
|
|
9180
9348
|
var moduleEntity, osEntity;
|
|
9181
9349
|
var init_system_entity = __esm({
|
|
9182
9350
|
"src/modules/system/system.entity.ts"() {
|
|
@@ -9194,7 +9362,7 @@ var init_system_entity = __esm({
|
|
|
9194
9362
|
name: useNameField({
|
|
9195
9363
|
size: 50
|
|
9196
9364
|
}),
|
|
9197
|
-
label:
|
|
9365
|
+
label: useTextField4({
|
|
9198
9366
|
label: { en: "Label", es: "Etiqueta" },
|
|
9199
9367
|
size: 100,
|
|
9200
9368
|
nullable: false,
|
|
@@ -9202,7 +9370,7 @@ var init_system_entity = __esm({
|
|
|
9202
9370
|
}),
|
|
9203
9371
|
icon: useIconField({ label: { en: "Icon", es: "Icono" }, size: 50 }),
|
|
9204
9372
|
type: {
|
|
9205
|
-
...
|
|
9373
|
+
...useSelectField3({
|
|
9206
9374
|
label: { en: "Type", es: "Tipo" },
|
|
9207
9375
|
options: [
|
|
9208
9376
|
{ value: "core", label: { en: "Core", es: "Core" } },
|
|
@@ -9218,7 +9386,7 @@ var init_system_entity = __esm({
|
|
|
9218
9386
|
description: useDescriptionField({
|
|
9219
9387
|
mode: "text"
|
|
9220
9388
|
}),
|
|
9221
|
-
routePrefix:
|
|
9389
|
+
routePrefix: useTextField4({
|
|
9222
9390
|
label: { en: "Route", es: "Ruta" },
|
|
9223
9391
|
size: 50,
|
|
9224
9392
|
nullable: true
|
|
@@ -9276,14 +9444,14 @@ var init_system_entity = __esm({
|
|
|
9276
9444
|
order: 1,
|
|
9277
9445
|
refreshInterval: 5e3,
|
|
9278
9446
|
fields: {
|
|
9279
|
-
hostname:
|
|
9447
|
+
hostname: useTextField4({
|
|
9280
9448
|
label: { en: "Hostname", es: "Nombre de servidor" },
|
|
9281
9449
|
size: 100,
|
|
9282
9450
|
nullable: false,
|
|
9283
9451
|
inputProps: { order: 1 }
|
|
9284
9452
|
}),
|
|
9285
9453
|
platform: {
|
|
9286
|
-
...
|
|
9454
|
+
...useSelectField3({
|
|
9287
9455
|
label: { en: "Platform", es: "Plataforma" },
|
|
9288
9456
|
options: [
|
|
9289
9457
|
{ value: "darwin", label: { en: "macOS", es: "macOS" } },
|
|
@@ -9297,7 +9465,7 @@ var init_system_entity = __esm({
|
|
|
9297
9465
|
inputProps: { order: 2 }
|
|
9298
9466
|
},
|
|
9299
9467
|
arch: {
|
|
9300
|
-
...
|
|
9468
|
+
...useSelectField3({
|
|
9301
9469
|
label: { en: "Architecture", es: "Arquitectura" },
|
|
9302
9470
|
options: [
|
|
9303
9471
|
{ value: "x64", label: { en: "x64", es: "x64" } },
|
|
@@ -9310,7 +9478,7 @@ var init_system_entity = __esm({
|
|
|
9310
9478
|
inputProps: { order: 3 }
|
|
9311
9479
|
},
|
|
9312
9480
|
type: {
|
|
9313
|
-
...
|
|
9481
|
+
...useTextField4({
|
|
9314
9482
|
label: { en: "Type", es: "Tipo" },
|
|
9315
9483
|
size: 30,
|
|
9316
9484
|
nullable: false
|
|
@@ -9318,7 +9486,7 @@ var init_system_entity = __esm({
|
|
|
9318
9486
|
inputProps: { order: 4 }
|
|
9319
9487
|
},
|
|
9320
9488
|
release: {
|
|
9321
|
-
...
|
|
9489
|
+
...useTextField4({
|
|
9322
9490
|
label: { en: "Release", es: "Versi\xF3n" },
|
|
9323
9491
|
size: 50,
|
|
9324
9492
|
nullable: false
|
|
@@ -9341,7 +9509,7 @@ var init_system_entity = __esm({
|
|
|
9341
9509
|
inputProps: { order: 7, format: "duration" }
|
|
9342
9510
|
},
|
|
9343
9511
|
cpuModel: {
|
|
9344
|
-
...
|
|
9512
|
+
...useTextField4({
|
|
9345
9513
|
label: { en: "CPU Model", es: "Modelo de CPU" },
|
|
9346
9514
|
size: 100,
|
|
9347
9515
|
nullable: false
|
|
@@ -9407,7 +9575,7 @@ var init_system_entity = __esm({
|
|
|
9407
9575
|
});
|
|
9408
9576
|
|
|
9409
9577
|
// src/modules/system/migration-history.entity.ts
|
|
9410
|
-
import { useIdField as useIdField2, useTextField as
|
|
9578
|
+
import { useIdField as useIdField2, useTextField as useTextField5, useNumberField as useNumberField3, useSelectField as useSelectField4, useDatetimeField as useDatetimeField2, useTextareaField as useTextareaField2 } from "@gzl10/nexus-sdk/fields";
|
|
9411
9579
|
var migrationHistoryEntity;
|
|
9412
9580
|
var init_migration_history_entity = __esm({
|
|
9413
9581
|
"src/modules/system/migration-history.entity.ts"() {
|
|
@@ -9424,9 +9592,9 @@ var init_migration_history_entity = __esm({
|
|
|
9424
9592
|
calendarFrom: "executed_at",
|
|
9425
9593
|
fields: {
|
|
9426
9594
|
id: useIdField2(),
|
|
9427
|
-
name:
|
|
9595
|
+
name: useTextField5({ label: { en: "Migration Name", es: "Nombre de la Migraci\xF3n" }, required: true, size: 255, unique: true, meta: { sortable: true, searchable: true } }),
|
|
9428
9596
|
batch: useNumberField3({ label: { en: "Batch", es: "Lote" }, required: true, meta: { sortable: true } }),
|
|
9429
|
-
status:
|
|
9597
|
+
status: useSelectField4({
|
|
9430
9598
|
label: { en: "Status", es: "Estado" },
|
|
9431
9599
|
options: [
|
|
9432
9600
|
{ value: "running", label: { en: "Running", es: "Ejecutando" } },
|
|
@@ -9458,7 +9626,7 @@ var init_migration_history_entity = __esm({
|
|
|
9458
9626
|
});
|
|
9459
9627
|
|
|
9460
9628
|
// src/modules/system/env-config.entity.ts
|
|
9461
|
-
import { useTextField as
|
|
9629
|
+
import { useTextField as useTextField6, useSelectField as useSelectField5, useCheckboxField as useCheckboxField2 } from "@gzl10/nexus-sdk/fields";
|
|
9462
9630
|
function maskValue(value, sensitive) {
|
|
9463
9631
|
if (!sensitive) return value;
|
|
9464
9632
|
try {
|
|
@@ -9483,14 +9651,14 @@ var init_env_config_entity = __esm({
|
|
|
9483
9651
|
routePrefix: "/env-config",
|
|
9484
9652
|
defaultSort: { field: "category", order: "asc" },
|
|
9485
9653
|
fields: {
|
|
9486
|
-
name:
|
|
9654
|
+
name: useTextField6({
|
|
9487
9655
|
label: { en: "Variable", es: "Variable" },
|
|
9488
9656
|
size: 100,
|
|
9489
9657
|
nullable: false,
|
|
9490
9658
|
meta: { sortable: true, searchable: true }
|
|
9491
9659
|
}),
|
|
9492
9660
|
category: {
|
|
9493
|
-
...
|
|
9661
|
+
...useSelectField5({
|
|
9494
9662
|
label: { en: "Category", es: "Categor\xEDa" },
|
|
9495
9663
|
options: [
|
|
9496
9664
|
{ value: "server", label: { en: "Server", es: "Servidor" } },
|
|
@@ -9505,18 +9673,18 @@ var init_env_config_entity = __esm({
|
|
|
9505
9673
|
meta: { sortable: true }
|
|
9506
9674
|
})
|
|
9507
9675
|
},
|
|
9508
|
-
source:
|
|
9676
|
+
source: useTextField6({
|
|
9509
9677
|
label: { en: "Source", es: "Origen" },
|
|
9510
9678
|
size: 50,
|
|
9511
9679
|
nullable: false,
|
|
9512
9680
|
meta: { sortable: true }
|
|
9513
9681
|
}),
|
|
9514
|
-
value:
|
|
9682
|
+
value: useTextField6({
|
|
9515
9683
|
label: { en: "Value", es: "Valor" },
|
|
9516
9684
|
size: 255,
|
|
9517
9685
|
nullable: true
|
|
9518
9686
|
}),
|
|
9519
|
-
default:
|
|
9687
|
+
default: useTextField6({
|
|
9520
9688
|
label: { en: "Default", es: "Por defecto" },
|
|
9521
9689
|
size: 100,
|
|
9522
9690
|
nullable: true
|
|
@@ -10222,7 +10390,7 @@ var init_system = __esm({
|
|
|
10222
10390
|
});
|
|
10223
10391
|
|
|
10224
10392
|
// src/modules/ui-settings/ui-branding.entity.ts
|
|
10225
|
-
import { useTextField as
|
|
10393
|
+
import { useTextField as useTextField7, useImageField } from "@gzl10/nexus-sdk/fields";
|
|
10226
10394
|
var uiBrandingEntity;
|
|
10227
10395
|
var init_ui_branding_entity = __esm({
|
|
10228
10396
|
"src/modules/ui-settings/ui-branding.entity.ts"() {
|
|
@@ -10242,7 +10410,7 @@ var init_ui_branding_entity = __esm({
|
|
|
10242
10410
|
favicon: null
|
|
10243
10411
|
},
|
|
10244
10412
|
fields: {
|
|
10245
|
-
appName:
|
|
10413
|
+
appName: useTextField7({
|
|
10246
10414
|
label: { en: "App Name", es: "Nombre de la App" },
|
|
10247
10415
|
hint: { en: "Displayed in the header, browser tab and emails", es: "Se muestra en el header, pesta\xF1a del navegador y emails" },
|
|
10248
10416
|
size: 100,
|
|
@@ -10283,7 +10451,7 @@ var init_ui_branding_entity = __esm({
|
|
|
10283
10451
|
});
|
|
10284
10452
|
|
|
10285
10453
|
// src/modules/ui-settings/ui-theme.entity.ts
|
|
10286
|
-
import { useSelectField as
|
|
10454
|
+
import { useSelectField as useSelectField6, useColorField } from "@gzl10/nexus-sdk/fields";
|
|
10287
10455
|
var uiThemeEntity;
|
|
10288
10456
|
var init_ui_theme_entity = __esm({
|
|
10289
10457
|
"src/modules/ui-settings/ui-theme.entity.ts"() {
|
|
@@ -10308,7 +10476,7 @@ var init_ui_theme_entity = __esm({
|
|
|
10308
10476
|
},
|
|
10309
10477
|
fields: {
|
|
10310
10478
|
// === Typography ===
|
|
10311
|
-
font:
|
|
10479
|
+
font: useSelectField6({
|
|
10312
10480
|
label: { en: "Font", es: "Fuente" },
|
|
10313
10481
|
hint: { en: "Primary font for headings and UI elements", es: "Fuente principal para t\xEDtulos y elementos de interfaz" },
|
|
10314
10482
|
options: [
|
|
@@ -10321,7 +10489,7 @@ var init_ui_theme_entity = __esm({
|
|
|
10321
10489
|
]
|
|
10322
10490
|
}),
|
|
10323
10491
|
// === Theme & Colors ===
|
|
10324
|
-
theme:
|
|
10492
|
+
theme: useSelectField6({
|
|
10325
10493
|
label: { en: "Theme", es: "Tema" },
|
|
10326
10494
|
hint: { en: "System follows your device preferences", es: "Sistema sigue las preferencias de tu dispositivo" },
|
|
10327
10495
|
options: [
|
|
@@ -10330,7 +10498,7 @@ var init_ui_theme_entity = __esm({
|
|
|
10330
10498
|
{ value: "system", label: { en: "System", es: "Sistema" } }
|
|
10331
10499
|
]
|
|
10332
10500
|
}),
|
|
10333
|
-
dopamineTheme:
|
|
10501
|
+
dopamineTheme: useSelectField6({
|
|
10334
10502
|
label: { en: "Dopamine Theme", es: "Tema Dopamina" },
|
|
10335
10503
|
hint: { en: "Vibrant color presets optimized for light and dark modes (2025/2026 trends)", es: "Presets de colores vibrantes optimizados para modo claro y oscuro (tendencias 2025/2026)" },
|
|
10336
10504
|
options: [
|
|
@@ -10348,7 +10516,7 @@ var init_ui_theme_entity = __esm({
|
|
|
10348
10516
|
]
|
|
10349
10517
|
}),
|
|
10350
10518
|
// === Login Layout ===
|
|
10351
|
-
loginLayout:
|
|
10519
|
+
loginLayout: useSelectField6({
|
|
10352
10520
|
label: { en: "Login Layout", es: "Dise\xF1o de Login" },
|
|
10353
10521
|
hint: { en: "Visual layout for authentication pages", es: "Dise\xF1o visual para p\xE1ginas de autenticaci\xF3n" },
|
|
10354
10522
|
options: [
|
|
@@ -10379,7 +10547,7 @@ var init_ui_theme_entity = __esm({
|
|
|
10379
10547
|
});
|
|
10380
10548
|
|
|
10381
10549
|
// src/modules/ui-settings/ui-effects.entity.ts
|
|
10382
|
-
import { useSelectField as
|
|
10550
|
+
import { useSelectField as useSelectField7, useSwitchField as useSwitchField2 } from "@gzl10/nexus-sdk/fields";
|
|
10383
10551
|
var uiEffectsEntity;
|
|
10384
10552
|
var init_ui_effects_entity = __esm({
|
|
10385
10553
|
"src/modules/ui-settings/ui-effects.entity.ts"() {
|
|
@@ -10399,7 +10567,7 @@ var init_ui_effects_entity = __esm({
|
|
|
10399
10567
|
enableOrganicShapes: false
|
|
10400
10568
|
},
|
|
10401
10569
|
fields: {
|
|
10402
|
-
glassIntensity:
|
|
10570
|
+
glassIntensity: useSelectField7({
|
|
10403
10571
|
label: { en: "Glass Intensity", es: "Intensidad Glass" },
|
|
10404
10572
|
hint: { en: "Glassmorphism blur effect on cards and modals", es: "Efecto de desenfoque glassmorphism en cards y modales" },
|
|
10405
10573
|
options: [
|
|
@@ -10409,7 +10577,7 @@ var init_ui_effects_entity = __esm({
|
|
|
10409
10577
|
{ value: "high", label: { en: "High", es: "Alta" } }
|
|
10410
10578
|
]
|
|
10411
10579
|
}),
|
|
10412
|
-
borderStyle:
|
|
10580
|
+
borderStyle: useSelectField7({
|
|
10413
10581
|
label: { en: "Border Style", es: "Estilo de Bordes" },
|
|
10414
10582
|
hint: { en: "Corner radius for buttons, cards and inputs", es: "Radio de esquinas para botones, cards e inputs" },
|
|
10415
10583
|
options: [
|
|
@@ -10443,7 +10611,7 @@ var init_ui_effects_entity = __esm({
|
|
|
10443
10611
|
});
|
|
10444
10612
|
|
|
10445
10613
|
// src/modules/ui-settings/ui-accessibility.entity.ts
|
|
10446
|
-
import { useSelectField as
|
|
10614
|
+
import { useSelectField as useSelectField8, useSwitchField as useSwitchField3 } from "@gzl10/nexus-sdk/fields";
|
|
10447
10615
|
var uiAccessibilityEntity;
|
|
10448
10616
|
var init_ui_accessibility_entity = __esm({
|
|
10449
10617
|
"src/modules/ui-settings/ui-accessibility.entity.ts"() {
|
|
@@ -10462,7 +10630,7 @@ var init_ui_accessibility_entity = __esm({
|
|
|
10462
10630
|
highContrast: false
|
|
10463
10631
|
},
|
|
10464
10632
|
fields: {
|
|
10465
|
-
typographyScale:
|
|
10633
|
+
typographyScale: useSelectField8({
|
|
10466
10634
|
label: { en: "Typography Scale", es: "Escala Tipogr\xE1fica" },
|
|
10467
10635
|
hint: { en: "Adjusts font sizes for better readability (WCAG 1.4.4)", es: "Ajusta tama\xF1os de fuente para mejor legibilidad (WCAG 1.4.4)" },
|
|
10468
10636
|
options: [
|
|
@@ -11453,7 +11621,7 @@ var init_storage_service = __esm({
|
|
|
11453
11621
|
});
|
|
11454
11622
|
|
|
11455
11623
|
// src/modules/storage/storage.entity.ts
|
|
11456
|
-
import { useIdField as useIdField3, useTextField as
|
|
11624
|
+
import { useIdField as useIdField3, useTextField as useTextField8, useSelectField as useSelectField9, useUrlField, useNumberField as useNumberField4, useCheckboxField as useCheckboxField3, useJsonField as useJsonField2, useMetadataField, usePublicField } from "@gzl10/nexus-sdk/fields";
|
|
11457
11625
|
var DEFAULT_MAX_SIZE2, storageConfigEntity, storageFilesEntity;
|
|
11458
11626
|
var init_storage_entity = __esm({
|
|
11459
11627
|
"src/modules/storage/storage.entity.ts"() {
|
|
@@ -11479,7 +11647,7 @@ var init_storage_entity = __esm({
|
|
|
11479
11647
|
},
|
|
11480
11648
|
fields: {
|
|
11481
11649
|
id: useIdField3(),
|
|
11482
|
-
scope:
|
|
11650
|
+
scope: useTextField8({
|
|
11483
11651
|
label: { en: "Scope", es: "\xC1mbito" },
|
|
11484
11652
|
disabled: true,
|
|
11485
11653
|
size: 100,
|
|
@@ -11488,7 +11656,7 @@ var init_storage_entity = __esm({
|
|
|
11488
11656
|
hint: { en: "Unique identifier (e.g. default_filesystem, default_s3)", es: "Identificador \xFAnico (ej: default_filesystem, default_s3)" }
|
|
11489
11657
|
}),
|
|
11490
11658
|
driver: {
|
|
11491
|
-
...
|
|
11659
|
+
...useSelectField9({
|
|
11492
11660
|
label: { en: "Driver", es: "Controlador" },
|
|
11493
11661
|
required: true,
|
|
11494
11662
|
hint: { en: "Storage backend", es: "Backend de almacenamiento" },
|
|
@@ -11511,7 +11679,7 @@ var init_storage_entity = __esm({
|
|
|
11511
11679
|
nullable: false,
|
|
11512
11680
|
displayProps: { format: "bytes" }
|
|
11513
11681
|
}),
|
|
11514
|
-
allowed_mime_types:
|
|
11682
|
+
allowed_mime_types: useTextField8({
|
|
11515
11683
|
label: { en: "Allowed MIME Types", es: "Tipos MIME permitidos" },
|
|
11516
11684
|
hint: { en: "Allowed types separated by comma (e.g. image/*,application/pdf)", es: "Tipos permitidos separados por coma (ej: image/*,application/pdf)" },
|
|
11517
11685
|
size: 1e3,
|
|
@@ -11676,21 +11844,21 @@ var init_storage_entity = __esm({
|
|
|
11676
11844
|
],
|
|
11677
11845
|
fields: {
|
|
11678
11846
|
id: useIdField3(),
|
|
11679
|
-
filename:
|
|
11847
|
+
filename: useTextField8({
|
|
11680
11848
|
label: { en: "Original Filename", es: "Nombre original" },
|
|
11681
11849
|
required: true,
|
|
11682
11850
|
size: 255,
|
|
11683
11851
|
nullable: false,
|
|
11684
11852
|
meta: { sortable: true, searchable: true }
|
|
11685
11853
|
}),
|
|
11686
|
-
disk_filename:
|
|
11854
|
+
disk_filename: useTextField8({
|
|
11687
11855
|
label: { en: "Disk Filename", es: "Nombre en disco" },
|
|
11688
11856
|
required: true,
|
|
11689
11857
|
hidden: true,
|
|
11690
11858
|
size: 255,
|
|
11691
11859
|
nullable: false
|
|
11692
11860
|
}),
|
|
11693
|
-
mimetype:
|
|
11861
|
+
mimetype: useTextField8({
|
|
11694
11862
|
label: { en: "MIME Type", es: "Tipo MIME" },
|
|
11695
11863
|
required: true,
|
|
11696
11864
|
size: 100,
|
|
@@ -11706,14 +11874,14 @@ var init_storage_entity = __esm({
|
|
|
11706
11874
|
meta: { sortable: true },
|
|
11707
11875
|
displayProps: { format: "bytes" }
|
|
11708
11876
|
}),
|
|
11709
|
-
folder:
|
|
11877
|
+
folder: useTextField8({
|
|
11710
11878
|
label: { en: "Folder", es: "Carpeta" },
|
|
11711
11879
|
size: 100,
|
|
11712
11880
|
nullable: true,
|
|
11713
11881
|
index: true,
|
|
11714
11882
|
meta: { searchable: true }
|
|
11715
11883
|
}),
|
|
11716
|
-
scope:
|
|
11884
|
+
scope: useTextField8({
|
|
11717
11885
|
label: { en: "Storage Scope", es: "\xC1mbito de almacenamiento" },
|
|
11718
11886
|
hidden: true,
|
|
11719
11887
|
size: 50,
|
|
@@ -11724,7 +11892,7 @@ var init_storage_entity = __esm({
|
|
|
11724
11892
|
es: "\xC1mbito de configuraci\xF3n de almacenamiento usado para este archivo"
|
|
11725
11893
|
}
|
|
11726
11894
|
}),
|
|
11727
|
-
path:
|
|
11895
|
+
path: useTextField8({
|
|
11728
11896
|
label: { en: "Full Path", es: "Ruta completa" },
|
|
11729
11897
|
required: true,
|
|
11730
11898
|
hidden: true,
|
|
@@ -11737,13 +11905,13 @@ var init_storage_entity = __esm({
|
|
|
11737
11905
|
nullable: true,
|
|
11738
11906
|
meta: { exportable: true, showInDisplay: false }
|
|
11739
11907
|
}),
|
|
11740
|
-
thumbnail_path:
|
|
11908
|
+
thumbnail_path: useTextField8({
|
|
11741
11909
|
label: { en: "Thumbnail Path", es: "Ruta de miniatura" },
|
|
11742
11910
|
size: 500,
|
|
11743
11911
|
nullable: true,
|
|
11744
11912
|
meta: { showInDisplay: false }
|
|
11745
11913
|
}),
|
|
11746
|
-
hash:
|
|
11914
|
+
hash: useTextField8({
|
|
11747
11915
|
label: { en: "SHA256 Hash", es: "Hash SHA256" },
|
|
11748
11916
|
hidden: true,
|
|
11749
11917
|
size: 64,
|
|
@@ -12240,7 +12408,7 @@ var init_storage = __esm({
|
|
|
12240
12408
|
});
|
|
12241
12409
|
|
|
12242
12410
|
// src/modules/users/users.entity.ts
|
|
12243
|
-
import { useIdField as useIdField4, useSelectField as
|
|
12411
|
+
import { useIdField as useIdField4, useSelectField as useSelectField10, useEmailField, usePasswordField, useTextField as useTextField9, useDatetimeField as useDatetimeField3, useCheckboxField as useCheckboxField4, useImageField as useImageField2, useNameField as useNameField2, useMetadataField as useMetadataField2, useDescriptionField as useDescriptionField2 } from "@gzl10/nexus-sdk/fields";
|
|
12244
12412
|
import { z as z2 } from "zod";
|
|
12245
12413
|
var userEntity, roleEntity, userRoleEntity;
|
|
12246
12414
|
var init_users_entity = __esm({
|
|
@@ -12303,7 +12471,7 @@ var init_users_entity = __esm({
|
|
|
12303
12471
|
nullable: true,
|
|
12304
12472
|
meta: { exportable: true, showInForm: false, showInDisplay: false }
|
|
12305
12473
|
}),
|
|
12306
|
-
consent_version:
|
|
12474
|
+
consent_version: useTextField9({
|
|
12307
12475
|
label: { en: "Consent Version", es: "Versi\xF3n de consentimiento" },
|
|
12308
12476
|
hidden: true,
|
|
12309
12477
|
size: 20,
|
|
@@ -12314,7 +12482,7 @@ var init_users_entity = __esm({
|
|
|
12314
12482
|
label: { en: "Marketing Opt-in", es: "Aceptar marketing" },
|
|
12315
12483
|
meta: { exportable: true, showInForm: false, showInDisplay: false }
|
|
12316
12484
|
}),
|
|
12317
|
-
locale:
|
|
12485
|
+
locale: useSelectField10({
|
|
12318
12486
|
label: { en: "Language", es: "Idioma" },
|
|
12319
12487
|
options: [
|
|
12320
12488
|
{ value: "es", label: { en: "Spanish", es: "Espa\xF1ol" } },
|
|
@@ -12324,13 +12492,13 @@ var init_users_entity = __esm({
|
|
|
12324
12492
|
meta: { sortable: true },
|
|
12325
12493
|
defaultValue: "en"
|
|
12326
12494
|
}),
|
|
12327
|
-
timezone:
|
|
12495
|
+
timezone: useSelectField10({
|
|
12328
12496
|
label: { en: "Timezone", es: "Zona horaria" },
|
|
12329
12497
|
master: "timezones",
|
|
12330
12498
|
meta: { sortable: true },
|
|
12331
12499
|
defaultValue: "timezones:Europe/Madrid"
|
|
12332
12500
|
}),
|
|
12333
|
-
type:
|
|
12501
|
+
type: useSelectField10({
|
|
12334
12502
|
label: { en: "Type", es: "Tipo" },
|
|
12335
12503
|
defaultValue: "human",
|
|
12336
12504
|
options: [
|
|
@@ -12499,7 +12667,7 @@ var init_users_entity = __esm({
|
|
|
12499
12667
|
expose: false,
|
|
12500
12668
|
fields: {
|
|
12501
12669
|
id: useIdField4(),
|
|
12502
|
-
user_id:
|
|
12670
|
+
user_id: useSelectField10({
|
|
12503
12671
|
label: { en: "User", es: "Usuario" },
|
|
12504
12672
|
required: true,
|
|
12505
12673
|
table: "users",
|
|
@@ -12510,7 +12678,7 @@ var init_users_entity = __esm({
|
|
|
12510
12678
|
labelField: "name",
|
|
12511
12679
|
meta: { searchable: true }
|
|
12512
12680
|
}),
|
|
12513
|
-
role_id:
|
|
12681
|
+
role_id: useSelectField10({
|
|
12514
12682
|
label: { en: "Role", es: "Rol" },
|
|
12515
12683
|
required: true,
|
|
12516
12684
|
table: "roles",
|
|
@@ -13454,7 +13622,7 @@ var init_users = __esm({
|
|
|
13454
13622
|
});
|
|
13455
13623
|
|
|
13456
13624
|
// src/modules/auth/auth.entity.ts
|
|
13457
|
-
import { useIdField as useIdField5, useTextField as
|
|
13625
|
+
import { useIdField as useIdField5, useTextField as useTextField10, useSelectField as useSelectField11, useDatetimeField as useDatetimeField4, useEmailField as useEmailField2, useMetadataField as useMetadataField3, useExpiresAtField } from "@gzl10/nexus-sdk/fields";
|
|
13458
13626
|
var refreshTokenEntity, authIdentitiesEntity;
|
|
13459
13627
|
var init_auth_entity = __esm({
|
|
13460
13628
|
"src/modules/auth/auth.entity.ts"() {
|
|
@@ -13469,7 +13637,7 @@ var init_auth_entity = __esm({
|
|
|
13469
13637
|
expose: false,
|
|
13470
13638
|
fields: {
|
|
13471
13639
|
id: useIdField5(),
|
|
13472
|
-
token:
|
|
13640
|
+
token: useTextField10({
|
|
13473
13641
|
label: { en: "Token", es: "Token" },
|
|
13474
13642
|
hidden: true,
|
|
13475
13643
|
size: 255,
|
|
@@ -13496,14 +13664,14 @@ var init_auth_entity = __esm({
|
|
|
13496
13664
|
nullable: true,
|
|
13497
13665
|
meta: { sortable: true }
|
|
13498
13666
|
}),
|
|
13499
|
-
device_id:
|
|
13667
|
+
device_id: useTextField10({
|
|
13500
13668
|
label: { en: "Device ID", es: "ID de dispositivo" },
|
|
13501
13669
|
size: 64,
|
|
13502
13670
|
index: true,
|
|
13503
13671
|
nullable: true,
|
|
13504
13672
|
meta: { searchable: true }
|
|
13505
13673
|
}),
|
|
13506
|
-
device_name:
|
|
13674
|
+
device_name: useTextField10({
|
|
13507
13675
|
label: { en: "Device", es: "Dispositivo" },
|
|
13508
13676
|
size: 100,
|
|
13509
13677
|
nullable: true,
|
|
@@ -13535,7 +13703,7 @@ var init_auth_entity = __esm({
|
|
|
13535
13703
|
order: 5,
|
|
13536
13704
|
fields: {
|
|
13537
13705
|
id: useIdField5(),
|
|
13538
|
-
user_id:
|
|
13706
|
+
user_id: useSelectField11({
|
|
13539
13707
|
label: { en: "User", es: "Usuario" },
|
|
13540
13708
|
table: "users",
|
|
13541
13709
|
column: "id",
|
|
@@ -13547,7 +13715,7 @@ var init_auth_entity = __esm({
|
|
|
13547
13715
|
labelField: "name",
|
|
13548
13716
|
meta: { searchable: true }
|
|
13549
13717
|
}),
|
|
13550
|
-
provider:
|
|
13718
|
+
provider: useTextField10({
|
|
13551
13719
|
label: { en: "Provider", es: "Proveedor" },
|
|
13552
13720
|
required: true,
|
|
13553
13721
|
size: 50,
|
|
@@ -13556,7 +13724,7 @@ var init_auth_entity = __esm({
|
|
|
13556
13724
|
hint: { en: "e.g. pocketid, google, microsoft", es: "ej. pocketid, google, microsoft" },
|
|
13557
13725
|
meta: { sortable: true, searchable: true }
|
|
13558
13726
|
}),
|
|
13559
|
-
provider_user_id:
|
|
13727
|
+
provider_user_id: useTextField10({
|
|
13560
13728
|
label: { en: "Provider User ID", es: "ID de usuario del proveedor" },
|
|
13561
13729
|
required: true,
|
|
13562
13730
|
size: 255,
|
|
@@ -13851,7 +14019,7 @@ var init_auth_middleware = __esm({
|
|
|
13851
14019
|
});
|
|
13852
14020
|
|
|
13853
14021
|
// src/modules/auth/auth.pat.entity.ts
|
|
13854
|
-
import { useIdField as useIdField6, useTextField as
|
|
14022
|
+
import { useIdField as useIdField6, useTextField as useTextField11, useSelectField as useSelectField12, useDatetimeField as useDatetimeField5, useExpiresAtField as useExpiresAtField2 } from "@gzl10/nexus-sdk/fields";
|
|
13855
14023
|
var personalTokenEntity;
|
|
13856
14024
|
var init_auth_pat_entity = __esm({
|
|
13857
14025
|
"src/modules/auth/auth.pat.entity.ts"() {
|
|
@@ -13868,7 +14036,7 @@ var init_auth_pat_entity = __esm({
|
|
|
13868
14036
|
routePrefix: "/personal-tokens",
|
|
13869
14037
|
fields: {
|
|
13870
14038
|
id: useIdField6(),
|
|
13871
|
-
user_id:
|
|
14039
|
+
user_id: useSelectField12({
|
|
13872
14040
|
label: { en: "User", es: "Usuario" },
|
|
13873
14041
|
table: "users",
|
|
13874
14042
|
column: "id",
|
|
@@ -13880,7 +14048,7 @@ var init_auth_pat_entity = __esm({
|
|
|
13880
14048
|
labelField: "name",
|
|
13881
14049
|
meta: { searchable: true }
|
|
13882
14050
|
}),
|
|
13883
|
-
name:
|
|
14051
|
+
name: useTextField11({
|
|
13884
14052
|
label: { en: "Name", es: "Nombre" },
|
|
13885
14053
|
required: true,
|
|
13886
14054
|
size: 100,
|
|
@@ -13888,14 +14056,14 @@ var init_auth_pat_entity = __esm({
|
|
|
13888
14056
|
hint: { en: "Descriptive name for this token", es: "Nombre descriptivo para este token" },
|
|
13889
14057
|
meta: { searchable: true }
|
|
13890
14058
|
}),
|
|
13891
|
-
token_prefix:
|
|
14059
|
+
token_prefix: useTextField11({
|
|
13892
14060
|
label: { en: "Token", es: "Token" },
|
|
13893
14061
|
size: 20,
|
|
13894
14062
|
disabled: true,
|
|
13895
14063
|
nullable: false,
|
|
13896
14064
|
hint: { en: "Partial token for identification", es: "Token parcial para identificaci\xF3n" }
|
|
13897
14065
|
}),
|
|
13898
|
-
token_hash:
|
|
14066
|
+
token_hash: useTextField11({
|
|
13899
14067
|
label: { en: "Token Hash", es: "Hash del token" },
|
|
13900
14068
|
size: 64,
|
|
13901
14069
|
hidden: true,
|
|
@@ -13903,7 +14071,7 @@ var init_auth_pat_entity = __esm({
|
|
|
13903
14071
|
unique: true,
|
|
13904
14072
|
meta: { exportable: false }
|
|
13905
14073
|
}),
|
|
13906
|
-
scope:
|
|
14074
|
+
scope: useSelectField12({
|
|
13907
14075
|
label: { en: "Permission", es: "Permiso" },
|
|
13908
14076
|
required: true,
|
|
13909
14077
|
options: [
|
|
@@ -15659,7 +15827,7 @@ var init_mail_service = __esm({
|
|
|
15659
15827
|
});
|
|
15660
15828
|
|
|
15661
15829
|
// src/modules/mail/mail.entity.ts
|
|
15662
|
-
import { useIdField as useIdField7, useTextField as
|
|
15830
|
+
import { useIdField as useIdField7, useTextField as useTextField12, useSelectField as useSelectField13, useNumberField as useNumberField5, useSwitchField as useSwitchField4, useEmailField as useEmailField3, usePasswordField as usePasswordField2, useTextareaField as useTextareaField3, useTagsField as useTagsField2, useDatetimeField as useDatetimeField6 } from "@gzl10/nexus-sdk/fields";
|
|
15663
15831
|
import nodemailer2 from "nodemailer";
|
|
15664
15832
|
async function getMailConfigFromDB(ctx) {
|
|
15665
15833
|
const configService = ctx.services["config"];
|
|
@@ -15722,7 +15890,7 @@ var init_mail_entity = __esm({
|
|
|
15722
15890
|
},
|
|
15723
15891
|
fields: {
|
|
15724
15892
|
id: useIdField7(),
|
|
15725
|
-
host:
|
|
15893
|
+
host: useTextField12({
|
|
15726
15894
|
label: { en: "SMTP Host", es: "Host SMTP" },
|
|
15727
15895
|
size: 255,
|
|
15728
15896
|
nullable: false,
|
|
@@ -15742,7 +15910,7 @@ var init_mail_entity = __esm({
|
|
|
15742
15910
|
nullable: false,
|
|
15743
15911
|
hint: { en: "Default: SMTP_FROM env var", es: "Por defecto: variable SMTP_FROM" }
|
|
15744
15912
|
}),
|
|
15745
|
-
auth_user:
|
|
15913
|
+
auth_user: useTextField12({
|
|
15746
15914
|
label: { en: "Auth User", es: "Usuario de autenticaci\xF3n" },
|
|
15747
15915
|
size: 255,
|
|
15748
15916
|
nullable: true,
|
|
@@ -15774,12 +15942,12 @@ var init_mail_entity = __esm({
|
|
|
15774
15942
|
required: true,
|
|
15775
15943
|
validation: { format: "email" }
|
|
15776
15944
|
}),
|
|
15777
|
-
subject:
|
|
15945
|
+
subject: useTextField12({
|
|
15778
15946
|
label: { en: "Subject", es: "Asunto" },
|
|
15779
15947
|
required: true,
|
|
15780
15948
|
validation: { min: 1, max: 255 }
|
|
15781
15949
|
}),
|
|
15782
|
-
title:
|
|
15950
|
+
title: useTextField12({
|
|
15783
15951
|
label: { en: "Title", es: "T\xEDtulo" },
|
|
15784
15952
|
hint: { en: "Large title in email header", es: "T\xEDtulo grande en la cabecera del correo" }
|
|
15785
15953
|
}),
|
|
@@ -15923,20 +16091,20 @@ var init_mail_entity = __esm({
|
|
|
15923
16091
|
nullable: false,
|
|
15924
16092
|
meta: { sortable: true }
|
|
15925
16093
|
}),
|
|
15926
|
-
to:
|
|
16094
|
+
to: useTextField12({
|
|
15927
16095
|
label: { en: "Recipient(s)", es: "Destinatario(s)" },
|
|
15928
16096
|
size: 1e3,
|
|
15929
16097
|
nullable: false,
|
|
15930
16098
|
meta: { searchable: true }
|
|
15931
16099
|
}),
|
|
15932
|
-
subject:
|
|
16100
|
+
subject: useTextField12({
|
|
15933
16101
|
label: { en: "Subject", es: "Asunto" },
|
|
15934
16102
|
size: 255,
|
|
15935
16103
|
nullable: false,
|
|
15936
16104
|
meta: { searchable: true, sortable: true }
|
|
15937
16105
|
}),
|
|
15938
16106
|
status: {
|
|
15939
|
-
...
|
|
16107
|
+
...useSelectField13({
|
|
15940
16108
|
label: { en: "Status", es: "Estado" },
|
|
15941
16109
|
options: [
|
|
15942
16110
|
{ value: "pending", label: { en: "Pending", es: "Pendiente" } },
|
|
@@ -15950,7 +16118,7 @@ var init_mail_entity = __esm({
|
|
|
15950
16118
|
}),
|
|
15951
16119
|
validation: { enum: ["pending", "sent", "failed", "bounced"] }
|
|
15952
16120
|
},
|
|
15953
|
-
message_id:
|
|
16121
|
+
message_id: useTextField12({
|
|
15954
16122
|
label: { en: "Message ID", es: "ID de mensaje" },
|
|
15955
16123
|
hidden: true,
|
|
15956
16124
|
size: 255,
|
|
@@ -15960,7 +16128,7 @@ var init_mail_entity = __esm({
|
|
|
15960
16128
|
label: { en: "Error", es: "Error" },
|
|
15961
16129
|
nullable: true
|
|
15962
16130
|
}),
|
|
15963
|
-
sent_by:
|
|
16131
|
+
sent_by: useSelectField13({
|
|
15964
16132
|
label: { en: "Sent by", es: "Enviado por" },
|
|
15965
16133
|
table: "users",
|
|
15966
16134
|
column: "id",
|
|
@@ -16595,7 +16763,7 @@ var init_toggle_plugin_action = __esm({
|
|
|
16595
16763
|
});
|
|
16596
16764
|
|
|
16597
16765
|
// src/modules/plugins/plugins.entity.ts
|
|
16598
|
-
import { useTextField as
|
|
16766
|
+
import { useTextField as useTextField13, useSelectField as useSelectField14, useCheckboxField as useCheckboxField5 } from "@gzl10/nexus-sdk/fields";
|
|
16599
16767
|
import { OFFICIAL_PLUGINS } from "@gzl10/nexus-sdk";
|
|
16600
16768
|
var allowPluginManagement, pluginsEntity;
|
|
16601
16769
|
var init_plugins_entity = __esm({
|
|
@@ -16614,30 +16782,30 @@ var init_plugins_entity = __esm({
|
|
|
16614
16782
|
routePrefix: "/",
|
|
16615
16783
|
defaultSort: { field: "name", order: "asc" },
|
|
16616
16784
|
fields: {
|
|
16617
|
-
name:
|
|
16785
|
+
name: useTextField13({
|
|
16618
16786
|
label: { en: "Name", es: "Nombre" },
|
|
16619
16787
|
size: 50,
|
|
16620
16788
|
nullable: false,
|
|
16621
16789
|
meta: { sortable: true, searchable: true }
|
|
16622
16790
|
}),
|
|
16623
|
-
code:
|
|
16791
|
+
code: useTextField13({
|
|
16624
16792
|
label: { en: "Code", es: "C\xF3digo" },
|
|
16625
16793
|
size: 10,
|
|
16626
16794
|
nullable: false,
|
|
16627
16795
|
meta: { sortable: true }
|
|
16628
16796
|
}),
|
|
16629
|
-
label:
|
|
16797
|
+
label: useTextField13({
|
|
16630
16798
|
label: { en: "Label", es: "Etiqueta" },
|
|
16631
16799
|
size: 100,
|
|
16632
16800
|
nullable: false,
|
|
16633
16801
|
meta: { sortable: true }
|
|
16634
16802
|
}),
|
|
16635
|
-
version:
|
|
16803
|
+
version: useTextField13({
|
|
16636
16804
|
label: { en: "Version", es: "Versi\xF3n" },
|
|
16637
16805
|
size: 20,
|
|
16638
16806
|
nullable: false
|
|
16639
16807
|
}),
|
|
16640
|
-
category:
|
|
16808
|
+
category: useSelectField14({
|
|
16641
16809
|
label: { en: "Category", es: "Categor\xEDa" },
|
|
16642
16810
|
options: [
|
|
16643
16811
|
{ value: "content", label: { en: "Content", es: "Contenido" } },
|
|
@@ -16778,8 +16946,8 @@ var init_plugins = __esm({
|
|
|
16778
16946
|
// src/modules/audit/audit.entity.ts
|
|
16779
16947
|
import {
|
|
16780
16948
|
useIdField as useIdField8,
|
|
16781
|
-
useTextField as
|
|
16782
|
-
useSelectField as
|
|
16949
|
+
useTextField as useTextField14,
|
|
16950
|
+
useSelectField as useSelectField15,
|
|
16783
16951
|
useTextareaField as useTextareaField4,
|
|
16784
16952
|
useJsonField as useJsonField3,
|
|
16785
16953
|
useDatetimeField as useDatetimeField7,
|
|
@@ -16802,7 +16970,7 @@ var init_audit_entity = __esm({
|
|
|
16802
16970
|
fields: {
|
|
16803
16971
|
id: useIdField8(),
|
|
16804
16972
|
source: {
|
|
16805
|
-
...
|
|
16973
|
+
...useTextField14({
|
|
16806
16974
|
label: { en: "Source", es: "Origen" },
|
|
16807
16975
|
size: 100,
|
|
16808
16976
|
nullable: false,
|
|
@@ -16812,7 +16980,7 @@ var init_audit_entity = __esm({
|
|
|
16812
16980
|
validation: { min: 1, max: 100 }
|
|
16813
16981
|
},
|
|
16814
16982
|
action: {
|
|
16815
|
-
...
|
|
16983
|
+
...useTextField14({
|
|
16816
16984
|
label: { en: "Action", es: "Acci\xF3n" },
|
|
16817
16985
|
size: 100,
|
|
16818
16986
|
nullable: false,
|
|
@@ -16821,7 +16989,7 @@ var init_audit_entity = __esm({
|
|
|
16821
16989
|
}),
|
|
16822
16990
|
validation: { min: 1, max: 100 }
|
|
16823
16991
|
},
|
|
16824
|
-
actor_id:
|
|
16992
|
+
actor_id: useSelectField15({
|
|
16825
16993
|
label: { en: "Actor", es: "Actor" },
|
|
16826
16994
|
table: "users",
|
|
16827
16995
|
column: "id",
|
|
@@ -16838,20 +17006,20 @@ var init_audit_entity = __esm({
|
|
|
16838
17006
|
nullable: true,
|
|
16839
17007
|
meta: { searchable: true }
|
|
16840
17008
|
}),
|
|
16841
|
-
resource_type:
|
|
17009
|
+
resource_type: useTextField14({
|
|
16842
17010
|
label: { en: "Resource Type", es: "Tipo de recurso" },
|
|
16843
17011
|
size: 100,
|
|
16844
17012
|
nullable: true,
|
|
16845
17013
|
index: true,
|
|
16846
17014
|
meta: { searchable: true }
|
|
16847
17015
|
}),
|
|
16848
|
-
resource_id:
|
|
17016
|
+
resource_id: useTextField14({
|
|
16849
17017
|
label: { en: "Resource ID", es: "ID del recurso" },
|
|
16850
17018
|
size: 100,
|
|
16851
17019
|
nullable: true,
|
|
16852
17020
|
meta: { searchable: true }
|
|
16853
17021
|
}),
|
|
16854
|
-
ip_address:
|
|
17022
|
+
ip_address: useTextField14({
|
|
16855
17023
|
label: { en: "IP Address", es: "Direcci\xF3n IP" },
|
|
16856
17024
|
size: 45,
|
|
16857
17025
|
nullable: true,
|
|
@@ -17618,6 +17786,7 @@ var init_error_codes = __esm({
|
|
|
17618
17786
|
DB_CONSTRAINT_UNIQUE: "DB_CONSTRAINT_UNIQUE",
|
|
17619
17787
|
DB_CONSTRAINT_FK: "DB_CONSTRAINT_FK",
|
|
17620
17788
|
DB_CONNECTION_ERROR: "DB_CONNECTION_ERROR",
|
|
17789
|
+
DATABASE_NOT_READY: "DATABASE_NOT_READY",
|
|
17621
17790
|
// System
|
|
17622
17791
|
SYSTEM_INTERNAL_ERROR: "SYSTEM_INTERNAL_ERROR"
|
|
17623
17792
|
};
|
|
@@ -17941,7 +18110,7 @@ var init_env = __esm({
|
|
|
17941
18110
|
envSchema = z8.object({
|
|
17942
18111
|
NODE_ENV: z8.enum(["development", "production", "test"]).default("development"),
|
|
17943
18112
|
PORT: z8.coerce.number().default(3e3),
|
|
17944
|
-
CORS_ORIGIN: z8.string().default("
|
|
18113
|
+
CORS_ORIGIN: z8.string().default("*"),
|
|
17945
18114
|
BACKEND_URL: z8.string().optional(),
|
|
17946
18115
|
DATABASE_URL: z8.string().default("file:./dev.db"),
|
|
17947
18116
|
REDIS_URL: z8.string().url().optional(),
|
|
@@ -20210,10 +20379,31 @@ var init_base_service = __esm({
|
|
|
20210
20379
|
* Override in subclasses for entity-specific search
|
|
20211
20380
|
*/
|
|
20212
20381
|
applySearch(qb, search) {
|
|
20382
|
+
const searchTerm = `%${search}%`;
|
|
20383
|
+
const searchableFields = [];
|
|
20384
|
+
const fields = "fields" in this.definition ? this.definition.fields : {};
|
|
20385
|
+
for (const [name, field] of Object.entries(fields)) {
|
|
20386
|
+
if (field.meta?.searchable) {
|
|
20387
|
+
searchableFields.push(name);
|
|
20388
|
+
}
|
|
20389
|
+
}
|
|
20213
20390
|
if ("labelField" in this.definition && this.definition.labelField) {
|
|
20214
|
-
const
|
|
20215
|
-
|
|
20391
|
+
const lf = this.definition.labelField;
|
|
20392
|
+
if (!searchableFields.includes(lf)) {
|
|
20393
|
+
searchableFields.unshift(lf);
|
|
20394
|
+
}
|
|
20216
20395
|
}
|
|
20396
|
+
if (searchableFields.length === 0) return qb;
|
|
20397
|
+
qb.where(function() {
|
|
20398
|
+
for (const fieldName of searchableFields) {
|
|
20399
|
+
const field = fields[fieldName];
|
|
20400
|
+
if (field?.db?.type === "json") {
|
|
20401
|
+
this.orWhereRaw(`CAST(?? AS TEXT) LIKE ?`, [fieldName, searchTerm]);
|
|
20402
|
+
} else {
|
|
20403
|
+
this.orWhere(fieldName, "like", searchTerm);
|
|
20404
|
+
}
|
|
20405
|
+
}
|
|
20406
|
+
});
|
|
20217
20407
|
return qb;
|
|
20218
20408
|
}
|
|
20219
20409
|
/**
|
|
@@ -23687,15 +23877,6 @@ var init_ensure_system_tables = __esm({
|
|
|
23687
23877
|
}
|
|
23688
23878
|
});
|
|
23689
23879
|
|
|
23690
|
-
// src/cli/shared.ts
|
|
23691
|
-
import { consola } from "consola";
|
|
23692
|
-
var init_shared = __esm({
|
|
23693
|
-
"src/cli/shared.ts"() {
|
|
23694
|
-
"use strict";
|
|
23695
|
-
init_logger();
|
|
23696
|
-
}
|
|
23697
|
-
});
|
|
23698
|
-
|
|
23699
23880
|
// src/db/migration-sources.ts
|
|
23700
23881
|
function buildMigrationSources() {
|
|
23701
23882
|
const sources = [
|
|
@@ -23715,9 +23896,7 @@ function buildMigrationSources() {
|
|
|
23715
23896
|
var init_migration_sources = __esm({
|
|
23716
23897
|
"src/db/migration-sources.ts"() {
|
|
23717
23898
|
"use strict";
|
|
23718
|
-
init_shared();
|
|
23719
23899
|
init_paths();
|
|
23720
|
-
init_plugin_ops();
|
|
23721
23900
|
init_module_store();
|
|
23722
23901
|
}
|
|
23723
23902
|
});
|
|
@@ -24995,6 +25174,10 @@ function handleDbError(err) {
|
|
|
24995
25174
|
{ path: "foreignKey", message: "Foreign key constraint violation" }
|
|
24996
25175
|
]);
|
|
24997
25176
|
}
|
|
25177
|
+
if (code === "42P01" || code === "ER_NO_SUCH_TABLE" || dbErr.errno === 1146 || msg.includes("no such table")) {
|
|
25178
|
+
logger.error({ err }, "Database table not found \u2014 database may need migration or was wiped");
|
|
25179
|
+
throw new AppError({ code: ErrorCodes.DATABASE_NOT_READY, message: "Database not ready" }, 503);
|
|
25180
|
+
}
|
|
24998
25181
|
logger.error({ err }, "Unexpected database error");
|
|
24999
25182
|
throw new AppError({ code: ErrorCodes.SYSTEM_INTERNAL_ERROR, message: "Internal database error" }, 500);
|
|
25000
25183
|
}
|
|
@@ -27277,6 +27460,33 @@ async function setupModuleRoutes(app) {
|
|
|
27277
27460
|
}
|
|
27278
27461
|
}
|
|
27279
27462
|
const caslRegistry = /* @__PURE__ */ new Map();
|
|
27463
|
+
function mergeActionPermissions(existing, incoming) {
|
|
27464
|
+
const merged = { ...existing };
|
|
27465
|
+
for (const [role, perm] of Object.entries(incoming)) {
|
|
27466
|
+
if (!merged[role]) {
|
|
27467
|
+
merged[role] = perm;
|
|
27468
|
+
} else {
|
|
27469
|
+
const existingArr = Array.isArray(merged[role]) ? merged[role] : [merged[role]];
|
|
27470
|
+
const incomingArr = Array.isArray(perm) ? perm : [perm];
|
|
27471
|
+
merged[role] = [...existingArr, ...incomingArr];
|
|
27472
|
+
}
|
|
27473
|
+
}
|
|
27474
|
+
return merged;
|
|
27475
|
+
}
|
|
27476
|
+
function registerActionCasl(action) {
|
|
27477
|
+
const casl = action.casl;
|
|
27478
|
+
if (!casl || !("subject" in casl) || !casl.subject || !("permissions" in casl) || !casl.permissions) return;
|
|
27479
|
+
const subject2 = casl.subject;
|
|
27480
|
+
const existing = caslRegistry.get(subject2);
|
|
27481
|
+
if (existing) {
|
|
27482
|
+
existing.permissions = mergeActionPermissions(existing.permissions, casl.permissions);
|
|
27483
|
+
} else {
|
|
27484
|
+
caslRegistry.set(subject2, {
|
|
27485
|
+
subject: subject2,
|
|
27486
|
+
permissions: casl.permissions ?? {}
|
|
27487
|
+
});
|
|
27488
|
+
}
|
|
27489
|
+
}
|
|
27280
27490
|
for (const mod of modules) {
|
|
27281
27491
|
for (const def of mod.definitions ?? []) {
|
|
27282
27492
|
const casl = def.casl;
|
|
@@ -27286,6 +27496,12 @@ async function setupModuleRoutes(app) {
|
|
|
27286
27496
|
subject: casl.subject,
|
|
27287
27497
|
permissions: casl.permissions ?? {}
|
|
27288
27498
|
});
|
|
27499
|
+
for (const action of def.actions ?? []) {
|
|
27500
|
+
registerActionCasl(action);
|
|
27501
|
+
}
|
|
27502
|
+
}
|
|
27503
|
+
for (const action of mod.actions ?? []) {
|
|
27504
|
+
registerActionCasl(action);
|
|
27289
27505
|
}
|
|
27290
27506
|
}
|
|
27291
27507
|
setEntityDefinitions(caslRegistry);
|
|
@@ -27670,7 +27886,7 @@ function isFrpcInstalled() {
|
|
|
27670
27886
|
return false;
|
|
27671
27887
|
}
|
|
27672
27888
|
}
|
|
27673
|
-
function startTunnel(config3) {
|
|
27889
|
+
async function startTunnel(config3) {
|
|
27674
27890
|
if (tunnelProcess) return true;
|
|
27675
27891
|
if (!isFrpcInstalled()) {
|
|
27676
27892
|
logger.warn("frpc binary not found \u2014 tunnel disabled. Install with: brew install frp");
|
|
@@ -27682,24 +27898,49 @@ function startTunnel(config3) {
|
|
|
27682
27898
|
tunnelProcess = spawn("frpc", ["-c", tmpConfigPath], {
|
|
27683
27899
|
stdio: ["ignore", "pipe", "pipe"]
|
|
27684
27900
|
});
|
|
27685
|
-
|
|
27686
|
-
|
|
27687
|
-
|
|
27688
|
-
|
|
27689
|
-
|
|
27690
|
-
|
|
27691
|
-
|
|
27692
|
-
|
|
27693
|
-
|
|
27694
|
-
|
|
27695
|
-
|
|
27696
|
-
|
|
27697
|
-
|
|
27698
|
-
|
|
27901
|
+
outputBuffer = "";
|
|
27902
|
+
const stripAnsi = (s) => s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
27903
|
+
return new Promise((resolve2) => {
|
|
27904
|
+
let settled = false;
|
|
27905
|
+
const collectOutput = (data) => {
|
|
27906
|
+
const msg = stripAnsi(data.toString()).trim();
|
|
27907
|
+
if (!msg) return;
|
|
27908
|
+
outputBuffer += msg + "\n";
|
|
27909
|
+
logger.debug({ component: "tunnel" }, msg);
|
|
27910
|
+
if (!settled && msg.includes("start proxy success")) {
|
|
27911
|
+
settled = true;
|
|
27912
|
+
const url = getTunnelUrl(config3.subdomain, config3.server);
|
|
27913
|
+
logger.info({ url, component: "tunnel" }, `Tunnel active \u2192 ${url}`);
|
|
27914
|
+
resolve2(true);
|
|
27915
|
+
}
|
|
27916
|
+
};
|
|
27917
|
+
tunnelProcess.stdout?.on("data", collectOutput);
|
|
27918
|
+
tunnelProcess.stderr?.on("data", collectOutput);
|
|
27919
|
+
tunnelProcess.on("exit", (code) => {
|
|
27920
|
+
if (code !== 0 && code !== null) {
|
|
27921
|
+
const output = outputBuffer.trim();
|
|
27922
|
+
const hint = output.includes("authorization failed") || output.includes("auth failed") || output.includes("invalid token") ? " \u2014 check FRPC_TOKEN is correct" : output.includes("login to the server failed") ? ` \u2014 ${output.split("\n").pop()}` : "";
|
|
27923
|
+
logger.error(
|
|
27924
|
+
{ code, reason: output || void 0, component: "tunnel" },
|
|
27925
|
+
`frpc failed to start${hint}`
|
|
27926
|
+
);
|
|
27927
|
+
}
|
|
27928
|
+
tunnelProcess = null;
|
|
27929
|
+
outputBuffer = "";
|
|
27930
|
+
cleanupConfig();
|
|
27931
|
+
if (!settled) {
|
|
27932
|
+
settled = true;
|
|
27933
|
+
resolve2(false);
|
|
27934
|
+
}
|
|
27935
|
+
});
|
|
27936
|
+
setTimeout(() => {
|
|
27937
|
+
if (!settled) {
|
|
27938
|
+
settled = true;
|
|
27939
|
+
logger.warn({ component: "tunnel" }, "frpc connection timeout (5s) \u2014 tunnel may not be active");
|
|
27940
|
+
resolve2(false);
|
|
27941
|
+
}
|
|
27942
|
+
}, 5e3);
|
|
27699
27943
|
});
|
|
27700
|
-
const url = getTunnelUrl(config3.subdomain, config3.server);
|
|
27701
|
-
logger.info({ url, component: "tunnel" }, `Tunnel enabled \u2192 ${url}`);
|
|
27702
|
-
return true;
|
|
27703
27944
|
}
|
|
27704
27945
|
function stopTunnel() {
|
|
27705
27946
|
if (tunnelProcess) {
|
|
@@ -27717,13 +27958,244 @@ function cleanupConfig() {
|
|
|
27717
27958
|
tmpConfigPath = null;
|
|
27718
27959
|
}
|
|
27719
27960
|
}
|
|
27720
|
-
var tunnelProcess, tmpConfigPath;
|
|
27961
|
+
var tunnelProcess, tmpConfigPath, outputBuffer;
|
|
27721
27962
|
var init_tunnel = __esm({
|
|
27722
27963
|
"src/core/tunnel.ts"() {
|
|
27723
27964
|
"use strict";
|
|
27724
27965
|
init_core();
|
|
27725
27966
|
tunnelProcess = null;
|
|
27726
27967
|
tmpConfigPath = null;
|
|
27968
|
+
outputBuffer = "";
|
|
27969
|
+
}
|
|
27970
|
+
});
|
|
27971
|
+
|
|
27972
|
+
// src/cli/shared.ts
|
|
27973
|
+
import { consola } from "consola";
|
|
27974
|
+
function initCli() {
|
|
27975
|
+
const config3 = getLoggerConfig();
|
|
27976
|
+
initLoggerService({ ...config3, level: "error", sentry: void 0 });
|
|
27977
|
+
setLoggerInstance(getPinoLogger());
|
|
27978
|
+
}
|
|
27979
|
+
var init_shared = __esm({
|
|
27980
|
+
"src/cli/shared.ts"() {
|
|
27981
|
+
"use strict";
|
|
27982
|
+
init_logger();
|
|
27983
|
+
}
|
|
27984
|
+
});
|
|
27985
|
+
|
|
27986
|
+
// src/cli/migrate-commands.ts
|
|
27987
|
+
import { readFileSync as readFileSync8, existsSync as existsSync12 } from "fs";
|
|
27988
|
+
import { join as join14 } from "path";
|
|
27989
|
+
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
27990
|
+
import Table from "cli-table3";
|
|
27991
|
+
import { consola as consola2 } from "consola";
|
|
27992
|
+
async function loadSelfPlugin() {
|
|
27993
|
+
const projectPath2 = getProjectPath();
|
|
27994
|
+
const pkgPath = join14(projectPath2, "package.json");
|
|
27995
|
+
if (!existsSync12(pkgPath)) return;
|
|
27996
|
+
try {
|
|
27997
|
+
const pkg2 = JSON.parse(readFileSync8(pkgPath, "utf-8"));
|
|
27998
|
+
const pkgName = pkg2?.name;
|
|
27999
|
+
if (!pkgName || !/nexus-plugin-/.test(pkgName)) return;
|
|
28000
|
+
const srcEntry = join14(projectPath2, "src", "index.ts");
|
|
28001
|
+
const distEntry = join14(projectPath2, "dist", "index.js");
|
|
28002
|
+
if (existsSync12(srcEntry)) {
|
|
28003
|
+
try {
|
|
28004
|
+
const { tsImport } = await import("tsx/esm/api");
|
|
28005
|
+
const mod = await tsImport(
|
|
28006
|
+
pathToFileURL3(srcEntry).href,
|
|
28007
|
+
import.meta.url
|
|
28008
|
+
);
|
|
28009
|
+
const manifest = extractPluginManifest(mod);
|
|
28010
|
+
if (manifest) {
|
|
28011
|
+
if (!manifest.migrationsDir) {
|
|
28012
|
+
manifest.migrationsDir = join14(projectPath2, "migrations");
|
|
28013
|
+
}
|
|
28014
|
+
registerPlugin(manifest);
|
|
28015
|
+
return;
|
|
28016
|
+
}
|
|
28017
|
+
} catch (err) {
|
|
28018
|
+
console.error(` \u26A0 Failed to load plugin src/index.ts: ${err.message}`);
|
|
28019
|
+
}
|
|
28020
|
+
}
|
|
28021
|
+
if (existsSync12(distEntry)) {
|
|
28022
|
+
try {
|
|
28023
|
+
const mod = await import(pathToFileURL3(distEntry).href);
|
|
28024
|
+
const manifest = extractPluginManifest(mod);
|
|
28025
|
+
if (manifest) {
|
|
28026
|
+
if (!manifest.migrationsDir) {
|
|
28027
|
+
manifest.migrationsDir = join14(projectPath2, "migrations");
|
|
28028
|
+
}
|
|
28029
|
+
registerPlugin(manifest);
|
|
28030
|
+
return;
|
|
28031
|
+
}
|
|
28032
|
+
} catch (err) {
|
|
28033
|
+
console.error(` \u26A0 Failed to load plugin dist/index.js: ${err.message}`);
|
|
28034
|
+
}
|
|
28035
|
+
}
|
|
28036
|
+
} catch {
|
|
28037
|
+
}
|
|
28038
|
+
}
|
|
28039
|
+
async function loadModulesForMigration() {
|
|
28040
|
+
loadCoreModules();
|
|
28041
|
+
await loadSelfPlugin();
|
|
28042
|
+
const config3 = await loadNexusConfig();
|
|
28043
|
+
if (config3.plugins?.length) {
|
|
28044
|
+
const sorted = topologicalSortPlugins(config3.plugins);
|
|
28045
|
+
for (const plugin of sorted) {
|
|
28046
|
+
registerPlugin(plugin);
|
|
28047
|
+
}
|
|
28048
|
+
}
|
|
28049
|
+
const coreNames = new Set(getOrderedModules().map((m2) => m2.name));
|
|
28050
|
+
for (const mod of config3.modules ?? []) {
|
|
28051
|
+
if (!coreNames.has(mod.name)) {
|
|
28052
|
+
registerModule(mod, { source: "standalone" });
|
|
28053
|
+
}
|
|
28054
|
+
}
|
|
28055
|
+
}
|
|
28056
|
+
var init_migrate_commands = __esm({
|
|
28057
|
+
"src/cli/migrate-commands.ts"() {
|
|
28058
|
+
"use strict";
|
|
28059
|
+
init_database();
|
|
28060
|
+
init_engine();
|
|
28061
|
+
init_load_config();
|
|
28062
|
+
init_shared();
|
|
28063
|
+
init_paths();
|
|
28064
|
+
init_connection();
|
|
28065
|
+
init_ensure_system_tables();
|
|
28066
|
+
init_migration_generator();
|
|
28067
|
+
init_migration_runner();
|
|
28068
|
+
}
|
|
28069
|
+
});
|
|
28070
|
+
|
|
28071
|
+
// src/cli/seed-commands.ts
|
|
28072
|
+
var seed_commands_exports = {};
|
|
28073
|
+
__export(seed_commands_exports, {
|
|
28074
|
+
handleSeedExport: () => handleSeedExport,
|
|
28075
|
+
importSeedFiles: () => importSeedFiles
|
|
28076
|
+
});
|
|
28077
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync6, writeFileSync as writeFileSync3, readdirSync as readdirSync2, readFileSync as readFileSync9 } from "fs";
|
|
28078
|
+
import { join as join15, basename as basename4 } from "path";
|
|
28079
|
+
import { consola as consola3 } from "consola";
|
|
28080
|
+
function deserializeJsonFields(record, fields) {
|
|
28081
|
+
const result = { ...record };
|
|
28082
|
+
for (const [name, field] of Object.entries(fields)) {
|
|
28083
|
+
if (field.db?.type === "json" && typeof result[name] === "string") {
|
|
28084
|
+
try {
|
|
28085
|
+
result[name] = JSON.parse(result[name]);
|
|
28086
|
+
} catch {
|
|
28087
|
+
}
|
|
28088
|
+
}
|
|
28089
|
+
}
|
|
28090
|
+
return result;
|
|
28091
|
+
}
|
|
28092
|
+
function serializeJsonFields(record, fields) {
|
|
28093
|
+
const result = { ...record };
|
|
28094
|
+
for (const [name, field] of Object.entries(fields)) {
|
|
28095
|
+
if (field.db?.type === "json" && typeof result[name] === "object" && result[name] !== null) {
|
|
28096
|
+
result[name] = JSON.stringify(result[name]);
|
|
28097
|
+
}
|
|
28098
|
+
}
|
|
28099
|
+
return result;
|
|
28100
|
+
}
|
|
28101
|
+
async function handleSeedExport(entity) {
|
|
28102
|
+
initCli();
|
|
28103
|
+
await loadModulesForMigration();
|
|
28104
|
+
const db2 = getDb();
|
|
28105
|
+
try {
|
|
28106
|
+
const modules = getOrderedModules();
|
|
28107
|
+
const seedDir = join15(getProjectPath(), "data", "seeds");
|
|
28108
|
+
const seedableEntities = [];
|
|
28109
|
+
for (const mod of modules) {
|
|
28110
|
+
for (const def of mod.definitions ?? []) {
|
|
28111
|
+
if (!("seedable" in def) || !def.seedable) continue;
|
|
28112
|
+
if (entity && def.table !== entity) continue;
|
|
28113
|
+
seedableEntities.push({
|
|
28114
|
+
module: mod.name,
|
|
28115
|
+
table: def.table,
|
|
28116
|
+
fields: def.fields
|
|
28117
|
+
});
|
|
28118
|
+
}
|
|
28119
|
+
}
|
|
28120
|
+
if (seedableEntities.length === 0) {
|
|
28121
|
+
if (entity) {
|
|
28122
|
+
consola3.warn(`No seedable entity found with table "${entity}"`);
|
|
28123
|
+
} else {
|
|
28124
|
+
consola3.warn("No seedable entities found");
|
|
28125
|
+
}
|
|
28126
|
+
return;
|
|
28127
|
+
}
|
|
28128
|
+
if (!existsSync13(seedDir)) {
|
|
28129
|
+
mkdirSync6(seedDir, { recursive: true });
|
|
28130
|
+
}
|
|
28131
|
+
for (const { module: modName, table, fields } of seedableEntities) {
|
|
28132
|
+
const rows = await db2(table).orderBy("id");
|
|
28133
|
+
if (rows.length === 0) {
|
|
28134
|
+
consola3.info(`${table}: no records, skipping`);
|
|
28135
|
+
continue;
|
|
28136
|
+
}
|
|
28137
|
+
const exported = rows.map(
|
|
28138
|
+
(row) => deserializeJsonFields(row, fields)
|
|
28139
|
+
);
|
|
28140
|
+
const filePath = join15(seedDir, `${table}.json`);
|
|
28141
|
+
writeFileSync3(filePath, JSON.stringify(exported, null, 2) + "\n", "utf-8");
|
|
28142
|
+
consola3.success(`${table}: exported ${rows.length} records to data/seeds/${table}.json (module: ${modName})`);
|
|
28143
|
+
}
|
|
28144
|
+
} catch (err) {
|
|
28145
|
+
consola3.error("Seed export failed:", err);
|
|
28146
|
+
} finally {
|
|
28147
|
+
await db2.destroy();
|
|
28148
|
+
process.exit(0);
|
|
28149
|
+
}
|
|
28150
|
+
}
|
|
28151
|
+
async function importSeedFiles(db2, modules, logger2) {
|
|
28152
|
+
const seedDir = join15(getProjectPath(), "data", "seeds");
|
|
28153
|
+
if (!existsSync13(seedDir)) return;
|
|
28154
|
+
const files = readdirSync2(seedDir).filter((f) => f.endsWith(".json"));
|
|
28155
|
+
if (files.length === 0) return;
|
|
28156
|
+
const seedableDefs = /* @__PURE__ */ new Map();
|
|
28157
|
+
for (const mod of modules) {
|
|
28158
|
+
for (const rawDef of mod.definitions ?? []) {
|
|
28159
|
+
const def = rawDef;
|
|
28160
|
+
if (!def["seedable"] || !def["table"] || !def["fields"]) continue;
|
|
28161
|
+
seedableDefs.set(
|
|
28162
|
+
def["table"],
|
|
28163
|
+
{ fields: def["fields"], module: mod.name }
|
|
28164
|
+
);
|
|
28165
|
+
}
|
|
28166
|
+
}
|
|
28167
|
+
for (const file of files) {
|
|
28168
|
+
const table = basename4(file, ".json");
|
|
28169
|
+
const defInfo = seedableDefs.get(table);
|
|
28170
|
+
if (!defInfo) {
|
|
28171
|
+
logger2.debug(`data/seeds/${file}: skipped (entity "${table}" is not seedable)`);
|
|
28172
|
+
continue;
|
|
28173
|
+
}
|
|
28174
|
+
const filePath = join15(seedDir, file);
|
|
28175
|
+
const raw = readFileSync9(filePath, "utf-8");
|
|
28176
|
+
let records;
|
|
28177
|
+
try {
|
|
28178
|
+
records = JSON.parse(raw);
|
|
28179
|
+
} catch {
|
|
28180
|
+
logger2.info(`data/seeds/${file}: skipped (invalid JSON)`);
|
|
28181
|
+
continue;
|
|
28182
|
+
}
|
|
28183
|
+
if (!Array.isArray(records) || records.length === 0) continue;
|
|
28184
|
+
const rows = records.map((r) => serializeJsonFields(r, defInfo.fields));
|
|
28185
|
+
for (const row of rows) {
|
|
28186
|
+
await db2(table).insert(row).onConflict("id").merge();
|
|
28187
|
+
}
|
|
28188
|
+
logger2.info(`Seeded ${rows.length} records into ${table} from data/seeds/${file}`);
|
|
28189
|
+
}
|
|
28190
|
+
}
|
|
28191
|
+
var init_seed_commands = __esm({
|
|
28192
|
+
"src/cli/seed-commands.ts"() {
|
|
28193
|
+
"use strict";
|
|
28194
|
+
init_engine();
|
|
28195
|
+
init_paths();
|
|
28196
|
+
init_connection();
|
|
28197
|
+
init_shared();
|
|
28198
|
+
init_migrate_commands();
|
|
27727
28199
|
}
|
|
27728
28200
|
});
|
|
27729
28201
|
|
|
@@ -28046,6 +28518,15 @@ ${dirs}`);
|
|
|
28046
28518
|
}
|
|
28047
28519
|
const allDefinitions = modules.flatMap((m2) => m2.definitions ?? []);
|
|
28048
28520
|
await createMemoryTables(allDefinitions);
|
|
28521
|
+
try {
|
|
28522
|
+
const { importSeedFiles: importSeedFiles2 } = await Promise.resolve().then(() => (init_seed_commands(), seed_commands_exports));
|
|
28523
|
+
await importSeedFiles2(ctx.db.knex, modules, {
|
|
28524
|
+
info: (msg) => logger.info(msg),
|
|
28525
|
+
debug: (msg) => logger.debug(msg)
|
|
28526
|
+
});
|
|
28527
|
+
} catch (err) {
|
|
28528
|
+
logger.debug({ err }, "Seed file import skipped (no data/seeds/ or error)");
|
|
28529
|
+
}
|
|
28049
28530
|
logger.debug("Running seeds...");
|
|
28050
28531
|
for (const mod of modules) {
|
|
28051
28532
|
try {
|
|
@@ -28087,8 +28568,8 @@ async function start(config3) {
|
|
|
28087
28568
|
}
|
|
28088
28569
|
currentConfig = config3;
|
|
28089
28570
|
setLocales(config3?.locales ?? DEFAULT_LOCALES2);
|
|
28090
|
-
if (env.NODE_ENV === "development" && env.FRPC_SERVER &&
|
|
28091
|
-
process.env["
|
|
28571
|
+
if (env.NODE_ENV === "development" && env.FRPC_SERVER && !env.TRUST_PROXY) {
|
|
28572
|
+
process.env["TRUST_PROXY"] = "true";
|
|
28092
28573
|
}
|
|
28093
28574
|
const resolved = resolveConfig();
|
|
28094
28575
|
if (resolved.port > 0) {
|
|
@@ -28147,14 +28628,18 @@ async function start(config3) {
|
|
|
28147
28628
|
eventBridge.init();
|
|
28148
28629
|
const addr = server.address();
|
|
28149
28630
|
const actualPort = typeof addr === "object" && addr ? addr.port : resolved.port;
|
|
28631
|
+
let tunnelActive = false;
|
|
28150
28632
|
if (env.NODE_ENV === "development" && env.FRPC_SERVER && env.FRPC_SUBDOMAIN) {
|
|
28151
|
-
startTunnel({
|
|
28633
|
+
tunnelActive = await startTunnel({
|
|
28152
28634
|
server: env.FRPC_SERVER,
|
|
28153
28635
|
serverPort: env.FRPC_SERVER_PORT,
|
|
28154
28636
|
token: env.FRPC_TOKEN,
|
|
28155
28637
|
subdomain: env.FRPC_SUBDOMAIN,
|
|
28156
28638
|
localPort: actualPort
|
|
28157
28639
|
});
|
|
28640
|
+
if (tunnelActive && !env.BACKEND_URL) {
|
|
28641
|
+
process.env["BACKEND_URL"] = getTunnelUrl(env.FRPC_SUBDOMAIN, env.FRPC_SERVER);
|
|
28642
|
+
}
|
|
28158
28643
|
}
|
|
28159
28644
|
const baseUrl = env.BACKEND_URL || `http://localhost:${actualPort}`;
|
|
28160
28645
|
logger.debug({ libPath: getLibPath(), projectPath: getProjectPath() }, "Paths");
|