sonamu 0.2.46 → 0.2.48
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/bin/cli.js +48 -48
- package/dist/bin/cli.js.map +1 -1
- package/dist/{chunk-77XBF27L.js → chunk-76VBQWGE.js} +500 -186
- package/dist/chunk-76VBQWGE.js.map +1 -0
- package/dist/index.d.ts +67 -2
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/api/sonamu.ts +17 -0
- package/src/bin/cli.ts +1 -1
- package/src/entity/entity.ts +5 -0
- package/src/exceptions/so-exceptions.ts +27 -9
- package/src/index.ts +1 -0
- package/src/syncer/syncer.ts +32 -45
- package/src/templates/entity.template.ts +27 -25
- package/src/testing/fixture-manager.ts +431 -0
- package/src/types/types.ts +34 -0
- package/dist/chunk-77XBF27L.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -400,16 +400,28 @@ declare const TemplateOptions: z.ZodObject<{
|
|
|
400
400
|
parentId: z.ZodOptional<z.ZodString>;
|
|
401
401
|
title: z.ZodString;
|
|
402
402
|
table: z.ZodOptional<z.ZodString>;
|
|
403
|
+
props: z.ZodOptional<z.ZodArray<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>, "many">>;
|
|
404
|
+
indexes: z.ZodOptional<z.ZodArray<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>, "many">>;
|
|
405
|
+
subsets: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
|
|
406
|
+
enums: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>;
|
|
403
407
|
}, "strip", z.ZodTypeAny, {
|
|
404
408
|
entityId: string;
|
|
405
409
|
title: string;
|
|
406
410
|
parentId?: string | undefined;
|
|
407
411
|
table?: string | undefined;
|
|
412
|
+
props?: {}[] | undefined;
|
|
413
|
+
indexes?: {}[] | undefined;
|
|
414
|
+
subsets?: {} | undefined;
|
|
415
|
+
enums?: {} | undefined;
|
|
408
416
|
}, {
|
|
409
417
|
entityId: string;
|
|
410
418
|
title: string;
|
|
411
419
|
parentId?: string | undefined;
|
|
412
420
|
table?: string | undefined;
|
|
421
|
+
props?: {}[] | undefined;
|
|
422
|
+
indexes?: {}[] | undefined;
|
|
423
|
+
subsets?: {} | undefined;
|
|
424
|
+
enums?: {} | undefined;
|
|
413
425
|
}>;
|
|
414
426
|
init_types: z.ZodObject<{
|
|
415
427
|
entityId: z.ZodString;
|
|
@@ -571,6 +583,10 @@ declare const TemplateOptions: z.ZodObject<{
|
|
|
571
583
|
title: string;
|
|
572
584
|
parentId?: string | undefined;
|
|
573
585
|
table?: string | undefined;
|
|
586
|
+
props?: {}[] | undefined;
|
|
587
|
+
indexes?: {}[] | undefined;
|
|
588
|
+
subsets?: {} | undefined;
|
|
589
|
+
enums?: {} | undefined;
|
|
574
590
|
};
|
|
575
591
|
init_types: {
|
|
576
592
|
entityId: string;
|
|
@@ -638,6 +654,10 @@ declare const TemplateOptions: z.ZodObject<{
|
|
|
638
654
|
title: string;
|
|
639
655
|
parentId?: string | undefined;
|
|
640
656
|
table?: string | undefined;
|
|
657
|
+
props?: {}[] | undefined;
|
|
658
|
+
indexes?: {}[] | undefined;
|
|
659
|
+
subsets?: {} | undefined;
|
|
660
|
+
enums?: {} | undefined;
|
|
641
661
|
};
|
|
642
662
|
init_types: {
|
|
643
663
|
entityId: string;
|
|
@@ -722,6 +742,33 @@ declare const PathAndCode: z.ZodObject<{
|
|
|
722
742
|
code: string;
|
|
723
743
|
}>;
|
|
724
744
|
type PathAndCode = z.infer<typeof PathAndCode>;
|
|
745
|
+
type FixtureSearchOptions = {
|
|
746
|
+
entityId: string;
|
|
747
|
+
field: string;
|
|
748
|
+
value: string;
|
|
749
|
+
searchType: "equals" | "like";
|
|
750
|
+
};
|
|
751
|
+
type FixtureRecord = {
|
|
752
|
+
fixtureId: string;
|
|
753
|
+
entityId: string;
|
|
754
|
+
id: number;
|
|
755
|
+
columns: {
|
|
756
|
+
[key: string]: {
|
|
757
|
+
prop: EntityProp;
|
|
758
|
+
value: any;
|
|
759
|
+
};
|
|
760
|
+
};
|
|
761
|
+
fetchedRecords: string[];
|
|
762
|
+
belongsRecords: string[];
|
|
763
|
+
target?: FixtureRecord;
|
|
764
|
+
override?: boolean;
|
|
765
|
+
};
|
|
766
|
+
type FixtureImportResult = {
|
|
767
|
+
entityId: string;
|
|
768
|
+
data: {
|
|
769
|
+
[key: string]: any;
|
|
770
|
+
};
|
|
771
|
+
};
|
|
725
772
|
|
|
726
773
|
type ServiceClient = "axios" | "axios-multipart" | "swr" | "socketio" | "window-fetch";
|
|
727
774
|
type ApiDecoratorOptions = {
|
|
@@ -967,7 +1014,9 @@ declare class Syncer {
|
|
|
967
1014
|
resolveRenderType(key: string, zodType: z.ZodTypeAny): RenderingNode["renderType"];
|
|
968
1015
|
zodTypeToRenderingNode(zodType: z.ZodTypeAny, baseKey?: string): RenderingNode;
|
|
969
1016
|
getColumnsNode(entityId: string, subsetKey: string): Promise<RenderingNode>;
|
|
970
|
-
createEntity(
|
|
1017
|
+
createEntity(form: Omit<TemplateOptions["entity"], "title"> & {
|
|
1018
|
+
title?: string;
|
|
1019
|
+
}): Promise<void>;
|
|
971
1020
|
delEntity(entityId: string): Promise<{
|
|
972
1021
|
delPaths: string[];
|
|
973
1022
|
}>;
|
|
@@ -1004,6 +1053,9 @@ type SonamuConfig = {
|
|
|
1004
1053
|
prefix: string;
|
|
1005
1054
|
};
|
|
1006
1055
|
};
|
|
1056
|
+
type SonamuSecrets = {
|
|
1057
|
+
[key: string]: string;
|
|
1058
|
+
};
|
|
1007
1059
|
type SonamuFastifyConfig = {
|
|
1008
1060
|
contextProvider: (defaultContext: Pick<Context, "headers" | "reply">, request: FastifyRequest, reply: FastifyReply) => Context;
|
|
1009
1061
|
guardHandler: (guard: string, request: FastifyRequest, api: {
|
|
@@ -1044,6 +1096,9 @@ declare class SonamuClass {
|
|
|
1044
1096
|
private _config;
|
|
1045
1097
|
set config(config: SonamuConfig);
|
|
1046
1098
|
get config(): SonamuConfig;
|
|
1099
|
+
private _secrets;
|
|
1100
|
+
set secrets(secrets: SonamuSecrets);
|
|
1101
|
+
get secrets(): SonamuSecrets | null;
|
|
1047
1102
|
init(doSilent?: boolean, enableSync?: boolean, apiRootPath?: string): Promise<void>;
|
|
1048
1103
|
withFastify(server: FastifyInstance<Server, IncomingMessage, ServerResponse>, config: SonamuFastifyConfig): Promise<void>;
|
|
1049
1104
|
destroy(): Promise<void>;
|
|
@@ -1388,6 +1443,7 @@ declare class FixtureManagerClass {
|
|
|
1388
1443
|
private _fdb;
|
|
1389
1444
|
set fdb(fdb: Knex);
|
|
1390
1445
|
get fdb(): Knex;
|
|
1446
|
+
private dependencyGraph;
|
|
1391
1447
|
init(): void;
|
|
1392
1448
|
cleanAndSeed(usingTables?: string[]): Promise<void>;
|
|
1393
1449
|
getChecksum(db: Knex, tableName: string): Promise<any>;
|
|
@@ -1395,6 +1451,15 @@ declare class FixtureManagerClass {
|
|
|
1395
1451
|
importFixture(entityId: string, ids: number[]): Promise<void>;
|
|
1396
1452
|
getImportQueries(entityId: string, field: string, id: number): Promise<string[]>;
|
|
1397
1453
|
destory(): Promise<void>;
|
|
1454
|
+
getFixtures(sourceDBName: keyof SonamuDBConfig, targetDBName: keyof SonamuDBConfig, searchOptions: FixtureSearchOptions): Promise<FixtureRecord[]>;
|
|
1455
|
+
createFixtureRecord(entity: Entity, row: any, visitedEntities: Set<string>, records: FixtureRecord[], singleRecord?: boolean, _db?: Knex): Promise<void>;
|
|
1456
|
+
insertFixtures(dbName: keyof SonamuDBConfig, fixtures: FixtureRecord[]): Promise<FixtureImportResult[]>;
|
|
1457
|
+
private getInsertionOrder;
|
|
1458
|
+
private prepareInsertData;
|
|
1459
|
+
private buildDependencyGraph;
|
|
1460
|
+
private insertFixture;
|
|
1461
|
+
private handleManyToManyRelations;
|
|
1462
|
+
addFixtureLoader(code: string): Promise<void>;
|
|
1398
1463
|
}
|
|
1399
1464
|
declare const FixtureManager: FixtureManagerClass;
|
|
1400
1465
|
|
|
@@ -1416,4 +1481,4 @@ declare function findAppRootPath(): Promise<string>;
|
|
|
1416
1481
|
declare function findApiRootPath(): Promise<string>;
|
|
1417
1482
|
declare function nonNullable<T>(value: T): value is NonNullable<T>;
|
|
1418
1483
|
|
|
1419
|
-
export { AlreadyProcessedException, type ApiDecoratorOptions, type ApiParam, ApiParamType, type ArrayOr, BadRequestException, type BaseListParams, BaseModel, BaseModelClass, type BelongsToOneRelationProp, type BigIntegerProp, type BooleanProp, type CommonProp, type Context, type ContextExtend, DB, type DBPreset, type DateProp, type DateTimeProp, type DecimalProp, type DistributiveOmit, type DoubleProp, DuplicateRowException, type EntityIndex, type EntityJson, EntityManager, type EntityNamesRecord, type EntityProp, type EntityPropNode, type EntitySubsetRow, type EnumProp, type EnumsLabel, type EnumsLabelKo, type ExtendedApi, FixtureManager, FixtureManagerClass, type FlattenSubsetRow, type FloatProp, type GenMigrationCode, GenerateOptions, type HasManyRelationProp, type IntegerProp, InternalServerErrorException, type JsonProp, type KnexColumnType, type KnexError, type ListResult, type ManyToManyRelationProp, type MigrationColumn, type MigrationForeign, type MigrationIndex, type MigrationJoinTable, type MigrationSet, type MigrationSetAndJoinTable, type MigrationStatus, Migrator, type MigratorOptions, NotFoundException, type OneToOneRelationProp, PathAndCode, type RelationOn, type RelationProp, type RelationType, type RenderedTemplate, RenderingNode, type SMDInput, SQLDateTimeString, type ServiceClient, ServiceUnavailableException, SoException, Sonamu, type SonamuConfig, type SonamuDBConfig, SonamuQueryMode, type StringProp, type SubsetQuery, Syncer, TargetNotFoundException, TemplateKey, TemplateOptions, type TextProp, type TimeProp, type TimestampProp, type UBRef, UnauthorizedException, UpsertBuilder, type UuidProp, type VirtualProp, api, apiParamToTsCode, apiParamTypeToTsType, asArray, findApiRootPath, findAppRootPath, getTextTypeLength, getZodObjectFromApi, getZodObjectFromApiParams, getZodTypeFromApiParamType, globAsync, i, importMultiple, isBelongsToOneRelationProp, isBigIntegerProp, isBooleanProp, isCustomJoinClause, isDaemonServer, isDateProp, isDateTimeProp, isDecimalProp, isDevelopment, isDoubleProp, isEnumProp, isFloatProp, isHasManyRelationProp, isInDocker, isIntegerProp, isJsonProp, isKnexError, isLocal, isManyToManyRelationProp, isOneToOneRelationProp, isProduction, isRefField, isRelationProp, isRemote, isSoException, isStaging, isStringProp, isTest, isTextProp, isTimeProp, isTimestampProp, isUuidProp, isVirtualProp, nonNullable, objToMap, p, propNodeToZodTypeDef, propToZodTypeDef, registeredApis, serializeZodType, setupErrorHandler, unwrapPromiseOnce, zArrayable, zodTypeToTsTypeDef, zodTypeToZodCode };
|
|
1484
|
+
export { AlreadyProcessedException, type ApiDecoratorOptions, type ApiParam, ApiParamType, type ArrayOr, BadRequestException, type BaseListParams, BaseModel, BaseModelClass, type BelongsToOneRelationProp, type BigIntegerProp, type BooleanProp, type CommonProp, type Context, type ContextExtend, DB, type DBPreset, type DateProp, type DateTimeProp, type DecimalProp, type DistributiveOmit, type DoubleProp, DuplicateRowException, Entity, type EntityIndex, type EntityJson, EntityManager, type EntityNamesRecord, type EntityProp, type EntityPropNode, type EntitySubsetRow, type EnumProp, type EnumsLabel, type EnumsLabelKo, type ExtendedApi, type FixtureImportResult, FixtureManager, FixtureManagerClass, type FixtureRecord, type FixtureSearchOptions, type FlattenSubsetRow, type FloatProp, type GenMigrationCode, GenerateOptions, type HasManyRelationProp, type IntegerProp, InternalServerErrorException, type JsonProp, type KnexColumnType, type KnexError, type ListResult, type ManyToManyRelationProp, type MigrationColumn, type MigrationForeign, type MigrationIndex, type MigrationJoinTable, type MigrationSet, type MigrationSetAndJoinTable, type MigrationStatus, Migrator, type MigratorOptions, NotFoundException, type OneToOneRelationProp, PathAndCode, type RelationOn, type RelationProp, type RelationType, type RenderedTemplate, RenderingNode, type SMDInput, SQLDateTimeString, type ServiceClient, ServiceUnavailableException, SoException, Sonamu, type SonamuConfig, type SonamuDBConfig, SonamuQueryMode, type SonamuSecrets, type StringProp, type SubsetQuery, Syncer, TargetNotFoundException, TemplateKey, TemplateOptions, type TextProp, type TimeProp, type TimestampProp, type UBRef, UnauthorizedException, UpsertBuilder, type UuidProp, type VirtualProp, api, apiParamToTsCode, apiParamTypeToTsType, asArray, findApiRootPath, findAppRootPath, getTextTypeLength, getZodObjectFromApi, getZodObjectFromApiParams, getZodTypeFromApiParamType, globAsync, i, importMultiple, isBelongsToOneRelationProp, isBigIntegerProp, isBooleanProp, isCustomJoinClause, isDaemonServer, isDateProp, isDateTimeProp, isDecimalProp, isDevelopment, isDoubleProp, isEnumProp, isFloatProp, isHasManyRelationProp, isInDocker, isIntegerProp, isJsonProp, isKnexError, isLocal, isManyToManyRelationProp, isOneToOneRelationProp, isProduction, isRefField, isRelationProp, isRemote, isSoException, isStaging, isStringProp, isTest, isTextProp, isTimeProp, isTimestampProp, isUuidProp, isVirtualProp, nonNullable, objToMap, p, propNodeToZodTypeDef, propToZodTypeDef, registeredApis, serializeZodType, setupErrorHandler, unwrapPromiseOnce, zArrayable, zodTypeToTsTypeDef, zodTypeToZodCode };
|
package/dist/index.js
CHANGED
|
@@ -79,13 +79,14 @@
|
|
|
79
79
|
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
|
|
83
|
+
var _chunk76VBQWGEjs = require('./chunk-76VBQWGE.js');
|
|
83
84
|
|
|
84
85
|
// src/exceptions/error-handler.ts
|
|
85
86
|
function setupErrorHandler(server) {
|
|
86
87
|
server.setErrorHandler((error, request, reply) => {
|
|
87
88
|
_nullishCoalesce(error.statusCode, () => ( (error.statusCode = 400)));
|
|
88
|
-
if (
|
|
89
|
+
if (_chunk76VBQWGEjs.isSoException.call(void 0, error) && error.payload && Array.isArray(error.payload)) {
|
|
89
90
|
const issues = error.payload;
|
|
90
91
|
const [issue] = issues;
|
|
91
92
|
const message = `${issue.message} (${issue.path.join("/")})`;
|
|
@@ -421,5 +422,6 @@ function unique(columns) {
|
|
|
421
422
|
|
|
422
423
|
|
|
423
424
|
|
|
424
|
-
|
|
425
|
+
|
|
426
|
+
exports.AlreadyProcessedException = _chunk76VBQWGEjs.AlreadyProcessedException; exports.ApiParamType = _chunk76VBQWGEjs.ApiParamType; exports.BadRequestException = _chunk76VBQWGEjs.BadRequestException; exports.BaseModel = _chunk76VBQWGEjs.BaseModel; exports.BaseModelClass = _chunk76VBQWGEjs.BaseModelClass; exports.DB = _chunk76VBQWGEjs.DB; exports.DuplicateRowException = _chunk76VBQWGEjs.DuplicateRowException; exports.Entity = _chunk76VBQWGEjs.Entity; exports.EntityManager = _chunk76VBQWGEjs.EntityManager; exports.FixtureManager = _chunk76VBQWGEjs.FixtureManager; exports.FixtureManagerClass = _chunk76VBQWGEjs.FixtureManagerClass; exports.GenerateOptions = _chunk76VBQWGEjs.GenerateOptions; exports.InternalServerErrorException = _chunk76VBQWGEjs.InternalServerErrorException; exports.Migrator = _chunk76VBQWGEjs.Migrator; exports.NotFoundException = _chunk76VBQWGEjs.NotFoundException; exports.PathAndCode = _chunk76VBQWGEjs.PathAndCode; exports.RenderingNode = _chunk76VBQWGEjs.RenderingNode; exports.SQLDateTimeString = _chunk76VBQWGEjs.SQLDateTimeString; exports.ServiceUnavailableException = _chunk76VBQWGEjs.ServiceUnavailableException; exports.SoException = _chunk76VBQWGEjs.SoException; exports.Sonamu = _chunk76VBQWGEjs.Sonamu; exports.SonamuQueryMode = _chunk76VBQWGEjs.SonamuQueryMode; exports.Syncer = _chunk76VBQWGEjs.Syncer; exports.TargetNotFoundException = _chunk76VBQWGEjs.TargetNotFoundException; exports.TemplateKey = _chunk76VBQWGEjs.TemplateKey; exports.TemplateOptions = _chunk76VBQWGEjs.TemplateOptions; exports.UnauthorizedException = _chunk76VBQWGEjs.UnauthorizedException; exports.UpsertBuilder = _chunk76VBQWGEjs.UpsertBuilder; exports.api = _chunk76VBQWGEjs.api; exports.apiParamToTsCode = _chunk76VBQWGEjs.apiParamToTsCode; exports.apiParamTypeToTsType = _chunk76VBQWGEjs.apiParamTypeToTsType; exports.asArray = asArray; exports.findApiRootPath = _chunk76VBQWGEjs.findApiRootPath; exports.findAppRootPath = _chunk76VBQWGEjs.findAppRootPath; exports.getTextTypeLength = _chunk76VBQWGEjs.getTextTypeLength; exports.getZodObjectFromApi = _chunk76VBQWGEjs.getZodObjectFromApi; exports.getZodObjectFromApiParams = _chunk76VBQWGEjs.getZodObjectFromApiParams; exports.getZodTypeFromApiParamType = _chunk76VBQWGEjs.getZodTypeFromApiParamType; exports.globAsync = _chunk76VBQWGEjs.globAsync; exports.i = i; exports.importMultiple = _chunk76VBQWGEjs.importMultiple; exports.isBelongsToOneRelationProp = _chunk76VBQWGEjs.isBelongsToOneRelationProp; exports.isBigIntegerProp = _chunk76VBQWGEjs.isBigIntegerProp; exports.isBooleanProp = _chunk76VBQWGEjs.isBooleanProp; exports.isCustomJoinClause = _chunk76VBQWGEjs.isCustomJoinClause; exports.isDaemonServer = _chunk76VBQWGEjs.isDaemonServer; exports.isDateProp = _chunk76VBQWGEjs.isDateProp; exports.isDateTimeProp = _chunk76VBQWGEjs.isDateTimeProp; exports.isDecimalProp = _chunk76VBQWGEjs.isDecimalProp; exports.isDevelopment = _chunk76VBQWGEjs.isDevelopment; exports.isDoubleProp = _chunk76VBQWGEjs.isDoubleProp; exports.isEnumProp = _chunk76VBQWGEjs.isEnumProp; exports.isFloatProp = _chunk76VBQWGEjs.isFloatProp; exports.isHasManyRelationProp = _chunk76VBQWGEjs.isHasManyRelationProp; exports.isInDocker = _chunk76VBQWGEjs.isInDocker; exports.isIntegerProp = _chunk76VBQWGEjs.isIntegerProp; exports.isJsonProp = _chunk76VBQWGEjs.isJsonProp; exports.isKnexError = _chunk76VBQWGEjs.isKnexError; exports.isLocal = _chunk76VBQWGEjs.isLocal; exports.isManyToManyRelationProp = _chunk76VBQWGEjs.isManyToManyRelationProp; exports.isOneToOneRelationProp = _chunk76VBQWGEjs.isOneToOneRelationProp; exports.isProduction = _chunk76VBQWGEjs.isProduction; exports.isRefField = _chunk76VBQWGEjs.isRefField; exports.isRelationProp = _chunk76VBQWGEjs.isRelationProp; exports.isRemote = _chunk76VBQWGEjs.isRemote; exports.isSoException = _chunk76VBQWGEjs.isSoException; exports.isStaging = _chunk76VBQWGEjs.isStaging; exports.isStringProp = _chunk76VBQWGEjs.isStringProp; exports.isTest = _chunk76VBQWGEjs.isTest; exports.isTextProp = _chunk76VBQWGEjs.isTextProp; exports.isTimeProp = _chunk76VBQWGEjs.isTimeProp; exports.isTimestampProp = _chunk76VBQWGEjs.isTimestampProp; exports.isUuidProp = _chunk76VBQWGEjs.isUuidProp; exports.isVirtualProp = _chunk76VBQWGEjs.isVirtualProp; exports.nonNullable = _chunk76VBQWGEjs.nonNullable; exports.objToMap = objToMap; exports.p = p; exports.propNodeToZodTypeDef = _chunk76VBQWGEjs.propNodeToZodTypeDef; exports.propToZodTypeDef = _chunk76VBQWGEjs.propToZodTypeDef; exports.registeredApis = _chunk76VBQWGEjs.registeredApis; exports.serializeZodType = _chunk76VBQWGEjs.serializeZodType; exports.setupErrorHandler = setupErrorHandler; exports.unwrapPromiseOnce = _chunk76VBQWGEjs.unwrapPromiseOnce; exports.zArrayable = _chunk76VBQWGEjs.zArrayable; exports.zodTypeToTsTypeDef = _chunk76VBQWGEjs.zodTypeToTsTypeDef; exports.zodTypeToZodCode = _chunk76VBQWGEjs.zodTypeToZodCode;
|
|
425
427
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/exceptions/error-handler.ts","../src/entity/entity-utils.ts","../src/utils/model.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIO,SAAS,kBAAkB,QAAyB;AACzD,SAAO,gBAAgB,CAAC,OAAO,SAAS,UAAU;AAChD,UAAM,eAAN,MAAM,aAAe;AAErB,QAAI,cAAc,KAAK,KAAK,MAAM,WAAW,MAAM,QAAQ,MAAM,OAAO,GAAG;AACzE,YAAM,SAAS,MAAM;AACrB,YAAM,CAAC,KAAK,IAAI;AAChB,YAAM,UAAU,GAAG,MAAM,OAAO,KAAK,MAAM,KAAK,KAAK,GAAG,CAAC;AAEzD,cAAQ,IAAI,MAAM,GAAG,MAAM,UAAU,IAAI,OAAO,EAAE;AAClD,YAAM,OAAO,MAAM,cAAc,MAAM,MAAM,aAAa,GAAG,EAAE,KAAK;AAAA,QAClE,MAAM,MAAM;AAAA,QACZ,MAAM,MAAM;AAAA,QACZ;AAAA,QACA,kBAAkB,MAAM;AAAA,QACxB;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,cAAQ,IAAI,MAAM,GAAG,MAAM,UAAU,IAAI,MAAM,OAAO,EAAE;AACxD,YAAM,OAAO,MAAM,cAAc,MAAM,MAAM,aAAa,GAAG,EAAE,KAAK;AAAA,QAClE,MAAM,MAAM;AAAA,QACZ,MAAM,MAAM;AAAA,QACZ,SAAS,MAAM;AAAA,QACf,kBAAkB,MAAM;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACH;;;AC/BA,OAAO,gBAAgB;;;ACShB,SAAS,QAAW,OAAqB;AAC9C,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO;AAAA,EACT,OAAO;AACL,WAAO,CAAC,KAAU;AAAA,EACpB;AACF;AAEO,SAAS,SAAY,KAAyB;AACnD,QAAM,OAAO,OAAO,KAAK,GAAG;AAC5B,MAAI,KAAK,MAAM,CAAC,QAAQ,SAAS,GAAG,EAAE,SAAS,MAAM,GAAG,GAAG;AACzD,WAAO,IAAI,IAAe,KAAK,IAAI,CAAC,QAAQ,CAAC,SAAS,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AAAA,EACxE,OAAO;AACL,WAAO,IAAI,IAAe,OAAO,QAAQ,GAAG,CAAC;AAAA,EAC/C;AACF;;;ADGO,IAAM,IAAI;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,QACP,MACA,QACa;AACb,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,WACP,MACA,QACgB;AAChB,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,KAAK,MAAc,QAAmD;AAC7E,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,OACP,MACA,QACY;AACZ,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,MACP,MACA,QACW;AACX,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,IACP,GAAG;AAAA,EACL;AACF;AACA,SAAS,OACP,MACA,QACY;AACZ,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,IACP,GAAG;AAAA,EACL;AACF;AACA,SAAS,QACP,MACA,QACa;AACb,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,IACP,GAAG;AAAA,EACL;AACF;AACA,SAAS,QACP,MACA,QACa;AACb,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,KACP,MACA,QACU;AACV,MAAI,QAAQ,QAAQ,MAAM;AACxB,WAAO,OAAO;AACd,WAAO,YAAY;AAAA,EACrB;AACA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,SACP,MACA,QACc;AACd,MAAI,QAAQ,QAAQ,MAAM;AACxB,WAAO,OAAO;AACd,WAAO,YAAY;AAAA,EACrB;AACA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,KACP,MACA,QACU;AACV,MAAI,QAAQ,QAAQ,MAAM;AACxB,WAAO,OAAO;AACd,WAAO,YAAY;AAAA,EACrB;AACA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,UACP,MACA,QACe;AACf,MAAI,QAAQ,QAAQ,MAAM;AACxB,WAAO,OAAO;AACd,WAAO,YAAY;AAAA,EACrB;AACA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,KAAK,MAAc,QAAmD;AAC7E,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,KAAK,MAAc,QAAmD;AAC7E,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,MACP,MACA,QACU;AACV,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,IAAI,OAAO,MAAM,SAAS,WAAW,SAAS,IAAI,CAAC;AAAA,IACnD,GAAG;AAAA,EACL;AACF;AACA,SAAS,QACP,MACA,QACa;AACb,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,iBACP,MACA,QAIsB;AACtB,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,cAAc;AAAA,IACd,GAAG;AAAA,EACL;AACF;AACA,SAAS,qBACP,MACA,QAC0B;AAC1B,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,cAAc;AAAA,IACd,GAAG;AAAA,EACL;AACF;AACA,SAAS,gBACP,MACA,QACqB;AACrB,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,cAAc;AAAA,IACd,GAAG;AAAA,EACL;AACF;AACA,SAAS,mBACP,MACA,QACwB;AACxB,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,cAAc;AAAA,IACd,GAAG;AAAA,EACL;AACF;AAEO,IAAM,IAAI;AAAA,EACf;AAAA,EACA;AACF;AAEA,SAAS,MAAM,SAAyC;AACtD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,QAAQ,OAAO;AAAA,EAC1B;AACF;AAEA,SAAS,OAAO,SAAyC;AACvD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,QAAQ,OAAO;AAAA,EAC1B;AACF","sourcesContent":["import { FastifyInstance } from \"fastify\";\nimport { ZodIssue } from \"zod\";\nimport { isSoException } from \"./so-exceptions\";\n\nexport function setupErrorHandler(server: FastifyInstance) {\n server.setErrorHandler((error, request, reply) => {\n error.statusCode ??= 400;\n\n if (isSoException(error) && error.payload && Array.isArray(error.payload)) {\n const issues = error.payload as ZodIssue[];\n const [issue] = issues;\n const message = `${issue.message} (${issue.path.join(\"/\")})`;\n\n request.log.error(`${error.statusCode} ${message}`);\n reply.status(error.statusCode <= 501 ? error.statusCode : 501).send({\n name: error.name,\n code: error.code,\n message: message,\n validationErrors: error.validation,\n issues,\n });\n } else {\n request.log.error(`${error.statusCode} ${error.message}`);\n reply.status(error.statusCode <= 501 ? error.statusCode : 501).send({\n name: error.name,\n code: error.code,\n message: error.message,\n validationErrors: error.validation,\n });\n }\n });\n}\n","import inflection from \"inflection\";\nimport {\n BelongsToOneRelationProp,\n BigIntegerProp,\n BooleanProp,\n DateProp,\n DateTimeProp,\n DecimalProp,\n DistributiveOmit,\n DoubleProp,\n EnumProp,\n FloatProp,\n HasManyRelationProp,\n IntegerProp,\n JsonProp,\n ManyToManyRelationProp,\n OneToOneRelationProp,\n EntityIndex,\n StringProp,\n TextProp,\n TimeProp,\n TimestampProp,\n UuidProp,\n VirtualProp,\n} from \"../types/types\";\nimport { asArray } from \"../utils/model\";\n\nexport const p = {\n integer,\n bigInteger,\n text,\n string,\n float,\n double,\n decimal,\n boolean,\n date,\n dateTime,\n time,\n timestamp,\n json,\n uuid,\n enums,\n virtual,\n relationOneToOne,\n relationBelongsToOne,\n relationHasMany,\n relationManyToMany,\n};\n\nfunction integer(\n name: string,\n option?: Omit<IntegerProp, \"name\" | \"type\">\n): IntegerProp {\n return {\n name,\n type: \"integer\",\n ...option,\n };\n}\nfunction bigInteger(\n name: string,\n option?: Omit<BigIntegerProp, \"name\" | \"type\">\n): BigIntegerProp {\n return {\n name,\n type: \"bigInteger\",\n ...option,\n };\n}\nfunction text(name: string, option: Omit<TextProp, \"name\" | \"type\">): TextProp {\n return {\n name,\n type: \"text\",\n ...option,\n };\n}\nfunction string(\n name: string,\n option: Omit<StringProp, \"name\" | \"type\">\n): StringProp {\n return {\n name,\n type: \"string\",\n ...option,\n };\n}\nfunction float(\n name: string,\n option?: Omit<FloatProp, \"name\" | \"type\">\n): FloatProp {\n return {\n name,\n type: \"float\",\n precision: 8,\n scale: 2,\n ...option,\n };\n}\nfunction double(\n name: string,\n option?: Omit<DoubleProp, \"name\" | \"type\">\n): DoubleProp {\n return {\n name,\n type: \"double\",\n precision: 8,\n scale: 2,\n ...option,\n };\n}\nfunction decimal(\n name: string,\n option?: Omit<DecimalProp, \"name\" | \"type\">\n): DecimalProp {\n return {\n name,\n type: \"decimal\",\n precision: 8,\n scale: 2,\n ...option,\n };\n}\nfunction boolean(\n name: string,\n option?: Omit<BooleanProp, \"name\" | \"type\">\n): BooleanProp {\n return {\n name,\n type: \"boolean\",\n ...option,\n };\n}\nfunction date(\n name: string,\n option?: Omit<DateProp, \"name\" | \"type\"> & { now?: true }\n): DateProp {\n if (option?.now === true) {\n delete option.now;\n option.dbDefault = \"CURRENT_TIMESTAMP\";\n }\n return {\n name,\n type: \"date\",\n ...option,\n };\n}\nfunction dateTime(\n name: string,\n option?: Omit<DateTimeProp, \"name\" | \"type\"> & { now?: true }\n): DateTimeProp {\n if (option?.now === true) {\n delete option.now;\n option.dbDefault = \"CURRENT_TIMESTAMP\";\n }\n return {\n name,\n type: \"dateTime\",\n ...option,\n };\n}\nfunction time(\n name: string,\n option?: Omit<TimeProp, \"name\" | \"type\"> & { now?: true }\n): TimeProp {\n if (option?.now === true) {\n delete option.now;\n option.dbDefault = \"CURRENT_TIMESTAMP\";\n }\n return {\n name,\n type: \"time\",\n ...option,\n };\n}\nfunction timestamp(\n name: string,\n option?: Omit<TimestampProp, \"name\" | \"type\"> & { now?: true }\n): TimestampProp {\n if (option?.now === true) {\n delete option.now;\n option.dbDefault = \"CURRENT_TIMESTAMP\";\n }\n return {\n name,\n type: \"timestamp\",\n ...option,\n };\n}\nfunction json(name: string, option: Omit<JsonProp, \"name\" | \"type\">): JsonProp {\n return {\n name,\n type: \"json\",\n ...option,\n };\n}\nfunction uuid(name: string, option: Omit<UuidProp, \"name\" | \"type\">): UuidProp {\n return {\n name,\n type: \"uuid\",\n ...option,\n };\n}\nfunction enums(\n name: string,\n option: Omit<EnumProp, \"name\" | \"type\" | \"id\"> & { id?: string }\n): EnumProp {\n return {\n name,\n type: \"enum\",\n id: option.id ?? `$Model${inflection.camelize(name)}`,\n ...option,\n };\n}\nfunction virtual(\n name: string,\n option: Omit<VirtualProp, \"name\" | \"type\" | \"dbDefault\" | \"toFilter\">\n): VirtualProp {\n return {\n name,\n type: \"virtual\",\n ...option,\n };\n}\nfunction relationOneToOne(\n name: string,\n option: DistributiveOmit<\n OneToOneRelationProp,\n \"name\" | \"type\" | \"relationType\"\n >\n): OneToOneRelationProp {\n return {\n name,\n type: \"relation\",\n relationType: \"OneToOne\",\n ...option,\n };\n}\nfunction relationBelongsToOne(\n name: string,\n option: Omit<BelongsToOneRelationProp, \"name\" | \"type\" | \"relationType\">\n): BelongsToOneRelationProp {\n return {\n name,\n type: \"relation\",\n relationType: \"BelongsToOne\",\n ...option,\n };\n}\nfunction relationHasMany(\n name: string,\n option: Omit<HasManyRelationProp, \"name\" | \"type\" | \"relationType\">\n): HasManyRelationProp {\n return {\n name,\n type: \"relation\",\n relationType: \"HasMany\",\n ...option,\n };\n}\nfunction relationManyToMany(\n name: string,\n option: Omit<ManyToManyRelationProp, \"name\" | \"type\" | \"relationType\">\n): ManyToManyRelationProp {\n return {\n name,\n type: \"relation\",\n relationType: \"ManyToMany\",\n ...option,\n };\n}\n\nexport const i = {\n index,\n unique,\n};\n\nfunction index(columns: string | string[]): EntityIndex {\n return {\n type: \"index\",\n columns: asArray(columns),\n };\n}\n\nfunction unique(columns: string | string[]): EntityIndex {\n return {\n type: \"unique\",\n columns: asArray(columns),\n };\n}\n","import _ from \"lodash\";\n\nexport type ListResult<T> = {\n rows: T[];\n total?: number;\n};\n\nexport type ArrayOr<T> = T | T[];\n\nexport function asArray<T>(param: T | T[]): T[] {\n if (Array.isArray(param)) {\n return param;\n } else {\n return [param as T] as T[];\n }\n}\n\nexport function objToMap<T>(obj: { [k: string]: T }) {\n const keys = Object.keys(obj);\n if (keys.every((key) => parseInt(key).toString() === key)) {\n return new Map<number, T>(keys.map((key) => [parseInt(key), obj[key]]));\n } else {\n return new Map<string, T>(Object.entries(obj));\n }\n}\n\nexport interface BaseListParams {\n id?: number | number[];\n num?: number;\n page?: number;\n keyword?: string;\n queryMode?: \"list\" | \"count\" | \"both\";\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/exceptions/error-handler.ts","../src/entity/entity-utils.ts","../src/utils/model.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIO,SAAS,kBAAkB,QAAyB;AACzD,SAAO,gBAAgB,CAAC,OAAO,SAAS,UAAU;AAChD,UAAM,eAAN,MAAM,aAAe;AAErB,QAAI,cAAc,KAAK,KAAK,MAAM,WAAW,MAAM,QAAQ,MAAM,OAAO,GAAG;AACzE,YAAM,SAAS,MAAM;AACrB,YAAM,CAAC,KAAK,IAAI;AAChB,YAAM,UAAU,GAAG,MAAM,OAAO,KAAK,MAAM,KAAK,KAAK,GAAG,CAAC;AAEzD,cAAQ,IAAI,MAAM,GAAG,MAAM,UAAU,IAAI,OAAO,EAAE;AAClD,YAAM,OAAO,MAAM,cAAc,MAAM,MAAM,aAAa,GAAG,EAAE,KAAK;AAAA,QAClE,MAAM,MAAM;AAAA,QACZ,MAAM,MAAM;AAAA,QACZ;AAAA,QACA,kBAAkB,MAAM;AAAA,QACxB;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,cAAQ,IAAI,MAAM,GAAG,MAAM,UAAU,IAAI,MAAM,OAAO,EAAE;AACxD,YAAM,OAAO,MAAM,cAAc,MAAM,MAAM,aAAa,GAAG,EAAE,KAAK;AAAA,QAClE,MAAM,MAAM;AAAA,QACZ,MAAM,MAAM;AAAA,QACZ,SAAS,MAAM;AAAA,QACf,kBAAkB,MAAM;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACH;;;AC/BA,OAAO,gBAAgB;;;ACShB,SAAS,QAAW,OAAqB;AAC9C,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO;AAAA,EACT,OAAO;AACL,WAAO,CAAC,KAAU;AAAA,EACpB;AACF;AAEO,SAAS,SAAY,KAAyB;AACnD,QAAM,OAAO,OAAO,KAAK,GAAG;AAC5B,MAAI,KAAK,MAAM,CAAC,QAAQ,SAAS,GAAG,EAAE,SAAS,MAAM,GAAG,GAAG;AACzD,WAAO,IAAI,IAAe,KAAK,IAAI,CAAC,QAAQ,CAAC,SAAS,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;AAAA,EACxE,OAAO;AACL,WAAO,IAAI,IAAe,OAAO,QAAQ,GAAG,CAAC;AAAA,EAC/C;AACF;;;ADGO,IAAM,IAAI;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,QACP,MACA,QACa;AACb,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,WACP,MACA,QACgB;AAChB,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,KAAK,MAAc,QAAmD;AAC7E,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,OACP,MACA,QACY;AACZ,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,MACP,MACA,QACW;AACX,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,IACP,GAAG;AAAA,EACL;AACF;AACA,SAAS,OACP,MACA,QACY;AACZ,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,IACP,GAAG;AAAA,EACL;AACF;AACA,SAAS,QACP,MACA,QACa;AACb,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,IACP,GAAG;AAAA,EACL;AACF;AACA,SAAS,QACP,MACA,QACa;AACb,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,KACP,MACA,QACU;AACV,MAAI,QAAQ,QAAQ,MAAM;AACxB,WAAO,OAAO;AACd,WAAO,YAAY;AAAA,EACrB;AACA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,SACP,MACA,QACc;AACd,MAAI,QAAQ,QAAQ,MAAM;AACxB,WAAO,OAAO;AACd,WAAO,YAAY;AAAA,EACrB;AACA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,KACP,MACA,QACU;AACV,MAAI,QAAQ,QAAQ,MAAM;AACxB,WAAO,OAAO;AACd,WAAO,YAAY;AAAA,EACrB;AACA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,UACP,MACA,QACe;AACf,MAAI,QAAQ,QAAQ,MAAM;AACxB,WAAO,OAAO;AACd,WAAO,YAAY;AAAA,EACrB;AACA,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,KAAK,MAAc,QAAmD;AAC7E,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,KAAK,MAAc,QAAmD;AAC7E,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,MACP,MACA,QACU;AACV,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,IAAI,OAAO,MAAM,SAAS,WAAW,SAAS,IAAI,CAAC;AAAA,IACnD,GAAG;AAAA,EACL;AACF;AACA,SAAS,QACP,MACA,QACa;AACb,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AACF;AACA,SAAS,iBACP,MACA,QAIsB;AACtB,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,cAAc;AAAA,IACd,GAAG;AAAA,EACL;AACF;AACA,SAAS,qBACP,MACA,QAC0B;AAC1B,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,cAAc;AAAA,IACd,GAAG;AAAA,EACL;AACF;AACA,SAAS,gBACP,MACA,QACqB;AACrB,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,cAAc;AAAA,IACd,GAAG;AAAA,EACL;AACF;AACA,SAAS,mBACP,MACA,QACwB;AACxB,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,cAAc;AAAA,IACd,GAAG;AAAA,EACL;AACF;AAEO,IAAM,IAAI;AAAA,EACf;AAAA,EACA;AACF;AAEA,SAAS,MAAM,SAAyC;AACtD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,QAAQ,OAAO;AAAA,EAC1B;AACF;AAEA,SAAS,OAAO,SAAyC;AACvD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,QAAQ,OAAO;AAAA,EAC1B;AACF","sourcesContent":["import { FastifyInstance } from \"fastify\";\nimport { ZodIssue } from \"zod\";\nimport { isSoException } from \"./so-exceptions\";\n\nexport function setupErrorHandler(server: FastifyInstance) {\n server.setErrorHandler((error, request, reply) => {\n error.statusCode ??= 400;\n\n if (isSoException(error) && error.payload && Array.isArray(error.payload)) {\n const issues = error.payload as ZodIssue[];\n const [issue] = issues;\n const message = `${issue.message} (${issue.path.join(\"/\")})`;\n\n request.log.error(`${error.statusCode} ${message}`);\n reply.status(error.statusCode <= 501 ? error.statusCode : 501).send({\n name: error.name,\n code: error.code,\n message: message,\n validationErrors: error.validation,\n issues,\n });\n } else {\n request.log.error(`${error.statusCode} ${error.message}`);\n reply.status(error.statusCode <= 501 ? error.statusCode : 501).send({\n name: error.name,\n code: error.code,\n message: error.message,\n validationErrors: error.validation,\n });\n }\n });\n}\n","import inflection from \"inflection\";\nimport {\n BelongsToOneRelationProp,\n BigIntegerProp,\n BooleanProp,\n DateProp,\n DateTimeProp,\n DecimalProp,\n DistributiveOmit,\n DoubleProp,\n EnumProp,\n FloatProp,\n HasManyRelationProp,\n IntegerProp,\n JsonProp,\n ManyToManyRelationProp,\n OneToOneRelationProp,\n EntityIndex,\n StringProp,\n TextProp,\n TimeProp,\n TimestampProp,\n UuidProp,\n VirtualProp,\n} from \"../types/types\";\nimport { asArray } from \"../utils/model\";\n\nexport const p = {\n integer,\n bigInteger,\n text,\n string,\n float,\n double,\n decimal,\n boolean,\n date,\n dateTime,\n time,\n timestamp,\n json,\n uuid,\n enums,\n virtual,\n relationOneToOne,\n relationBelongsToOne,\n relationHasMany,\n relationManyToMany,\n};\n\nfunction integer(\n name: string,\n option?: Omit<IntegerProp, \"name\" | \"type\">\n): IntegerProp {\n return {\n name,\n type: \"integer\",\n ...option,\n };\n}\nfunction bigInteger(\n name: string,\n option?: Omit<BigIntegerProp, \"name\" | \"type\">\n): BigIntegerProp {\n return {\n name,\n type: \"bigInteger\",\n ...option,\n };\n}\nfunction text(name: string, option: Omit<TextProp, \"name\" | \"type\">): TextProp {\n return {\n name,\n type: \"text\",\n ...option,\n };\n}\nfunction string(\n name: string,\n option: Omit<StringProp, \"name\" | \"type\">\n): StringProp {\n return {\n name,\n type: \"string\",\n ...option,\n };\n}\nfunction float(\n name: string,\n option?: Omit<FloatProp, \"name\" | \"type\">\n): FloatProp {\n return {\n name,\n type: \"float\",\n precision: 8,\n scale: 2,\n ...option,\n };\n}\nfunction double(\n name: string,\n option?: Omit<DoubleProp, \"name\" | \"type\">\n): DoubleProp {\n return {\n name,\n type: \"double\",\n precision: 8,\n scale: 2,\n ...option,\n };\n}\nfunction decimal(\n name: string,\n option?: Omit<DecimalProp, \"name\" | \"type\">\n): DecimalProp {\n return {\n name,\n type: \"decimal\",\n precision: 8,\n scale: 2,\n ...option,\n };\n}\nfunction boolean(\n name: string,\n option?: Omit<BooleanProp, \"name\" | \"type\">\n): BooleanProp {\n return {\n name,\n type: \"boolean\",\n ...option,\n };\n}\nfunction date(\n name: string,\n option?: Omit<DateProp, \"name\" | \"type\"> & { now?: true }\n): DateProp {\n if (option?.now === true) {\n delete option.now;\n option.dbDefault = \"CURRENT_TIMESTAMP\";\n }\n return {\n name,\n type: \"date\",\n ...option,\n };\n}\nfunction dateTime(\n name: string,\n option?: Omit<DateTimeProp, \"name\" | \"type\"> & { now?: true }\n): DateTimeProp {\n if (option?.now === true) {\n delete option.now;\n option.dbDefault = \"CURRENT_TIMESTAMP\";\n }\n return {\n name,\n type: \"dateTime\",\n ...option,\n };\n}\nfunction time(\n name: string,\n option?: Omit<TimeProp, \"name\" | \"type\"> & { now?: true }\n): TimeProp {\n if (option?.now === true) {\n delete option.now;\n option.dbDefault = \"CURRENT_TIMESTAMP\";\n }\n return {\n name,\n type: \"time\",\n ...option,\n };\n}\nfunction timestamp(\n name: string,\n option?: Omit<TimestampProp, \"name\" | \"type\"> & { now?: true }\n): TimestampProp {\n if (option?.now === true) {\n delete option.now;\n option.dbDefault = \"CURRENT_TIMESTAMP\";\n }\n return {\n name,\n type: \"timestamp\",\n ...option,\n };\n}\nfunction json(name: string, option: Omit<JsonProp, \"name\" | \"type\">): JsonProp {\n return {\n name,\n type: \"json\",\n ...option,\n };\n}\nfunction uuid(name: string, option: Omit<UuidProp, \"name\" | \"type\">): UuidProp {\n return {\n name,\n type: \"uuid\",\n ...option,\n };\n}\nfunction enums(\n name: string,\n option: Omit<EnumProp, \"name\" | \"type\" | \"id\"> & { id?: string }\n): EnumProp {\n return {\n name,\n type: \"enum\",\n id: option.id ?? `$Model${inflection.camelize(name)}`,\n ...option,\n };\n}\nfunction virtual(\n name: string,\n option: Omit<VirtualProp, \"name\" | \"type\" | \"dbDefault\" | \"toFilter\">\n): VirtualProp {\n return {\n name,\n type: \"virtual\",\n ...option,\n };\n}\nfunction relationOneToOne(\n name: string,\n option: DistributiveOmit<\n OneToOneRelationProp,\n \"name\" | \"type\" | \"relationType\"\n >\n): OneToOneRelationProp {\n return {\n name,\n type: \"relation\",\n relationType: \"OneToOne\",\n ...option,\n };\n}\nfunction relationBelongsToOne(\n name: string,\n option: Omit<BelongsToOneRelationProp, \"name\" | \"type\" | \"relationType\">\n): BelongsToOneRelationProp {\n return {\n name,\n type: \"relation\",\n relationType: \"BelongsToOne\",\n ...option,\n };\n}\nfunction relationHasMany(\n name: string,\n option: Omit<HasManyRelationProp, \"name\" | \"type\" | \"relationType\">\n): HasManyRelationProp {\n return {\n name,\n type: \"relation\",\n relationType: \"HasMany\",\n ...option,\n };\n}\nfunction relationManyToMany(\n name: string,\n option: Omit<ManyToManyRelationProp, \"name\" | \"type\" | \"relationType\">\n): ManyToManyRelationProp {\n return {\n name,\n type: \"relation\",\n relationType: \"ManyToMany\",\n ...option,\n };\n}\n\nexport const i = {\n index,\n unique,\n};\n\nfunction index(columns: string | string[]): EntityIndex {\n return {\n type: \"index\",\n columns: asArray(columns),\n };\n}\n\nfunction unique(columns: string | string[]): EntityIndex {\n return {\n type: \"unique\",\n columns: asArray(columns),\n };\n}\n","import _ from \"lodash\";\n\nexport type ListResult<T> = {\n rows: T[];\n total?: number;\n};\n\nexport type ArrayOr<T> = T | T[];\n\nexport function asArray<T>(param: T | T[]): T[] {\n if (Array.isArray(param)) {\n return param;\n } else {\n return [param as T] as T[];\n }\n}\n\nexport function objToMap<T>(obj: { [k: string]: T }) {\n const keys = Object.keys(obj);\n if (keys.every((key) => parseInt(key).toString() === key)) {\n return new Map<number, T>(keys.map((key) => [parseInt(key), obj[key]]));\n } else {\n return new Map<string, T>(Object.entries(obj));\n }\n}\n\nexport interface BaseListParams {\n id?: number | number[];\n num?: number;\n page?: number;\n keyword?: string;\n queryMode?: \"list\" | \"count\" | \"both\";\n}\n"]}
|
package/package.json
CHANGED
package/src/api/sonamu.ts
CHANGED
|
@@ -29,6 +29,9 @@ export type SonamuConfig = {
|
|
|
29
29
|
prefix: string;
|
|
30
30
|
};
|
|
31
31
|
};
|
|
32
|
+
export type SonamuSecrets = {
|
|
33
|
+
[key: string]: string;
|
|
34
|
+
};
|
|
32
35
|
type SonamuFastifyConfig = {
|
|
33
36
|
contextProvider: (
|
|
34
37
|
defaultContext: Pick<Context, "headers" | "reply">,
|
|
@@ -117,6 +120,14 @@ class SonamuClass {
|
|
|
117
120
|
return this._config;
|
|
118
121
|
}
|
|
119
122
|
|
|
123
|
+
private _secrets: SonamuSecrets | null = null;
|
|
124
|
+
set secrets(secrets: SonamuSecrets) {
|
|
125
|
+
this._secrets = secrets;
|
|
126
|
+
}
|
|
127
|
+
get secrets(): SonamuSecrets | null {
|
|
128
|
+
return this._secrets;
|
|
129
|
+
}
|
|
130
|
+
|
|
120
131
|
async init(
|
|
121
132
|
doSilent: boolean = false,
|
|
122
133
|
enableSync: boolean = true,
|
|
@@ -129,12 +140,18 @@ class SonamuClass {
|
|
|
129
140
|
|
|
130
141
|
this.apiRootPath = apiRootPath ?? (await findApiRootPath());
|
|
131
142
|
const configPath = path.join(this.apiRootPath, "sonamu.config.json");
|
|
143
|
+
const secretsPath = path.join(this.apiRootPath, "sonamu.secrets.json");
|
|
132
144
|
if (fs.existsSync(configPath) === false) {
|
|
133
145
|
throw new Error(`Cannot find sonamu.config.json in ${configPath}`);
|
|
134
146
|
}
|
|
135
147
|
this.config = JSON.parse(
|
|
136
148
|
fs.readFileSync(configPath).toString()
|
|
137
149
|
) as SonamuConfig;
|
|
150
|
+
if (fs.existsSync(secretsPath)) {
|
|
151
|
+
this.secrets = JSON.parse(
|
|
152
|
+
fs.readFileSync(secretsPath).toString()
|
|
153
|
+
) as SonamuSecrets;
|
|
154
|
+
}
|
|
138
155
|
|
|
139
156
|
// DB 로드
|
|
140
157
|
this.dbConfig = await DB.readKnexfile();
|
package/src/bin/cli.ts
CHANGED
|
@@ -289,7 +289,7 @@ async function stub_practice(name: string) {
|
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
async function stub_entity(entityId: string) {
|
|
292
|
-
await Sonamu.syncer.createEntity(entityId);
|
|
292
|
+
await Sonamu.syncer.createEntity({ entityId });
|
|
293
293
|
}
|
|
294
294
|
|
|
295
295
|
async function scaffold_model(entityId: string) {
|
package/src/entity/entity.ts
CHANGED
|
@@ -16,7 +16,10 @@ export function isSoException(err: any): err is SoException {
|
|
|
16
16
|
잘못된 매개변수 등 요청사항에 문제가 있는 경우
|
|
17
17
|
*/
|
|
18
18
|
export class BadRequestException extends SoException {
|
|
19
|
-
constructor(
|
|
19
|
+
constructor(
|
|
20
|
+
public message = "Bad Request",
|
|
21
|
+
public payload?: unknown
|
|
22
|
+
) {
|
|
20
23
|
super(400, message, payload);
|
|
21
24
|
}
|
|
22
25
|
}
|
|
@@ -25,7 +28,10 @@ export class BadRequestException extends SoException {
|
|
|
25
28
|
로그인이 반드시 필요한 케이스에 로그아웃 상태인 경우 / 접근 권한이 없는 요청시
|
|
26
29
|
*/
|
|
27
30
|
export class UnauthorizedException extends SoException {
|
|
28
|
-
constructor(
|
|
31
|
+
constructor(
|
|
32
|
+
public message = "Unauthorized",
|
|
33
|
+
public payload?: unknown
|
|
34
|
+
) {
|
|
29
35
|
super(401, message, payload);
|
|
30
36
|
}
|
|
31
37
|
}
|
|
@@ -34,7 +40,10 @@ export class UnauthorizedException extends SoException {
|
|
|
34
40
|
존재하지 않는 레코드에 접근시
|
|
35
41
|
*/
|
|
36
42
|
export class NotFoundException extends SoException {
|
|
37
|
-
constructor(
|
|
43
|
+
constructor(
|
|
44
|
+
public message = "Not Found",
|
|
45
|
+
public payload?: unknown
|
|
46
|
+
) {
|
|
38
47
|
super(404, message, payload);
|
|
39
48
|
}
|
|
40
49
|
}
|
|
@@ -67,8 +76,11 @@ export class InternalServerErrorException extends SoException {
|
|
|
67
76
|
이미 처리함
|
|
68
77
|
*/
|
|
69
78
|
export class AlreadyProcessedException extends SoException {
|
|
70
|
-
constructor(
|
|
71
|
-
|
|
79
|
+
constructor(
|
|
80
|
+
public message = "Already Processed",
|
|
81
|
+
public payload?: unknown
|
|
82
|
+
) {
|
|
83
|
+
super(541, message, payload);
|
|
72
84
|
}
|
|
73
85
|
}
|
|
74
86
|
|
|
@@ -76,8 +88,11 @@ export class AlreadyProcessedException extends SoException {
|
|
|
76
88
|
중복 허용하지 않는 케이스에 중복 요청
|
|
77
89
|
*/
|
|
78
90
|
export class DuplicateRowException extends SoException {
|
|
79
|
-
constructor(
|
|
80
|
-
|
|
91
|
+
constructor(
|
|
92
|
+
public message = "Duplicate Row",
|
|
93
|
+
public payload?: unknown
|
|
94
|
+
) {
|
|
95
|
+
super(542, message, payload);
|
|
81
96
|
}
|
|
82
97
|
}
|
|
83
98
|
|
|
@@ -85,7 +100,10 @@ export class DuplicateRowException extends SoException {
|
|
|
85
100
|
뭔가를 하려고 했으나 대상이 없음
|
|
86
101
|
*/
|
|
87
102
|
export class TargetNotFoundException extends SoException {
|
|
88
|
-
constructor(
|
|
89
|
-
|
|
103
|
+
constructor(
|
|
104
|
+
public message = "Target Not Found",
|
|
105
|
+
public payload?: unknown
|
|
106
|
+
) {
|
|
107
|
+
super(520, message, payload);
|
|
90
108
|
}
|
|
91
109
|
}
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from "./database/db";
|
|
|
7
7
|
export * from "./database/upsert-builder";
|
|
8
8
|
export * from "./exceptions/error-handler";
|
|
9
9
|
export * from "./exceptions/so-exceptions";
|
|
10
|
+
export * from "./entity/entity";
|
|
10
11
|
export * from "./entity/entity-manager";
|
|
11
12
|
export * from "./entity/entity-utils";
|
|
12
13
|
export * from "./entity/migrator";
|
package/src/syncer/syncer.ts
CHANGED
|
@@ -1023,38 +1023,32 @@ export class Syncer {
|
|
|
1023
1023
|
(name) => name !== names.constant
|
|
1024
1024
|
);
|
|
1025
1025
|
|
|
1026
|
-
return keys.reduce(
|
|
1027
|
-
(
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
);
|
|
1038
|
-
});
|
|
1039
|
-
return result;
|
|
1040
|
-
}
|
|
1026
|
+
return keys.reduce((result, key) => {
|
|
1027
|
+
const tpl = this.getTemplate(key);
|
|
1028
|
+
if (key.startsWith("view_enums")) {
|
|
1029
|
+
enumsKeys.map((componentId) => {
|
|
1030
|
+
const { target, path: p } = tpl.getTargetAndPath(names, componentId);
|
|
1031
|
+
result[`${key}__${componentId}`] = fs.existsSync(
|
|
1032
|
+
path.join(Sonamu.appRootPath, target, p)
|
|
1033
|
+
);
|
|
1034
|
+
});
|
|
1035
|
+
return result;
|
|
1036
|
+
}
|
|
1041
1037
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1038
|
+
const { target, path: p } = tpl.getTargetAndPath(names);
|
|
1039
|
+
const { targets } = Sonamu.config.sync;
|
|
1040
|
+
if (target.includes(":target")) {
|
|
1041
|
+
targets.map((t) => {
|
|
1042
|
+
result[`${key}__${t}`] = fs.existsSync(
|
|
1043
|
+
path.join(Sonamu.appRootPath, target.replace(":target", t), p)
|
|
1044
|
+
);
|
|
1045
|
+
});
|
|
1046
|
+
} else {
|
|
1047
|
+
result[key] = fs.existsSync(path.join(Sonamu.appRootPath, target, p));
|
|
1048
|
+
}
|
|
1053
1049
|
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
{} as Record<`${TemplateKey}${string}`, boolean>
|
|
1057
|
-
);
|
|
1050
|
+
return result;
|
|
1051
|
+
}, {} as Record<`${TemplateKey}${string}`, boolean>);
|
|
1058
1052
|
}
|
|
1059
1053
|
|
|
1060
1054
|
async getZodTypeById(zodTypeId: string): Promise<z.ZodTypeAny> {
|
|
@@ -1099,8 +1093,9 @@ export class Syncer {
|
|
|
1099
1093
|
const obj = await propNode.children.reduce(
|
|
1100
1094
|
async (promise, childPropNode) => {
|
|
1101
1095
|
const result = await promise;
|
|
1102
|
-
result[childPropNode.prop!.name] =
|
|
1103
|
-
|
|
1096
|
+
result[childPropNode.prop!.name] = await this.propNodeToZodType(
|
|
1097
|
+
childPropNode
|
|
1098
|
+
);
|
|
1104
1099
|
return result;
|
|
1105
1100
|
},
|
|
1106
1101
|
{} as any
|
|
@@ -1329,21 +1324,13 @@ export class Syncer {
|
|
|
1329
1324
|
}
|
|
1330
1325
|
|
|
1331
1326
|
async createEntity(
|
|
1332
|
-
|
|
1333
|
-
parentId?: string,
|
|
1334
|
-
table?: string,
|
|
1335
|
-
title?: string
|
|
1327
|
+
form: Omit<TemplateOptions["entity"], "title"> & { title?: string }
|
|
1336
1328
|
) {
|
|
1337
|
-
if (!/^[A-Z][a-zA-Z0-9]*$/.test(entityId)) {
|
|
1329
|
+
if (!/^[A-Z][a-zA-Z0-9]*$/.test(form.entityId)) {
|
|
1338
1330
|
throw new BadRequestException("entityId는 CamelCase 형식이어야 합니다.");
|
|
1339
1331
|
}
|
|
1340
1332
|
|
|
1341
|
-
await this.generateTemplate("entity",
|
|
1342
|
-
entityId,
|
|
1343
|
-
parentId,
|
|
1344
|
-
table,
|
|
1345
|
-
title,
|
|
1346
|
-
});
|
|
1333
|
+
await this.generateTemplate("entity", form);
|
|
1347
1334
|
|
|
1348
1335
|
// reload entities
|
|
1349
1336
|
await EntityManager.reload();
|
|
@@ -1352,9 +1339,9 @@ export class Syncer {
|
|
|
1352
1339
|
await this.actionGenerateSchemas();
|
|
1353
1340
|
|
|
1354
1341
|
// generate types
|
|
1355
|
-
if (parentId === undefined) {
|
|
1342
|
+
if (form.parentId === undefined) {
|
|
1356
1343
|
await this.generateTemplate("init_types", {
|
|
1357
|
-
entityId,
|
|
1344
|
+
entityId: form.entityId,
|
|
1358
1345
|
});
|
|
1359
1346
|
}
|
|
1360
1347
|
}
|
|
@@ -39,37 +39,39 @@ export class Template__entity extends Template {
|
|
|
39
39
|
title: title ?? entityId,
|
|
40
40
|
parentId,
|
|
41
41
|
table: table ?? names.fsPlural.replace(/\-/g, "_"),
|
|
42
|
-
props:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
42
|
+
props: options.props?.length
|
|
43
|
+
? options.props
|
|
44
|
+
: [
|
|
45
|
+
{ name: "id", type: "integer", unsigned: true, desc: "ID" },
|
|
46
|
+
...(parent
|
|
47
|
+
? [
|
|
48
|
+
{
|
|
49
|
+
type: "relation",
|
|
50
|
+
name: parent.names.camel,
|
|
51
|
+
relationType: "BelongsToOne",
|
|
52
|
+
with: parentId,
|
|
53
|
+
onUpdate: "CASCADE",
|
|
54
|
+
onDelete: "CASCADE",
|
|
55
|
+
desc: parent.entity.title,
|
|
56
|
+
},
|
|
57
|
+
]
|
|
58
|
+
: []),
|
|
59
|
+
{
|
|
60
|
+
name: "created_at",
|
|
61
|
+
type: "timestamp",
|
|
62
|
+
desc: "등록일시",
|
|
63
|
+
dbDefault: "CURRENT_TIMESTAMP",
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
indexes: [...(options.indexes ?? [])],
|
|
67
|
+
subsets: options.subsets ?? {
|
|
66
68
|
...(parentId
|
|
67
69
|
? {}
|
|
68
70
|
: {
|
|
69
71
|
A: ["id", "created_at"],
|
|
70
72
|
}),
|
|
71
73
|
},
|
|
72
|
-
enums: {
|
|
74
|
+
enums: options.enums ?? {
|
|
73
75
|
...(parentId
|
|
74
76
|
? {}
|
|
75
77
|
: {
|