sonamu 0.4.9 → 0.4.11
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/{base-model-C24du9JT.d.ts → base-model-Br6krkwK.d.ts} +1 -1
- package/dist/{base-model-IZdmwmB5.d.mts → base-model-BvVra-8f.d.mts} +1 -1
- package/dist/bin/cli.js +51 -51
- package/dist/bin/cli.mjs +2 -2
- package/dist/{chunk-OTL37JQ4.mjs → chunk-634GIW42.mjs} +10 -8
- package/dist/chunk-634GIW42.mjs.map +1 -0
- package/dist/{chunk-AK547YMV.mjs → chunk-A2BDNO7E.mjs} +2 -2
- package/dist/{chunk-LD7OHPVK.js → chunk-GUKIIOZI.js} +108 -106
- package/dist/chunk-GUKIIOZI.js.map +1 -0
- package/dist/{chunk-IV7ZWWBN.mjs → chunk-GUV6I64Y.mjs} +69 -40
- package/dist/chunk-GUV6I64Y.mjs.map +1 -0
- package/dist/{chunk-2VEHSKNA.js → chunk-KX4762I3.js} +69 -40
- package/dist/chunk-KX4762I3.js.map +1 -0
- package/dist/{chunk-L3RJSG2K.mjs → chunk-PGPMEMK6.mjs} +2 -2
- package/dist/{chunk-IDNBP4MH.js → chunk-QIHV5UYF.js} +4 -4
- package/dist/{chunk-GHF56FO6.js → chunk-Z53BUBO4.js} +7 -7
- package/dist/database/drivers/knex/base-model.d.mts +2 -2
- package/dist/database/drivers/knex/base-model.d.ts +2 -2
- package/dist/database/drivers/knex/base-model.js +8 -8
- package/dist/database/drivers/knex/base-model.mjs +3 -3
- package/dist/database/drivers/kysely/base-model.d.mts +2 -2
- package/dist/database/drivers/kysely/base-model.d.ts +2 -2
- package/dist/database/drivers/kysely/base-model.js +9 -9
- package/dist/database/drivers/kysely/base-model.mjs +3 -3
- package/dist/index.d.mts +13 -5
- package/dist/index.d.ts +13 -5
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +15 -3
- package/dist/index.mjs.map +1 -1
- package/dist/{model-Dbbfpk2X.d.ts → model-DWoinpJ7.d.mts} +79 -9
- package/dist/{model-Dbbfpk2X.d.mts → model-DWoinpJ7.d.ts} +79 -9
- package/package.json +1 -1
- package/src/api/base-frame.ts +14 -0
- package/src/api/decorators.ts +2 -1
- package/src/entity/entity-utils.ts +1 -0
- package/src/entity/migrator.ts +8 -6
- package/src/index.ts +1 -0
- package/src/syncer/syncer.ts +76 -39
- package/src/templates/service.template.ts +4 -6
- package/src/types/types.ts +19 -7
- package/dist/chunk-2VEHSKNA.js.map +0 -1
- package/dist/chunk-IV7ZWWBN.mjs.map +0 -1
- package/dist/chunk-LD7OHPVK.js.map +0 -1
- package/dist/chunk-OTL37JQ4.mjs.map +0 -1
- /package/dist/{chunk-AK547YMV.mjs.map → chunk-A2BDNO7E.mjs.map} +0 -0
- /package/dist/{chunk-L3RJSG2K.mjs.map → chunk-PGPMEMK6.mjs.map} +0 -0
- /package/dist/{chunk-IDNBP4MH.js.map → chunk-QIHV5UYF.js.map} +0 -0
- /package/dist/{chunk-GHF56FO6.js.map → chunk-Z53BUBO4.js.map} +0 -0
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/exceptions/error-handler.ts","../src/entity/entity-utils.ts"],"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"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/api/base-frame.ts","../src/exceptions/error-handler.ts","../src/entity/entity-utils.ts"],"sourcesContent":["import { Knex } from \"knex\";\nimport { DB } from \"../database/db\";\nimport { DBPreset } from \"../database/types\";\nimport { UpsertBuilder } from \"../database/upsert-builder\";\n\nexport abstract class BaseFrameClass {\n getDB(which: DBPreset): Knex {\n return DB.getDB(which) as Knex;\n }\n\n getUpsertBuilder() {\n return new UpsertBuilder<\"knex\">();\n }\n}\n","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 option.useConstraint = (option.useConstraint ?? true) as false;\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"],"mappings":"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","names":[]}
|
|
@@ -100,16 +100,18 @@ type OneToOneRelationProp = _RelationProp & {
|
|
|
100
100
|
customJoinClause?: string;
|
|
101
101
|
} & ({
|
|
102
102
|
hasJoinColumn: true;
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
useConstraint?: boolean;
|
|
104
|
+
onUpdate?: RelationOn;
|
|
105
|
+
onDelete?: RelationOn;
|
|
105
106
|
} | {
|
|
106
107
|
hasJoinColumn: false;
|
|
107
108
|
});
|
|
108
109
|
type BelongsToOneRelationProp = _RelationProp & {
|
|
109
110
|
relationType: "BelongsToOne";
|
|
110
111
|
customJoinClause?: string;
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
useConstraint?: boolean;
|
|
113
|
+
onUpdate?: RelationOn;
|
|
114
|
+
onDelete?: RelationOn;
|
|
113
115
|
};
|
|
114
116
|
type HasManyRelationProp = _RelationProp & {
|
|
115
117
|
relationType: "HasMany";
|
|
@@ -467,11 +469,59 @@ declare const TemplateOptions: z.ZodObject<{
|
|
|
467
469
|
entityId: string;
|
|
468
470
|
}>;
|
|
469
471
|
service: z.ZodObject<{
|
|
470
|
-
|
|
472
|
+
namesRecord: z.ZodObject<{
|
|
473
|
+
fs: z.ZodString;
|
|
474
|
+
fsPlural: z.ZodString;
|
|
475
|
+
camel: z.ZodString;
|
|
476
|
+
camelPlural: z.ZodString;
|
|
477
|
+
capital: z.ZodString;
|
|
478
|
+
capitalPlural: z.ZodString;
|
|
479
|
+
upper: z.ZodString;
|
|
480
|
+
constant: z.ZodString;
|
|
481
|
+
}, "strip", z.ZodTypeAny, {
|
|
482
|
+
fs: string;
|
|
483
|
+
fsPlural: string;
|
|
484
|
+
camel: string;
|
|
485
|
+
camelPlural: string;
|
|
486
|
+
capital: string;
|
|
487
|
+
capitalPlural: string;
|
|
488
|
+
upper: string;
|
|
489
|
+
constant: string;
|
|
490
|
+
}, {
|
|
491
|
+
fs: string;
|
|
492
|
+
fsPlural: string;
|
|
493
|
+
camel: string;
|
|
494
|
+
camelPlural: string;
|
|
495
|
+
capital: string;
|
|
496
|
+
capitalPlural: string;
|
|
497
|
+
upper: string;
|
|
498
|
+
constant: string;
|
|
499
|
+
}>;
|
|
500
|
+
modelTsPath: z.ZodString;
|
|
471
501
|
}, "strip", z.ZodTypeAny, {
|
|
472
|
-
|
|
502
|
+
namesRecord: {
|
|
503
|
+
fs: string;
|
|
504
|
+
fsPlural: string;
|
|
505
|
+
camel: string;
|
|
506
|
+
camelPlural: string;
|
|
507
|
+
capital: string;
|
|
508
|
+
capitalPlural: string;
|
|
509
|
+
upper: string;
|
|
510
|
+
constant: string;
|
|
511
|
+
};
|
|
512
|
+
modelTsPath: string;
|
|
473
513
|
}, {
|
|
474
|
-
|
|
514
|
+
namesRecord: {
|
|
515
|
+
fs: string;
|
|
516
|
+
fsPlural: string;
|
|
517
|
+
camel: string;
|
|
518
|
+
camelPlural: string;
|
|
519
|
+
capital: string;
|
|
520
|
+
capitalPlural: string;
|
|
521
|
+
upper: string;
|
|
522
|
+
constant: string;
|
|
523
|
+
};
|
|
524
|
+
modelTsPath: string;
|
|
475
525
|
}>;
|
|
476
526
|
view_list: z.ZodObject<{
|
|
477
527
|
entityId: z.ZodString;
|
|
@@ -609,7 +659,17 @@ declare const TemplateOptions: z.ZodObject<{
|
|
|
609
659
|
entityId: string;
|
|
610
660
|
};
|
|
611
661
|
service: {
|
|
612
|
-
|
|
662
|
+
namesRecord: {
|
|
663
|
+
fs: string;
|
|
664
|
+
fsPlural: string;
|
|
665
|
+
camel: string;
|
|
666
|
+
camelPlural: string;
|
|
667
|
+
capital: string;
|
|
668
|
+
capitalPlural: string;
|
|
669
|
+
upper: string;
|
|
670
|
+
constant: string;
|
|
671
|
+
};
|
|
672
|
+
modelTsPath: string;
|
|
613
673
|
};
|
|
614
674
|
view_list: {
|
|
615
675
|
entityId: string;
|
|
@@ -681,7 +741,17 @@ declare const TemplateOptions: z.ZodObject<{
|
|
|
681
741
|
entityId: string;
|
|
682
742
|
};
|
|
683
743
|
service: {
|
|
684
|
-
|
|
744
|
+
namesRecord: {
|
|
745
|
+
fs: string;
|
|
746
|
+
fsPlural: string;
|
|
747
|
+
camel: string;
|
|
748
|
+
camelPlural: string;
|
|
749
|
+
capital: string;
|
|
750
|
+
capitalPlural: string;
|
|
751
|
+
upper: string;
|
|
752
|
+
constant: string;
|
|
753
|
+
};
|
|
754
|
+
modelTsPath: string;
|
|
685
755
|
};
|
|
686
756
|
view_list: {
|
|
687
757
|
entityId: string;
|
|
@@ -100,16 +100,18 @@ type OneToOneRelationProp = _RelationProp & {
|
|
|
100
100
|
customJoinClause?: string;
|
|
101
101
|
} & ({
|
|
102
102
|
hasJoinColumn: true;
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
useConstraint?: boolean;
|
|
104
|
+
onUpdate?: RelationOn;
|
|
105
|
+
onDelete?: RelationOn;
|
|
105
106
|
} | {
|
|
106
107
|
hasJoinColumn: false;
|
|
107
108
|
});
|
|
108
109
|
type BelongsToOneRelationProp = _RelationProp & {
|
|
109
110
|
relationType: "BelongsToOne";
|
|
110
111
|
customJoinClause?: string;
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
useConstraint?: boolean;
|
|
113
|
+
onUpdate?: RelationOn;
|
|
114
|
+
onDelete?: RelationOn;
|
|
113
115
|
};
|
|
114
116
|
type HasManyRelationProp = _RelationProp & {
|
|
115
117
|
relationType: "HasMany";
|
|
@@ -467,11 +469,59 @@ declare const TemplateOptions: z.ZodObject<{
|
|
|
467
469
|
entityId: string;
|
|
468
470
|
}>;
|
|
469
471
|
service: z.ZodObject<{
|
|
470
|
-
|
|
472
|
+
namesRecord: z.ZodObject<{
|
|
473
|
+
fs: z.ZodString;
|
|
474
|
+
fsPlural: z.ZodString;
|
|
475
|
+
camel: z.ZodString;
|
|
476
|
+
camelPlural: z.ZodString;
|
|
477
|
+
capital: z.ZodString;
|
|
478
|
+
capitalPlural: z.ZodString;
|
|
479
|
+
upper: z.ZodString;
|
|
480
|
+
constant: z.ZodString;
|
|
481
|
+
}, "strip", z.ZodTypeAny, {
|
|
482
|
+
fs: string;
|
|
483
|
+
fsPlural: string;
|
|
484
|
+
camel: string;
|
|
485
|
+
camelPlural: string;
|
|
486
|
+
capital: string;
|
|
487
|
+
capitalPlural: string;
|
|
488
|
+
upper: string;
|
|
489
|
+
constant: string;
|
|
490
|
+
}, {
|
|
491
|
+
fs: string;
|
|
492
|
+
fsPlural: string;
|
|
493
|
+
camel: string;
|
|
494
|
+
camelPlural: string;
|
|
495
|
+
capital: string;
|
|
496
|
+
capitalPlural: string;
|
|
497
|
+
upper: string;
|
|
498
|
+
constant: string;
|
|
499
|
+
}>;
|
|
500
|
+
modelTsPath: z.ZodString;
|
|
471
501
|
}, "strip", z.ZodTypeAny, {
|
|
472
|
-
|
|
502
|
+
namesRecord: {
|
|
503
|
+
fs: string;
|
|
504
|
+
fsPlural: string;
|
|
505
|
+
camel: string;
|
|
506
|
+
camelPlural: string;
|
|
507
|
+
capital: string;
|
|
508
|
+
capitalPlural: string;
|
|
509
|
+
upper: string;
|
|
510
|
+
constant: string;
|
|
511
|
+
};
|
|
512
|
+
modelTsPath: string;
|
|
473
513
|
}, {
|
|
474
|
-
|
|
514
|
+
namesRecord: {
|
|
515
|
+
fs: string;
|
|
516
|
+
fsPlural: string;
|
|
517
|
+
camel: string;
|
|
518
|
+
camelPlural: string;
|
|
519
|
+
capital: string;
|
|
520
|
+
capitalPlural: string;
|
|
521
|
+
upper: string;
|
|
522
|
+
constant: string;
|
|
523
|
+
};
|
|
524
|
+
modelTsPath: string;
|
|
475
525
|
}>;
|
|
476
526
|
view_list: z.ZodObject<{
|
|
477
527
|
entityId: z.ZodString;
|
|
@@ -609,7 +659,17 @@ declare const TemplateOptions: z.ZodObject<{
|
|
|
609
659
|
entityId: string;
|
|
610
660
|
};
|
|
611
661
|
service: {
|
|
612
|
-
|
|
662
|
+
namesRecord: {
|
|
663
|
+
fs: string;
|
|
664
|
+
fsPlural: string;
|
|
665
|
+
camel: string;
|
|
666
|
+
camelPlural: string;
|
|
667
|
+
capital: string;
|
|
668
|
+
capitalPlural: string;
|
|
669
|
+
upper: string;
|
|
670
|
+
constant: string;
|
|
671
|
+
};
|
|
672
|
+
modelTsPath: string;
|
|
613
673
|
};
|
|
614
674
|
view_list: {
|
|
615
675
|
entityId: string;
|
|
@@ -681,7 +741,17 @@ declare const TemplateOptions: z.ZodObject<{
|
|
|
681
741
|
entityId: string;
|
|
682
742
|
};
|
|
683
743
|
service: {
|
|
684
|
-
|
|
744
|
+
namesRecord: {
|
|
745
|
+
fs: string;
|
|
746
|
+
fsPlural: string;
|
|
747
|
+
camel: string;
|
|
748
|
+
camelPlural: string;
|
|
749
|
+
capital: string;
|
|
750
|
+
capitalPlural: string;
|
|
751
|
+
upper: string;
|
|
752
|
+
constant: string;
|
|
753
|
+
};
|
|
754
|
+
modelTsPath: string;
|
|
685
755
|
};
|
|
686
756
|
view_list: {
|
|
687
757
|
entityId: string;
|
package/package.json
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Knex } from "knex";
|
|
2
|
+
import { DB } from "../database/db";
|
|
3
|
+
import { DBPreset } from "../database/types";
|
|
4
|
+
import { UpsertBuilder } from "../database/upsert-builder";
|
|
5
|
+
|
|
6
|
+
export abstract class BaseFrameClass {
|
|
7
|
+
getDB(which: DBPreset): Knex {
|
|
8
|
+
return DB.getDB(which) as Knex;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
getUpsertBuilder() {
|
|
12
|
+
return new UpsertBuilder<"knex">();
|
|
13
|
+
}
|
|
14
|
+
}
|
package/src/api/decorators.ts
CHANGED
|
@@ -49,8 +49,9 @@ export function api(options: ApiDecoratorOptions = {}) {
|
|
|
49
49
|
return function (target: Object, propertyKey: string) {
|
|
50
50
|
const modelName = target.constructor.name.match(/(.+)Class$/)![1];
|
|
51
51
|
const methodName = propertyKey;
|
|
52
|
+
|
|
52
53
|
const defaultPath = `/${inflection.camelize(
|
|
53
|
-
modelName.replace(/Model$/, ""),
|
|
54
|
+
modelName.replace(/Model$/, "").replace(/Frame$/, ""),
|
|
54
55
|
true
|
|
55
56
|
)}/${inflection.camelize(propertyKey, true)}`;
|
|
56
57
|
|
|
@@ -240,6 +240,7 @@ function relationBelongsToOne(
|
|
|
240
240
|
name: string,
|
|
241
241
|
option: Omit<BelongsToOneRelationProp, "name" | "type" | "relationType">
|
|
242
242
|
): BelongsToOneRelationProp {
|
|
243
|
+
option.useConstraint = (option.useConstraint ?? true) as false;
|
|
243
244
|
return {
|
|
244
245
|
name,
|
|
245
246
|
type: "relation",
|
package/src/entity/migrator.ts
CHANGED
|
@@ -1246,12 +1246,14 @@ export class Migrator {
|
|
|
1246
1246
|
unsigned: true,
|
|
1247
1247
|
nullable: prop.nullable ?? false,
|
|
1248
1248
|
});
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1249
|
+
if ((prop.useConstraint ?? true) === true) {
|
|
1250
|
+
r.foreigns.push({
|
|
1251
|
+
columns: [idColumnName],
|
|
1252
|
+
to: `${inflection.underscore(inflection.pluralize(prop.with)).toLowerCase()}.id`,
|
|
1253
|
+
onUpdate: prop.onUpdate ?? "RESTRICT",
|
|
1254
|
+
onDelete: prop.onDelete ?? "RESTRICT",
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1255
1257
|
}
|
|
1256
1258
|
|
|
1257
1259
|
return r;
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./api/code-converters";
|
|
|
2
2
|
export * from "./api/context";
|
|
3
3
|
export * from "./api/decorators";
|
|
4
4
|
export * from "./api/sonamu";
|
|
5
|
+
export * from "./api/base-frame";
|
|
5
6
|
export * from "./database/db";
|
|
6
7
|
export * from "./database/upsert-builder";
|
|
7
8
|
export * from "./database/types";
|
package/src/syncer/syncer.ts
CHANGED
|
@@ -5,7 +5,7 @@ import crypto from "crypto";
|
|
|
5
5
|
import equal from "fast-deep-equal";
|
|
6
6
|
import _ from "lodash";
|
|
7
7
|
import inflection from "inflection";
|
|
8
|
-
import { EntityManager } from "../entity/entity-manager";
|
|
8
|
+
import { EntityManager, EntityNamesRecord } from "../entity/entity-manager";
|
|
9
9
|
import ts from "typescript";
|
|
10
10
|
import {
|
|
11
11
|
ApiParam,
|
|
@@ -79,7 +79,13 @@ import { Template__kysely_interface } from "../templates/kysely_types.template";
|
|
|
79
79
|
import { DB } from "../database/db";
|
|
80
80
|
import { setTimeout as setTimeoutPromises } from "timers/promises";
|
|
81
81
|
|
|
82
|
-
type FileType =
|
|
82
|
+
type FileType =
|
|
83
|
+
| "model"
|
|
84
|
+
| "types"
|
|
85
|
+
| "functions"
|
|
86
|
+
| "generated"
|
|
87
|
+
| "entity"
|
|
88
|
+
| "frame";
|
|
83
89
|
type GlobPattern = {
|
|
84
90
|
[key in FileType]: string;
|
|
85
91
|
};
|
|
@@ -200,7 +206,7 @@ export class Syncer {
|
|
|
200
206
|
// 다른 부분 찾아 액션
|
|
201
207
|
const diffGroups = _.groupBy(diffFiles, (r) => {
|
|
202
208
|
const matched = r.match(
|
|
203
|
-
/\.(model|types|functions|entity|generated)\.[tj]s/
|
|
209
|
+
/\.(model|types|functions|entity|generated|frame)\.[tj]s/
|
|
204
210
|
);
|
|
205
211
|
return matched![1];
|
|
206
212
|
}) as unknown as DiffGroups;
|
|
@@ -255,12 +261,44 @@ export class Syncer {
|
|
|
255
261
|
}
|
|
256
262
|
|
|
257
263
|
// 트리거: model
|
|
258
|
-
if (diffTypes.includes("model")) {
|
|
259
|
-
const entityIds = this.getEntityIdFromPath(diffGroups["model"]);
|
|
264
|
+
if (diffTypes.includes("model") || diffTypes.includes("frame")) {
|
|
260
265
|
console.log("// 액션: 서비스 생성");
|
|
261
|
-
|
|
266
|
+
const mergedGroup = [
|
|
267
|
+
...(diffGroups["model"] ?? []),
|
|
268
|
+
...(diffGroups["frame"] ?? []),
|
|
269
|
+
];
|
|
270
|
+
const params: { namesRecord: EntityNamesRecord; modelTsPath: string }[] =
|
|
271
|
+
mergedGroup.map((modelPath) => {
|
|
272
|
+
if (modelPath.endsWith(".model.js")) {
|
|
273
|
+
const entityId = this.getEntityIdFromPath([modelPath])[0];
|
|
274
|
+
return {
|
|
275
|
+
namesRecord: EntityManager.getNamesFromId(entityId),
|
|
276
|
+
modelTsPath: path.join(
|
|
277
|
+
Sonamu.apiRootPath,
|
|
278
|
+
modelPath
|
|
279
|
+
.replace("/dist/", "/src/")
|
|
280
|
+
.replace(".model.js", ".model.ts")
|
|
281
|
+
),
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
if (modelPath.endsWith("frame.js")) {
|
|
285
|
+
const [, frameName] = modelPath.match(/.+\/(.+)\.frame.js$/) ?? [];
|
|
286
|
+
return {
|
|
287
|
+
namesRecord: EntityManager.getNamesFromId(frameName),
|
|
288
|
+
modelTsPath: path.join(
|
|
289
|
+
Sonamu.apiRootPath,
|
|
290
|
+
modelPath
|
|
291
|
+
.replace("/dist/", "/src/")
|
|
292
|
+
.replace(".frame.js", ".frame.ts")
|
|
293
|
+
),
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
throw new Error("not reachable");
|
|
297
|
+
});
|
|
298
|
+
await this.actionGenerateServices(params);
|
|
299
|
+
|
|
262
300
|
console.log("// 액션: HTTP파일 생성");
|
|
263
|
-
await this.actionGenerateHttps(
|
|
301
|
+
await this.actionGenerateHttps();
|
|
264
302
|
}
|
|
265
303
|
|
|
266
304
|
// 저장
|
|
@@ -292,19 +330,18 @@ export class Syncer {
|
|
|
292
330
|
.flat();
|
|
293
331
|
}
|
|
294
332
|
|
|
295
|
-
async actionGenerateServices(
|
|
333
|
+
async actionGenerateServices(
|
|
334
|
+
paramsArray: {
|
|
335
|
+
namesRecord: EntityNamesRecord;
|
|
336
|
+
modelTsPath: string;
|
|
337
|
+
}[]
|
|
338
|
+
): Promise<string[]> {
|
|
296
339
|
return (
|
|
297
340
|
await Promise.all(
|
|
298
|
-
|
|
299
|
-
this.generateTemplate(
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
entityId,
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
overwrite: true,
|
|
306
|
-
}
|
|
307
|
-
)
|
|
341
|
+
paramsArray.map(async (params) =>
|
|
342
|
+
this.generateTemplate("service", params, {
|
|
343
|
+
overwrite: true,
|
|
344
|
+
})
|
|
308
345
|
)
|
|
309
346
|
)
|
|
310
347
|
)
|
|
@@ -312,10 +349,10 @@ export class Syncer {
|
|
|
312
349
|
.flat();
|
|
313
350
|
}
|
|
314
351
|
|
|
315
|
-
async actionGenerateHttps(
|
|
352
|
+
async actionGenerateHttps(): Promise<string[]> {
|
|
316
353
|
const [res] = await this.generateTemplate(
|
|
317
354
|
"generated_http",
|
|
318
|
-
{
|
|
355
|
+
{},
|
|
319
356
|
{ overwrite: true }
|
|
320
357
|
);
|
|
321
358
|
return res;
|
|
@@ -383,6 +420,7 @@ export class Syncer {
|
|
|
383
420
|
functions: Sonamu.apiRootPath + "/src/application/**/*.functions.ts",
|
|
384
421
|
/* compiled-JS 체크 */
|
|
385
422
|
model: Sonamu.apiRootPath + "/dist/application/**/*.model.js",
|
|
423
|
+
frame: Sonamu.apiRootPath + "/dist/application/**/*.frame.js",
|
|
386
424
|
};
|
|
387
425
|
|
|
388
426
|
const filePaths = (
|
|
@@ -525,6 +563,12 @@ export class Syncer {
|
|
|
525
563
|
method.methodName === api.methodName
|
|
526
564
|
);
|
|
527
565
|
});
|
|
566
|
+
if (currentModelApis.length === 0) {
|
|
567
|
+
// const p = path.join(tmpdir(), "sonamu-syncer-error.json");
|
|
568
|
+
// writeFileSync(p, JSON.stringify(registeredApis, null, 2));
|
|
569
|
+
// execSync(`open ${p}`);
|
|
570
|
+
throw new Error(`현재 파일에 사전 등록된 API가 없습니다. ${filePath}`);
|
|
571
|
+
}
|
|
528
572
|
|
|
529
573
|
// 등록된 API에 현재 메소드 타입 정보 확장
|
|
530
574
|
const extendedApis = currentModelApis.map((api) => {
|
|
@@ -722,7 +766,7 @@ export class Syncer {
|
|
|
722
766
|
async autoloadApis() {
|
|
723
767
|
const pathPattern = path.join(
|
|
724
768
|
Sonamu.apiRootPath,
|
|
725
|
-
"/src/application/**/*.model.ts"
|
|
769
|
+
"/src/application/**/*.{model,frame}.ts"
|
|
726
770
|
);
|
|
727
771
|
// console.debug(chalk.yellow(`autoload:APIs @ ${pathPattern}`));
|
|
728
772
|
|
|
@@ -737,7 +781,7 @@ export class Syncer {
|
|
|
737
781
|
async autoloadModels(): Promise<{ [modelName: string]: unknown }> {
|
|
738
782
|
const pathPattern = path.join(
|
|
739
783
|
Sonamu.apiRootPath,
|
|
740
|
-
"dist/application/**/*.model.js"
|
|
784
|
+
"dist/application/**/*.{model,frame}.js"
|
|
741
785
|
);
|
|
742
786
|
// console.debug(chalk.yellow(`autoload:models @ ${pathPattern}`));
|
|
743
787
|
|
|
@@ -752,7 +796,9 @@ export class Syncer {
|
|
|
752
796
|
.map(({ imported }) => Object.entries(imported))
|
|
753
797
|
.flat();
|
|
754
798
|
this.models = Object.fromEntries(
|
|
755
|
-
functions.filter(
|
|
799
|
+
functions.filter(
|
|
800
|
+
([name]) => name.endsWith("Model") || name.endsWith("Frame")
|
|
801
|
+
)
|
|
756
802
|
);
|
|
757
803
|
return this.models;
|
|
758
804
|
}
|
|
@@ -839,22 +885,13 @@ export class Syncer {
|
|
|
839
885
|
const template: Template = this.getTemplate(key);
|
|
840
886
|
|
|
841
887
|
let extra: unknown[] = [];
|
|
842
|
-
if (
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
)
|
|
846
|
-
) {
|
|
847
|
-
const entityId = (options as TemplateOptions["
|
|
848
|
-
|
|
849
|
-
if (key === "service" || key === "generated_http") {
|
|
850
|
-
// service 필요 정보 (API 리스트)
|
|
851
|
-
const entity = EntityManager.get(entityId!);
|
|
852
|
-
const modelTsPath = `${path.join(
|
|
853
|
-
Sonamu.apiRootPath,
|
|
854
|
-
"/src/application"
|
|
855
|
-
)}/${entity.names.fs}/${entity.names.fs}.model.ts`;
|
|
856
|
-
extra = [await this.readApisFromFile(modelTsPath)];
|
|
857
|
-
} else if (key === "view_list" || key === "model") {
|
|
888
|
+
if (key === "service") {
|
|
889
|
+
// service 필요 정보 (API 리스트)
|
|
890
|
+
const { modelTsPath } = options as TemplateOptions["service"];
|
|
891
|
+
extra = [await this.readApisFromFile(modelTsPath)];
|
|
892
|
+
} else if (["model", "view_list", "view_form"].includes(key)) {
|
|
893
|
+
const entityId = (options as TemplateOptions["model"]).entityId;
|
|
894
|
+
if (key === "view_list" || key === "model") {
|
|
858
895
|
// view_list 필요 정보 (컬럼 노드, 리스트파라미터 노드)
|
|
859
896
|
const columnsNode = await this.getColumnsNode(entityId, "A");
|
|
860
897
|
const listParamsZodType = await this.getZodTypeById(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import inflection from "inflection";
|
|
2
2
|
import _ from "lodash";
|
|
3
3
|
import { TemplateOptions } from "../types/types";
|
|
4
|
-
import {
|
|
4
|
+
import { EntityNamesRecord } from "../entity/entity-manager";
|
|
5
5
|
import { ApiParamType, ApiParam } from "../types/types";
|
|
6
6
|
import {
|
|
7
7
|
apiParamTypeToTsType,
|
|
@@ -24,9 +24,7 @@ export class Template__service extends Template {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
render({
|
|
28
|
-
const names = EntityManager.getNamesFromId(entityId);
|
|
29
|
-
|
|
27
|
+
render({ namesRecord }: TemplateOptions["service"], apis: ExtendedApi[]) {
|
|
30
28
|
// 서비스 TypeSource
|
|
31
29
|
const { lines, importKeys } = this.getTypeSource(apis);
|
|
32
30
|
|
|
@@ -36,7 +34,7 @@ export class Template__service extends Template {
|
|
|
36
34
|
);
|
|
37
35
|
|
|
38
36
|
return {
|
|
39
|
-
...this.getTargetAndPath(
|
|
37
|
+
...this.getTargetAndPath(namesRecord),
|
|
40
38
|
body: lines.join("\n"),
|
|
41
39
|
importKeys: importKeys.filter(
|
|
42
40
|
(key) => ["ListResult"].includes(key) === false
|
|
@@ -154,7 +152,7 @@ export class Template__service extends Template {
|
|
|
154
152
|
})
|
|
155
153
|
.join("\n\n");
|
|
156
154
|
|
|
157
|
-
return `export namespace ${modelName.replace(/Model$/, "Service")} {
|
|
155
|
+
return `export namespace ${modelName.replace(/Model$/, "Service").replace(/Frame$/, "Service")} {
|
|
158
156
|
${methodCodes}
|
|
159
157
|
}`;
|
|
160
158
|
})
|
package/src/types/types.ts
CHANGED
|
@@ -124,8 +124,8 @@ type _RelationProp = {
|
|
|
124
124
|
type: "relation";
|
|
125
125
|
name: string;
|
|
126
126
|
with: string;
|
|
127
|
-
nullable?: boolean;
|
|
128
|
-
toFilter?: true;
|
|
127
|
+
nullable?: boolean; // DEFAULT: false
|
|
128
|
+
toFilter?: true; // DEFAULT: false
|
|
129
129
|
desc?: string;
|
|
130
130
|
};
|
|
131
131
|
export type OneToOneRelationProp = _RelationProp & {
|
|
@@ -134,8 +134,9 @@ export type OneToOneRelationProp = _RelationProp & {
|
|
|
134
134
|
} & (
|
|
135
135
|
| {
|
|
136
136
|
hasJoinColumn: true;
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
useConstraint?: boolean; // DEFAULT: true
|
|
138
|
+
onUpdate?: RelationOn; // DEFAULT: RESTRICT
|
|
139
|
+
onDelete?: RelationOn; // DEFAULT: RESTRICT
|
|
139
140
|
}
|
|
140
141
|
| {
|
|
141
142
|
hasJoinColumn: false;
|
|
@@ -144,8 +145,9 @@ export type OneToOneRelationProp = _RelationProp & {
|
|
|
144
145
|
export type BelongsToOneRelationProp = _RelationProp & {
|
|
145
146
|
relationType: "BelongsToOne";
|
|
146
147
|
customJoinClause?: string;
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
useConstraint?: boolean; // DEFAULT: true
|
|
149
|
+
onUpdate?: RelationOn; // DEFAULT: RESTRICT
|
|
150
|
+
onDelete?: RelationOn; // DEFAULT: RESTRICT
|
|
149
151
|
};
|
|
150
152
|
export type HasManyRelationProp = _RelationProp & {
|
|
151
153
|
relationType: "HasMany";
|
|
@@ -684,7 +686,17 @@ export const TemplateOptions = z.object({
|
|
|
684
686
|
entityId: z.string(),
|
|
685
687
|
}),
|
|
686
688
|
service: z.object({
|
|
687
|
-
|
|
689
|
+
namesRecord: z.object({
|
|
690
|
+
fs: z.string(),
|
|
691
|
+
fsPlural: z.string(),
|
|
692
|
+
camel: z.string(),
|
|
693
|
+
camelPlural: z.string(),
|
|
694
|
+
capital: z.string(),
|
|
695
|
+
capitalPlural: z.string(),
|
|
696
|
+
upper: z.string(),
|
|
697
|
+
constant: z.string(),
|
|
698
|
+
}),
|
|
699
|
+
modelTsPath: z.string(),
|
|
688
700
|
}),
|
|
689
701
|
view_list: z.object({
|
|
690
702
|
entityId: z.string(),
|