metal-orm 1.0.93 → 1.0.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +757 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +229 -1
- package/dist/index.d.ts +229 -1
- package/dist/index.js +739 -23
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
- package/src/decorators/bootstrap.ts +11 -1
- package/src/decorators/decorator-metadata.ts +3 -1
- package/src/decorators/index.ts +27 -0
- package/src/decorators/transformers/built-in/string-transformers.ts +231 -0
- package/src/decorators/transformers/transformer-decorators.ts +137 -0
- package/src/decorators/transformers/transformer-executor.ts +172 -0
- package/src/decorators/transformers/transformer-metadata.ts +73 -0
- package/src/decorators/validators/built-in/br-cep-validator.ts +55 -0
- package/src/decorators/validators/built-in/br-cnpj-validator.ts +105 -0
- package/src/decorators/validators/built-in/br-cpf-validator.ts +103 -0
- package/src/decorators/validators/country-validator-registry.ts +64 -0
- package/src/decorators/validators/country-validators-decorators.ts +209 -0
- package/src/decorators/validators/country-validators.ts +105 -0
- package/src/decorators/validators/validator-metadata.ts +59 -0
- package/src/dto/openapi/utilities.ts +5 -0
- package/src/index.ts +4 -3
- package/src/orm/column-introspection.ts +43 -0
- package/src/orm/entity-metadata.ts +64 -45
package/dist/index.js
CHANGED
|
@@ -6142,7 +6142,8 @@ var ensureEntityMetadata = (target) => {
|
|
|
6142
6142
|
target,
|
|
6143
6143
|
tableName: target.name || "unknown",
|
|
6144
6144
|
columns: {},
|
|
6145
|
-
relations: {}
|
|
6145
|
+
relations: {},
|
|
6146
|
+
transformers: {}
|
|
6146
6147
|
};
|
|
6147
6148
|
metadataMap.set(target, meta);
|
|
6148
6149
|
}
|
|
@@ -6162,6 +6163,10 @@ var addRelationMetadata = (target, propertyKey, relation) => {
|
|
|
6162
6163
|
const meta = ensureEntityMetadata(target);
|
|
6163
6164
|
meta.relations[propertyKey] = relation;
|
|
6164
6165
|
};
|
|
6166
|
+
var addTransformerMetadata = (target, propertyKey, transformer) => {
|
|
6167
|
+
const meta = ensureEntityMetadata(target);
|
|
6168
|
+
meta.transformers[propertyKey] = transformer;
|
|
6169
|
+
};
|
|
6165
6170
|
var setEntityTableName = (target, tableName, hooks) => {
|
|
6166
6171
|
const meta = ensureEntityMetadata(target);
|
|
6167
6172
|
if (tableName && tableName.length > 0) {
|
|
@@ -7522,6 +7527,28 @@ var isTableDef = (value) => {
|
|
|
7522
7527
|
return true;
|
|
7523
7528
|
};
|
|
7524
7529
|
|
|
7530
|
+
// src/decorators/decorator-metadata.ts
|
|
7531
|
+
var METADATA_KEY = "metal-orm:decorators";
|
|
7532
|
+
var getOrCreateMetadataBag = (context) => {
|
|
7533
|
+
const metadata = context.metadata || (context.metadata = {});
|
|
7534
|
+
let bag = metadata[METADATA_KEY];
|
|
7535
|
+
if (!bag) {
|
|
7536
|
+
bag = { columns: [], relations: [], transformers: [] };
|
|
7537
|
+
metadata[METADATA_KEY] = bag;
|
|
7538
|
+
}
|
|
7539
|
+
return bag;
|
|
7540
|
+
};
|
|
7541
|
+
var readMetadataBag = (context) => {
|
|
7542
|
+
return context.metadata?.[METADATA_KEY];
|
|
7543
|
+
};
|
|
7544
|
+
var readMetadataBagFromConstructor = (ctor) => {
|
|
7545
|
+
const metadataSymbol = Symbol.metadata;
|
|
7546
|
+
if (!metadataSymbol) return void 0;
|
|
7547
|
+
const metadata = Reflect.get(ctor, metadataSymbol);
|
|
7548
|
+
return metadata?.[METADATA_KEY];
|
|
7549
|
+
};
|
|
7550
|
+
var getDecoratorMetadata = (ctor) => readMetadataBagFromConstructor(ctor);
|
|
7551
|
+
|
|
7525
7552
|
// src/decorators/bootstrap.ts
|
|
7526
7553
|
var unwrapTarget = (target) => {
|
|
7527
7554
|
if (typeof target === "function" && target.prototype === void 0) {
|
|
@@ -7618,6 +7645,12 @@ var bootstrapEntities = () => {
|
|
|
7618
7645
|
const metas = getAllEntityMetadata();
|
|
7619
7646
|
const tableMap = /* @__PURE__ */ new Map();
|
|
7620
7647
|
for (const meta of metas) {
|
|
7648
|
+
const decoratorMetadata = getDecoratorMetadata(meta.target);
|
|
7649
|
+
if (decoratorMetadata?.transformers) {
|
|
7650
|
+
for (const { propertyName, metadata } of decoratorMetadata.transformers) {
|
|
7651
|
+
addTransformerMetadata(meta.target, propertyName, metadata);
|
|
7652
|
+
}
|
|
7653
|
+
}
|
|
7621
7654
|
const table = buildTableDef(meta);
|
|
7622
7655
|
tableMap.set(meta.target, table);
|
|
7623
7656
|
}
|
|
@@ -12260,6 +12293,31 @@ var Orm = class {
|
|
|
12260
12293
|
}
|
|
12261
12294
|
};
|
|
12262
12295
|
|
|
12296
|
+
// src/orm/column-introspection.ts
|
|
12297
|
+
var getColumnDefFromTarget = (target, column) => {
|
|
12298
|
+
if (typeof target === "function") {
|
|
12299
|
+
const meta = getEntityMetadata(target);
|
|
12300
|
+
if (!meta?.columns) return void 0;
|
|
12301
|
+
return meta.columns[column];
|
|
12302
|
+
}
|
|
12303
|
+
const table = target;
|
|
12304
|
+
return table.columns[column];
|
|
12305
|
+
};
|
|
12306
|
+
var getColumnType = (target, column) => {
|
|
12307
|
+
const col2 = getColumnDefFromTarget(target, column);
|
|
12308
|
+
if (!col2?.type) return void 0;
|
|
12309
|
+
return normalizeColumnType(col2.type);
|
|
12310
|
+
};
|
|
12311
|
+
var getDateKind = (target, column) => {
|
|
12312
|
+
const type = getColumnType(target, column);
|
|
12313
|
+
if (!type) return void 0;
|
|
12314
|
+
if (type === "date") return "date";
|
|
12315
|
+
if (type === "datetime" || type === "timestamp" || type === "timestamptz") {
|
|
12316
|
+
return "date-time";
|
|
12317
|
+
}
|
|
12318
|
+
return void 0;
|
|
12319
|
+
};
|
|
12320
|
+
|
|
12263
12321
|
// src/orm/jsonify.ts
|
|
12264
12322
|
var jsonify = (value) => {
|
|
12265
12323
|
const record = value;
|
|
@@ -12271,28 +12329,6 @@ var jsonify = (value) => {
|
|
|
12271
12329
|
return result;
|
|
12272
12330
|
};
|
|
12273
12331
|
|
|
12274
|
-
// src/decorators/decorator-metadata.ts
|
|
12275
|
-
var METADATA_KEY = "metal-orm:decorators";
|
|
12276
|
-
var getOrCreateMetadataBag = (context) => {
|
|
12277
|
-
const metadata = context.metadata || (context.metadata = {});
|
|
12278
|
-
let bag = metadata[METADATA_KEY];
|
|
12279
|
-
if (!bag) {
|
|
12280
|
-
bag = { columns: [], relations: [] };
|
|
12281
|
-
metadata[METADATA_KEY] = bag;
|
|
12282
|
-
}
|
|
12283
|
-
return bag;
|
|
12284
|
-
};
|
|
12285
|
-
var readMetadataBag = (context) => {
|
|
12286
|
-
return context.metadata?.[METADATA_KEY];
|
|
12287
|
-
};
|
|
12288
|
-
var readMetadataBagFromConstructor = (ctor) => {
|
|
12289
|
-
const metadataSymbol = Symbol.metadata;
|
|
12290
|
-
if (!metadataSymbol) return void 0;
|
|
12291
|
-
const metadata = Reflect.get(ctor, metadataSymbol);
|
|
12292
|
-
return metadata?.[METADATA_KEY];
|
|
12293
|
-
};
|
|
12294
|
-
var getDecoratorMetadata = (ctor) => readMetadataBagFromConstructor(ctor);
|
|
12295
|
-
|
|
12296
12332
|
// src/decorators/entity.ts
|
|
12297
12333
|
var toSnakeCase2 = (value) => {
|
|
12298
12334
|
return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^a-z0-9_]+/gi, "_").replace(/__+/g, "_").replace(/^_|_$/g, "").toLowerCase();
|
|
@@ -12465,6 +12501,668 @@ function BelongsToMany(options) {
|
|
|
12465
12501
|
}));
|
|
12466
12502
|
}
|
|
12467
12503
|
|
|
12504
|
+
// src/decorators/transformers/built-in/string-transformers.ts
|
|
12505
|
+
var TrimTransformer = class {
|
|
12506
|
+
constructor(options = {}) {
|
|
12507
|
+
this.options = options;
|
|
12508
|
+
}
|
|
12509
|
+
name = "trim";
|
|
12510
|
+
sanitize(value) {
|
|
12511
|
+
if (typeof value !== "string") return value;
|
|
12512
|
+
if (this.options.trimAll) {
|
|
12513
|
+
return value.trim();
|
|
12514
|
+
}
|
|
12515
|
+
let result = value;
|
|
12516
|
+
if (this.options.trimStart) {
|
|
12517
|
+
result = result.trimStart();
|
|
12518
|
+
}
|
|
12519
|
+
if (this.options.trimEnd) {
|
|
12520
|
+
result = result.trimEnd();
|
|
12521
|
+
}
|
|
12522
|
+
if (!this.options.trimStart && !this.options.trimEnd && !this.options.trimAll) {
|
|
12523
|
+
result = result.trim();
|
|
12524
|
+
}
|
|
12525
|
+
return result;
|
|
12526
|
+
}
|
|
12527
|
+
};
|
|
12528
|
+
var CaseTransformer = class {
|
|
12529
|
+
constructor(caseType) {
|
|
12530
|
+
this.caseType = caseType;
|
|
12531
|
+
this.name = `case-${caseType}`;
|
|
12532
|
+
}
|
|
12533
|
+
name;
|
|
12534
|
+
sanitize(value) {
|
|
12535
|
+
if (typeof value !== "string") return value;
|
|
12536
|
+
switch (this.caseType) {
|
|
12537
|
+
case "lower":
|
|
12538
|
+
return value.toLowerCase();
|
|
12539
|
+
case "upper":
|
|
12540
|
+
return value.toUpperCase();
|
|
12541
|
+
case "capitalize":
|
|
12542
|
+
return value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();
|
|
12543
|
+
case "title":
|
|
12544
|
+
return value.split(" ").map(
|
|
12545
|
+
(word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
|
|
12546
|
+
).join(" ");
|
|
12547
|
+
default:
|
|
12548
|
+
return value;
|
|
12549
|
+
}
|
|
12550
|
+
}
|
|
12551
|
+
};
|
|
12552
|
+
var AlphanumericValidator = class {
|
|
12553
|
+
constructor(options = {}) {
|
|
12554
|
+
this.options = options;
|
|
12555
|
+
}
|
|
12556
|
+
name = "alphanumeric";
|
|
12557
|
+
validate(value) {
|
|
12558
|
+
if (typeof value !== "string") {
|
|
12559
|
+
return { isValid: false, error: "Value must be a string" };
|
|
12560
|
+
}
|
|
12561
|
+
const pattern = new RegExp(
|
|
12562
|
+
`^[a-zA-Z0-9${this.options.allowSpaces ? " " : ""}${this.options.allowUnderscores ? "_" : ""}${this.options.allowHyphens ? "-" : ""}]*$`
|
|
12563
|
+
);
|
|
12564
|
+
return pattern.test(value) ? { isValid: true } : { isValid: false, error: "Value must contain only alphanumeric characters" };
|
|
12565
|
+
}
|
|
12566
|
+
autoTransform(value) {
|
|
12567
|
+
if (typeof value !== "string") {
|
|
12568
|
+
return { success: false };
|
|
12569
|
+
}
|
|
12570
|
+
let result = value;
|
|
12571
|
+
result = result.replace(/[^a-zA-Z0-9]/g, (char2) => {
|
|
12572
|
+
if (char2 === " " && this.options.allowSpaces) return " ";
|
|
12573
|
+
if (char2 === "_" && this.options.allowUnderscores) return "_";
|
|
12574
|
+
if (char2 === "-" && this.options.allowHyphens) return "-";
|
|
12575
|
+
return "";
|
|
12576
|
+
});
|
|
12577
|
+
return {
|
|
12578
|
+
success: true,
|
|
12579
|
+
correctedValue: result,
|
|
12580
|
+
message: "Removed non-alphanumeric characters"
|
|
12581
|
+
};
|
|
12582
|
+
}
|
|
12583
|
+
};
|
|
12584
|
+
var EmailValidator = class {
|
|
12585
|
+
constructor(options = {}) {
|
|
12586
|
+
this.options = options;
|
|
12587
|
+
}
|
|
12588
|
+
name = "email";
|
|
12589
|
+
validate(value) {
|
|
12590
|
+
if (typeof value !== "string") {
|
|
12591
|
+
return { isValid: false, error: "Value must be a string" };
|
|
12592
|
+
}
|
|
12593
|
+
const emailPattern = this.options.allowPlus ? /^[^\s@]+@[^\s@]+\.[^\s@]+$/ : /^[^\s@+]+@[^\s@]+\.[^\s@]+$/;
|
|
12594
|
+
if (!emailPattern.test(value)) {
|
|
12595
|
+
return { isValid: false, error: "Value must be a valid email address" };
|
|
12596
|
+
}
|
|
12597
|
+
if (this.options.requireTLD) {
|
|
12598
|
+
const parts = value.split(".");
|
|
12599
|
+
if (parts.length < 3 || parts[parts.length - 1].length < 2) {
|
|
12600
|
+
return { isValid: false, error: "Email must have a valid top-level domain" };
|
|
12601
|
+
}
|
|
12602
|
+
}
|
|
12603
|
+
return { isValid: true };
|
|
12604
|
+
}
|
|
12605
|
+
autoTransform(value) {
|
|
12606
|
+
if (typeof value !== "string") {
|
|
12607
|
+
return { success: false };
|
|
12608
|
+
}
|
|
12609
|
+
let result = value.trim().toLowerCase();
|
|
12610
|
+
if (!this.options.allowPlus) {
|
|
12611
|
+
result = result.replace(/\+.*@/, "@");
|
|
12612
|
+
}
|
|
12613
|
+
return {
|
|
12614
|
+
success: true,
|
|
12615
|
+
correctedValue: result,
|
|
12616
|
+
message: "Trimmed and lowercased email"
|
|
12617
|
+
};
|
|
12618
|
+
}
|
|
12619
|
+
};
|
|
12620
|
+
var LengthValidator = class {
|
|
12621
|
+
constructor(options = {}) {
|
|
12622
|
+
this.options = options;
|
|
12623
|
+
}
|
|
12624
|
+
name = "length";
|
|
12625
|
+
validate(value) {
|
|
12626
|
+
if (typeof value !== "string") {
|
|
12627
|
+
return { isValid: false, error: "Value must be a string" };
|
|
12628
|
+
}
|
|
12629
|
+
if (this.options.exact !== void 0 && value.length !== this.options.exact) {
|
|
12630
|
+
return { isValid: false, error: `Value must be exactly ${this.options.exact} characters long` };
|
|
12631
|
+
}
|
|
12632
|
+
if (this.options.min !== void 0 && value.length < this.options.min) {
|
|
12633
|
+
return { isValid: false, error: `Value must be at least ${this.options.min} characters long` };
|
|
12634
|
+
}
|
|
12635
|
+
if (this.options.max !== void 0 && value.length > this.options.max) {
|
|
12636
|
+
return { isValid: false, error: `Value must be at most ${this.options.max} characters long` };
|
|
12637
|
+
}
|
|
12638
|
+
return { isValid: true };
|
|
12639
|
+
}
|
|
12640
|
+
autoTransform(value) {
|
|
12641
|
+
if (typeof value !== "string") {
|
|
12642
|
+
return { success: false };
|
|
12643
|
+
}
|
|
12644
|
+
let result = value;
|
|
12645
|
+
if (this.options.max !== void 0 && result.length > this.options.max) {
|
|
12646
|
+
result = result.slice(0, this.options.max);
|
|
12647
|
+
}
|
|
12648
|
+
if (this.options.min !== void 0 && result.length < this.options.min) {
|
|
12649
|
+
result = result.padEnd(this.options.min);
|
|
12650
|
+
}
|
|
12651
|
+
return {
|
|
12652
|
+
success: true,
|
|
12653
|
+
correctedValue: result,
|
|
12654
|
+
message: "Adjusted string length"
|
|
12655
|
+
};
|
|
12656
|
+
}
|
|
12657
|
+
};
|
|
12658
|
+
var PatternValidator = class {
|
|
12659
|
+
constructor(options = { pattern: /.*/ }) {
|
|
12660
|
+
this.options = options;
|
|
12661
|
+
}
|
|
12662
|
+
name = "pattern";
|
|
12663
|
+
validate(value) {
|
|
12664
|
+
if (typeof value !== "string") {
|
|
12665
|
+
return { isValid: false, error: "Value must be a string" };
|
|
12666
|
+
}
|
|
12667
|
+
const pattern = new RegExp(this.options.pattern.source, this.options.flags);
|
|
12668
|
+
if (!pattern.test(value)) {
|
|
12669
|
+
return { isValid: false, error: this.options.errorMessage || "Value does not match required pattern" };
|
|
12670
|
+
}
|
|
12671
|
+
return { isValid: true };
|
|
12672
|
+
}
|
|
12673
|
+
autoTransform(value) {
|
|
12674
|
+
if (typeof value !== "string" || !this.options.replacement) {
|
|
12675
|
+
return { success: false };
|
|
12676
|
+
}
|
|
12677
|
+
const pattern = new RegExp(this.options.pattern.source, this.options.flags);
|
|
12678
|
+
const result = value.replace(pattern, this.options.replacement);
|
|
12679
|
+
return {
|
|
12680
|
+
success: true,
|
|
12681
|
+
correctedValue: result,
|
|
12682
|
+
message: "Replaced pattern matches"
|
|
12683
|
+
};
|
|
12684
|
+
}
|
|
12685
|
+
};
|
|
12686
|
+
|
|
12687
|
+
// src/decorators/transformers/transformer-decorators.ts
|
|
12688
|
+
var normalizePropertyName3 = (name) => {
|
|
12689
|
+
if (typeof name === "symbol") {
|
|
12690
|
+
return name.description ?? name.toString();
|
|
12691
|
+
}
|
|
12692
|
+
return name;
|
|
12693
|
+
};
|
|
12694
|
+
var registerTransformerMetadata = (context, metadata) => {
|
|
12695
|
+
const propertyName = normalizePropertyName3(context.name);
|
|
12696
|
+
const bag = getOrCreateMetadataBag(context);
|
|
12697
|
+
let existing = bag.transformers.find((t) => t.propertyName === propertyName);
|
|
12698
|
+
if (!existing) {
|
|
12699
|
+
existing = {
|
|
12700
|
+
propertyName,
|
|
12701
|
+
metadata: {
|
|
12702
|
+
propertyName,
|
|
12703
|
+
transformers: [],
|
|
12704
|
+
validators: [],
|
|
12705
|
+
sanitizers: [],
|
|
12706
|
+
executionOrder: "both"
|
|
12707
|
+
}
|
|
12708
|
+
};
|
|
12709
|
+
bag.transformers.push(existing);
|
|
12710
|
+
}
|
|
12711
|
+
if (metadata.transformers) {
|
|
12712
|
+
existing.metadata.transformers.push(...metadata.transformers);
|
|
12713
|
+
}
|
|
12714
|
+
if (metadata.validators) {
|
|
12715
|
+
existing.metadata.validators.push(...metadata.validators);
|
|
12716
|
+
}
|
|
12717
|
+
if (metadata.sanitizers) {
|
|
12718
|
+
existing.metadata.sanitizers.push(...metadata.sanitizers);
|
|
12719
|
+
}
|
|
12720
|
+
if (metadata.executionOrder) {
|
|
12721
|
+
existing.metadata.executionOrder = metadata.executionOrder;
|
|
12722
|
+
}
|
|
12723
|
+
};
|
|
12724
|
+
function Trim(options) {
|
|
12725
|
+
return function(_value, context) {
|
|
12726
|
+
registerTransformerMetadata(context, {
|
|
12727
|
+
sanitizers: [new TrimTransformer(options)]
|
|
12728
|
+
});
|
|
12729
|
+
};
|
|
12730
|
+
}
|
|
12731
|
+
function Lower() {
|
|
12732
|
+
return function(_value, context) {
|
|
12733
|
+
registerTransformerMetadata(context, {
|
|
12734
|
+
sanitizers: [new CaseTransformer("lower")]
|
|
12735
|
+
});
|
|
12736
|
+
};
|
|
12737
|
+
}
|
|
12738
|
+
function Upper() {
|
|
12739
|
+
return function(_value, context) {
|
|
12740
|
+
registerTransformerMetadata(context, {
|
|
12741
|
+
sanitizers: [new CaseTransformer("upper")]
|
|
12742
|
+
});
|
|
12743
|
+
};
|
|
12744
|
+
}
|
|
12745
|
+
function Capitalize() {
|
|
12746
|
+
return function(_value, context) {
|
|
12747
|
+
registerTransformerMetadata(context, {
|
|
12748
|
+
sanitizers: [new CaseTransformer("capitalize")]
|
|
12749
|
+
});
|
|
12750
|
+
};
|
|
12751
|
+
}
|
|
12752
|
+
function Title() {
|
|
12753
|
+
return function(_value, context) {
|
|
12754
|
+
registerTransformerMetadata(context, {
|
|
12755
|
+
sanitizers: [new CaseTransformer("title")]
|
|
12756
|
+
});
|
|
12757
|
+
};
|
|
12758
|
+
}
|
|
12759
|
+
function Alphanumeric(options) {
|
|
12760
|
+
return function(_value, context) {
|
|
12761
|
+
registerTransformerMetadata(context, {
|
|
12762
|
+
validators: [new AlphanumericValidator(options)]
|
|
12763
|
+
});
|
|
12764
|
+
};
|
|
12765
|
+
}
|
|
12766
|
+
function Email(options) {
|
|
12767
|
+
return function(_value, context) {
|
|
12768
|
+
registerTransformerMetadata(context, {
|
|
12769
|
+
validators: [new EmailValidator(options)]
|
|
12770
|
+
});
|
|
12771
|
+
};
|
|
12772
|
+
}
|
|
12773
|
+
function Length(options) {
|
|
12774
|
+
return function(_value, context) {
|
|
12775
|
+
registerTransformerMetadata(context, {
|
|
12776
|
+
validators: [new LengthValidator(options)]
|
|
12777
|
+
});
|
|
12778
|
+
};
|
|
12779
|
+
}
|
|
12780
|
+
function Pattern(options) {
|
|
12781
|
+
return function(_value, context) {
|
|
12782
|
+
registerTransformerMetadata(context, {
|
|
12783
|
+
validators: [new PatternValidator(options)]
|
|
12784
|
+
});
|
|
12785
|
+
};
|
|
12786
|
+
}
|
|
12787
|
+
|
|
12788
|
+
// src/decorators/validators/country-validator-registry.ts
|
|
12789
|
+
var VALIDATOR_FACTORIES = /* @__PURE__ */ new Map();
|
|
12790
|
+
var registerValidator = (countryCode, identifierType, factory) => {
|
|
12791
|
+
const key = `${countryCode.toLowerCase()}-${identifierType.toLowerCase()}`;
|
|
12792
|
+
if (!countryCode) throw new Error("countryCode is required");
|
|
12793
|
+
if (!identifierType) throw new Error("identifierType is required");
|
|
12794
|
+
if (typeof factory !== "function") {
|
|
12795
|
+
throw new Error("factory must be a function that returns a validator");
|
|
12796
|
+
}
|
|
12797
|
+
VALIDATOR_FACTORIES.set(key, factory);
|
|
12798
|
+
};
|
|
12799
|
+
var resolveValidator = (countryCode, identifierType) => {
|
|
12800
|
+
const key = `${countryCode.toLowerCase()}-${identifierType.toLowerCase()}`;
|
|
12801
|
+
const factory = VALIDATOR_FACTORIES.get(key);
|
|
12802
|
+
return factory ? factory() : void 0;
|
|
12803
|
+
};
|
|
12804
|
+
var getRegisteredValidators = () => {
|
|
12805
|
+
return Array.from(VALIDATOR_FACTORIES.keys());
|
|
12806
|
+
};
|
|
12807
|
+
var hasValidator = (countryCode, identifierType) => {
|
|
12808
|
+
const key = `${countryCode.toLowerCase()}-${identifierType.toLowerCase()}`;
|
|
12809
|
+
return VALIDATOR_FACTORIES.has(key);
|
|
12810
|
+
};
|
|
12811
|
+
|
|
12812
|
+
// src/decorators/validators/built-in/br-cpf-validator.ts
|
|
12813
|
+
var CPFValidator = class {
|
|
12814
|
+
countryCode = "BR";
|
|
12815
|
+
identifierType = "cpf";
|
|
12816
|
+
name = "br-cpf";
|
|
12817
|
+
validate(value, options = {}) {
|
|
12818
|
+
const normalized = this.normalize(value);
|
|
12819
|
+
if (!/^\d{11}$/.test(normalized)) {
|
|
12820
|
+
return {
|
|
12821
|
+
isValid: false,
|
|
12822
|
+
error: options.errorMessage || "CPF must contain exactly 11 numeric digits"
|
|
12823
|
+
};
|
|
12824
|
+
}
|
|
12825
|
+
if (this.isKnownInvalid(normalized) && options.strict !== false) {
|
|
12826
|
+
return {
|
|
12827
|
+
isValid: false,
|
|
12828
|
+
error: options.errorMessage || "Invalid CPF number"
|
|
12829
|
+
};
|
|
12830
|
+
}
|
|
12831
|
+
if (!this.validateChecksum(normalized)) {
|
|
12832
|
+
return {
|
|
12833
|
+
isValid: false,
|
|
12834
|
+
error: options.errorMessage || "Invalid CPF checksum"
|
|
12835
|
+
};
|
|
12836
|
+
}
|
|
12837
|
+
return {
|
|
12838
|
+
isValid: true,
|
|
12839
|
+
normalizedValue: normalized,
|
|
12840
|
+
formattedValue: this.format(value)
|
|
12841
|
+
};
|
|
12842
|
+
}
|
|
12843
|
+
normalize(value) {
|
|
12844
|
+
return value.replace(/[^0-9]/g, "");
|
|
12845
|
+
}
|
|
12846
|
+
format(value) {
|
|
12847
|
+
const normalized = this.normalize(value);
|
|
12848
|
+
if (normalized.length !== 11) return value;
|
|
12849
|
+
return normalized.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, "$1.$2.$3-$4");
|
|
12850
|
+
}
|
|
12851
|
+
autoCorrect(value) {
|
|
12852
|
+
const normalized = this.normalize(value);
|
|
12853
|
+
if (normalized.length === 11) {
|
|
12854
|
+
return { success: true, correctedValue: this.format(normalized) };
|
|
12855
|
+
}
|
|
12856
|
+
if (normalized.length < 11) {
|
|
12857
|
+
const padded = normalized.padEnd(11, "0");
|
|
12858
|
+
return { success: true, correctedValue: this.format(padded) };
|
|
12859
|
+
}
|
|
12860
|
+
const truncated = normalized.slice(0, 11);
|
|
12861
|
+
return { success: true, correctedValue: this.format(truncated) };
|
|
12862
|
+
}
|
|
12863
|
+
isKnownInvalid(cpf) {
|
|
12864
|
+
return /^(\d)\1{10}$/.test(cpf);
|
|
12865
|
+
}
|
|
12866
|
+
validateChecksum(cpf) {
|
|
12867
|
+
const digits = cpf.split("").map(Number);
|
|
12868
|
+
let sum2 = 0;
|
|
12869
|
+
for (let i = 0; i < 9; i++) {
|
|
12870
|
+
sum2 += digits[i] * (10 - i);
|
|
12871
|
+
}
|
|
12872
|
+
let check1 = sum2 % 11;
|
|
12873
|
+
check1 = check1 < 2 ? 0 : 11 - check1;
|
|
12874
|
+
if (check1 !== digits[9]) {
|
|
12875
|
+
return false;
|
|
12876
|
+
}
|
|
12877
|
+
sum2 = 0;
|
|
12878
|
+
for (let i = 0; i < 10; i++) {
|
|
12879
|
+
sum2 += digits[i] * (11 - i);
|
|
12880
|
+
}
|
|
12881
|
+
let check2 = sum2 % 11;
|
|
12882
|
+
check2 = check2 < 2 ? 0 : 11 - check2;
|
|
12883
|
+
return check2 === digits[10];
|
|
12884
|
+
}
|
|
12885
|
+
};
|
|
12886
|
+
|
|
12887
|
+
// src/decorators/validators/built-in/br-cnpj-validator.ts
|
|
12888
|
+
var CNPJValidator = class {
|
|
12889
|
+
countryCode = "BR";
|
|
12890
|
+
identifierType = "cnpj";
|
|
12891
|
+
name = "br-cnpj";
|
|
12892
|
+
validate(value, options = {}) {
|
|
12893
|
+
const normalized = this.normalize(value);
|
|
12894
|
+
if (!/^\d{14}$/.test(normalized)) {
|
|
12895
|
+
return {
|
|
12896
|
+
isValid: false,
|
|
12897
|
+
error: options.errorMessage || "CNPJ must contain exactly 14 numeric digits"
|
|
12898
|
+
};
|
|
12899
|
+
}
|
|
12900
|
+
if (this.isKnownInvalid(normalized) && options.strict !== false) {
|
|
12901
|
+
return {
|
|
12902
|
+
isValid: false,
|
|
12903
|
+
error: options.errorMessage || "Invalid CNPJ number"
|
|
12904
|
+
};
|
|
12905
|
+
}
|
|
12906
|
+
if (!this.validateChecksum(normalized)) {
|
|
12907
|
+
return {
|
|
12908
|
+
isValid: false,
|
|
12909
|
+
error: options.errorMessage || "Invalid CNPJ checksum"
|
|
12910
|
+
};
|
|
12911
|
+
}
|
|
12912
|
+
return {
|
|
12913
|
+
isValid: true,
|
|
12914
|
+
normalizedValue: normalized,
|
|
12915
|
+
formattedValue: this.format(value)
|
|
12916
|
+
};
|
|
12917
|
+
}
|
|
12918
|
+
normalize(value) {
|
|
12919
|
+
return value.replace(/[^0-9]/g, "");
|
|
12920
|
+
}
|
|
12921
|
+
format(value) {
|
|
12922
|
+
const normalized = this.normalize(value);
|
|
12923
|
+
if (normalized.length !== 14) return value;
|
|
12924
|
+
return normalized.replace(/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/, "$1.$2.$3/$4-$5");
|
|
12925
|
+
}
|
|
12926
|
+
autoCorrect(value) {
|
|
12927
|
+
const normalized = this.normalize(value);
|
|
12928
|
+
if (normalized.length === 14) {
|
|
12929
|
+
return { success: true, correctedValue: this.format(normalized) };
|
|
12930
|
+
}
|
|
12931
|
+
if (normalized.length < 14) {
|
|
12932
|
+
const padded = normalized.padEnd(14, "0");
|
|
12933
|
+
return { success: true, correctedValue: this.format(padded) };
|
|
12934
|
+
}
|
|
12935
|
+
const truncated = normalized.slice(0, 14);
|
|
12936
|
+
return { success: true, correctedValue: this.format(truncated) };
|
|
12937
|
+
}
|
|
12938
|
+
isKnownInvalid(cnpj) {
|
|
12939
|
+
return /^(\d)\1{13}$/.test(cnpj);
|
|
12940
|
+
}
|
|
12941
|
+
validateChecksum(cnpj) {
|
|
12942
|
+
const digits = cnpj.split("").map(Number);
|
|
12943
|
+
const weights1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
12944
|
+
const weights2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
12945
|
+
let sum2 = 0;
|
|
12946
|
+
for (let i = 0; i < 12; i++) {
|
|
12947
|
+
sum2 += digits[i] * weights1[i];
|
|
12948
|
+
}
|
|
12949
|
+
let check1 = sum2 % 11;
|
|
12950
|
+
check1 = check1 < 2 ? 0 : 11 - check1;
|
|
12951
|
+
if (check1 !== digits[12]) {
|
|
12952
|
+
return false;
|
|
12953
|
+
}
|
|
12954
|
+
sum2 = 0;
|
|
12955
|
+
for (let i = 0; i < 13; i++) {
|
|
12956
|
+
sum2 += digits[i] * weights2[i];
|
|
12957
|
+
}
|
|
12958
|
+
let check2 = sum2 % 11;
|
|
12959
|
+
check2 = check2 < 2 ? 0 : 11 - check2;
|
|
12960
|
+
return check2 === digits[13];
|
|
12961
|
+
}
|
|
12962
|
+
};
|
|
12963
|
+
|
|
12964
|
+
// src/decorators/validators/built-in/br-cep-validator.ts
|
|
12965
|
+
var CEPValidator = class {
|
|
12966
|
+
countryCode = "BR";
|
|
12967
|
+
identifierType = "cep";
|
|
12968
|
+
name = "br-cep";
|
|
12969
|
+
validate(value, options = {}) {
|
|
12970
|
+
const normalized = this.normalize(value);
|
|
12971
|
+
if (!/^\d{8}$/.test(normalized)) {
|
|
12972
|
+
return {
|
|
12973
|
+
isValid: false,
|
|
12974
|
+
error: options.errorMessage || "CEP must contain exactly 8 numeric digits"
|
|
12975
|
+
};
|
|
12976
|
+
}
|
|
12977
|
+
return {
|
|
12978
|
+
isValid: true,
|
|
12979
|
+
normalizedValue: normalized,
|
|
12980
|
+
formattedValue: this.format(value)
|
|
12981
|
+
};
|
|
12982
|
+
}
|
|
12983
|
+
normalize(value) {
|
|
12984
|
+
return value.replace(/[^0-9]/g, "");
|
|
12985
|
+
}
|
|
12986
|
+
format(value) {
|
|
12987
|
+
const normalized = this.normalize(value);
|
|
12988
|
+
if (normalized.length !== 8) return value;
|
|
12989
|
+
return normalized.replace(/(\d{5})(\d{3})/, "$1-$2");
|
|
12990
|
+
}
|
|
12991
|
+
autoCorrect(value) {
|
|
12992
|
+
const normalized = this.normalize(value);
|
|
12993
|
+
if (normalized.length === 8) {
|
|
12994
|
+
return { success: true, correctedValue: this.format(normalized) };
|
|
12995
|
+
}
|
|
12996
|
+
if (normalized.length < 8) {
|
|
12997
|
+
const padded = normalized.padEnd(8, "0");
|
|
12998
|
+
return { success: true, correctedValue: this.format(padded) };
|
|
12999
|
+
}
|
|
13000
|
+
const truncated = normalized.slice(0, 8);
|
|
13001
|
+
return { success: true, correctedValue: this.format(truncated) };
|
|
13002
|
+
}
|
|
13003
|
+
};
|
|
13004
|
+
|
|
13005
|
+
// src/decorators/validators/country-validators-decorators.ts
|
|
13006
|
+
registerValidator("BR", "cpf", () => new CPFValidator());
|
|
13007
|
+
registerValidator("BR", "cnpj", () => new CNPJValidator());
|
|
13008
|
+
registerValidator("BR", "cep", () => new CEPValidator());
|
|
13009
|
+
var normalizePropertyName4 = (name) => {
|
|
13010
|
+
if (typeof name === "symbol") {
|
|
13011
|
+
return name.description ?? name.toString();
|
|
13012
|
+
}
|
|
13013
|
+
return name;
|
|
13014
|
+
};
|
|
13015
|
+
function CPF(options) {
|
|
13016
|
+
return function(_value, context) {
|
|
13017
|
+
const propertyName = normalizePropertyName4(context.name);
|
|
13018
|
+
const bag = getOrCreateMetadataBag(context);
|
|
13019
|
+
let existing = bag.transformers.find((t) => t.propertyName === propertyName);
|
|
13020
|
+
if (!existing) {
|
|
13021
|
+
existing = {
|
|
13022
|
+
propertyName,
|
|
13023
|
+
metadata: {
|
|
13024
|
+
propertyName,
|
|
13025
|
+
transformers: [],
|
|
13026
|
+
validators: [],
|
|
13027
|
+
sanitizers: [],
|
|
13028
|
+
executionOrder: "both"
|
|
13029
|
+
}
|
|
13030
|
+
};
|
|
13031
|
+
bag.transformers.push(existing);
|
|
13032
|
+
}
|
|
13033
|
+
const validator = new CPFValidator();
|
|
13034
|
+
existing.metadata.validators.push({
|
|
13035
|
+
name: validator.name,
|
|
13036
|
+
validate: (value) => {
|
|
13037
|
+
const result = validator.validate(value, {
|
|
13038
|
+
strict: options?.strict ?? true,
|
|
13039
|
+
errorMessage: options?.errorMessage
|
|
13040
|
+
});
|
|
13041
|
+
return {
|
|
13042
|
+
isValid: result.isValid,
|
|
13043
|
+
error: result.error,
|
|
13044
|
+
message: result.error
|
|
13045
|
+
};
|
|
13046
|
+
},
|
|
13047
|
+
autoTransform: (value) => {
|
|
13048
|
+
const correction = validator.autoCorrect(value);
|
|
13049
|
+
if (correction?.success) {
|
|
13050
|
+
return {
|
|
13051
|
+
success: true,
|
|
13052
|
+
correctedValue: correction.correctedValue,
|
|
13053
|
+
message: correction.message
|
|
13054
|
+
};
|
|
13055
|
+
}
|
|
13056
|
+
return { success: false };
|
|
13057
|
+
}
|
|
13058
|
+
});
|
|
13059
|
+
existing.metadata.sanitizers.push({
|
|
13060
|
+
name: "cpf-formatter",
|
|
13061
|
+
sanitize: (value) => validator.format(value)
|
|
13062
|
+
});
|
|
13063
|
+
};
|
|
13064
|
+
}
|
|
13065
|
+
function CNPJ(options) {
|
|
13066
|
+
return function(_value, context) {
|
|
13067
|
+
const propertyName = normalizePropertyName4(context.name);
|
|
13068
|
+
const bag = getOrCreateMetadataBag(context);
|
|
13069
|
+
let existing = bag.transformers.find((t) => t.propertyName === propertyName);
|
|
13070
|
+
if (!existing) {
|
|
13071
|
+
existing = {
|
|
13072
|
+
propertyName,
|
|
13073
|
+
metadata: {
|
|
13074
|
+
propertyName,
|
|
13075
|
+
transformers: [],
|
|
13076
|
+
validators: [],
|
|
13077
|
+
sanitizers: [],
|
|
13078
|
+
executionOrder: "both"
|
|
13079
|
+
}
|
|
13080
|
+
};
|
|
13081
|
+
bag.transformers.push(existing);
|
|
13082
|
+
}
|
|
13083
|
+
const validator = new CNPJValidator();
|
|
13084
|
+
existing.metadata.validators.push({
|
|
13085
|
+
name: validator.name,
|
|
13086
|
+
validate: (value) => {
|
|
13087
|
+
const result = validator.validate(value, {
|
|
13088
|
+
strict: options?.strict ?? true,
|
|
13089
|
+
errorMessage: options?.errorMessage
|
|
13090
|
+
});
|
|
13091
|
+
return {
|
|
13092
|
+
isValid: result.isValid,
|
|
13093
|
+
error: result.error,
|
|
13094
|
+
message: result.error
|
|
13095
|
+
};
|
|
13096
|
+
},
|
|
13097
|
+
autoTransform: (value) => {
|
|
13098
|
+
const correction = validator.autoCorrect(value);
|
|
13099
|
+
if (correction?.success) {
|
|
13100
|
+
return {
|
|
13101
|
+
success: true,
|
|
13102
|
+
correctedValue: correction.correctedValue,
|
|
13103
|
+
message: correction.message
|
|
13104
|
+
};
|
|
13105
|
+
}
|
|
13106
|
+
return { success: false };
|
|
13107
|
+
}
|
|
13108
|
+
});
|
|
13109
|
+
existing.metadata.sanitizers.push({
|
|
13110
|
+
name: "cnpj-formatter",
|
|
13111
|
+
sanitize: (value) => validator.format(value)
|
|
13112
|
+
});
|
|
13113
|
+
};
|
|
13114
|
+
}
|
|
13115
|
+
function CEP(options) {
|
|
13116
|
+
return function(_value, context) {
|
|
13117
|
+
const propertyName = normalizePropertyName4(context.name);
|
|
13118
|
+
const bag = getOrCreateMetadataBag(context);
|
|
13119
|
+
let existing = bag.transformers.find((t) => t.propertyName === propertyName);
|
|
13120
|
+
if (!existing) {
|
|
13121
|
+
existing = {
|
|
13122
|
+
propertyName,
|
|
13123
|
+
metadata: {
|
|
13124
|
+
propertyName,
|
|
13125
|
+
transformers: [],
|
|
13126
|
+
validators: [],
|
|
13127
|
+
sanitizers: [],
|
|
13128
|
+
executionOrder: "both"
|
|
13129
|
+
}
|
|
13130
|
+
};
|
|
13131
|
+
bag.transformers.push(existing);
|
|
13132
|
+
}
|
|
13133
|
+
const validator = new CEPValidator();
|
|
13134
|
+
existing.metadata.validators.push({
|
|
13135
|
+
name: validator.name,
|
|
13136
|
+
validate: (value) => {
|
|
13137
|
+
const result = validator.validate(value, {
|
|
13138
|
+
strict: options?.strict ?? true,
|
|
13139
|
+
errorMessage: options?.errorMessage
|
|
13140
|
+
});
|
|
13141
|
+
return {
|
|
13142
|
+
isValid: result.isValid,
|
|
13143
|
+
error: result.error,
|
|
13144
|
+
message: result.error
|
|
13145
|
+
};
|
|
13146
|
+
},
|
|
13147
|
+
autoTransform: (value) => {
|
|
13148
|
+
const correction = validator.autoCorrect(value);
|
|
13149
|
+
if (correction?.success) {
|
|
13150
|
+
return {
|
|
13151
|
+
success: true,
|
|
13152
|
+
correctedValue: correction.correctedValue,
|
|
13153
|
+
message: correction.message
|
|
13154
|
+
};
|
|
13155
|
+
}
|
|
13156
|
+
return { success: false };
|
|
13157
|
+
}
|
|
13158
|
+
});
|
|
13159
|
+
existing.metadata.sanitizers.push({
|
|
13160
|
+
name: "cep-formatter",
|
|
13161
|
+
sanitize: (value) => validator.format(value)
|
|
13162
|
+
});
|
|
13163
|
+
};
|
|
13164
|
+
}
|
|
13165
|
+
|
|
12468
13166
|
// src/core/execution/db-executor.ts
|
|
12469
13167
|
function rowsToQueryResult(rows) {
|
|
12470
13168
|
if (rows.length === 0) {
|
|
@@ -14279,11 +14977,16 @@ function pagedResponseToOpenApiSchema(itemSchema) {
|
|
|
14279
14977
|
};
|
|
14280
14978
|
}
|
|
14281
14979
|
export {
|
|
14980
|
+
Alphanumeric,
|
|
14282
14981
|
AsyncLocalStorage,
|
|
14283
14982
|
BelongsTo,
|
|
14284
14983
|
BelongsToMany,
|
|
14285
14984
|
BigIntTypeStrategy,
|
|
14286
14985
|
BooleanTypeStrategy,
|
|
14986
|
+
CEP,
|
|
14987
|
+
CNPJ,
|
|
14988
|
+
CPF,
|
|
14989
|
+
Capitalize,
|
|
14287
14990
|
Column,
|
|
14288
14991
|
ConstructorMaterializationStrategy,
|
|
14289
14992
|
DateTimeTypeStrategy,
|
|
@@ -14295,6 +14998,7 @@ export {
|
|
|
14295
14998
|
DefaultTypeStrategy,
|
|
14296
14999
|
DeleteQueryBuilder,
|
|
14297
15000
|
DomainEventBus,
|
|
15001
|
+
Email,
|
|
14298
15002
|
Entity,
|
|
14299
15003
|
EntityStatus,
|
|
14300
15004
|
HasMany,
|
|
@@ -14302,9 +15006,12 @@ export {
|
|
|
14302
15006
|
InsertQueryBuilder,
|
|
14303
15007
|
IntegerTypeStrategy,
|
|
14304
15008
|
InterceptorPipeline,
|
|
15009
|
+
Length,
|
|
15010
|
+
Lower,
|
|
14305
15011
|
MySqlDialect,
|
|
14306
15012
|
Orm,
|
|
14307
15013
|
OrmSession,
|
|
15014
|
+
Pattern,
|
|
14308
15015
|
Pool,
|
|
14309
15016
|
PostgresDialect,
|
|
14310
15017
|
PrimaryKey,
|
|
@@ -14315,9 +15022,12 @@ export {
|
|
|
14315
15022
|
SqlServerDialect,
|
|
14316
15023
|
SqliteDialect,
|
|
14317
15024
|
StringTypeStrategy,
|
|
15025
|
+
Title,
|
|
15026
|
+
Trim,
|
|
14318
15027
|
TypeMappingService,
|
|
14319
15028
|
TypeScriptGenerator,
|
|
14320
15029
|
UpdateQueryBuilder,
|
|
15030
|
+
Upper,
|
|
14321
15031
|
UuidTypeStrategy,
|
|
14322
15032
|
abs,
|
|
14323
15033
|
acos,
|
|
@@ -14432,9 +15142,12 @@ export {
|
|
|
14432
15142
|
generateSchemaSqlFor,
|
|
14433
15143
|
getColumn,
|
|
14434
15144
|
getColumnMap,
|
|
15145
|
+
getColumnType,
|
|
15146
|
+
getDateKind,
|
|
14435
15147
|
getDecoratorMetadata,
|
|
14436
15148
|
getDeterministicComponentName,
|
|
14437
15149
|
getOpenApiVersionForDialect,
|
|
15150
|
+
getRegisteredValidators,
|
|
14438
15151
|
getSchemaIntrospector,
|
|
14439
15152
|
getTableDefFromEntity,
|
|
14440
15153
|
greatest,
|
|
@@ -14445,6 +15158,7 @@ export {
|
|
|
14445
15158
|
hasNextPage as hasNextPageMeta,
|
|
14446
15159
|
hasOne,
|
|
14447
15160
|
hasPrevPage as hasPrevPageMeta,
|
|
15161
|
+
hasValidator,
|
|
14448
15162
|
hour,
|
|
14449
15163
|
hydrateRows,
|
|
14450
15164
|
ifNull,
|
|
@@ -14538,6 +15252,7 @@ export {
|
|
|
14538
15252
|
registerExpressionDispatcher,
|
|
14539
15253
|
registerOperandDispatcher,
|
|
14540
15254
|
registerSchemaIntrospector,
|
|
15255
|
+
registerValidator,
|
|
14541
15256
|
relationFilterToOpenApiSchema,
|
|
14542
15257
|
relationLoaderCache,
|
|
14543
15258
|
renderColumnDefinition,
|
|
@@ -14545,6 +15260,7 @@ export {
|
|
|
14545
15260
|
repeat,
|
|
14546
15261
|
replace,
|
|
14547
15262
|
replaceWithRefs,
|
|
15263
|
+
resolveValidator,
|
|
14548
15264
|
responseToRef,
|
|
14549
15265
|
reverse,
|
|
14550
15266
|
right,
|