@zipbul/baker 3.3.1 → 3.4.1

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/index.js +1 -10
  3. package/dist/src/collect.js +1 -26
  4. package/dist/src/configure.js +1 -43
  5. package/dist/src/create-rule.js +1 -41
  6. package/dist/src/decorators/field.js +1 -277
  7. package/dist/src/decorators/index.js +1 -2
  8. package/dist/src/decorators/recipe.js +1 -23
  9. package/dist/src/errors.js +1 -52
  10. package/dist/src/functions/check-call-options.js +1 -51
  11. package/dist/src/functions/deserialize.js +1 -57
  12. package/dist/src/functions/serialize.js +1 -52
  13. package/dist/src/functions/validate.js +1 -49
  14. package/dist/src/interfaces.js +0 -4
  15. package/dist/src/meta-access.js +1 -75
  16. package/dist/src/registry.js +1 -8
  17. package/dist/src/rule-metadata.js +1 -17
  18. package/dist/src/rule-plan.js +1 -117
  19. package/dist/src/rules/array.js +1 -96
  20. package/dist/src/rules/binary.d.ts +3 -0
  21. package/dist/src/rules/binary.js +3 -0
  22. package/dist/src/rules/combinators.js +1 -111
  23. package/dist/src/rules/common.js +1 -77
  24. package/dist/src/rules/date.js +1 -35
  25. package/dist/src/rules/index.d.ts +1 -0
  26. package/dist/src/rules/index.js +1 -9
  27. package/dist/src/rules/locales.js +1 -249
  28. package/dist/src/rules/number.js +1 -79
  29. package/dist/src/rules/object.js +1 -49
  30. package/dist/src/rules/string.js +10 -2033
  31. package/dist/src/rules/typechecker.js +5 -171
  32. package/dist/src/seal/circular-analyzer.js +1 -63
  33. package/dist/src/seal/codegen-utils.js +1 -18
  34. package/dist/src/seal/deserialize-builder.js +265 -1564
  35. package/dist/src/seal/expose-validator.js +1 -65
  36. package/dist/src/seal/seal-state.js +1 -18
  37. package/dist/src/seal/seal.js +1 -431
  38. package/dist/src/seal/serialize-builder.js +66 -370
  39. package/dist/src/seal/validate-meta.js +1 -61
  40. package/dist/src/symbols.js +1 -13
  41. package/dist/src/transformers/collection.transformer.js +1 -25
  42. package/dist/src/transformers/date.transformer.js +1 -18
  43. package/dist/src/transformers/index.js +1 -6
  44. package/dist/src/transformers/luxon.transformer.js +1 -34
  45. package/dist/src/transformers/moment.transformer.js +1 -32
  46. package/dist/src/transformers/number.transformer.js +1 -8
  47. package/dist/src/transformers/string.transformer.js +1 -12
  48. package/dist/src/types.js +0 -1
  49. package/dist/src/utils.js +1 -10
  50. package/package.json +2 -2
@@ -1,77 +1 @@
1
- import { makeRule } from '../rule-plan.js';
2
- // ─────────────────────────────────────────────────────────────────────────────
3
- // equals — strict equality (===). comparison value passed via refs (§4.8 C)
4
- // ─────────────────────────────────────────────────────────────────────────────
5
- export function equals(comparison) {
6
- return makeRule({
7
- name: 'equals',
8
- constraints: { value: comparison },
9
- validate: value => value === comparison,
10
- emit: (varName, ctx) => {
11
- const i = ctx.addRef(comparison);
12
- return `if (${varName} !== refs[${i}]) ${ctx.fail('equals')};`;
13
- },
14
- });
15
- }
16
- // ─────────────────────────────────────────────────────────────────────────────
17
- // notEquals — strict inequality (!==). comparison value passed via refs
18
- // ─────────────────────────────────────────────────────────────────────────────
19
- export function notEquals(comparison) {
20
- return makeRule({
21
- name: 'notEquals',
22
- constraints: { value: comparison },
23
- validate: value => value !== comparison,
24
- emit: (varName, ctx) => {
25
- const i = ctx.addRef(comparison);
26
- return `if (${varName} === refs[${i}]) ${ctx.fail('notEquals')};`;
27
- },
28
- });
29
- }
30
- // ─────────────────────────────────────────────────────────────────────────────
31
- // isEmpty — only undefined | null | '' are treated as empty (§4.8 A)
32
- // ─────────────────────────────────────────────────────────────────────────────
33
- export const isEmpty = makeRule({
34
- name: 'isEmpty',
35
- constraints: {},
36
- validate: value => value === undefined || value === null || value === '',
37
- emit: (varName, ctx) => `if (${varName} !== undefined && ${varName} !== null && ${varName} !== '') ${ctx.fail('isEmpty')};`,
38
- });
39
- // ─────────────────────────────────────────────────────────────────────────────
40
- // isNotEmpty — any value other than undefined | null | '' (§4.8 A)
41
- // ─────────────────────────────────────────────────────────────────────────────
42
- export const isNotEmpty = makeRule({
43
- name: 'isNotEmpty',
44
- constraints: {},
45
- validate: value => value !== undefined && value !== null && value !== '',
46
- emit: (varName, ctx) => `if (${varName} === undefined || ${varName} === null || ${varName} === '') ${ctx.fail('isNotEmpty')};`,
47
- });
48
- // ─────────────────────────────────────────────────────────────────────────────
49
- // isIn — checks inclusion in array. O(1) lookup via Set (§4.8 C)
50
- // ─────────────────────────────────────────────────────────────────────────────
51
- export function isIn(array) {
52
- const set = new Set(array);
53
- return makeRule({
54
- name: 'isIn',
55
- constraints: { values: array },
56
- validate: value => set.has(value),
57
- emit: (varName, ctx) => {
58
- const i = ctx.addRef(set);
59
- return `if (!refs[${i}].has(${varName})) ${ctx.fail('isIn')};`;
60
- },
61
- });
62
- }
63
- // ─────────────────────────────────────────────────────────────────────────────
64
- // isNotIn — checks exclusion from array. O(1) lookup via Set (§4.8 C)
65
- // ─────────────────────────────────────────────────────────────────────────────
66
- export function isNotIn(array) {
67
- const set = new Set(array);
68
- return makeRule({
69
- name: 'isNotIn',
70
- constraints: { values: array },
71
- validate: value => !set.has(value),
72
- emit: (varName, ctx) => {
73
- const i = ctx.addRef(set);
74
- return `if (refs[${i}].has(${varName})) ${ctx.fail('isNotIn')};`;
75
- },
76
- });
77
- }
1
+ import{makeRule as h}from"../rule-plan.js";export function equals(b){return h({name:"equals",constraints:{value:b},validate:(d)=>d===b,emit:(d,f)=>{const g=f.addRef(b);return`if (${d} !== refs[${g}]) ${f.fail("equals")};`}})}export function notEquals(b){return h({name:"notEquals",constraints:{value:b},validate:(d)=>d!==b,emit:(d,f)=>{const g=f.addRef(b);return`if (${d} === refs[${g}]) ${f.fail("notEquals")};`}})}export const isEmpty=h({name:"isEmpty",constraints:{},validate:(b)=>b===void 0||b===null||b==="",emit:(b,d)=>`if (${b} !== undefined && ${b} !== null && ${b} !== '') ${d.fail("isEmpty")};`});export const isNotEmpty=h({name:"isNotEmpty",constraints:{},validate:(b)=>b!==void 0&&b!==null&&b!=="",emit:(b,d)=>`if (${b} === undefined || ${b} === null || ${b} === '') ${d.fail("isNotEmpty")};`});export function isIn(b){const d=new Set(b);return h({name:"isIn",constraints:{values:b},validate:(f)=>d.has(f),emit:(f,g)=>{return`if (!refs[${g.addRef(d)}].has(${f})) ${g.fail("isIn")};`}})}export function isNotIn(b){const d=new Set(b);return h({name:"isNotIn",constraints:{values:b},validate:(f)=>!d.has(f),emit:(f,g)=>{return`if (refs[${g.addRef(d)}].has(${f})) ${g.fail("isNotIn")};`}})}
@@ -1,35 +1 @@
1
- import { makePlannedRule, planCompare, planLiteral, planOr, planTime } from '../rule-plan.js';
2
- // ─────────────────────────────────────────────────────────────────────────────
3
- // minDate — v >= date (inclusive, getTime comparison). (§4.8 C — refs function call)
4
- // ─────────────────────────────────────────────────────────────────────────────
5
- export function minDate(date) {
6
- const timestamp = date.getTime();
7
- const plan = {
8
- cacheKey: 'time',
9
- failure: planOr(planCompare(planTime(), '!==', planTime()), planCompare(planTime(), '<', planLiteral(timestamp))),
10
- };
11
- return makePlannedRule({
12
- name: 'minDate',
13
- requiresType: 'date',
14
- constraints: { min: date.toISOString() },
15
- plan,
16
- validate: value => value instanceof Date && value.getTime() >= timestamp,
17
- });
18
- }
19
- // ─────────────────────────────────────────────────────────────────────────────
20
- // maxDate — v <= date (inclusive, getTime comparison). (§4.8 C — refs function call)
21
- // ─────────────────────────────────────────────────────────────────────────────
22
- export function maxDate(date) {
23
- const timestamp = date.getTime();
24
- const plan = {
25
- cacheKey: 'time',
26
- failure: planOr(planCompare(planTime(), '!==', planTime()), planCompare(planTime(), '>', planLiteral(timestamp))),
27
- };
28
- return makePlannedRule({
29
- name: 'maxDate',
30
- requiresType: 'date',
31
- constraints: { max: date.toISOString() },
32
- plan,
33
- validate: value => value instanceof Date && value.getTime() <= timestamp,
34
- });
35
- }
1
+ import{makePlannedRule as q,planCompare as h,planLiteral as w,planOr as x,planTime as b}from"../rule-plan.js";export function minDate(c){const f=c.getTime(),j={cacheKey:"time",failure:x(h(b(),"!==",b()),h(b(),"<",w(f)))};return q({name:"minDate",requiresType:"date",constraints:{min:c.toISOString()},plan:j,validate:(g)=>g instanceof Date&&g.getTime()>=f})}export function maxDate(c){const f=c.getTime(),j={cacheKey:"time",failure:x(h(b(),"!==",b()),h(b(),">",w(f)))};return q({name:"maxDate",requiresType:"date",constraints:{max:c.toISOString()},plan:j,validate:(g)=>g instanceof Date&&g.getTime()<=f})}
@@ -10,3 +10,4 @@ export { arrayContains, arrayNotContains, arrayMinSize, arrayMaxSize, arrayUniqu
10
10
  export { isNotEmptyObject, isInstance } from './object';
11
11
  export type { IsNotEmptyObjectOptions } from './object';
12
12
  export { isMobilePhone, isPostalCode, isIdentityCard, isPassportNumber } from './locales';
13
+ export { isUint8Array, isByteSize } from './binary';
@@ -1,9 +1 @@
1
- export { isString, isNumber, isBoolean, isDate, isEnum, isInt, isArray, isObject, isRegExp, isFunction, isStatelessRegExp, } from './typechecker.js';
2
- export { oneOf, arrayEvery } from './combinators.js';
3
- export { min, max, isPositive, isNegative, isDivisibleBy } from './number.js';
4
- export { minDate, maxDate } from './date.js';
5
- export { equals, notEquals, isEmpty, isNotEmpty, isIn, isNotIn } from './common.js';
6
- export { minLength, maxLength, length, contains, notContains, matches, isLowercase, isUppercase, isAscii, isAlpha, isAlphanumeric, isHttpToken, isOrigin, isCorsOrigin, isBooleanString, isNumberString, isDecimal, isFullWidth, isHalfWidth, isVariableWidth, isMultibyte, isSurrogatePair, isHexadecimal, isOctal, isEmail, isURL, isUUID, isIP, isHexColor, isRgbColor, isHSL, isMACAddress, isISBN, isISIN, isISO8601, isISRC, isISSN, isJWT, isLatLong, isLocale, isDataURI, isFQDN, isPort, isEAN, isISO31661Alpha2, isISO31661Alpha3, isBIC, isFirebasePushId, isSemVer, isMongoId, isJSON, isBase32, isBase58, isBase64, isDateString, isMimeType, isCurrency, isMagnetURI, isCreditCard, isIBAN, isByteLength, isHash, isRFC3339, isMilitaryTime, isLatitude, isLongitude, isEthereumAddress, isBtcAddress, isISO4217CurrencyCode, isPhoneNumber, isStrongPassword, isTaxId, isULID, isCUID2, } from './string.js';
7
- export { arrayContains, arrayNotContains, arrayMinSize, arrayMaxSize, arrayUnique, arrayNotEmpty } from './array.js';
8
- export { isNotEmptyObject, isInstance } from './object.js';
9
- export { isMobilePhone, isPostalCode, isIdentityCard, isPassportNumber } from './locales.js';
1
+ export{isString,isNumber,isBoolean,isDate,isEnum,isInt,isArray,isObject,isRegExp,isFunction,isStatelessRegExp}from"./typechecker.js";export{oneOf,arrayEvery}from"./combinators.js";export{min,max,isPositive,isNegative,isDivisibleBy}from"./number.js";export{minDate,maxDate}from"./date.js";export{equals,notEquals,isEmpty,isNotEmpty,isIn,isNotIn}from"./common.js";export{minLength,maxLength,length,contains,notContains,matches,isLowercase,isUppercase,isAscii,isAlpha,isAlphanumeric,isHttpToken,isOrigin,isCorsOrigin,isBooleanString,isNumberString,isDecimal,isFullWidth,isHalfWidth,isVariableWidth,isMultibyte,isSurrogatePair,isHexadecimal,isOctal,isEmail,isURL,isUUID,isIP,isHexColor,isRgbColor,isHSL,isMACAddress,isISBN,isISIN,isISO8601,isISRC,isISSN,isJWT,isLatLong,isLocale,isDataURI,isFQDN,isPort,isEAN,isISO31661Alpha2,isISO31661Alpha3,isBIC,isFirebasePushId,isSemVer,isMongoId,isJSON,isBase32,isBase58,isBase64,isDateString,isMimeType,isCurrency,isMagnetURI,isCreditCard,isIBAN,isByteLength,isHash,isRFC3339,isMilitaryTime,isLatitude,isLongitude,isEthereumAddress,isBtcAddress,isISO4217CurrencyCode,isPhoneNumber,isStrongPassword,isTaxId,isULID,isCUID2}from"./string.js";export{arrayContains,arrayNotContains,arrayMinSize,arrayMaxSize,arrayUnique,arrayNotEmpty}from"./array.js";export{isNotEmptyObject,isInstance}from"./object.js";export{isMobilePhone,isPostalCode,isIdentityCard,isPassportNumber}from"./locales.js";export{isUint8Array,isByteSize}from"./binary.js";
@@ -1,249 +1 @@
1
- import { BakerError } from '../errors.js';
2
- import { makeRule } from '../rule-plan.js';
3
- // ─────────────────────────────────────────────────────────────────────────────
4
- // Locale-specific Validators
5
- // ─────────────────────────────────────────────────────────────────────────────
6
- // ─── isMobilePhone ────────────────────────────────────────────────────────────
7
- const MOBILE_PHONE_REGEXES = {
8
- 'ko-KR': /^(\+?82|0)1[016789]\d{7,8}$/,
9
- 'en-US': /^\+?1?[2-9]\d{2}[2-9]\d{6}$/,
10
- 'zh-CN': /^(\+?86)?1[3-9]\d{9}$/,
11
- 'zh-TW': /^(\+?886)?9\d{8}$/,
12
- 'ja-JP': /^(\+?81)?0?[789]0[0-9]{8}$/,
13
- 'de-DE': /^(\+?49)?1(5\d|6[0-9]|7[0-9])\d{8}$/,
14
- 'fr-FR': /^(\+?33)?[67]\d{8}$/,
15
- 'en-GB': /^(\+?44)?7[1-9]\d{8}$/,
16
- 'ru-RU': /^(\+?7)?9\d{9}$/,
17
- 'pt-BR': /^(\+?55)?[1-9]{2}9?\d{8}$/,
18
- 'in-IN': /^(\+?91)?[6-9]\d{9}$/,
19
- 'ar-SA': /^(\+?966)?5\d{8}$/,
20
- 'ar-EG': /^(\+?20)?1[0125]\d{8}$/,
21
- 'vi-VN': /^(\+?84)?[35789]\d{8}$/,
22
- 'th-TH': /^(\+?66)?[689]\d{8}$/,
23
- 'id-ID': /^(\+?62)?8\d{9,11}$/,
24
- 'ms-MY': /^(\+?60)?1\d{8,9}$/,
25
- 'nl-NL': /^(\+?31)?6\d{8}$/,
26
- 'it-IT': /^(\+?39)?3\d{9}$/,
27
- 'es-ES': /^(\+?34)?[67]\d{8}$/,
28
- 'pl-PL': /^(\+?48)?[45789]\d{8}$/,
29
- };
30
- function isMobilePhone(locale) {
31
- return makeLocaleRegexRule('isMobilePhone', locale, MOBILE_PHONE_REGEXES);
32
- }
33
- // ─── isPostalCode ─────────────────────────────────────────────────────────────
34
- const POSTAL_CODE_REGEXES = {
35
- AD: /^AD\d{3}$/,
36
- AT: /^\d{4}$/,
37
- AU: /^\d{4}$/,
38
- AZ: /^\d{4}$/,
39
- BE: /^\d{4}$/,
40
- BG: /^\d{4}$/,
41
- BR: /^\d{5}-?\d{3}$/,
42
- BY: /^\d{6}$/,
43
- CA: /^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z] ?\d[ABCEGHJ-NPRSTV-Z]\d$/i,
44
- CH: /^\d{4}$/,
45
- CN: /^\d{6}$/,
46
- CZ: /^\d{3} ?\d{2}$/,
47
- DE: /^\d{5}$/,
48
- DK: /^\d{4}$/,
49
- EE: /^\d{5}$/,
50
- ES: /^\d{5}$/,
51
- FI: /^\d{5}$/,
52
- FR: /^\d{2} ?\d{3}$/,
53
- GB: /^(GIR ?0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPSTUW]) ?[0-9][ABD-HJLNP-UW-Z]{2})$/i,
54
- GR: /^\d{3} ?\d{2}$/,
55
- HR: /^\d{5}$/,
56
- HU: /^\d{4}$/,
57
- ID: /^\d{5}$/,
58
- IL: /^\d{5}(\d{2})?$/,
59
- IN: /^\d{6}$/,
60
- IS: /^\d{3}$/,
61
- IT: /^\d{5}$/,
62
- JP: /^\d{3}-?\d{4}$/,
63
- KR: /^\d{5}$/,
64
- LI: /^(948[5-9]|949[0-7])$/,
65
- LT: /^LT-\d{5}$/,
66
- LU: /^\d{4}$/,
67
- LV: /^LV-\d{4}$/,
68
- MX: /^\d{5}$/,
69
- MT: /^[A-Z]{3} ?\d{4}$/i,
70
- MZ: /^\d{4}$/,
71
- NL: /^\d{4} ?[A-Z]{2}$/i,
72
- NO: /^\d{4}$/,
73
- NP: /^\d{5}$/,
74
- NZ: /^\d{4}$/,
75
- PH: /^\d{4}$/,
76
- PK: /^\d{5}$/,
77
- PL: /^\d{2}-\d{3}$/,
78
- PR: /^009\d{2}([ -]\d{4})?$/,
79
- PT: /^\d{4}-\d{3}$/,
80
- RO: /^\d{6}$/,
81
- RU: /^\d{6}$/,
82
- SE: /^\d{3} ?\d{2}$/,
83
- SG: /^\d{6}$/,
84
- SI: /^\d{4}$/,
85
- SK: /^\d{3} ?\d{2}$/,
86
- TH: /^\d{5}$/,
87
- TN: /^\d{4}$/,
88
- TW: /^\d{3}(\d{2})?$/,
89
- UA: /^\d{5}$/,
90
- US: /^\d{5}(-\d{4})?$/,
91
- ZA: /^\d{4}$/,
92
- ZM: /^\d{5}$/,
93
- };
94
- function isPostalCode(locale) {
95
- return makeLocaleRegexRule('isPostalCode', locale, POSTAL_CODE_REGEXES);
96
- }
97
- // ─── isIdentityCard ───────────────────────────────────────────────────────────
98
- const IDENTITY_CARD_REGEXES = {
99
- AF: /^\d{8}$/,
100
- AL: /^[A-Z]\d{8}[A-Z]$/i,
101
- AR: /^\d{7,8}$/,
102
- AZ: /^AZE\d{8}$/,
103
- BE: /^\d{11}$/,
104
- BG: /^\d{10}$/,
105
- BR: /^\d{9}$/,
106
- BY: /^[A-Z]{2}\d{7}$/i,
107
- CA: /^\d{9}$/,
108
- CH: /^756\d{10}$/,
109
- CN: /^\d{15}(\d{2}[0-9xX])?$/,
110
- CY: /^\d{7}[A-Z]$/i,
111
- CZ: /^\d{9,10}$/,
112
- DE: /^[LITOUAEVBMNPRSZDFGHCK]{9}$/i,
113
- DK: /^\d{10}$/,
114
- EE: /^\d{11}$/,
115
- ES: /^[0-9X-Z]\d{7}[TRWAGMYFPDXBNJZSQVHLCKE]$/i,
116
- FI: /^\d{6}[+-A]\d{3}[0-9A-FHJ-NPR-Y]$/,
117
- FR: /^\d{8,9}[0-9Á-ÿ]{1}$/i,
118
- GB: /^[A-Z]{2}\d{6}[A-Z]$/i,
119
- GR: /^[A-Z]{2}\d{6}$/i,
120
- HR: /^\d{11}$/,
121
- HU: /^\d{8}[A-Z]{2}$/i,
122
- ID: /^\d{16}$/,
123
- IE: /^\d{7}[A-W][A-W]?$/,
124
- IL: /^\d{9}$/,
125
- IN: /^\d{12}$/,
126
- IR: /^\d{10}$/,
127
- IS: /^\d{10}$/,
128
- IT: /^[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]$/i,
129
- JP: /^\d{12}$/,
130
- KR: /^\d{6}-\d{7}$/,
131
- LT: /^\d{11}$/,
132
- LU: /^\d{13}$/,
133
- LV: /^\d{6}-\d{5}$/,
134
- MK: /^\d{13}$/,
135
- MX: /^[A-Z]{4}\d{6}[HM][A-Z]{2}[B-DF-HJ-NP-TV-Z]{3}[A-Z0-9]\d$/i,
136
- MT: /^\d{7}[A-Z]$/i,
137
- NL: /^\d{9}$/,
138
- NO: /^\d{11}$/,
139
- PL: /^\d{11}$/,
140
- PT: /^[1-9]\d{7}[0-9TV]$/i,
141
- RO: /^\d{13}$/,
142
- RS: /^\d{13}$/,
143
- RU: /^\d{10}$/,
144
- SE: /^\d{10,12}$/,
145
- SI: /^\d{13}$/,
146
- SK: /^\d{9,10}$/,
147
- TH: /^\d{13}$/,
148
- TR: /^\d{11}$/,
149
- TW: /^[A-Z]\d{9}$/i,
150
- UA: /^\d{9}$/,
151
- US: /^\d{3}-\d{2}-\d{4}$/,
152
- ZA: /^\d{13}$/,
153
- };
154
- function isIdentityCard(locale) {
155
- return makeLocaleRegexRule('isIdentityCard', locale, IDENTITY_CARD_REGEXES);
156
- }
157
- // ─── isPassportNumber ─────────────────────────────────────────────────────────
158
- const PASSPORT_REGEXES = {
159
- AM: /^[A-Z]{2}\d{7}$/i,
160
- AR: /^[A-Z]{3}\d{6}$/i,
161
- AT: /^[A-Z]\d{7}$/i,
162
- AU: /^[A-Z]\d{7}$/i,
163
- AZ: /^[Aa]\d{8}$/,
164
- BE: /^[A-Z]{2}\d{6}$/i,
165
- BG: /^\d{9}$/,
166
- BH: /^[A-Z]{2}\d{6}$/i,
167
- BR: /^[A-Z]{2}\d{6}$/i,
168
- BY: /^[A-Z]{2}\d{7}$/i,
169
- CA: /^[A-Z]{2}\d{6}$/i,
170
- CH: /^[A-Z]\d{7}$/i,
171
- CN: /^G\d{8}$/,
172
- CY: /^[A-Z](\d{6}|\d{8})$/i,
173
- CZ: /^\d{8}$/,
174
- DE: /^[CFGHJKLMNPRTVWXYZ0-9]{9}$/i,
175
- DK: /^\d{9}$/,
176
- EE: /^([A-Z]\d{7}|[A-Z]{2}\d{7})$/i,
177
- ES: /^[A-Z0-9]{2}([A-Z0-9]?)\d{6}$/i,
178
- FI: /^[A-Z]{2}\d{7}$/i,
179
- FR: /^[A-Z0-9]{9}$/i,
180
- GB: /^\d{9}$/,
181
- GR: /^[A-Z]{2}\d{7}$/i,
182
- HR: /^\d{9}$/,
183
- HU: /^[A-Z]{2}(\d{6}|\d{7})$/i,
184
- ID: /^[A-C]\d{7}$/i,
185
- IE: /^[A-Z0-9]{2}\d{7}$/i,
186
- IL: /^\d{9}$/,
187
- IN: /^[A-Z]\d{7}$/i,
188
- IR: /^[A-Z]\d{8}$/i,
189
- IS: /^(A)\d{7}$/i,
190
- IT: /^[A-Z0-9]{9}$/i,
191
- JO: /^[A-Z]{2}\d{7}$/i,
192
- JP: /^[A-Z]{2}\d{7}$/i,
193
- KR: /^[A-Z][A-Z0-9]\d{7}$/i,
194
- KW: /^\d{8}$/,
195
- KZ: /^[A-Z]\d{8}$/i,
196
- LI: /^[A-Z]\d{6}X$/i,
197
- LT: /^[A-Z0-9]{8}$/i,
198
- LU: /^[A-Z0-9]{8}$/i,
199
- LV: /^[A-Z0-9]{2}\d{7}$/i,
200
- LY: /^[A-Z]{2}\d{7}$/i,
201
- MA: /^[A-Z0-9]{2}\d{7}$/i,
202
- MD: /^[A-Z]{2}\d{7}$/i,
203
- ME: /^[A-Z]{2}\d{7}$/i,
204
- MK: /^[A-Z]\d{7}$/i,
205
- MT: /^\d{7}$/,
206
- MX: /^[A-Z]\d{8}$/i,
207
- MY: /^[AHK]\d{8}[A-Z]$/i,
208
- NL: /^[A-NP-Z]{2}[A-NP-Z0-9]{6}\d$/i,
209
- NO: /^\d{9}$/,
210
- NZ: /^[A-Z]{2}\d{6}$/i,
211
- PH: /^[A-Z]\d{7}[A-Z]$/i,
212
- PK: /^[A-Z]{2}\d{7}$/i,
213
- PL: /^[A-Z]{2}\d{7}$/i,
214
- PT: /^[A-Z]\d{6}$/i,
215
- RO: /^\d{8}$/,
216
- RS: /^\d{9}$/,
217
- RU: /^\d{9}$/,
218
- SA: /^[A-Z]\d{8}$/i,
219
- SE: /^\d{8}$/,
220
- SL: /^(P)[A-Z]\d{7}$/i,
221
- SK: /^[0-9A-Z]\d{7}$/i,
222
- TH: /^[A-Z]{1,2}\d{6,7}$/i,
223
- TN: /^\d{8}$/,
224
- TR: /^[A-Z]\d{8}$/i,
225
- TW: /^[A-Z]\d{9}$/i,
226
- UA: /^[A-Z]{2}\d{6}$/i,
227
- US: /^\d{9}$/,
228
- ZA: /^[A-Z]\d{8}$/i,
229
- };
230
- function isPassportNumber(locale) {
231
- return makeLocaleRegexRule('isPassportNumber', locale, PASSPORT_REGEXES);
232
- }
233
- function makeLocaleRegexRule(name, locale, registry) {
234
- const re = registry[locale];
235
- if (!re) {
236
- throw new BakerError(`Unsupported locale: "${locale}" for ${name}`);
237
- }
238
- return makeRule({
239
- name,
240
- requiresType: 'string',
241
- constraints: { locale },
242
- validate: value => typeof value === 'string' && re.test(value),
243
- emit: (varName, ctx) => {
244
- const i = ctx.addRegex(re);
245
- return `if (!re[${i}].test(${varName})) ${ctx.fail(name)};`;
246
- },
247
- });
248
- }
249
- export { isMobilePhone, isPostalCode, isIdentityCard, isPassportNumber };
1
+ import{BakerError as K}from"../errors.js";import{makeRule as Q}from"../rule-plan.js";const U={"ko-KR":/^(\+?82|0)1[016789]\d{7,8}$/,"en-US":/^\+?1?[2-9]\d{2}[2-9]\d{6}$/,"zh-CN":/^(\+?86)?1[3-9]\d{9}$/,"zh-TW":/^(\+?886)?9\d{8}$/,"ja-JP":/^(\+?81)?0?[789]0[0-9]{8}$/,"de-DE":/^(\+?49)?1(5\d|6[0-9]|7[0-9])\d{8}$/,"fr-FR":/^(\+?33)?[67]\d{8}$/,"en-GB":/^(\+?44)?7[1-9]\d{8}$/,"ru-RU":/^(\+?7)?9\d{9}$/,"pt-BR":/^(\+?55)?[1-9]{2}9?\d{8}$/,"in-IN":/^(\+?91)?[6-9]\d{9}$/,"ar-SA":/^(\+?966)?5\d{8}$/,"ar-EG":/^(\+?20)?1[0125]\d{8}$/,"vi-VN":/^(\+?84)?[35789]\d{8}$/,"th-TH":/^(\+?66)?[689]\d{8}$/,"id-ID":/^(\+?62)?8\d{9,11}$/,"ms-MY":/^(\+?60)?1\d{8,9}$/,"nl-NL":/^(\+?31)?6\d{8}$/,"it-IT":/^(\+?39)?3\d{9}$/,"es-ES":/^(\+?34)?[67]\d{8}$/,"pl-PL":/^(\+?48)?[45789]\d{8}$/};function isMobilePhone(f){return q("isMobilePhone",f,U)}const V={AD:/^AD\d{3}$/,AT:/^\d{4}$/,AU:/^\d{4}$/,AZ:/^\d{4}$/,BE:/^\d{4}$/,BG:/^\d{4}$/,BR:/^\d{5}-?\d{3}$/,BY:/^\d{6}$/,CA:/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z] ?\d[ABCEGHJ-NPRSTV-Z]\d$/i,CH:/^\d{4}$/,CN:/^\d{6}$/,CZ:/^\d{3} ?\d{2}$/,DE:/^\d{5}$/,DK:/^\d{4}$/,EE:/^\d{5}$/,ES:/^\d{5}$/,FI:/^\d{5}$/,FR:/^\d{2} ?\d{3}$/,GB:/^(GIR ?0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPSTUW]) ?[0-9][ABD-HJLNP-UW-Z]{2})$/i,GR:/^\d{3} ?\d{2}$/,HR:/^\d{5}$/,HU:/^\d{4}$/,ID:/^\d{5}$/,IL:/^\d{5}(\d{2})?$/,IN:/^\d{6}$/,IS:/^\d{3}$/,IT:/^\d{5}$/,JP:/^\d{3}-?\d{4}$/,KR:/^\d{5}$/,LI:/^(948[5-9]|949[0-7])$/,LT:/^LT-\d{5}$/,LU:/^\d{4}$/,LV:/^LV-\d{4}$/,MX:/^\d{5}$/,MT:/^[A-Z]{3} ?\d{4}$/i,MZ:/^\d{4}$/,NL:/^\d{4} ?[A-Z]{2}$/i,NO:/^\d{4}$/,NP:/^\d{5}$/,NZ:/^\d{4}$/,PH:/^\d{4}$/,PK:/^\d{5}$/,PL:/^\d{2}-\d{3}$/,PR:/^009\d{2}([ -]\d{4})?$/,PT:/^\d{4}-\d{3}$/,RO:/^\d{6}$/,RU:/^\d{6}$/,SE:/^\d{3} ?\d{2}$/,SG:/^\d{6}$/,SI:/^\d{4}$/,SK:/^\d{3} ?\d{2}$/,TH:/^\d{5}$/,TN:/^\d{4}$/,TW:/^\d{3}(\d{2})?$/,UA:/^\d{5}$/,US:/^\d{5}(-\d{4})?$/,ZA:/^\d{4}$/,ZM:/^\d{5}$/};function isPostalCode(f){return q("isPostalCode",f,V)}const W={AF:/^\d{8}$/,AL:/^[A-Z]\d{8}[A-Z]$/i,AR:/^\d{7,8}$/,AZ:/^AZE\d{8}$/,BE:/^\d{11}$/,BG:/^\d{10}$/,BR:/^\d{9}$/,BY:/^[A-Z]{2}\d{7}$/i,CA:/^\d{9}$/,CH:/^756\d{10}$/,CN:/^\d{15}(\d{2}[0-9xX])?$/,CY:/^\d{7}[A-Z]$/i,CZ:/^\d{9,10}$/,DE:/^[LITOUAEVBMNPRSZDFGHCK]{9}$/i,DK:/^\d{10}$/,EE:/^\d{11}$/,ES:/^[0-9X-Z]\d{7}[TRWAGMYFPDXBNJZSQVHLCKE]$/i,FI:/^\d{6}[+-A]\d{3}[0-9A-FHJ-NPR-Y]$/,FR:/^\d{8,9}[0-9\u00C1-\u00FF]{1}$/i,GB:/^[A-Z]{2}\d{6}[A-Z]$/i,GR:/^[A-Z]{2}\d{6}$/i,HR:/^\d{11}$/,HU:/^\d{8}[A-Z]{2}$/i,ID:/^\d{16}$/,IE:/^\d{7}[A-W][A-W]?$/,IL:/^\d{9}$/,IN:/^\d{12}$/,IR:/^\d{10}$/,IS:/^\d{10}$/,IT:/^[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]$/i,JP:/^\d{12}$/,KR:/^\d{6}-\d{7}$/,LT:/^\d{11}$/,LU:/^\d{13}$/,LV:/^\d{6}-\d{5}$/,MK:/^\d{13}$/,MX:/^[A-Z]{4}\d{6}[HM][A-Z]{2}[B-DF-HJ-NP-TV-Z]{3}[A-Z0-9]\d$/i,MT:/^\d{7}[A-Z]$/i,NL:/^\d{9}$/,NO:/^\d{11}$/,PL:/^\d{11}$/,PT:/^[1-9]\d{7}[0-9TV]$/i,RO:/^\d{13}$/,RS:/^\d{13}$/,RU:/^\d{10}$/,SE:/^\d{10,12}$/,SI:/^\d{13}$/,SK:/^\d{9,10}$/,TH:/^\d{13}$/,TR:/^\d{11}$/,TW:/^[A-Z]\d{9}$/i,UA:/^\d{9}$/,US:/^\d{3}-\d{2}-\d{4}$/,ZA:/^\d{13}$/};function isIdentityCard(f){return q("isIdentityCard",f,W)}const Z={AM:/^[A-Z]{2}\d{7}$/i,AR:/^[A-Z]{3}\d{6}$/i,AT:/^[A-Z]\d{7}$/i,AU:/^[A-Z]\d{7}$/i,AZ:/^[Aa]\d{8}$/,BE:/^[A-Z]{2}\d{6}$/i,BG:/^\d{9}$/,BH:/^[A-Z]{2}\d{6}$/i,BR:/^[A-Z]{2}\d{6}$/i,BY:/^[A-Z]{2}\d{7}$/i,CA:/^[A-Z]{2}\d{6}$/i,CH:/^[A-Z]\d{7}$/i,CN:/^G\d{8}$/,CY:/^[A-Z](\d{6}|\d{8})$/i,CZ:/^\d{8}$/,DE:/^[CFGHJKLMNPRTVWXYZ0-9]{9}$/i,DK:/^\d{9}$/,EE:/^([A-Z]\d{7}|[A-Z]{2}\d{7})$/i,ES:/^[A-Z0-9]{2}([A-Z0-9]?)\d{6}$/i,FI:/^[A-Z]{2}\d{7}$/i,FR:/^[A-Z0-9]{9}$/i,GB:/^\d{9}$/,GR:/^[A-Z]{2}\d{7}$/i,HR:/^\d{9}$/,HU:/^[A-Z]{2}(\d{6}|\d{7})$/i,ID:/^[A-C]\d{7}$/i,IE:/^[A-Z0-9]{2}\d{7}$/i,IL:/^\d{9}$/,IN:/^[A-Z]\d{7}$/i,IR:/^[A-Z]\d{8}$/i,IS:/^(A)\d{7}$/i,IT:/^[A-Z0-9]{9}$/i,JO:/^[A-Z]{2}\d{7}$/i,JP:/^[A-Z]{2}\d{7}$/i,KR:/^[A-Z][A-Z0-9]\d{7}$/i,KW:/^\d{8}$/,KZ:/^[A-Z]\d{8}$/i,LI:/^[A-Z]\d{6}X$/i,LT:/^[A-Z0-9]{8}$/i,LU:/^[A-Z0-9]{8}$/i,LV:/^[A-Z0-9]{2}\d{7}$/i,LY:/^[A-Z]{2}\d{7}$/i,MA:/^[A-Z0-9]{2}\d{7}$/i,MD:/^[A-Z]{2}\d{7}$/i,ME:/^[A-Z]{2}\d{7}$/i,MK:/^[A-Z]\d{7}$/i,MT:/^\d{7}$/,MX:/^[A-Z]\d{8}$/i,MY:/^[AHK]\d{8}[A-Z]$/i,NL:/^[A-NP-Z]{2}[A-NP-Z0-9]{6}\d$/i,NO:/^\d{9}$/,NZ:/^[A-Z]{2}\d{6}$/i,PH:/^[A-Z]\d{7}[A-Z]$/i,PK:/^[A-Z]{2}\d{7}$/i,PL:/^[A-Z]{2}\d{7}$/i,PT:/^[A-Z]\d{6}$/i,RO:/^\d{8}$/,RS:/^\d{9}$/,RU:/^\d{9}$/,SA:/^[A-Z]\d{8}$/i,SE:/^\d{8}$/,SL:/^(P)[A-Z]\d{7}$/i,SK:/^[0-9A-Z]\d{7}$/i,TH:/^[A-Z]{1,2}\d{6,7}$/i,TN:/^\d{8}$/,TR:/^[A-Z]\d{8}$/i,TW:/^[A-Z]\d{9}$/i,UA:/^[A-Z]{2}\d{6}$/i,US:/^\d{9}$/,ZA:/^[A-Z]\d{8}$/i};function isPassportNumber(f){return q("isPassportNumber",f,Z)}function q(f,w,J){const z=J[w];if(!z)throw new K(`Unsupported locale: "${w}" for ${f}`);return Q({name:f,requiresType:"string",constraints:{locale:w},validate:(j)=>typeof j==="string"&&z.test(j),emit:(j,F)=>{return`if (!re[${F.addRegex(z)}].test(${j})) ${F.fail(f)};`}})}export{isMobilePhone,isPostalCode,isIdentityCard,isPassportNumber};
@@ -1,79 +1 @@
1
- import { BakerError } from '../errors.js';
2
- import { makePlannedRule, makeRule, planCompare, planLiteral, planOr, planValue } from '../rule-plan.js';
3
- // ─────────────────────────────────────────────────────────────────────────────
4
- // min — v >= n check. requiresType='number' (§4.7, §4.8 A)
5
- // ─────────────────────────────────────────────────────────────────────────────
6
- export function min(n, opts) {
7
- if (!Number.isFinite(n)) {
8
- throw new BakerError(`min: bound must be a finite number, got ${n}`);
9
- }
10
- const exclusive = opts?.exclusive ?? false;
11
- const plan = {
12
- failure: planOr(planCompare(planValue(), '!==', planValue()), planCompare(planValue(), exclusive ? '<=' : '<', planLiteral(n))),
13
- };
14
- return makePlannedRule({
15
- name: 'min',
16
- requiresType: 'number',
17
- constraints: exclusive ? { min: n, exclusive: true } : { min: n },
18
- plan,
19
- validate: exclusive ? value => typeof value === 'number' && value > n : value => typeof value === 'number' && value >= n,
20
- });
21
- }
22
- // ─────────────────────────────────────────────────────────────────────────────
23
- // max — v <= n check. requiresType='number' (§4.7, §4.8 A)
24
- // ─────────────────────────────────────────────────────────────────────────────
25
- export function max(n, opts) {
26
- if (!Number.isFinite(n)) {
27
- throw new BakerError(`max: bound must be a finite number, got ${n}`);
28
- }
29
- const exclusive = opts?.exclusive ?? false;
30
- const plan = {
31
- failure: planOr(planCompare(planValue(), '!==', planValue()), planCompare(planValue(), exclusive ? '>=' : '>', planLiteral(n))),
32
- };
33
- return makePlannedRule({
34
- name: 'max',
35
- requiresType: 'number',
36
- constraints: exclusive ? { max: n, exclusive: true } : { max: n },
37
- plan,
38
- validate: exclusive ? value => typeof value === 'number' && value < n : value => typeof value === 'number' && value <= n,
39
- });
40
- }
41
- // ─────────────────────────────────────────────────────────────────────────────
42
- // isPositive — v > 0 (0 not included). requiresType='number' (§4.8 A)
43
- // ─────────────────────────────────────────────────────────────────────────────
44
- export const isPositive = makePlannedRule({
45
- name: 'isPositive',
46
- requiresType: 'number',
47
- constraints: { min: 0, exclusive: true },
48
- plan: {
49
- failure: planOr(planCompare(planValue(), '!==', planValue()), planCompare(planValue(), '<=', planLiteral(0))),
50
- },
51
- validate: value => typeof value === 'number' && value > 0,
52
- });
53
- // ─────────────────────────────────────────────────────────────────────────────
54
- // isNegative — v < 0 (0 not included). requiresType='number' (§4.8 A)
55
- // ─────────────────────────────────────────────────────────────────────────────
56
- export const isNegative = makePlannedRule({
57
- name: 'isNegative',
58
- requiresType: 'number',
59
- constraints: { max: 0, exclusive: true },
60
- plan: {
61
- failure: planOr(planCompare(planValue(), '!==', planValue()), planCompare(planValue(), '>=', planLiteral(0))),
62
- },
63
- validate: value => typeof value === 'number' && value < 0,
64
- });
65
- // ─────────────────────────────────────────────────────────────────────────────
66
- // isDivisibleBy — v % n === 0 check. requiresType='number' (§4.8 A)
67
- // ─────────────────────────────────────────────────────────────────────────────
68
- export function isDivisibleBy(n) {
69
- if (n === 0) {
70
- throw new BakerError('isDivisibleBy: divisor must not be zero');
71
- }
72
- return makeRule({
73
- name: 'isDivisibleBy',
74
- requiresType: 'number',
75
- constraints: { divisor: n },
76
- validate: value => typeof value === 'number' && value % n === 0,
77
- emit: (varName, ctx) => `if (${varName} % ${n} !== 0) ${ctx.fail('isDivisibleBy')};`,
78
- });
79
- }
1
+ import{BakerError as D}from"../errors.js";import{makePlannedRule as w,makeRule as F,planCompare as q,planLiteral as y,planOr as z,planValue as f}from"../rule-plan.js";export function min(b,j){if(!Number.isFinite(b))throw new D(`min: bound must be a finite number, got ${b}`);const h=j?.exclusive??!1,A={failure:z(q(f(),"!==",f()),q(f(),h?"<=":"<",y(b)))};return w({name:"min",requiresType:"number",constraints:h?{min:b,exclusive:!0}:{min:b},plan:A,validate:h?(g)=>typeof g==="number"&&g>b:(g)=>typeof g==="number"&&g>=b})}export function max(b,j){if(!Number.isFinite(b))throw new D(`max: bound must be a finite number, got ${b}`);const h=j?.exclusive??!1,A={failure:z(q(f(),"!==",f()),q(f(),h?">=":">",y(b)))};return w({name:"max",requiresType:"number",constraints:h?{max:b,exclusive:!0}:{max:b},plan:A,validate:h?(g)=>typeof g==="number"&&g<b:(g)=>typeof g==="number"&&g<=b})}export const isPositive=w({name:"isPositive",requiresType:"number",constraints:{min:0,exclusive:!0},plan:{failure:z(q(f(),"!==",f()),q(f(),"<=",y(0)))},validate:(b)=>typeof b==="number"&&b>0});export const isNegative=w({name:"isNegative",requiresType:"number",constraints:{max:0,exclusive:!0},plan:{failure:z(q(f(),"!==",f()),q(f(),">=",y(0)))},validate:(b)=>typeof b==="number"&&b<0});export function isDivisibleBy(b){if(b===0)throw new D("isDivisibleBy: divisor must not be zero");return F({name:"isDivisibleBy",requiresType:"number",constraints:{divisor:b},validate:(j)=>typeof j==="number"&&j%b===0,emit:(j,h)=>`if (${j} % ${b} !== 0) ${h.fail("isDivisibleBy")};`})}
@@ -1,49 +1 @@
1
- import { makeRule } from '../rule-plan.js';
2
- export function isNotEmptyObject(options) {
3
- const validate = (value) => {
4
- if (value === null || typeof value !== 'object' || Array.isArray(value)) {
5
- return false;
6
- }
7
- const obj = value;
8
- if (options?.nullable) {
9
- for (const k in obj) {
10
- if (obj[k] != null) {
11
- return true;
12
- }
13
- }
14
- return false;
15
- }
16
- for (const _k in obj) {
17
- return true;
18
- }
19
- return false;
20
- };
21
- return makeRule({
22
- name: 'isNotEmptyObject',
23
- requiresType: 'object',
24
- constraints: { nullable: options?.nullable },
25
- validate,
26
- // Codegen: for-in with break — measured ~1 ns faster than Object.keys allocation
27
- // (Bun 1.3.13 / i7-13700K). The generated body is not subject to source-lint rules.
28
- emit: (varName, ctx) => {
29
- if (options?.nullable) {
30
- return `{var __ne=false;for(var __k in ${varName}){if(${varName}[__k]!=null){__ne=true;break;}}if(!__ne) ${ctx.fail('isNotEmptyObject')};}`;
31
- }
32
- return `{var __ne=false;for(var __k in ${varName}){__ne=true;break;}if(!__ne) ${ctx.fail('isNotEmptyObject')};}`;
33
- },
34
- });
35
- }
36
- // ─────────────────────────────────────────────────────────────────────────────
37
- // isInstance(targetType) — checks if value is an instance of a specific class
38
- // ─────────────────────────────────────────────────────────────────────────────
39
- export function isInstance(targetType) {
40
- return makeRule({
41
- name: 'isInstance',
42
- constraints: { type: targetType.name },
43
- validate: value => value instanceof targetType,
44
- emit: (varName, ctx) => {
45
- const i = ctx.addRef(targetType);
46
- return `if (!(${varName} instanceof refs[${i}])) ${ctx.fail('isInstance')};`;
47
- },
48
- });
49
- }
1
+ import{makeRule as A}from"../rule-plan.js";export function isNotEmptyObject(q){const w=(f)=>{if(f===null||typeof f!=="object"||Array.isArray(f))return!1;const h=f;if(q?.nullable){for(const z in h)if(h[z]!=null)return!0;return!1}for(const z in h)return!0;return!1};return A({name:"isNotEmptyObject",requiresType:"object",constraints:{nullable:q?.nullable},validate:w,emit:(f,h)=>{if(q?.nullable)return`{var __ne=false;for(var __k in ${f}){if(${f}[__k]!=null){__ne=true;break;}}if(!__ne) ${h.fail("isNotEmptyObject")};}`;return`{var __ne=false;for(var __k in ${f}){__ne=true;break;}if(!__ne) ${h.fail("isNotEmptyObject")};}`}})}export function isInstance(q){return A({name:"isInstance",constraints:{type:q.name},validate:(w)=>w instanceof q,emit:(w,f)=>{const h=f.addRef(q);return`if (!(${w} instanceof refs[${h}])) ${f.fail("isInstance")};`}})}