@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
|
-
});
|