@palmares/schemas 0.1.21 → 0.1.22
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/CHANGELOG.md +9 -0
- package/package.json +10 -4
- package/.turbo/turbo-build$colon$watch.log +0 -24
- package/.turbo/turbo-build.log +0 -13
- package/.turbo/turbo-build:watch.log +0 -26
- package/__tests__/.drizzle/migrations/0000_skinny_harrier.sql +0 -22
- package/__tests__/.drizzle/migrations/meta/0000_snapshot.json +0 -156
- package/__tests__/.drizzle/migrations/meta/_journal.json +0 -13
- package/__tests__/.drizzle/schema.ts +0 -35
- package/__tests__/drizzle.config.ts +0 -11
- package/__tests__/eslint.config.js +0 -10
- package/__tests__/manage.ts +0 -5
- package/__tests__/node_modules/.bin/drizzle-kit +0 -17
- package/__tests__/node_modules/.bin/node-gyp +0 -17
- package/__tests__/node_modules/.bin/tsc +0 -17
- package/__tests__/node_modules/.bin/tsserver +0 -17
- package/__tests__/node_modules/.bin/tsx +0 -17
- package/__tests__/package.json +0 -34
- package/__tests__/sqlite.db +0 -0
- package/__tests__/src/core/array.test.ts +0 -131
- package/__tests__/src/core/boolean.test.ts +0 -66
- package/__tests__/src/core/datetime.test.ts +0 -102
- package/__tests__/src/core/index.ts +0 -35
- package/__tests__/src/core/model.test.ts +0 -260
- package/__tests__/src/core/models.ts +0 -50
- package/__tests__/src/core/numbers.test.ts +0 -177
- package/__tests__/src/core/object.test.ts +0 -218
- package/__tests__/src/core/string.test.ts +0 -222
- package/__tests__/src/core/test.test.ts +0 -59
- package/__tests__/src/core/types.test.ts +0 -97
- package/__tests__/src/core/union.test.ts +0 -99
- package/__tests__/src/settings.ts +0 -69
- package/__tests__/tsconfig.json +0 -11
- package/src/adapter/fields/array.ts +0 -31
- package/src/adapter/fields/boolean.ts +0 -43
- package/src/adapter/fields/datetime.ts +0 -43
- package/src/adapter/fields/index.ts +0 -72
- package/src/adapter/fields/number.ts +0 -43
- package/src/adapter/fields/object.ts +0 -52
- package/src/adapter/fields/string.ts +0 -43
- package/src/adapter/fields/union.ts +0 -43
- package/src/adapter/index.ts +0 -37
- package/src/adapter/types.ts +0 -276
- package/src/compile.ts +0 -14
- package/src/conf.ts +0 -30
- package/src/constants.ts +0 -7
- package/src/domain.ts +0 -15
- package/src/exceptions.ts +0 -17
- package/src/index.ts +0 -318
- package/src/middleware.ts +0 -52
- package/src/model.ts +0 -518
- package/src/parsers/convert-from-number.ts +0 -13
- package/src/parsers/convert-from-string.ts +0 -19
- package/src/parsers/index.ts +0 -2
- package/src/schema/array.ts +0 -825
- package/src/schema/boolean.ts +0 -792
- package/src/schema/datetime.ts +0 -704
- package/src/schema/index.ts +0 -5
- package/src/schema/number.ts +0 -929
- package/src/schema/object.ts +0 -799
- package/src/schema/schema.ts +0 -1179
- package/src/schema/string.ts +0 -941
- package/src/schema/types.ts +0 -154
- package/src/schema/union.ts +0 -724
- package/src/types.ts +0 -66
- package/src/utils.ts +0 -389
- package/src/validators/array.ts +0 -183
- package/src/validators/boolean.ts +0 -52
- package/src/validators/datetime.ts +0 -121
- package/src/validators/number.ts +0 -178
- package/src/validators/object.ts +0 -56
- package/src/validators/schema.ts +0 -142
- package/src/validators/string.ts +0 -278
- package/src/validators/types.ts +0 -1
- package/src/validators/union.ts +0 -52
- package/src/validators/utils.ts +0 -226
- package/tsconfig.json +0 -9
- package/tsconfig.types.json +0 -10
@@ -1,66 +0,0 @@
|
|
1
|
-
import * as p from '@palmares/schemas';
|
2
|
-
import { describe } from '@palmares/tests';
|
3
|
-
|
4
|
-
import type JestTestAdapter from '@palmares/jest-tests';
|
5
|
-
|
6
|
-
describe<JestTestAdapter>('Boolean Tests', ({ test }) => {
|
7
|
-
test('optional', async ({ expect }) => {
|
8
|
-
const booleanSchema = p.boolean();
|
9
|
-
const booleanSchemaWithCustomMessage = p.boolean().nonOptional({ message: 'hello' });
|
10
|
-
|
11
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
12
|
-
await Promise.all([
|
13
|
-
booleanSchema.parse(undefined as any),
|
14
|
-
booleanSchemaWithCustomMessage.parse(undefined as any),
|
15
|
-
booleanSchema.parse(true)
|
16
|
-
]);
|
17
|
-
|
18
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
19
|
-
expect(errorsOnFail?.[0]?.code).toBe('required');
|
20
|
-
expect(errorsOnFail?.[0]?.message).toBe('Required');
|
21
|
-
expect((errorsOnValid || []).length).toBe(0);
|
22
|
-
expect(parsed).toBe(true);
|
23
|
-
});
|
24
|
-
|
25
|
-
test('nullable', async ({ expect }) => {
|
26
|
-
const booleanSchema = p.boolean();
|
27
|
-
const booleanSchemaWithCustomMessage = p.boolean().nonNullable({ message: 'hello' });
|
28
|
-
|
29
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
30
|
-
await Promise.all([
|
31
|
-
booleanSchema.parse(null as any),
|
32
|
-
booleanSchemaWithCustomMessage.parse(null as any),
|
33
|
-
booleanSchema.parse(true)
|
34
|
-
]);
|
35
|
-
|
36
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
37
|
-
expect(errorsOnFail?.[0]?.code).toBe('null');
|
38
|
-
expect(errorsOnFail?.[0]?.message).toBe('Cannot be null');
|
39
|
-
expect((errorsOnValid || []).length).toBe(0);
|
40
|
-
expect(parsed).toBe(true);
|
41
|
-
});
|
42
|
-
|
43
|
-
test('true and false values', async ({ expect }) => {
|
44
|
-
const booleanSchema = p.boolean().trueValues(['Y']).falseValues(['N']);
|
45
|
-
|
46
|
-
const [{ errors: errorsTrue, parsed: parsedTrue }, { errors: errorsFalse, parsed: parsedFalse }] =
|
47
|
-
await Promise.all([booleanSchema.parse('Y'), booleanSchema.parse('N')]);
|
48
|
-
|
49
|
-
expect((errorsTrue || []).length).toBe(0);
|
50
|
-
expect((errorsFalse || []).length).toBe(0);
|
51
|
-
expect(parsedTrue).toBe(true);
|
52
|
-
expect(parsedFalse).toBe(false);
|
53
|
-
});
|
54
|
-
|
55
|
-
test('number and string values', async ({ expect }) => {
|
56
|
-
const booleanSchema = p.boolean().allowNumber().allowString();
|
57
|
-
|
58
|
-
const [{ errors: errorsNumber, parsed: parsedNumber }, { errors: errorsString, parsed: parsedString }] =
|
59
|
-
await Promise.all([booleanSchema.parse(1), booleanSchema.parse('true')]);
|
60
|
-
|
61
|
-
expect((errorsNumber || []).length).toBe(0);
|
62
|
-
expect((errorsString || []).length).toBe(0);
|
63
|
-
expect(parsedNumber).toBe(true);
|
64
|
-
expect(parsedString).toBe(true);
|
65
|
-
});
|
66
|
-
});
|
@@ -1,102 +0,0 @@
|
|
1
|
-
import * as p from '@palmares/schemas';
|
2
|
-
import { describe } from '@palmares/tests';
|
3
|
-
|
4
|
-
import type JestTestAdapter from '@palmares/jest-tests';
|
5
|
-
|
6
|
-
describe<JestTestAdapter>('Datetime Tests', ({ test }) => {
|
7
|
-
test('optional', async ({ expect }) => {
|
8
|
-
const datetimeSchema = p.datetime();
|
9
|
-
const datetimeSchemaWithCustomMessage = p.datetime().nonOptional({ message: 'hello' });
|
10
|
-
const now = new Date();
|
11
|
-
|
12
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
13
|
-
await Promise.all([
|
14
|
-
datetimeSchema.parse(undefined as any),
|
15
|
-
datetimeSchemaWithCustomMessage.parse(undefined as any),
|
16
|
-
datetimeSchema.parse(now)
|
17
|
-
]);
|
18
|
-
|
19
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
20
|
-
expect(errorsOnFail?.[0]?.code).toBe('required');
|
21
|
-
expect(errorsOnFail?.[0]?.message).toBe('Required');
|
22
|
-
expect((errorsOnValid || []).length).toBe(0);
|
23
|
-
expect(parsed.toISOString()).toBe(now.toISOString());
|
24
|
-
});
|
25
|
-
|
26
|
-
test('nullable', async ({ expect }) => {
|
27
|
-
const datetimeSchema = p.datetime();
|
28
|
-
const datetimeSchemaWithCustomMessage = p.datetime().nonNullable({ message: 'hello' });
|
29
|
-
const now = new Date();
|
30
|
-
|
31
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
32
|
-
await Promise.all([
|
33
|
-
datetimeSchema.parse(null as any),
|
34
|
-
datetimeSchemaWithCustomMessage.parse(null as any),
|
35
|
-
datetimeSchema.parse(now)
|
36
|
-
]);
|
37
|
-
|
38
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
39
|
-
expect(errorsOnFail?.[0]?.code).toBe('null');
|
40
|
-
expect(errorsOnFail?.[0]?.message).toBe('Cannot be null');
|
41
|
-
expect((errorsOnValid || []).length).toBe(0);
|
42
|
-
expect(parsed.toISOString()).toBe(now.toISOString());
|
43
|
-
});
|
44
|
-
|
45
|
-
test('below', async ({ expect }) => {
|
46
|
-
const nowMinus10Minutes = new Date();
|
47
|
-
nowMinus10Minutes.setMinutes(-10);
|
48
|
-
const nowMinus20Minutes = new Date();
|
49
|
-
nowMinus20Minutes.setMinutes(-20);
|
50
|
-
const datetimeSchema = p.datetime().below(nowMinus10Minutes);
|
51
|
-
const datetimeSchemaWithCustomMessage = p
|
52
|
-
.datetime()
|
53
|
-
.below(nowMinus10Minutes, { message: 'hello', inclusive: false });
|
54
|
-
|
55
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
56
|
-
await Promise.all([
|
57
|
-
datetimeSchema.parse(nowMinus10Minutes),
|
58
|
-
datetimeSchemaWithCustomMessage.parse(nowMinus10Minutes),
|
59
|
-
datetimeSchema.parse(nowMinus20Minutes)
|
60
|
-
]);
|
61
|
-
|
62
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
63
|
-
expect(errorsOnFail?.[0]?.code).toBe('below');
|
64
|
-
expect(errorsOnFail?.[0]?.message).toBe('Value is not below the specified date');
|
65
|
-
expect((errorsOnValid || []).length).toBe(0);
|
66
|
-
expect(parsed.toISOString()).toBe(nowMinus20Minutes.toISOString());
|
67
|
-
});
|
68
|
-
|
69
|
-
test('above', async ({ expect }) => {
|
70
|
-
const nowPlus10Minutes = new Date();
|
71
|
-
nowPlus10Minutes.setMinutes(nowPlus10Minutes.getMinutes() + 10);
|
72
|
-
const nowPlus20Minutes = new Date();
|
73
|
-
nowPlus20Minutes.setMinutes(nowPlus20Minutes.getMinutes() + 20);
|
74
|
-
const datetimeSchema = p.datetime().above(nowPlus10Minutes);
|
75
|
-
const datetimeSchemaWithCustomMessage = p
|
76
|
-
.datetime()
|
77
|
-
.below(nowPlus10Minutes, { message: 'hello', inclusive: false });
|
78
|
-
|
79
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
80
|
-
await Promise.all([
|
81
|
-
datetimeSchema.parse(nowPlus10Minutes),
|
82
|
-
datetimeSchemaWithCustomMessage.parse(nowPlus10Minutes),
|
83
|
-
datetimeSchema.parse(nowPlus20Minutes)
|
84
|
-
]);
|
85
|
-
|
86
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
87
|
-
expect(errorsOnFail?.[0]?.code).toBe('above');
|
88
|
-
expect(errorsOnFail?.[0]?.message).toBe('Value is not above the specified date');
|
89
|
-
expect((errorsOnValid || []).length).toBe(0);
|
90
|
-
expect(parsed.toISOString()).toBe(nowPlus20Minutes.toISOString());
|
91
|
-
});
|
92
|
-
|
93
|
-
test('allowString', async ({ expect }) => {
|
94
|
-
const datetimeSchema = p.datetime().allowString();
|
95
|
-
const now = new Date();
|
96
|
-
|
97
|
-
const { errors: errorsOnValid, parsed } = await datetimeSchema.parse(now.toISOString());
|
98
|
-
|
99
|
-
expect((errorsOnValid || []).length).toBe(0);
|
100
|
-
expect((parsed as Date).toISOString()).toBe(now.toISOString());
|
101
|
-
});
|
102
|
-
});
|
@@ -1,35 +0,0 @@
|
|
1
|
-
import { domain } from '@palmares/core';
|
2
|
-
import { testDomainModifier, } from '@palmares/tests';
|
3
|
-
import { databaseDomainModifier } from '@palmares/databases';
|
4
|
-
import { migrate } from 'drizzle-orm/better-sqlite3/migrator';
|
5
|
-
|
6
|
-
import * as models from './models';
|
7
|
-
import { db } from '../settings';
|
8
|
-
|
9
|
-
export default domain('testingZodSchemas', __dirname, {
|
10
|
-
commands: {
|
11
|
-
drizzleMigrate: {
|
12
|
-
description: 'Migrate the database using drizzle',
|
13
|
-
keywordArgs: undefined,
|
14
|
-
positionalArgs: undefined,
|
15
|
-
handler: () => {
|
16
|
-
migrate(db as any, { migrationsFolder: './.drizzle/migrations' });
|
17
|
-
}
|
18
|
-
}
|
19
|
-
},
|
20
|
-
modifiers: [testDomainModifier, databaseDomainModifier] as const,
|
21
|
-
getMigrations: () => [],
|
22
|
-
getModels: () => models,
|
23
|
-
getTests: () => [
|
24
|
-
//__dirname + '/test.test.ts',
|
25
|
-
//__dirname + '/numbers.test.ts',
|
26
|
-
//__dirname + '/boolean.test.ts',
|
27
|
-
//__dirname + '/datetime.test.ts',
|
28
|
-
//__dirname + '/object.test.ts',
|
29
|
-
//__dirname + '/union.test.ts',
|
30
|
-
//__dirname + '/array.test.ts',
|
31
|
-
//__dirname + '/types.test.ts',
|
32
|
-
//__dirname + '/string.test.ts',
|
33
|
-
__dirname + '/model.test.ts'
|
34
|
-
]
|
35
|
-
});
|
@@ -1,260 +0,0 @@
|
|
1
|
-
import * as p from '@palmares/schemas';
|
2
|
-
import { afterAll, beforeAll, describe } from '@palmares/tests';
|
3
|
-
import { Company, User } from './models';
|
4
|
-
|
5
|
-
describe('Model tests', ({ test }) => {
|
6
|
-
beforeAll(async () => {
|
7
|
-
await Company.default.set({
|
8
|
-
name: 'Targaryen',
|
9
|
-
usersOfCompany: [{
|
10
|
-
name: 'Rhaenyra Targaryen',
|
11
|
-
age: 25
|
12
|
-
}, {
|
13
|
-
name: 'Aegon Targaryen',
|
14
|
-
age: 21
|
15
|
-
}]
|
16
|
-
}, {
|
17
|
-
includes: [{
|
18
|
-
model: User
|
19
|
-
}]
|
20
|
-
})
|
21
|
-
await Company.default.set({
|
22
|
-
name: 'Stark',
|
23
|
-
usersOfCompany: [{
|
24
|
-
name: 'Arya Stark',
|
25
|
-
age: 22
|
26
|
-
}, {
|
27
|
-
name: 'Ned Stark',
|
28
|
-
age: 46
|
29
|
-
}, {
|
30
|
-
name: 'Sansa Stark',
|
31
|
-
age: 26
|
32
|
-
}]
|
33
|
-
}, {
|
34
|
-
includes: [{
|
35
|
-
model: User
|
36
|
-
}]
|
37
|
-
})
|
38
|
-
});
|
39
|
-
|
40
|
-
|
41
|
-
test('basic', async ({ expect }) => {
|
42
|
-
const modelWithAllFields = p.modelSchema(User, {
|
43
|
-
omit: []
|
44
|
-
});
|
45
|
-
const modelWithFieldsOmitted = p.modelSchema(User, {
|
46
|
-
omit: ['id', 'createdAt']
|
47
|
-
});
|
48
|
-
const modelWithAFewFieldsShown = p.modelSchema(User, {
|
49
|
-
show: ['name', 'age', 'companyId']
|
50
|
-
});
|
51
|
-
const data = await User.default.get({
|
52
|
-
search: {
|
53
|
-
name: {
|
54
|
-
like: '%Stark'
|
55
|
-
}
|
56
|
-
}
|
57
|
-
})
|
58
|
-
|
59
|
-
const [
|
60
|
-
dataWithAllFields,
|
61
|
-
dataWithFieldsOmitted,
|
62
|
-
dataWithFewFieldsShown,
|
63
|
-
{ parsed: parsedDataWithAllFields, errors: errorsOfAllFields },
|
64
|
-
{ parsed: parsedDataWithFieldsOmitted, errors: errorsOfFieldsOmitted },
|
65
|
-
{ parsed: parsedDataWithFewFieldsShown, errors: errorsOfAFewFieldsShown }
|
66
|
-
] = await Promise.all([
|
67
|
-
modelWithAllFields.data(structuredClone(data[0])),
|
68
|
-
modelWithFieldsOmitted.data(structuredClone(data[0])),
|
69
|
-
modelWithAFewFieldsShown.data(structuredClone(data[0])),
|
70
|
-
modelWithAllFields.parse(structuredClone(data[0])),
|
71
|
-
modelWithFieldsOmitted.parse(structuredClone(data[0])),
|
72
|
-
modelWithAFewFieldsShown.parse(structuredClone(data[0])),
|
73
|
-
])
|
74
|
-
|
75
|
-
expect(
|
76
|
-
Object.keys(dataWithAllFields).every((key) => ['id', 'name', 'age', 'updatedAt', 'createdAt', 'companyId'].includes(key))
|
77
|
-
).toBe(true);
|
78
|
-
expect(
|
79
|
-
Object.keys(dataWithFieldsOmitted).every((key) => ['name', 'age', 'updatedAt', 'companyId'].includes(key)) &&
|
80
|
-
Object.keys(dataWithFieldsOmitted).every((key) => !['id', 'createdAt'].includes(key))
|
81
|
-
).toBe(true);
|
82
|
-
expect(
|
83
|
-
Object.keys(dataWithFewFieldsShown).every((key) => ['age', 'name', 'companyId'].includes(key)) &&
|
84
|
-
Object.keys(dataWithFewFieldsShown).every((key) => !['createdAt', 'id', 'updatedAt'].includes(key))
|
85
|
-
).toBe(true);
|
86
|
-
expect(
|
87
|
-
Object.keys(parsedDataWithAllFields).every((key) => ['id', 'name', 'age', 'updatedAt', 'createdAt', 'companyId'].includes(key))
|
88
|
-
).toBe(true);
|
89
|
-
expect(
|
90
|
-
Object.keys(parsedDataWithFieldsOmitted).every((key) => ['name', 'age', 'updatedAt', 'companyId'].includes(key)) &&
|
91
|
-
Object.keys(parsedDataWithFieldsOmitted).every((key) => !['id', 'createdAt'].includes(key))
|
92
|
-
).toBe(true);
|
93
|
-
expect(
|
94
|
-
Object.keys(parsedDataWithFewFieldsShown).every((key) => ['age', 'name', 'companyId'].includes(key)) &&
|
95
|
-
Object.keys(parsedDataWithFewFieldsShown).every((key) => !['createdAt', 'id', 'updatedAt'].includes(key))
|
96
|
-
).toBe(true);
|
97
|
-
expect((errorsOfAllFields || []).length).toBe(0);
|
98
|
-
expect((errorsOfFieldsOmitted || []).length).toBe(0);
|
99
|
-
expect((errorsOfAFewFieldsShown || []).length).toBe(0);
|
100
|
-
});
|
101
|
-
|
102
|
-
test('array', async ({expect}) => {
|
103
|
-
const modelWithAllFields = p.modelSchema(User, {
|
104
|
-
many: true,
|
105
|
-
omit: []
|
106
|
-
});
|
107
|
-
const modelWithFieldsOmitted = p.modelSchema(User, {
|
108
|
-
many: true,
|
109
|
-
omit: ['id', 'createdAt']
|
110
|
-
});
|
111
|
-
const modelWithAFewFieldsShown = p.modelSchema(User, {
|
112
|
-
many: true,
|
113
|
-
show: ['name', 'age', 'companyId']
|
114
|
-
});
|
115
|
-
const data = await User.default.get({
|
116
|
-
search: {
|
117
|
-
name: {
|
118
|
-
like: '%Stark'
|
119
|
-
}
|
120
|
-
}
|
121
|
-
});
|
122
|
-
|
123
|
-
const [
|
124
|
-
dataWithAllFields,
|
125
|
-
dataWithFieldsOmitted,
|
126
|
-
dataWithFewFieldsShown,
|
127
|
-
{ parsed: parsedDataWithAllFields, errors: errorsOfAllFields },
|
128
|
-
{ parsed: parsedDataWithFieldsOmitted, errors: errorsOfFieldsOmitted },
|
129
|
-
{ parsed: parsedDataWithFewFieldsShown, errors: errorsOfAFewFieldsShown }
|
130
|
-
] = await Promise.all([
|
131
|
-
modelWithAllFields.data(structuredClone(data)),
|
132
|
-
modelWithFieldsOmitted.data(structuredClone(data)),
|
133
|
-
modelWithAFewFieldsShown.data(structuredClone(data)),
|
134
|
-
modelWithAllFields.parse(structuredClone(data)),
|
135
|
-
modelWithFieldsOmitted.parse(structuredClone(data)),
|
136
|
-
modelWithAFewFieldsShown.parse(structuredClone(data)),
|
137
|
-
])
|
138
|
-
|
139
|
-
expect(
|
140
|
-
Object.keys(dataWithAllFields[0]).every((key) => ['id', 'name', 'age', 'updatedAt', 'createdAt', 'companyId'].includes(key))
|
141
|
-
).toBe(true);
|
142
|
-
expect(
|
143
|
-
Object.keys(dataWithFieldsOmitted[0]).every((key) => ['name', 'age', 'updatedAt', 'companyId'].includes(key)) &&
|
144
|
-
Object.keys(dataWithFieldsOmitted[0]).every((key) => !['id', 'createdAt'].includes(key))
|
145
|
-
).toBe(true);
|
146
|
-
expect(
|
147
|
-
Object.keys(dataWithFewFieldsShown[0]).every((key) => ['age', 'name', 'companyId'].includes(key)) &&
|
148
|
-
Object.keys(dataWithFewFieldsShown[0]).every((key) => !['createdAt', 'id', 'updatedAt'].includes(key))
|
149
|
-
).toBe(true);
|
150
|
-
expect(
|
151
|
-
Object.keys(parsedDataWithAllFields[0]).every((key) => ['id', 'name', 'age', 'updatedAt', 'createdAt', 'companyId'].includes(key))
|
152
|
-
).toBe(true);
|
153
|
-
expect(
|
154
|
-
Object.keys(parsedDataWithFieldsOmitted[0]).every((key) => ['name', 'age', 'updatedAt', 'companyId'].includes(key)) &&
|
155
|
-
Object.keys(parsedDataWithFieldsOmitted[0]).every((key) => !['id', 'createdAt'].includes(key))
|
156
|
-
).toBe(true);
|
157
|
-
expect(
|
158
|
-
Object.keys(parsedDataWithFewFieldsShown[0]).every((key) => ['age', 'name', 'companyId'].includes(key)) &&
|
159
|
-
Object.keys(parsedDataWithFewFieldsShown[0]).every((key) => !['createdAt', 'id', 'updatedAt'].includes(key))
|
160
|
-
).toBe(true);
|
161
|
-
expect(dataWithAllFields.length).toBe(data.length);
|
162
|
-
expect(dataWithFieldsOmitted.length).toBe(data.length);
|
163
|
-
expect(dataWithFewFieldsShown.length).toBe(data.length);
|
164
|
-
expect(parsedDataWithAllFields.length).toBe(data.length);
|
165
|
-
expect(parsedDataWithFieldsOmitted.length).toBe(data.length);
|
166
|
-
expect(parsedDataWithFewFieldsShown.length).toBe(data.length);
|
167
|
-
expect((errorsOfAllFields || []).length).toBe(0);
|
168
|
-
expect((errorsOfFieldsOmitted || []).length).toBe(0);
|
169
|
-
expect((errorsOfAFewFieldsShown || []).length).toBe(0);
|
170
|
-
});
|
171
|
-
|
172
|
-
test('auto join', async ({ expect }) => {
|
173
|
-
const companyModel = p.modelSchema(Company, {
|
174
|
-
omit: ['translatable'],
|
175
|
-
}).optional({ outputOnly: true });
|
176
|
-
const userModel = p.modelSchema(User, {
|
177
|
-
many: true,
|
178
|
-
omit: []
|
179
|
-
}).optional({ outputOnly: true });
|
180
|
-
|
181
|
-
const arrayModelDirectly = p.modelSchema(User, {
|
182
|
-
many: true,
|
183
|
-
fields: {
|
184
|
-
company: companyModel
|
185
|
-
},
|
186
|
-
omit: [],
|
187
|
-
});
|
188
|
-
const arrayModelIndirectly = p.modelSchema(Company, {
|
189
|
-
many: true,
|
190
|
-
fields: {
|
191
|
-
usersOfCompany: userModel
|
192
|
-
},
|
193
|
-
omit: [],
|
194
|
-
})
|
195
|
-
const objectModelDirectly = p.modelSchema(User, {
|
196
|
-
fields: {
|
197
|
-
company: companyModel
|
198
|
-
},
|
199
|
-
omit: [],
|
200
|
-
});
|
201
|
-
|
202
|
-
const objectModelIndirectly = p.modelSchema(Company, {
|
203
|
-
fields: {
|
204
|
-
usersOfCompany: userModel
|
205
|
-
},
|
206
|
-
omit: [],
|
207
|
-
});
|
208
|
-
|
209
|
-
const userData = await User.default.get({
|
210
|
-
search: {
|
211
|
-
name: {
|
212
|
-
like: '%Stark'
|
213
|
-
}
|
214
|
-
}
|
215
|
-
});
|
216
|
-
const companyData = await Company.default.get({
|
217
|
-
search: {
|
218
|
-
name: 'Targaryen'
|
219
|
-
}
|
220
|
-
});
|
221
|
-
|
222
|
-
const [
|
223
|
-
arrayModelDirectlyData,
|
224
|
-
arrayModelIndirectlyData,
|
225
|
-
objectModelDirectlyData,
|
226
|
-
objectModelIndirectlyData
|
227
|
-
] = await Promise.all([
|
228
|
-
arrayModelDirectly.data(structuredClone(userData)),
|
229
|
-
arrayModelIndirectly.data(structuredClone(companyData)),
|
230
|
-
objectModelDirectly.data(structuredClone(userData[0])),
|
231
|
-
objectModelIndirectly.data(structuredClone(companyData[0]))
|
232
|
-
]);
|
233
|
-
|
234
|
-
expect(arrayModelDirectlyData.length).toBe(3);
|
235
|
-
expect(arrayModelDirectlyData[0].company.name).toBe('Stark');
|
236
|
-
expect(arrayModelDirectlyData[2].company.name).toBe('Stark')
|
237
|
-
expect(arrayModelIndirectlyData[0].usersOfCompany.length).toBe(2);
|
238
|
-
expect(arrayModelIndirectlyData[0].usersOfCompany[0].companyId).toBe(arrayModelIndirectlyData[0].id as number);
|
239
|
-
expect(objectModelDirectlyData.company.name).toBe('Stark');
|
240
|
-
expect(objectModelIndirectlyData.usersOfCompany.length).toBe(2);
|
241
|
-
expect(objectModelIndirectlyData.usersOfCompany[0].companyId).toBe(objectModelIndirectlyData.id as number);
|
242
|
-
});
|
243
|
-
|
244
|
-
afterAll(async () => {
|
245
|
-
await User.default.remove({
|
246
|
-
search: {
|
247
|
-
name: {
|
248
|
-
in: ['Arya Stark', 'Ned Stark', 'Sansa Stark', 'Sansa Start', 'Rhaenyra Targaryen', 'Aegon Targaryen']
|
249
|
-
}
|
250
|
-
}
|
251
|
-
});
|
252
|
-
await Company.default.remove({
|
253
|
-
search: {
|
254
|
-
name: {
|
255
|
-
in: ['Stark', 'Targaryen']
|
256
|
-
}
|
257
|
-
}
|
258
|
-
});
|
259
|
-
});
|
260
|
-
});
|
@@ -1,50 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
AutoField,
|
3
|
-
CharField,
|
4
|
-
DateField,
|
5
|
-
ForeignKeyField,
|
6
|
-
IntegerField,
|
7
|
-
Model,
|
8
|
-
ON_DELETE,
|
9
|
-
TranslatableField,
|
10
|
-
define
|
11
|
-
} from '@palmares/databases';
|
12
|
-
|
13
|
-
import type { ModelOptionsType } from '@palmares/databases';
|
14
|
-
|
15
|
-
export const Company = define('Company', {
|
16
|
-
fields: {
|
17
|
-
id: AutoField.new(),
|
18
|
-
name: CharField.new({ maxLength: 255 }),
|
19
|
-
translatable: TranslatableField.new({
|
20
|
-
// eslint-disable-next-line ts/require-await
|
21
|
-
translate: async () => {
|
22
|
-
return `d.real('translatable')`;
|
23
|
-
}
|
24
|
-
})
|
25
|
-
},
|
26
|
-
options: {
|
27
|
-
tableName: 'companies'
|
28
|
-
}
|
29
|
-
});
|
30
|
-
|
31
|
-
export class User extends Model<User>() {
|
32
|
-
fields = {
|
33
|
-
id: AutoField.new(),
|
34
|
-
companyId: ForeignKeyField.new({
|
35
|
-
onDelete: ON_DELETE.CASCADE,
|
36
|
-
relatedName: 'usersOfCompany',
|
37
|
-
relationName: 'company',
|
38
|
-
toField: 'id',
|
39
|
-
relatedTo: Company
|
40
|
-
}),
|
41
|
-
name: CharField.new({ maxLength: 255, dbIndex: true, allowNull: true }),
|
42
|
-
age: IntegerField.new({ dbIndex: true }),
|
43
|
-
updatedAt: DateField.new({ autoNow: true }),
|
44
|
-
createdAt: DateField.new({ autoNowAdd: true })
|
45
|
-
};
|
46
|
-
|
47
|
-
options: ModelOptionsType<User> = {
|
48
|
-
tableName: 'users'
|
49
|
-
};
|
50
|
-
}
|
@@ -1,177 +0,0 @@
|
|
1
|
-
import * as p from '@palmares/schemas';
|
2
|
-
import { describe } from '@palmares/tests';
|
3
|
-
|
4
|
-
import type JestTestAdapter from '@palmares/jest-tests';
|
5
|
-
|
6
|
-
describe<JestTestAdapter>('Number Tests', ({ test }) => {
|
7
|
-
test('optional', async ({ expect }) => {
|
8
|
-
const numberSchema = p.number();
|
9
|
-
const numberSchemaWithCustomMessage = p.number().nonOptional({ message: 'hello' });
|
10
|
-
|
11
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
12
|
-
await Promise.all([
|
13
|
-
numberSchema.parse(undefined as any),
|
14
|
-
numberSchemaWithCustomMessage.parse(undefined as any),
|
15
|
-
numberSchema.parse(1)
|
16
|
-
]);
|
17
|
-
|
18
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
19
|
-
expect(errorsOnFail?.[0]?.code).toBe('required');
|
20
|
-
expect(errorsOnFail?.[0]?.message).toBe('Required');
|
21
|
-
expect((errorsOnValid || []).length).toBe(0);
|
22
|
-
expect(parsed).toBe(1);
|
23
|
-
});
|
24
|
-
|
25
|
-
test('nullable', async ({ expect }) => {
|
26
|
-
const numberSchema = p.number();
|
27
|
-
const numberSchemaWithCustomMessage = p.number().nonNullable({ message: 'hello' });
|
28
|
-
|
29
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
30
|
-
await Promise.all([
|
31
|
-
numberSchema.parse(null as any),
|
32
|
-
numberSchemaWithCustomMessage.parse(null as any),
|
33
|
-
numberSchema.parse(1)
|
34
|
-
]);
|
35
|
-
|
36
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
37
|
-
expect(errorsOnFail?.[0]?.code).toBe('null');
|
38
|
-
expect(errorsOnFail?.[0]?.message).toBe('Cannot be null');
|
39
|
-
expect((errorsOnValid || []).length).toBe(0);
|
40
|
-
expect(parsed).toBe(1);
|
41
|
-
});
|
42
|
-
|
43
|
-
test('maxDigits', async ({ expect }) => {
|
44
|
-
const numberSchema = p.number().maxDigits(5);
|
45
|
-
const numberSchemaWithCustomMessage = p.number().maxDigits(5, { message: 'hello' });
|
46
|
-
|
47
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
48
|
-
await Promise.all([
|
49
|
-
numberSchema.parse(1234567),
|
50
|
-
numberSchemaWithCustomMessage.parse(1234567),
|
51
|
-
numberSchema.parse(1)
|
52
|
-
]);
|
53
|
-
|
54
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
55
|
-
expect(errorsOnFail?.[0]?.code).toBe('maxDigits');
|
56
|
-
expect(errorsOnFail?.[0]?.message).toBe('The number should have at most 5 digits');
|
57
|
-
expect((errorsOnValid || []).length).toBe(0);
|
58
|
-
expect(parsed).toBe(1);
|
59
|
-
});
|
60
|
-
|
61
|
-
test('decimalPlaces', async ({ expect }) => {
|
62
|
-
const numberSchema = p.number().decimalPlaces(2);
|
63
|
-
const numberSchemaWithCustomMessage = p.number().decimalPlaces(2, { message: 'hello' });
|
64
|
-
|
65
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
66
|
-
await Promise.all([
|
67
|
-
numberSchema.parse(123.4567),
|
68
|
-
numberSchemaWithCustomMessage.parse(123.4567),
|
69
|
-
numberSchema.parse(1)
|
70
|
-
]);
|
71
|
-
|
72
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
73
|
-
expect(errorsOnFail?.[0]?.code).toBe('decimalPlaces');
|
74
|
-
expect(errorsOnFail?.[0]?.message).toBe('The number should have 2 decimal places');
|
75
|
-
expect((errorsOnValid || []).length).toBe(0);
|
76
|
-
expect(parsed).toBe(1);
|
77
|
-
});
|
78
|
-
|
79
|
-
test('is', async ({ expect }) => {
|
80
|
-
const numberSchema = p.number().is([1, 2]);
|
81
|
-
const numberSchemaWithCustomMessage = p.number().is([1, 2], { message: 'hello' });
|
82
|
-
|
83
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
84
|
-
await Promise.all([
|
85
|
-
numberSchema.parse(123.4567 as any),
|
86
|
-
numberSchemaWithCustomMessage.parse(123.4567 as any),
|
87
|
-
numberSchema.parse(1)
|
88
|
-
]);
|
89
|
-
|
90
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
91
|
-
expect(errorsOnFail?.[0]?.code).toBe('is');
|
92
|
-
expect(errorsOnFail?.[0]?.message).toBe('The value should be equal to 1,2');
|
93
|
-
expect((errorsOnValid || []).length).toBe(0);
|
94
|
-
expect(parsed).toBe(1);
|
95
|
-
});
|
96
|
-
|
97
|
-
test('is', async ({ expect }) => {
|
98
|
-
const numberSchema = p.number().is([1, 2]);
|
99
|
-
const numberSchemaWithCustomMessage = p.number().is([1, 2], { message: 'hello' });
|
100
|
-
|
101
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
102
|
-
await Promise.all([
|
103
|
-
numberSchema.parse(123.4567 as any),
|
104
|
-
numberSchemaWithCustomMessage.parse(123.4567 as any),
|
105
|
-
numberSchema.parse(1)
|
106
|
-
]);
|
107
|
-
|
108
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
109
|
-
expect(errorsOnFail?.[0]?.code).toBe('is');
|
110
|
-
expect(errorsOnFail?.[0]?.message).toBe('The value should be equal to 1,2');
|
111
|
-
expect((errorsOnValid || []).length).toBe(0);
|
112
|
-
expect(parsed).toBe(1);
|
113
|
-
});
|
114
|
-
|
115
|
-
test('integer', async ({ expect }) => {
|
116
|
-
const numberSchema = p.number().integer();
|
117
|
-
const numberSchemaWithCustomMessage = p.number().integer({ message: 'hello' });
|
118
|
-
|
119
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
120
|
-
await Promise.all([
|
121
|
-
numberSchema.parse(123.4567 as any),
|
122
|
-
numberSchemaWithCustomMessage.parse(123.4567 as any),
|
123
|
-
numberSchema.parse(1)
|
124
|
-
]);
|
125
|
-
|
126
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
127
|
-
expect(errorsOnFail?.[0]?.code).toBe('integer');
|
128
|
-
expect(errorsOnFail?.[0]?.message).toBe('The number should be an integer.');
|
129
|
-
expect((errorsOnValid || []).length).toBe(0);
|
130
|
-
expect(parsed).toBe(1);
|
131
|
-
});
|
132
|
-
|
133
|
-
test('max', async ({ expect }) => {
|
134
|
-
const numberSchema = p.number().max(100, { inclusive: true });
|
135
|
-
const numberSchemaWithCustomMessage = p.number().max(100, { message: 'hello' });
|
136
|
-
|
137
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
138
|
-
await Promise.all([
|
139
|
-
numberSchema.parse(123 as any),
|
140
|
-
numberSchemaWithCustomMessage.parse(123 as any),
|
141
|
-
numberSchema.parse(100)
|
142
|
-
]);
|
143
|
-
|
144
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
145
|
-
expect(errorsOnFail?.[0]?.code).toBe('max');
|
146
|
-
expect(errorsOnFail?.[0]?.message).toBe(
|
147
|
-
'The number is greater than the allowed 100. The value 100 is accepted as well.'
|
148
|
-
);
|
149
|
-
expect((errorsOnValid || []).length).toBe(0);
|
150
|
-
expect(parsed).toBe(100);
|
151
|
-
});
|
152
|
-
|
153
|
-
test('min', async ({ expect }) => {
|
154
|
-
const numberSchema = p.number().min(100, { inclusive: true });
|
155
|
-
const numberSchemaWithCustomMessage = p.number().min(100, { message: 'hello' });
|
156
|
-
|
157
|
-
const [{ errors: errorsOnFail }, { errors: errorsOnFailWithCustomMessage }, { errors: errorsOnValid, parsed }] =
|
158
|
-
await Promise.all([numberSchema.parse(1), numberSchemaWithCustomMessage.parse(1), numberSchema.parse(100)]);
|
159
|
-
|
160
|
-
expect(errorsOnFailWithCustomMessage?.[0]?.message).toBe('hello');
|
161
|
-
expect(errorsOnFail?.[0]?.code).toBe('min');
|
162
|
-
expect(errorsOnFail?.[0]?.message).toBe(
|
163
|
-
'The number is less than the allowed 100. The value 100 is accepted as well.'
|
164
|
-
);
|
165
|
-
expect((errorsOnValid || []).length).toBe(0);
|
166
|
-
expect(parsed).toBe(100);
|
167
|
-
});
|
168
|
-
|
169
|
-
test('allowString', async ({ expect }) => {
|
170
|
-
const numberSchema = p.number().allowString();
|
171
|
-
|
172
|
-
const { errors, parsed } = await numberSchema.parse('100');
|
173
|
-
|
174
|
-
expect((errors || []).length).toBe(0);
|
175
|
-
expect(parsed).toBe(100);
|
176
|
-
});
|
177
|
-
});
|