vsrepo 1.1.2 → 1.1.3
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.
|
@@ -1,84 +1,127 @@
|
|
|
1
|
-
import
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import { VSRepoConfigError, VSRepoBuildError } from "./VSRepoError.js";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
4
|
+
const stringSchema = z.string().trim().nonempty();
|
|
5
|
+
const objectSchema = z.looseObject({});
|
|
6
|
+
const booleanSchema = z.boolean();
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
export function validateConfig(config) {
|
|
9
|
+
const configSchema = z.strictObject({
|
|
10
|
+
tableName: stringSchema,
|
|
11
|
+
pkName: stringSchema,
|
|
12
|
+
selectModels: z.record(stringSchema, objectSchema).optional(),
|
|
13
|
+
defaultSelectModel: stringSchema.optional(),
|
|
14
|
+
requiredWhere: objectSchema.optional(),
|
|
15
|
+
relations: z.record(
|
|
16
|
+
stringSchema,
|
|
17
|
+
z.strictObject({
|
|
18
|
+
mode: z.enum(['otm', 'mtm', 'mto', 'oto']),
|
|
19
|
+
restriction: z.enum(['set', 'add']),
|
|
20
|
+
pk: stringSchema,
|
|
21
|
+
nullAble: booleanSchema.optional(),
|
|
22
|
+
})
|
|
23
|
+
).optional(),
|
|
24
|
+
methods: z.record(stringSchema, z.strictObject({
|
|
25
|
+
map: booleanSchema,
|
|
26
|
+
selectModel: stringSchema.or(z.literal(false)).optional(),
|
|
27
|
+
whereType: z.enum(["overwrite", "extending"]).optional(),
|
|
28
|
+
proxyTo: stringSchema.optional(),
|
|
29
|
+
pushWhere: objectSchema.optional(),
|
|
30
|
+
fbMode: z.enum(["one", "list"]).optional(),
|
|
31
|
+
injectOrdenation: objectSchema.or(z.array(objectSchema)).optional(),
|
|
32
|
+
injectPagination: objectSchema.optional()
|
|
33
|
+
})).optional()
|
|
34
|
+
}).superRefine((config, ctx)=>{
|
|
35
|
+
if (config.defaultSelectModel && !config.selectModels?.[config.defaultSelectModel]) {
|
|
36
|
+
ctx.addIssue({
|
|
37
|
+
code: "vs_custom",
|
|
38
|
+
path: ["defaultSelectModel"],
|
|
39
|
+
message: "must be a valid key of 'selectModels'",
|
|
40
|
+
});
|
|
19
41
|
}
|
|
20
42
|
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
43
|
+
if (config.methods) {
|
|
44
|
+
for (const [key, method] of Object.entries(config.methods)) {
|
|
45
|
+
if (method.selectModel && !config.selectModels?.[method.selectModel]) {
|
|
46
|
+
ctx.addIssue({
|
|
47
|
+
code: "vs_custom",
|
|
48
|
+
path: ["methods", key, "selectModel"],
|
|
49
|
+
message: "must be a valid key of 'selectModels'",
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
24
53
|
}
|
|
54
|
+
});
|
|
25
55
|
|
|
26
|
-
|
|
56
|
+
const configParsed = configSchema.safeParse(config);
|
|
27
57
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
58
|
+
if(!configParsed.success) {
|
|
59
|
+
const firstIssue = configParsed.error.issues[0];
|
|
60
|
+
const path = firstIssue.path.length ? firstIssue.path.join(".") : "config";
|
|
61
|
+
throw new VSRepoConfigError(`[VSRepository] (config) ${path}: ${firstIssue.message}`)
|
|
31
62
|
}
|
|
32
63
|
|
|
33
|
-
|
|
34
|
-
const error = new this.throws("");
|
|
35
|
-
error.message = `[VSRepository] (${error.type}) '${fieldName}' ${reason}.`;
|
|
36
|
-
return error;
|
|
37
|
-
}
|
|
64
|
+
return configParsed.data;
|
|
38
65
|
}
|
|
39
66
|
|
|
40
|
-
export function
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
67
|
+
export function validateBuildConfig(buildConfig, buildInstance) {
|
|
68
|
+
const activeSchema = booleanSchema.default(true);
|
|
69
|
+
const defaultSelectSchema = buildInstance.selectModels ?
|
|
70
|
+
z.enum(Object.keys(buildInstance.selectModels)).optional()
|
|
71
|
+
: z.never("can only be passed if you have configured 'selectModels'.");
|
|
72
|
+
const ignoreRequiredWhereSchema = booleanSchema.default(false);
|
|
73
|
+
|
|
74
|
+
const buildConfigSchema = z.strictObject({
|
|
75
|
+
freeze: booleanSchema.default(true),
|
|
76
|
+
showWorking: booleanSchema.default(false),
|
|
77
|
+
baseMethods: z.strictObject({
|
|
78
|
+
get: z.strictObject({
|
|
79
|
+
active: activeSchema,
|
|
80
|
+
defaultSelect: defaultSelectSchema,
|
|
81
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
82
|
+
}).optional(),
|
|
83
|
+
getOrThrow: z.strictObject({
|
|
84
|
+
active: activeSchema,
|
|
85
|
+
defaultSelect: defaultSelectSchema,
|
|
86
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
87
|
+
}).optional(),
|
|
88
|
+
getAll: z.strictObject({
|
|
89
|
+
active: activeSchema,
|
|
90
|
+
defaultSelect: defaultSelectSchema,
|
|
91
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
92
|
+
}).optional(),
|
|
93
|
+
remove: z.strictObject({
|
|
94
|
+
active: activeSchema,
|
|
95
|
+
defaultSelect: defaultSelectSchema,
|
|
96
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
97
|
+
}).optional(),
|
|
98
|
+
save: z.strictObject({
|
|
99
|
+
active: activeSchema,
|
|
100
|
+
defaultSelect: defaultSelectSchema,
|
|
101
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
102
|
+
}).optional(),
|
|
103
|
+
removeList: z.strictObject({
|
|
104
|
+
active: activeSchema,
|
|
105
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
106
|
+
}).optional(),
|
|
107
|
+
total: z.strictObject({
|
|
108
|
+
active: activeSchema,
|
|
109
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
110
|
+
}).optional(),
|
|
111
|
+
has: z.strictObject({
|
|
112
|
+
active: activeSchema,
|
|
113
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
114
|
+
}).optional(),
|
|
115
|
+
}).optional()
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const buildConfigParsed = buildConfigSchema.safeParse(buildConfig);
|
|
119
|
+
|
|
120
|
+
if(!buildConfigParsed.success) {
|
|
121
|
+
const firstIssue = buildConfigParsed.error.issues[0];
|
|
122
|
+
const path = firstIssue.path.length ? firstIssue.path.join(".") : "config";
|
|
123
|
+
throw new VSRepoBuildError(`[VSRepository] (build) ${path}: ${firstIssue.message}`)
|
|
54
124
|
}
|
|
55
125
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
for (const key of Object.keys(config.relations)) {
|
|
60
|
-
const relation = config.relations[key];
|
|
61
|
-
|
|
62
|
-
validator.validate(relation.pk, "pk", "string", false, false, `of relation '${key}' must be a string`);
|
|
63
|
-
validator.validate(relation.mode, "mode", (field) => ['otm', 'mtm', 'mto', 'oto'].includes(field), false, false, `of relation '${key}' must be 'otm', 'mtm', 'mto' or 'oto'`);
|
|
64
|
-
validator.validate(relation.restriction, "restriction", (field) => ['set', 'add'].includes(field), false, false, `of relation '${key}' must be 'set' or 'add'`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
validator.validate(config.requiredWhere, "requiredWhere", "object", true);
|
|
69
|
-
|
|
70
|
-
if(config.methods !== undefined) {
|
|
71
|
-
validator.validate(config.methods, "methods", "object");
|
|
72
|
-
|
|
73
|
-
for (const [key, value] of Object.entries(config.methods)) {
|
|
74
|
-
validator.validate(value.map, "map", "boolean", false, false, `on ${key} must be a valid boolean`);
|
|
75
|
-
validator.validate(value.whereType, "whereType", (field) => ['extending', 'overwrite'].includes(field), true, false, `on ${key} must be 'extending' or 'overwrite'`);
|
|
76
|
-
validator.validate(value.selectModel, "selectModel", (field) => !!(field === false || (config.selectModels && Object.keys(config.selectModels).includes(field))), true, false, `on ${key} must be a valid key of 'selectModels'`);
|
|
77
|
-
validator.validate(value.proxyTo, "proxyTo", "string", true, false, `on ${key} must be a valid string`);
|
|
78
|
-
validator.validate(value.fbMode, "fbMode", (field) => ['one', 'list'].includes(field), true, false, `on ${key} must be 'one' or 'list'`);
|
|
79
|
-
validator.validate(value.pushWhere, "pushWhere", "object", true, false, `on ${key} must be a valid object`);
|
|
80
|
-
validator.validate(value.injectOrdenation, "injectOrdenation", "object", true, false, `on ${key} must be a valid object or array`);
|
|
81
|
-
validator.validate(value.injectPagination, "injectPagination", "object", true, false, `on ${key} must be a valid object`);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
126
|
+
return buildConfigParsed.data;
|
|
127
|
+
}
|
|
@@ -590,6 +590,11 @@ export type BuiltRepository<T extends object, M extends Prisma.ModelName, Config
|
|
|
590
590
|
* Estende o repository com métodos personalizados sem perder a tipagem.
|
|
591
591
|
*/
|
|
592
592
|
extend<E>(extensionFunc: (repo: BuiltRepository<T, M, Config, C>) => E): BuiltRepository<T, M, Config, C> & E;
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Instância do Prisma Client passada no `build`.
|
|
596
|
+
*/
|
|
597
|
+
readonly prisma: DbClient;
|
|
593
598
|
} & DynamicMethods<T, M, Config, PrismaModelInputs<M>> & InjectedBaseMethods<T, M, Config, C>;
|
|
594
599
|
|
|
595
600
|
/**
|
|
@@ -605,7 +610,7 @@ export declare class VSRepository<T extends object, M extends Prisma.ModelName,
|
|
|
605
610
|
/**
|
|
606
611
|
* Constrói o repository final com os métodos base e dinâmicos.
|
|
607
612
|
*/
|
|
608
|
-
build<C extends BuildConfig<
|
|
613
|
+
build<C extends BuildConfig<keyof ExtractSelectModels<Config>>>(prisma: DbClient, config?: C): BuiltRepository<T, M, Config, C>;
|
|
609
614
|
vsrepocache: never;
|
|
610
615
|
}
|
|
611
616
|
|
|
@@ -9,7 +9,7 @@ export * from "./VSRepoError.js";
|
|
|
9
9
|
|
|
10
10
|
// * Importando classes de erro
|
|
11
11
|
import { VSRepoBuildError, VSRepoExtendError, VSRepoRuntimeError } from "./VSRepoError.js";
|
|
12
|
-
import { validateConfig } from "./VSRepoUtils.js";
|
|
12
|
+
import { validateBuildConfig, validateConfig } from "./VSRepoUtils.js";
|
|
13
13
|
|
|
14
14
|
// * Essa é a classe pincipal, é a partir dela que serão criados os objetos dos repositories
|
|
15
15
|
export class VSRepository {
|
|
@@ -29,7 +29,7 @@ export class VSRepository {
|
|
|
29
29
|
methods;
|
|
30
30
|
|
|
31
31
|
constructor(config) {
|
|
32
|
-
validateConfig(config);
|
|
32
|
+
config = validateConfig(config);
|
|
33
33
|
|
|
34
34
|
this.vsrepocache = new Map();
|
|
35
35
|
this.tableName = config.tableName;
|
|
@@ -59,18 +59,17 @@ export class VSRepository {
|
|
|
59
59
|
return extended;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
build(prisma, config = {}) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if(typeof config !== 'object' || config === null) {
|
|
66
|
-
throw new VSRepoBuildError(`[VSRepository] (build) 'config' must be a valid object.`);
|
|
67
|
-
}
|
|
68
|
-
if(config.freeze === undefined) {
|
|
69
|
-
config.freeze = true;
|
|
62
|
+
build(prisma, config = { freeze: true, showWorking: false }) {
|
|
63
|
+
if(typeof prisma !== 'object' || prisma === null) {
|
|
64
|
+
throw new VSRepoBuildError(`[VSRepository] (build) 'prisma' must be a valid Prisma Client.`);
|
|
70
65
|
}
|
|
71
66
|
|
|
72
67
|
const buildInstance = Object.create(this);
|
|
73
68
|
|
|
69
|
+
config = validateBuildConfig(config, buildInstance);
|
|
70
|
+
|
|
71
|
+
const showWorking = config.showWorking;
|
|
72
|
+
|
|
74
73
|
const relationsKeys = buildInstance.relations ? Object.keys(buildInstance.relations) : [];
|
|
75
74
|
|
|
76
75
|
const methods = buildInstance.methods;
|
|
@@ -487,10 +486,6 @@ export class VSRepository {
|
|
|
487
486
|
whereArgs.push(buildedWhere);
|
|
488
487
|
}
|
|
489
488
|
|
|
490
|
-
if(showWorking) {
|
|
491
|
-
console.log(`[VSRepository] (build) Where object builded to ${keyToMap}:\n`, JSON.stringify(buildedWhere, null, 2));
|
|
492
|
-
}
|
|
493
|
-
|
|
494
489
|
if(buildedWhere.autoInjectVal === undefined) argsCount++;
|
|
495
490
|
}
|
|
496
491
|
|
|
@@ -700,9 +695,9 @@ export class VSRepository {
|
|
|
700
695
|
const missingParams = whereParams.concat(otherParams).slice(args.length);
|
|
701
696
|
throw new VSRepoRuntimeError(`[VSRepository] (runtime) Missing parameters: ${missingParams.join(', ')}`);
|
|
702
697
|
} else if(args.length > argsCount) {
|
|
703
|
-
const optionsArg = args[args.length - 1]
|
|
698
|
+
const optionsArg = args[args.length - 1];
|
|
704
699
|
db = optionsArg.db ?? db;
|
|
705
|
-
optionsSelectModel = optionsArg.selectModel
|
|
700
|
+
optionsSelectModel = optionsArg.selectModel;
|
|
706
701
|
} else {
|
|
707
702
|
args.push('1')
|
|
708
703
|
}
|
|
@@ -1198,7 +1193,9 @@ export class VSRepository {
|
|
|
1198
1193
|
}
|
|
1199
1194
|
}
|
|
1200
1195
|
|
|
1201
|
-
|
|
1196
|
+
buildInstance.prisma = prisma;
|
|
1197
|
+
|
|
1198
|
+
if(config.freeze) Object.freeze(buildInstance);
|
|
1202
1199
|
return buildInstance;
|
|
1203
1200
|
}
|
|
1204
1201
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vsrepo",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Uma biblioteca de repository pattern para Prisma",
|
|
5
5
|
"homepage": "https://github.com/jaobrabo123/VSRepository#readme",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/jaobrabo123/VSRepository"
|
|
8
|
+
"url": "git+https://github.com/jaobrabo123/VSRepository.git"
|
|
9
9
|
},
|
|
10
10
|
"main": "./VSRepository/index.js",
|
|
11
11
|
"types": "./VSRepository/index.d.ts",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"scripts"
|
|
33
33
|
],
|
|
34
34
|
"bin": {
|
|
35
|
-
"vsrepo": "
|
|
35
|
+
"vsrepo": "scripts/configure-prisma-import.mjs"
|
|
36
36
|
},
|
|
37
37
|
"engines": {
|
|
38
38
|
"node": ">=18"
|
|
@@ -63,5 +63,8 @@
|
|
|
63
63
|
"prisma": "^7.8.0",
|
|
64
64
|
"tsx": "^4.22.3",
|
|
65
65
|
"typescript": "^6.0.3"
|
|
66
|
+
},
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"zod": "^4.4.3"
|
|
66
69
|
}
|
|
67
|
-
}
|
|
70
|
+
}
|