@gzl10/nexus-sdk 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +15 -21
- package/dist/index.js +139 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ import { Logger } from 'pino';
|
|
|
11
11
|
* que pueden ser escritos a archivos o usados en runtime.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
/** Directorio estándar para código generado */
|
|
15
|
+
declare const GENERATED_DIR = "__generated__";
|
|
14
16
|
/**
|
|
15
17
|
* Entidades que persisten en BD local con tabla propia
|
|
16
18
|
* Excluye: action, external, virtual, computed, single (usa tabla compartida)
|
|
@@ -130,6 +132,15 @@ declare function generateSchemasFile(definitions: EntityDefinition[]): string;
|
|
|
130
132
|
* writeFileSync('users.models.ts', code)
|
|
131
133
|
*/
|
|
132
134
|
declare function generateModelsFile(definitions: EntityDefinition[]): string;
|
|
135
|
+
/**
|
|
136
|
+
* Genera archivo completo de migración Knex para múltiples entidades
|
|
137
|
+
* Consolida todas las entidades de un módulo en un solo archivo de migración
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* const code = generateMigrationsFile([userEntity, roleEntity])
|
|
141
|
+
* writeFileSync('users.migrate.ts', code)
|
|
142
|
+
*/
|
|
143
|
+
declare function generateMigrationsFile(definitions: EntityDefinition[]): string;
|
|
133
144
|
|
|
134
145
|
/**
|
|
135
146
|
* @gzl10/nexus-sdk
|
|
@@ -634,21 +645,6 @@ interface ModuleAbilities {
|
|
|
634
645
|
* Usa BaseUser y AbilityLike para tipado básico sin depender del backend
|
|
635
646
|
*/
|
|
636
647
|
type PluginAuthRequest = AuthRequest<BaseUser, AbilityLike>;
|
|
637
|
-
/**
|
|
638
|
-
* Resolver de usuarios para plugins
|
|
639
|
-
* Permite acceder a usuarios sin conocer la implementación interna
|
|
640
|
-
*/
|
|
641
|
-
interface UsersResolver {
|
|
642
|
-
findById: (id: string) => Promise<BaseUser | null>;
|
|
643
|
-
findByIds: (ids: string[]) => Promise<BaseUser[]>;
|
|
644
|
-
}
|
|
645
|
-
/**
|
|
646
|
-
* Servicios core inyectados por el backend
|
|
647
|
-
* Los plugins acceden a estos servicios via ctx.services
|
|
648
|
-
*/
|
|
649
|
-
interface CoreServices {
|
|
650
|
-
users?: UsersResolver;
|
|
651
|
-
}
|
|
652
648
|
/**
|
|
653
649
|
* Helpers para migraciones de base de datos
|
|
654
650
|
*/
|
|
@@ -713,8 +709,8 @@ interface ModuleContext {
|
|
|
713
709
|
data?: Record<string, unknown>;
|
|
714
710
|
}) => Promise<unknown>;
|
|
715
711
|
};
|
|
716
|
-
/** Servicios de módulos
|
|
717
|
-
services:
|
|
712
|
+
/** Servicios de módulos (inyectados por backend) */
|
|
713
|
+
services: Record<string, unknown>;
|
|
718
714
|
}
|
|
719
715
|
/**
|
|
720
716
|
* Manifest de un módulo Nexus
|
|
@@ -722,8 +718,6 @@ interface ModuleContext {
|
|
|
722
718
|
interface ModuleManifest {
|
|
723
719
|
/** Identificador único del módulo (ej: 'users', 'posts') */
|
|
724
720
|
name: string;
|
|
725
|
-
/** Código único del módulo (ej: 'USR', 'PST'). Opcional si pertenece a un plugin */
|
|
726
|
-
code?: string;
|
|
727
721
|
/** Nombre para mostrar en UI. Opcional si pertenece a un plugin */
|
|
728
722
|
label?: string;
|
|
729
723
|
/** Icono del módulo (Iconify MDI: 'mdi:account-group') */
|
|
@@ -736,7 +730,7 @@ interface ModuleManifest {
|
|
|
736
730
|
dependencies?: string[];
|
|
737
731
|
/** Requisitos para activar el módulo */
|
|
738
732
|
required?: ModuleRequirements;
|
|
739
|
-
/** Función de migración de base de datos */
|
|
733
|
+
/** Función de migración de base de datos. Normalmente se genera desde definitions (EntityDefinition) */
|
|
740
734
|
migrate?: (ctx: ModuleContext) => Promise<void>;
|
|
741
735
|
/** Función de seed de datos iniciales */
|
|
742
736
|
seed?: (ctx: ModuleContext) => Promise<void>;
|
|
@@ -781,4 +775,4 @@ interface PluginManifest {
|
|
|
781
775
|
modules: ModuleManifest[];
|
|
782
776
|
}
|
|
783
777
|
|
|
784
|
-
export { type AbilityLike, type ActionEntityDefinition, type AuthRequest, type BaseUser, type CaslAction, type CollectionEntityDefinition, type ComputedEntityDefinition, type ConfigEntityDefinition, type
|
|
778
|
+
export { type AbilityLike, type ActionEntityDefinition, type AuthRequest, type BaseUser, type CaslAction, type CollectionEntityDefinition, type ComputedEntityDefinition, type ConfigEntityDefinition, type DbType, type EntityCaslConfig, type EntityDefinition, type EntityIndex, type EventEntityDefinition, type ExternalEntityDefinition, type FieldCaslAccess, type FieldDbConfig, type FieldDefinition, type FieldMeta, type FieldOptions, type FieldRelation, type FieldValidation, type FieldValidationConfig, type ForbiddenErrorConstructor, type ForbiddenErrorInstance, type FormField, type FormFieldType, GENERATED_DIR, type GeneratedPermission, type InputType, type KnexAlterTableBuilder, type KnexCreateTableBuilder, type KnexTransaction, type ListType, type MigrationHelpers, type ModuleAbilities, type ModuleContext, type ModuleManifest, type ModuleMiddlewares, type ModuleRequirements, type NonPersistentEntityDefinition, type OwnershipCondition, type PaginatedResult, type PaginationParams, type PersistentEntityDefinition, type PluginAuthRequest, type PluginCategory, type PluginManifest, type ReferenceEntityDefinition, type RolePermission, type SingleEntityDefinition, type TempEntityDefinition, type ValidateSchemas, type ValidationSchema, type ViewEntityDefinition, type VirtualEntityDefinition, generateCaslPermissions, generateCaslSeed, generateMigration, generateMigrationsFile, generateModel, generateModelsFile, generateReadOnlyModel, generateReadOnlySchema, generateSchemasFile, generateZodSchema, getEntityName, getEntitySubject, hasTable, isPersistentEntity, isSingletonEntity };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/generators.ts
|
|
2
|
+
var GENERATED_DIR = "__generated__";
|
|
2
3
|
function isPersistentEntity(entity) {
|
|
3
4
|
const withoutOwnTable = ["action", "external", "virtual", "computed", "single"];
|
|
4
5
|
return !withoutOwnTable.includes(entity.type ?? "collection");
|
|
@@ -648,10 +649,148 @@ function generateModelsFile(definitions) {
|
|
|
648
649
|
}
|
|
649
650
|
return lines.join("\n");
|
|
650
651
|
}
|
|
652
|
+
function generateMigrationsFile(definitions) {
|
|
653
|
+
const persistentEntities = definitions.filter(isPersistentEntity);
|
|
654
|
+
if (persistentEntities.length === 0) {
|
|
655
|
+
return [
|
|
656
|
+
"/**",
|
|
657
|
+
" * AUTO-GENERATED - Do not edit manually",
|
|
658
|
+
" * Generated from EntityDefinition via @gzl10/nexus-sdk generators",
|
|
659
|
+
" */",
|
|
660
|
+
"",
|
|
661
|
+
"import type { ModuleContext } from '@gzl10/nexus-sdk'",
|
|
662
|
+
"",
|
|
663
|
+
"// No persistent entities to migrate",
|
|
664
|
+
"export async function migrate(_ctx: ModuleContext): Promise<void> {}",
|
|
665
|
+
""
|
|
666
|
+
].join("\n");
|
|
667
|
+
}
|
|
668
|
+
const lines = [
|
|
669
|
+
"/**",
|
|
670
|
+
" * AUTO-GENERATED - Do not edit manually",
|
|
671
|
+
" * Generated from EntityDefinition via @gzl10/nexus-sdk generators",
|
|
672
|
+
" */",
|
|
673
|
+
"",
|
|
674
|
+
"import type { ModuleContext, Knex } from '@gzl10/nexus-sdk'",
|
|
675
|
+
"",
|
|
676
|
+
"export async function migrate(ctx: ModuleContext): Promise<void> {",
|
|
677
|
+
" const { db, logger, helpers } = ctx",
|
|
678
|
+
" const { addTimestamps, addAuditFieldsIfMissing } = helpers",
|
|
679
|
+
""
|
|
680
|
+
];
|
|
681
|
+
for (const entity of persistentEntities) {
|
|
682
|
+
const { table, fields } = entity;
|
|
683
|
+
const timestamps = "timestamps" in entity ? entity.timestamps : false;
|
|
684
|
+
const audit = "audit" in entity ? entity.audit : false;
|
|
685
|
+
const indexes = "indexes" in entity ? entity.indexes : void 0;
|
|
686
|
+
const name = getEntityName(entity);
|
|
687
|
+
lines.push(` // === ${name.toUpperCase()} ===`);
|
|
688
|
+
lines.push(` if (!(await db.schema.hasTable('${table}'))) {`);
|
|
689
|
+
lines.push(` await db.schema.createTable('${table}', (table: Knex.CreateTableBuilder) => {`);
|
|
690
|
+
for (const [fieldName, field] of Object.entries(fields)) {
|
|
691
|
+
const columnCode = generateColumnCodeInline(fieldName, field);
|
|
692
|
+
lines.push(` ${columnCode}`);
|
|
693
|
+
}
|
|
694
|
+
if (timestamps) {
|
|
695
|
+
lines.push(` addTimestamps(table, db)`);
|
|
696
|
+
}
|
|
697
|
+
if (indexes?.length) {
|
|
698
|
+
lines.push("");
|
|
699
|
+
for (const idx of indexes) {
|
|
700
|
+
if (idx.unique) {
|
|
701
|
+
lines.push(` table.unique([${idx.columns.map((c) => `'${c}'`).join(", ")}])`);
|
|
702
|
+
} else {
|
|
703
|
+
lines.push(` table.index([${idx.columns.map((c) => `'${c}'`).join(", ")}])`);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
lines.push(` })`);
|
|
708
|
+
lines.push(` logger.info('Created table: ${table}')`);
|
|
709
|
+
lines.push(` }`);
|
|
710
|
+
if (audit) {
|
|
711
|
+
lines.push(` await addAuditFieldsIfMissing(db, '${table}')`);
|
|
712
|
+
}
|
|
713
|
+
lines.push("");
|
|
714
|
+
}
|
|
715
|
+
lines.push("}");
|
|
716
|
+
lines.push("");
|
|
717
|
+
return lines.join("\n");
|
|
718
|
+
}
|
|
719
|
+
function generateColumnCodeInline(name, field) {
|
|
720
|
+
const { db } = field;
|
|
721
|
+
let code = "";
|
|
722
|
+
switch (db.type) {
|
|
723
|
+
case "string":
|
|
724
|
+
code = db.size ? `table.string('${name}', ${db.size})` : `table.string('${name}')`;
|
|
725
|
+
break;
|
|
726
|
+
case "text":
|
|
727
|
+
code = `table.text('${name}')`;
|
|
728
|
+
break;
|
|
729
|
+
case "integer":
|
|
730
|
+
code = `table.integer('${name}')`;
|
|
731
|
+
break;
|
|
732
|
+
case "decimal":
|
|
733
|
+
if (db.precision) {
|
|
734
|
+
code = `table.decimal('${name}', ${db.precision[0]}, ${db.precision[1]})`;
|
|
735
|
+
} else {
|
|
736
|
+
code = `table.decimal('${name}')`;
|
|
737
|
+
}
|
|
738
|
+
break;
|
|
739
|
+
case "boolean":
|
|
740
|
+
code = `table.boolean('${name}')`;
|
|
741
|
+
break;
|
|
742
|
+
case "date":
|
|
743
|
+
code = `table.date('${name}')`;
|
|
744
|
+
break;
|
|
745
|
+
case "datetime":
|
|
746
|
+
code = `table.datetime('${name}')`;
|
|
747
|
+
break;
|
|
748
|
+
case "json":
|
|
749
|
+
code = `table.json('${name}')`;
|
|
750
|
+
break;
|
|
751
|
+
case "uuid":
|
|
752
|
+
code = `table.uuid('${name}')`;
|
|
753
|
+
break;
|
|
754
|
+
default:
|
|
755
|
+
code = `table.string('${name}')`;
|
|
756
|
+
}
|
|
757
|
+
if (name === "id") {
|
|
758
|
+
code += ".primary()";
|
|
759
|
+
}
|
|
760
|
+
if (!db.nullable) {
|
|
761
|
+
code += ".notNullable()";
|
|
762
|
+
} else {
|
|
763
|
+
code += ".nullable()";
|
|
764
|
+
}
|
|
765
|
+
if (db.unique) {
|
|
766
|
+
code += ".unique()";
|
|
767
|
+
}
|
|
768
|
+
if (db.default !== void 0) {
|
|
769
|
+
if (typeof db.default === "string") {
|
|
770
|
+
code += `.defaultTo('${db.default}')`;
|
|
771
|
+
} else if (typeof db.default === "boolean") {
|
|
772
|
+
code += `.defaultTo(${db.default})`;
|
|
773
|
+
} else {
|
|
774
|
+
code += `.defaultTo(${db.default})`;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
if (db.index) {
|
|
778
|
+
code += ".index()";
|
|
779
|
+
}
|
|
780
|
+
if (field.relation) {
|
|
781
|
+
code += `.references('${field.relation.column ?? "id"}').inTable('${field.relation.table}')`;
|
|
782
|
+
if (field.relation.onDelete) {
|
|
783
|
+
code += `.onDelete('${field.relation.onDelete}')`;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return code;
|
|
787
|
+
}
|
|
651
788
|
export {
|
|
789
|
+
GENERATED_DIR,
|
|
652
790
|
generateCaslPermissions,
|
|
653
791
|
generateCaslSeed,
|
|
654
792
|
generateMigration,
|
|
793
|
+
generateMigrationsFile,
|
|
655
794
|
generateModel,
|
|
656
795
|
generateModelsFile,
|
|
657
796
|
generateReadOnlyModel,
|