arkos 1.4.7-beta → 1.4.8-beta
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/cjs/generated.js +7 -0
- package/dist/cjs/generated.js.map +1 -0
- package/dist/cjs/modules/base/utils/error-prettifier.js +188 -0
- package/dist/cjs/modules/base/utils/error-prettifier.js.map +1 -0
- package/dist/cjs/types/arkos-prisma-input.bak.js +3 -0
- package/dist/cjs/types/arkos-prisma-input.bak.js.map +1 -0
- package/dist/cjs/types/arkos-prisma-input.js +3 -0
- package/dist/cjs/types/arkos-prisma-input.js.map +1 -0
- package/dist/cjs/utils/arkos-router/arkos-router-openapi-manager.js +126 -0
- package/dist/cjs/utils/arkos-router/arkos-router-openapi-manager.js.map +1 -0
- package/dist/cjs/utils/cli/remove-dir-cli.js +10 -0
- package/dist/cjs/utils/cli/remove-dir-cli.js.map +1 -0
- package/dist/cjs/utils/cli/utils/cli.helpers.js +1 -1
- package/dist/cjs/utils/cli/utils/static-types-generator.js +558 -0
- package/dist/cjs/utils/cli/utils/static-types-generator.js.map +1 -0
- package/dist/cjs/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js +550 -0
- package/dist/cjs/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js.map +1 -0
- package/dist/cjs/utils/cli/utils/template-generator/templates/generate-multiple-components.js +141 -0
- package/dist/cjs/utils/cli/utils/template-generator/templates/generate-multiple-components.js.map +1 -0
- package/dist/cjs/utils/cli/utils/template-generator/templates/zod-schema-generator.js +351 -0
- package/dist/cjs/utils/cli/utils/template-generator/templates/zod-schema-generator.js.map +1 -0
- package/dist/cjs/utils/helpers/global.helpers.js +13 -2
- package/dist/cjs/utils/helpers/global.helpers.js.map +1 -1
- package/dist/cjs/utils/remove-dir.js +1 -4
- package/dist/cjs/utils/remove-dir.js.map +1 -1
- package/dist/esm/generated.js +3 -0
- package/dist/esm/generated.js.map +1 -0
- package/dist/esm/modules/base/utils/error-prettifier.js +184 -0
- package/dist/esm/modules/base/utils/error-prettifier.js.map +1 -0
- package/dist/esm/types/arkos-prisma-input.bak.js +2 -0
- package/dist/esm/types/arkos-prisma-input.bak.js.map +1 -0
- package/dist/esm/types/arkos-prisma-input.js +2 -0
- package/dist/esm/types/arkos-prisma-input.js.map +1 -0
- package/dist/esm/utils/arkos-router/arkos-router-openapi-manager.js +121 -0
- package/dist/esm/utils/arkos-router/arkos-router-openapi-manager.js.map +1 -0
- package/dist/esm/utils/cli/remove-dir-cli.js +8 -0
- package/dist/esm/utils/cli/remove-dir-cli.js.map +1 -0
- package/dist/esm/utils/cli/utils/cli.helpers.js +1 -1
- package/dist/esm/utils/cli/utils/static-types-generator.js +553 -0
- package/dist/esm/utils/cli/utils/static-types-generator.js.map +1 -0
- package/dist/esm/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js +543 -0
- package/dist/esm/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js.map +1 -0
- package/dist/esm/utils/cli/utils/template-generator/templates/generate-multiple-components.js +135 -0
- package/dist/esm/utils/cli/utils/template-generator/templates/generate-multiple-components.js.map +1 -0
- package/dist/esm/utils/cli/utils/template-generator/templates/zod-schema-generator.js +344 -0
- package/dist/esm/utils/cli/utils/template-generator/templates/zod-schema-generator.js.map +1 -0
- package/dist/esm/utils/helpers/global.helpers.js +13 -2
- package/dist/esm/utils/helpers/global.helpers.js.map +1 -1
- package/dist/esm/utils/remove-dir.js +1 -5
- package/dist/esm/utils/remove-dir.js.map +1 -1
- package/dist/types/generated.d.ts +4 -0
- package/dist/types/modules/base/utils/error-prettifier.d.ts +127 -0
- package/dist/types/types/arkos-prisma-input.bak.d.ts +237 -0
- package/dist/types/types/arkos-prisma-input.d.ts +160 -0
- package/dist/types/utils/arkos-router/arkos-router-openapi-manager.d.ts +45 -0
- package/dist/types/utils/cli/remove-dir-cli.d.ts +1 -0
- package/dist/types/utils/cli/utils/static-types-generator.d.ts +36 -0
- package/dist/types/utils/cli/utils/template-generator/templates/class-validator-dto-generator.d.ts +17 -0
- package/dist/types/utils/cli/utils/template-generator/templates/generate-multiple-components.d.ts +6 -0
- package/dist/types/utils/cli/utils/template-generator/templates/zod-schema-generator.d.ts +14 -0
- package/dist/types/utils/remove-dir.d.ts +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Auto-generated: re-exports from @arkosjs/generated
|
|
2
|
+
// This file is overwritten by scripts/generate-post-build-types.ts at build time.
|
|
3
|
+
"use strict";
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.PrismaClient = void 0;
|
|
6
|
+
const generated_1 = require("@arkosjs/generated");
|
|
7
|
+
exports.PrismaClient = generated_1.PrismaClient;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generated.js","sourceRoot":"","sources":["../../src/generated.ts"],"names":[],"mappings":";;;AAyIA,MAAa,YAAY;CAExB;AAFD,oCAEC","sourcesContent":["/**\n * @maintainers THIS FILE IS A STUB — DO NOT PUT REAL LOGIC HERE.\n *\n * This file exists only so the Arkos source compiles during development.\n * It is completely overwritten at build time by `scripts/generate-post-build-types.ts`,\n * which replaces it with re-exports from `@arkosjs/types` — a folder generated\n * in the user's `node_modules` by `npx arkos prisma generate`.\n *\n * This is the single gateway for all Prisma-dependent types and values.\n * DO NOT import from `@prisma/client` or any user-project-specific module\n * anywhere else in the codebase — add it here instead.\n *\n * To add a new generated type or value:\n * 1. Add a stub export here\n * 2. Add the real export to the `npx arkos prisma generate` output in\n * `src/utils/cli/commands/prisma-generate.command.ts`\n * 3. Add it to the overwrite in `scripts/generate-post-build-types.ts`\n */\n\n/**\n * A map of all Prisma models in the user's project.\n * Each key is a kebab-case model name, each value contains the full\n * Prisma delegate, payload, and args types for that model.\n *\n * Stub during Arkos development — replaced with real generated types\n * after `npx arkos prisma generate`.\n *\n * @example\n * ```ts\n * class BaseService<TModelName extends keyof PrismaModels<any>> {}\n * ```\n */\n\ninterface StubWhereArgs {\n where?: { id?: any; [key: string]: any };\n [key: string]: any;\n}\n\ninterface StubWhereUniqueArgs {\n where: { id?: any; [key: string]: any };\n [key: string]: any;\n}\n\ninterface StubDataArgs {\n data: Record<string, any>;\n [key: string]: any;\n}\n\ninterface StubWhereDataArgs {\n where: { id?: any; [key: string]: any };\n data: Record<string, any>;\n [key: string]: any;\n}\n\ninterface StubPaginationArgs extends StubWhereArgs {\n orderBy?: Record<string, any>;\n select?: Record<string, any>;\n include?: Record<string, any>;\n skip?: number;\n take?: number;\n cursor?: Record<string, any>;\n}\n\ninterface StubCountArgs extends StubWhereArgs {\n select?: Record<string, any>;\n orderBy?: Record<string, any>;\n skip?: number;\n take?: number;\n cursor?: Record<string, any>;\n}\n\n/**\n * Extracts the `where` filter type from a Prisma args type.\n * @example ExtractPrismaFilters<PrismaModels<any>['user']['FindManyArgs']>\n */\nexport type ExtractPrismaFilters<T> = T extends {\n where?: infer W;\n [key: string]: any;\n}\n ? W\n : any;\n\n/**\n * Extracts the `data` type from a Prisma args type.\n * @example ExtractPrismaData<PrismaModels<any>['user']['CreateArgs']>\n */\nexport type ExtractPrismaData<T> = T extends {\n data: infer D;\n [key: string]: any;\n}\n ? D\n : any;\n\n/**\n * Extracts query options from a Prisma args type by omitting the specified keys.\n * @example ExtractPrismaQueryOptions<PrismaModels<any>['user']['CreateArgs'], 'data'>\n */\nexport type ExtractPrismaQueryOptions<T, K extends keyof T = never> = Omit<\n T,\n K\n>;\n\n/**\n * A map of all Prisma models in the user's project.\n * Each key is a kebab-case model name, each value contains the full\n * Prisma delegate, payload, and args types for that model.\n *\n * Stub during Arkos development — replaced with real generated types\n * after `npx arkos prisma generate`.\n *\n * @example\n * ```ts\n * class BaseService<TModelName extends keyof PrismaModels<any>> {}\n * ```\n */\nexport type PrismaModels<T extends Record<string, any>> = Record<\n string,\n {\n Delegate: Record<string, (...args: any[]) => any>;\n GetPayload: Record<string, any>;\n FindManyArgs: StubPaginationArgs;\n FindFirstArgs: StubPaginationArgs;\n CreateArgs: StubDataArgs;\n CreateManyArgs: StubDataArgs;\n UpdateArgs: StubWhereDataArgs;\n UpdateManyArgs: StubWhereDataArgs;\n DeleteArgs: StubWhereUniqueArgs;\n DeleteManyArgs: StubWhereArgs;\n CountArgs: StubCountArgs;\n }\n>;\n\n/**\n * Stub PrismaClient for Arkos development.\n * Replaced with the real `PrismaClient` from `@prisma/client` after\n * `npx arkos prisma generate`.\n */\nexport class PrismaClient {\n [key: string]: any;\n}\n"]}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ErrorPrettifier = void 0;
|
|
4
|
+
const change_case_helpers_1 = require("../../../utils/helpers/change-case.helpers");
|
|
5
|
+
class ErrorPrettifier {
|
|
6
|
+
prettify(library, error) {
|
|
7
|
+
if (library === "class-validator") {
|
|
8
|
+
return this.prettifyClassValidator(error);
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
return this.prettifyZod(error);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
toPascalCase(path) {
|
|
15
|
+
return path
|
|
16
|
+
.split(".")
|
|
17
|
+
.map((part) => (0, change_case_helpers_1.pascalCase)(part))
|
|
18
|
+
.join("");
|
|
19
|
+
}
|
|
20
|
+
replaceFieldInMessage(message, fieldName, fullPath) {
|
|
21
|
+
if (!fullPath.includes(".") && !fullPath.includes("[")) {
|
|
22
|
+
return message;
|
|
23
|
+
}
|
|
24
|
+
const regex = new RegExp(`^${fieldName}\\b`, "i");
|
|
25
|
+
if (regex.test(message)) {
|
|
26
|
+
return message.replace(regex, `'${fullPath}'`);
|
|
27
|
+
}
|
|
28
|
+
const wordBoundaryRegex = new RegExp(`\\b${fieldName}\\b`, "gi");
|
|
29
|
+
if (wordBoundaryRegex.test(message)) {
|
|
30
|
+
return message.replace(wordBoundaryRegex, `'${fullPath}'`);
|
|
31
|
+
}
|
|
32
|
+
return `'${fullPath}' ${message}`;
|
|
33
|
+
}
|
|
34
|
+
prettifyClassValidator(errors, parentPath = "") {
|
|
35
|
+
const result = [];
|
|
36
|
+
for (const error of errors) {
|
|
37
|
+
const currentPath = parentPath
|
|
38
|
+
? `${parentPath}.${error.property}`
|
|
39
|
+
: error.property;
|
|
40
|
+
if (error.children && error.children.length > 0) {
|
|
41
|
+
result.push(...this.prettifyClassValidator(error.children, currentPath));
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (error.constraints) {
|
|
45
|
+
const fieldPascal = this.toPascalCase(currentPath);
|
|
46
|
+
for (const [constraintKey, originalMessage] of Object.entries(error.constraints)) {
|
|
47
|
+
const constraintName = constraintKey.charAt(0).toUpperCase() + constraintKey.slice(1);
|
|
48
|
+
const message = this.replaceFieldInMessage(originalMessage, error.property, currentPath);
|
|
49
|
+
result.push({
|
|
50
|
+
message: message,
|
|
51
|
+
code: `${fieldPascal}${constraintName}Constraint`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
mapZodToConstraintName(issue) {
|
|
59
|
+
switch (issue.code) {
|
|
60
|
+
case "invalid_type":
|
|
61
|
+
const expected = issue.expected;
|
|
62
|
+
switch (expected) {
|
|
63
|
+
case "string":
|
|
64
|
+
return "IsStringConstraint";
|
|
65
|
+
case "number":
|
|
66
|
+
return "IsNumberConstraint";
|
|
67
|
+
case "boolean":
|
|
68
|
+
return "IsBooleanConstraint";
|
|
69
|
+
case "array":
|
|
70
|
+
return "IsArrayConstraint";
|
|
71
|
+
case "object":
|
|
72
|
+
return "IsObjectConstraint";
|
|
73
|
+
case "date":
|
|
74
|
+
return "IsDateConstraint";
|
|
75
|
+
default:
|
|
76
|
+
return "InvalidTypeConstraint";
|
|
77
|
+
}
|
|
78
|
+
case "too_small":
|
|
79
|
+
if (issue.type === "string") {
|
|
80
|
+
return "MinLengthConstraint";
|
|
81
|
+
}
|
|
82
|
+
else if (issue.type === "number") {
|
|
83
|
+
return "MinConstraint";
|
|
84
|
+
}
|
|
85
|
+
else if (issue.type === "array") {
|
|
86
|
+
return "ArrayMinSizeConstraint";
|
|
87
|
+
}
|
|
88
|
+
return "TooSmallConstraint";
|
|
89
|
+
case "too_big":
|
|
90
|
+
if (issue.type === "string") {
|
|
91
|
+
return "MaxLengthConstraint";
|
|
92
|
+
}
|
|
93
|
+
else if (issue.type === "number") {
|
|
94
|
+
return "MaxConstraint";
|
|
95
|
+
}
|
|
96
|
+
else if (issue.type === "array") {
|
|
97
|
+
return "ArrayMaxSizeConstraint";
|
|
98
|
+
}
|
|
99
|
+
return "TooBigConstraint";
|
|
100
|
+
case "invalid_string":
|
|
101
|
+
if ("validation" in issue) {
|
|
102
|
+
const validation = issue.validation;
|
|
103
|
+
if (validation === "email")
|
|
104
|
+
return "IsEmailConstraint";
|
|
105
|
+
if (validation === "uuid")
|
|
106
|
+
return "IsUuidConstraint";
|
|
107
|
+
if (validation === "url")
|
|
108
|
+
return "IsUrlConstraint";
|
|
109
|
+
if (typeof validation === "object" && "includes" in validation)
|
|
110
|
+
return "ContainsConstraint";
|
|
111
|
+
if (typeof validation === "object" && "startsWith" in validation)
|
|
112
|
+
return "StartsWithConstraint";
|
|
113
|
+
if (typeof validation === "object" && "endsWith" in validation)
|
|
114
|
+
return "EndsWithConstraint";
|
|
115
|
+
}
|
|
116
|
+
return "InvalidStringConstraint";
|
|
117
|
+
case "invalid_enum_value":
|
|
118
|
+
return "IsEnumConstraint";
|
|
119
|
+
case "invalid_literal":
|
|
120
|
+
return "EqualsConstraint";
|
|
121
|
+
case "unrecognized_keys":
|
|
122
|
+
return "UnrecognizedKeysConstraint";
|
|
123
|
+
case "invalid_union":
|
|
124
|
+
return "InvalidUnionConstraint";
|
|
125
|
+
case "invalid_date":
|
|
126
|
+
return "IsDateConstraint";
|
|
127
|
+
case "custom":
|
|
128
|
+
return "CustomConstraint";
|
|
129
|
+
default:
|
|
130
|
+
return "ValidationConstraint";
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
prettifyZod(error) {
|
|
134
|
+
const result = [];
|
|
135
|
+
for (const issue of error.issues) {
|
|
136
|
+
const fieldPath = issue.path
|
|
137
|
+
.map((segment, index) => {
|
|
138
|
+
if (typeof segment === "number") {
|
|
139
|
+
return `[${segment}]`;
|
|
140
|
+
}
|
|
141
|
+
return index === 0 ? segment : `.${segment}`;
|
|
142
|
+
})
|
|
143
|
+
.join("")
|
|
144
|
+
.replace(/\.\[/g, "[");
|
|
145
|
+
const fieldPascal = fieldPath
|
|
146
|
+
? this.toPascalCase(fieldPath.replace(/\[\d+\]/g, ""))
|
|
147
|
+
: "";
|
|
148
|
+
const constraintName = this.mapZodToConstraintName(issue);
|
|
149
|
+
const message = this.injectFieldPathInZodMessage(issue.message, fieldPath, issue);
|
|
150
|
+
result.push({
|
|
151
|
+
message: message,
|
|
152
|
+
code: `${fieldPascal}${constraintName}`,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
injectFieldPathInZodMessage(message, fieldPath, issue) {
|
|
158
|
+
if (!fieldPath) {
|
|
159
|
+
return message;
|
|
160
|
+
}
|
|
161
|
+
if (message === "Required") {
|
|
162
|
+
return `'${fieldPath}' is required`;
|
|
163
|
+
}
|
|
164
|
+
if (message.startsWith("String must")) {
|
|
165
|
+
return message.replace(/^String must/, `'${fieldPath}' must`);
|
|
166
|
+
}
|
|
167
|
+
if (message.startsWith("Number must")) {
|
|
168
|
+
return message.replace(/^Number must/, `'${fieldPath}' must`);
|
|
169
|
+
}
|
|
170
|
+
if (message.startsWith("Array must")) {
|
|
171
|
+
return message.replace(/^Array must/, `'${fieldPath}' must`);
|
|
172
|
+
}
|
|
173
|
+
if (message.startsWith("Expected")) {
|
|
174
|
+
return `'${fieldPath}' must be valid: ${message}`;
|
|
175
|
+
}
|
|
176
|
+
if (message.startsWith("Invalid ")) {
|
|
177
|
+
const type = message.replace("Invalid ", "");
|
|
178
|
+
return `'${fieldPath}' must be a valid ${type}`;
|
|
179
|
+
}
|
|
180
|
+
if (!message.toLowerCase().includes(fieldPath))
|
|
181
|
+
return `'${fieldPath}' ${message}`;
|
|
182
|
+
return message;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
exports.ErrorPrettifier = ErrorPrettifier;
|
|
186
|
+
const errorPrettifier = new ErrorPrettifier();
|
|
187
|
+
exports.default = errorPrettifier;
|
|
188
|
+
//# sourceMappingURL=error-prettifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-prettifier.js","sourceRoot":"","sources":["../../../../../src/modules/base/utils/error-prettifier.ts"],"names":[],"mappings":"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","sourcesContent":["import { ValidationError } from \"class-validator\";\nimport { ZodError, ZodIssue } from \"zod\";\nimport { pascalCase } from \"../../../utils/helpers/change-case.helpers\";\n\n/**\n * Prettified error result with consistent format\n */\nexport interface PrettifiedError {\n /** Human-readable error message */\n message: string;\n /** Field name + constraint type code (e.g., 'NameIsStringConstraint') */\n code: string;\n}\n\n/**\n * Supported validation library types\n */\nexport type ValidationLibrary = \"class-validator\" | \"zod\";\n\n/**\n * ErrorPrettifier class for normalizing validation errors from class-validator and Zod\n * into a consistent format with field name + constraint code pattern.\n *\n * @example\n * ```typescript\n * const prettifier = new ErrorPrettifier();\n *\n * // Class-validator example\n * const classValidatorErrors = await validate(userDto);\n * const prettified = prettifier.prettify('class-validator', classValidatorErrors);\n * // [{ message: 'name must be a string', code: 'NameIsStringConstraint' }]\n *\n * // Zod example\n * try {\n * schema.parse(data);\n * } catch (error) {\n * const prettified = prettifier.prettify('zod', error);\n * // [{ message: 'name must be a string', code: 'NameIsStringConstraint' }]\n * }\n *\n * // Nested errors\n * // [{ message: 'user.address.street must be a string', code: 'UserAddressStreetIsStringConstraint' }]\n * ```\n */\nexport class ErrorPrettifier {\n /**\n * Prettifies validation errors from class-validator or Zod into a consistent format.\n *\n * @param library - The validation library type ('class-validator' or 'zod')\n * @param error - The validation error(s) from the library\n * @returns Array of prettified errors with consistent message and code format\n */\n prettify(\n library: \"class-validator\",\n error: ValidationError[]\n ): PrettifiedError[];\n prettify(library: \"zod\", error: ZodError): PrettifiedError[];\n prettify(\n library: ValidationLibrary,\n error: ValidationError[] | ZodError\n ): PrettifiedError[] {\n if (library === \"class-validator\") {\n return this.prettifyClassValidator(error as ValidationError[]);\n } else {\n return this.prettifyZod(error as ZodError);\n }\n }\n\n /**\n * Converts a field path to PascalCase for code generation.\n *\n * @example\n * ```typescript\n * toPascalCase('user.address.street') // 'UserAddressStreet'\n * toPascalCase('email') // 'Email'\n * ```\n *\n * @param path - Dot-separated field path\n * @returns PascalCase version of the path\n */\n private toPascalCase(path: string): string {\n return path\n .split(\".\")\n .map((part) => pascalCase(part))\n .join(\"\");\n }\n\n /**\n * Replaces the field name in the validation message with the full path.\n * Handles array indices like tags[0] and nested paths like user.address.street.\n *\n * @example\n * ```typescript\n * replaceFieldInMessage('id must be a UUID', 'id', 'user.id')\n * // Returns: ''user.id' must be a UUID'\n *\n * replaceFieldInMessage('name must be a string', 'name', 'tags[0].name')\n * // Returns: ''tags[0].name' must be a string'\n * ```\n *\n * @param message - Original validation message\n * @param fieldName - Original field name\n * @param fullPath - Full path including parent properties\n * @returns Message with field name replaced by full path\n */\n private replaceFieldInMessage(\n message: string,\n fieldName: string,\n fullPath: string\n ): string {\n // If it's a top-level field (no dots or brackets), return original message\n if (!fullPath.includes(\".\") && !fullPath.includes(\"[\")) {\n return message;\n }\n\n // Replace the field name at the start of the message with the full path\n // Handle cases like \"id must be a UUID\" -> \"'user.id' must be a UUID\"\n const regex = new RegExp(`^${fieldName}\\\\b`, \"i\");\n if (regex.test(message)) {\n return message.replace(regex, `'${fullPath}'`);\n }\n\n // If field name is not at the start, try to find it and replace\n // This handles cases like \"must be a valid id\" or other formats\n const wordBoundaryRegex = new RegExp(`\\\\b${fieldName}\\\\b`, \"gi\");\n if (wordBoundaryRegex.test(message)) {\n return message.replace(wordBoundaryRegex, `'${fullPath}'`);\n }\n\n // If we can't find the field name in the message, prepend the path\n return `'${fullPath}' ${message}`;\n }\n\n /**\n * Prettifies class-validator ValidationError array.\n * Handles nested validation errors recursively.\n *\n * @param errors - Array of ValidationError from class-validator\n * @param parentPath - Parent path for nested errors (used internally)\n * @returns Array of prettified errors\n */\n private prettifyClassValidator(\n errors: ValidationError[],\n parentPath: string = \"\"\n ): PrettifiedError[] {\n const result: PrettifiedError[] = [];\n\n for (const error of errors) {\n const currentPath = parentPath\n ? `${parentPath}.${error.property}`\n : error.property;\n\n if (error.children && error.children.length > 0) {\n result.push(\n ...this.prettifyClassValidator(error.children, currentPath)\n );\n continue;\n }\n\n if (error.constraints) {\n const fieldPascal = this.toPascalCase(currentPath);\n\n for (const [constraintKey, originalMessage] of Object.entries(\n error.constraints\n )) {\n const constraintName =\n constraintKey.charAt(0).toUpperCase() + constraintKey.slice(1);\n\n const message = this.replaceFieldInMessage(\n originalMessage,\n error.property,\n currentPath\n );\n\n result.push({\n message: message,\n code: `${fieldPascal}${constraintName}Constraint`,\n });\n }\n }\n }\n\n return result;\n }\n\n /**\n * Maps Zod error codes and validation info to class-validator style constraint names.\n *\n * @param issue - Zod validation issue\n * @returns Class-validator style constraint name\n */\n private mapZodToConstraintName(issue: ZodIssue): string {\n switch (issue.code) {\n case \"invalid_type\":\n const expected = issue.expected;\n switch (expected) {\n case \"string\":\n return \"IsStringConstraint\";\n case \"number\":\n return \"IsNumberConstraint\";\n case \"boolean\":\n return \"IsBooleanConstraint\";\n case \"array\":\n return \"IsArrayConstraint\";\n case \"object\":\n return \"IsObjectConstraint\";\n case \"date\":\n return \"IsDateConstraint\";\n default:\n return \"InvalidTypeConstraint\";\n }\n\n case \"too_small\":\n if (issue.type === \"string\") {\n return \"MinLengthConstraint\";\n } else if (issue.type === \"number\") {\n return \"MinConstraint\";\n } else if (issue.type === \"array\") {\n return \"ArrayMinSizeConstraint\";\n }\n return \"TooSmallConstraint\";\n\n case \"too_big\":\n if (issue.type === \"string\") {\n return \"MaxLengthConstraint\";\n } else if (issue.type === \"number\") {\n return \"MaxConstraint\";\n } else if (issue.type === \"array\") {\n return \"ArrayMaxSizeConstraint\";\n }\n return \"TooBigConstraint\";\n\n case \"invalid_string\":\n if (\"validation\" in issue) {\n const validation = issue.validation;\n if (validation === \"email\") return \"IsEmailConstraint\";\n if (validation === \"uuid\") return \"IsUuidConstraint\";\n if (validation === \"url\") return \"IsUrlConstraint\";\n if (typeof validation === \"object\" && \"includes\" in validation)\n return \"ContainsConstraint\";\n if (typeof validation === \"object\" && \"startsWith\" in validation)\n return \"StartsWithConstraint\";\n if (typeof validation === \"object\" && \"endsWith\" in validation)\n return \"EndsWithConstraint\";\n }\n return \"InvalidStringConstraint\";\n\n case \"invalid_enum_value\":\n return \"IsEnumConstraint\";\n\n case \"invalid_literal\":\n return \"EqualsConstraint\";\n\n case \"unrecognized_keys\":\n return \"UnrecognizedKeysConstraint\";\n\n case \"invalid_union\":\n return \"InvalidUnionConstraint\";\n\n case \"invalid_date\":\n return \"IsDateConstraint\";\n\n case \"custom\":\n return \"CustomConstraint\";\n\n default:\n return \"ValidationConstraint\";\n }\n }\n\n /**\n * Prettifies Zod ZodError.\n * Handles nested paths and multiple issues per field.\n *\n * @param error - ZodError from Zod validation\n * @returns Array of prettified errors\n */\n private prettifyZod(error: ZodError): PrettifiedError[] {\n const result: PrettifiedError[] = [];\n\n for (const issue of error.issues) {\n // Build the field path from the issue path\n const fieldPath = issue.path\n .map((segment, index) => {\n // Handle array indices: convert to bracket notation\n if (typeof segment === \"number\") {\n return `[${segment}]`;\n }\n // First segment doesn't need a dot prefix\n return index === 0 ? segment : `.${segment}`;\n })\n .join(\"\")\n .replace(/\\.\\[/g, \"[\"); // Clean up .[ to just [\n\n const fieldPascal = fieldPath\n ? this.toPascalCase(fieldPath.replace(/\\[\\d+\\]/g, \"\"))\n : \"\";\n\n // Map Zod error code to constraint name\n const constraintName = this.mapZodToConstraintName(issue);\n\n // Inject the field path into the message naturally\n const message = this.injectFieldPathInZodMessage(\n issue.message,\n fieldPath,\n issue\n );\n\n result.push({\n message: message,\n code: `${fieldPascal}${constraintName}`,\n });\n }\n\n return result;\n }\n\n /**\n * Injects the field path into Zod error messages naturally.\n *\n * @example\n * ```typescript\n * injectFieldPathInZodMessage('String must contain at least 100 character(s)', 'user.id', issue)\n * // Returns: ''user.id' must contain at least 100 character(s)'\n *\n * injectFieldPathInZodMessage('Required', 'email', issue)\n * // Returns: ''email' is required'\n * ```\n *\n * @param message - Original Zod error message\n * @param fieldPath - Full field path (e.g., 'user.id', 'tags[0].name')\n * @param issue - Zod issue for context\n * @returns Message with field path injected naturally\n */\n private injectFieldPathInZodMessage(\n message: string,\n fieldPath: string,\n issue: ZodIssue\n ): string {\n if (!fieldPath) {\n return message;\n }\n\n // \"Required\" -> \"'fieldPath' is required\"\n if (message === \"Required\") {\n return `'${fieldPath}' is required`;\n }\n\n // \"String must...\" -> \"'fieldPath' must...\"\n if (message.startsWith(\"String must\")) {\n return message.replace(/^String must/, `'${fieldPath}' must`);\n }\n\n // \"Number must...\" -> \"'fieldPath' must...\"\n if (message.startsWith(\"Number must\")) {\n return message.replace(/^Number must/, `'${fieldPath}' must`);\n }\n\n // \"Array must...\" -> \"'fieldPath' must...\"\n if (message.startsWith(\"Array must\")) {\n return message.replace(/^Array must/, `'${fieldPath}' must`);\n }\n\n // \"Expected string, received number\" -> \"'fieldPath': Expected string, received number\"\n if (message.startsWith(\"Expected\")) {\n return `'${fieldPath}' must be valid: ${message}`;\n }\n\n // \"Invalid email\" -> \"'fieldPath' must be a valid email\"\n if (message.startsWith(\"Invalid \")) {\n const type = message.replace(\"Invalid \", \"\");\n return `'${fieldPath}' must be a valid ${type}`;\n }\n\n // For any other message, return the message\n if (!message.toLowerCase().includes(fieldPath))\n return `'${fieldPath}' ${message}`;\n return message;\n }\n}\n\nconst errorPrettifier = new ErrorPrettifier();\n\nexport default errorPrettifier;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arkos-prisma-input.bak.js","sourceRoot":"","sources":["../../../src/types/arkos-prisma-input.bak.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Helper type to exclude properties from T that exist in U\n * Used internally by XOR to create mutually exclusive types\n */\ntype Without<T, U> = {\n [P in Exclude<keyof T, keyof U>]?: never;\n};\n/**\n * XOR (Exclusive OR) type for mutually exclusive union types\n * Ensures that properties from T and U cannot be mixed together\n * @see https://stackoverflow.com/questions/42123407/does-typescript-support-mutually-exclusive-types\n */\ntype XOR<T, U> = T extends object\n ? U extends object\n ? (Without<T, U> & U) | (Without<U, T> & T)\n : U\n : T;\n/**\n * Extract type from Prisma's Enumerable wrapper\n * Currently acts as identity but can be extended to handle array unwrapping\n */\n// type Unpack<T> = T extends Array<infer U> ? U : T extends (infer U)[] ? U : T;\ntype Unpack<T> = T;\n/**\n * Checks if a field is a Prisma relation field\n * A field is considered a relation if it has any of: create, connect, connectOrCreate, update, delete, disconnect\n * Handles optional fields by excluding undefined before checking\n * @template T - The type to check\n * @returns true if T is a relation field, false otherwise\n */\nexport type IsRelationField<T> =\n Exclude<T, undefined> extends\n | {\n create?: { id?: any } | { id?: any }[];\n }\n | {\n connect?: { id?: any } | { id?: any }[];\n }\n | {\n update?: { where?: { id?: any }; data?: any };\n }\n | {\n delete?: { where?: { id?: any } };\n }\n | {\n disconnect?: { where?: { id?: any } };\n }\n ? true\n : false;\n\n/**\n * Checks if a Prisma relation field is an array/many relation\n * Detects relations that support multiple records (one-to-many or many-to-many)\n * @template T - The relation field type\n * @returns true if it's an array relation, false otherwise\n */\nexport type IsArrayRelation<T> =\n Exclude<T, undefined> extends { createMany?: any }\n ? true\n : Exclude<T, undefined> extends { deleteMany?: any }\n ? true\n : false;\n\n/**\n * Extracts the create data type from a Prisma relation field\n * @template T - The relation field type\n * @returns The type used in the create operation, or never if not present\n */\nexport type ExtractCreateType<T> =\n Exclude<T, undefined> extends { create?: infer C }\n ? C extends Array<infer U>\n ? (U & {\n apiAction?: \"create\";\n })[]\n : C & {\n apiAction?: \"create\";\n }\n : never;\n\ntype ExtractConnectType<\n T,\n action extends \"connect\" | \"delete\" | \"udpate\" | \"disconnect\" | \"deleteMany\",\n> =\n Exclude<T, undefined> extends { [k in action]?: infer C }\n ? C extends Array<infer U>\n ? (U & {\n apiAction?: action;\n })[]\n : C & {\n apiAction?: action;\n }\n : never;\n/**\n * Extracts and merges the update data type from a Prisma relation field\n * Combines the 'where' clause and 'data' fields into a single type\n * @template T - The relation field type\n * @returns Merged type of where & data fields, or never if not present\n */\ntype ExtractUpdateType<T> = T extends {\n update?: infer U;\n}\n ? U extends Array<infer Item>\n ? Item extends {\n where: infer W;\n data: infer D;\n }\n ? ((W & D) & { apiAction?: \"update\" })[]\n : never\n : U extends {\n where: infer W;\n data: infer D;\n }\n ? (W & D) & { apiAction?: \"update\" }\n : never\n : never;\n\n/**\n * Creates a flattened union type for a single relation field\n * Combines all possible Prisma operations (create, connect, update, delete, etc.) into a discriminated union\n * Each variant includes an optional apiAction field for explicit operation specification\n * @template T - The Prisma relation field type\n */\ntype FlattenRelationField<T> =\n /**\n * Create Operation - Creates a new related entity\n * Extracts the 'create' data type and recursively flattens nested relations\n * @example { name: \"New Item\", apiAction?: \"create\" }\n */\n | (ExtractCreateType<T> extends never\n ? never\n : FlattenRelations<ExtractCreateType<T>>)\n /**\n * Connect Operation - Links to an existing entity using unique fields\n * Extracts the 'connect' data type (typically unique identifiers like id, email, etc.)\n * @example { id: 123, apiAction?: \"connect\" } or { email: \"user@example.com\", apiAction?: \"connect\" }\n */\n | (ExtractConnectType<T, \"connect\"> extends never\n ? never\n : FlattenRelations<ExtractConnectType<T, \"connect\">>)\n /**\n * Update Operation - Modifies an existing related entity\n * Combines the 'where' clause and 'data' fields into a single flat object\n * @example { id: 123, name: \"Updated Name\", apiAction?: \"update\" }\n */\n | (ExtractUpdateType<T> extends never\n ? never\n : FlattenRelations<ExtractUpdateType<T>> & {\n apiAction?: \"update\";\n })\n /**\n * Delete Operation - Removes a related entity from the database\n * Requires unique identifier(s) and explicit apiAction: \"delete\"\n * For arrays, automatically uses deleteMany; for singular relations uses delete\n * @example { id: 123, apiAction: \"delete\" }\n */\n | (T extends {\n delete?: any;\n }\n ? {\n apiAction: \"delete\";\n } & ExtractConnectType<T, \"delete\">\n : never)\n /**\n * Disconnect Operation - Breaks the relationship without deleting the entity\n * Requires unique identifier(s) and explicit apiAction: \"disconnect\"\n * Only available for optional relations\n * @example { id: 123, apiAction: \"disconnect\" }\n */\n | (T extends {\n disconnect?: any;\n }\n ? {\n apiAction: \"disconnect\";\n } & ExtractConnectType<T, \"disconnect\">\n : never)\n /**\n * Set Operation - Replaces all related entities with a new set\n * Typically used for many-to-many relations to completely replace the relation set\n * @example { id: 456, apiAction?: \"set\" }\n */\n | (T extends {\n set?: infer S;\n }\n ? Unpack<S> & {\n apiAction?: \"set\";\n }\n : never)\n /**\n * Delete Many Operation - Removes multiple related entities matching criteria\n * Requires unique identifier(s) and explicit apiAction: \"deleteMany\"\n * Used for bulk deletion of related records\n * @example { id: 123, apiAction: \"deleteMany\" }\n */\n | (T extends {\n deleteMany?: any;\n }\n ? {\n apiAction: \"deleteMany\";\n } & ExtractConnectType<T, \"deleteMany\">\n : never);\n\n/**\n * Ensures array relations only accept arrays, not single objects\n * For array relations (one-to-many, many-to-many), forces array type\n * For singular relations (one-to-one, many-to-one), keeps XOR behavior\n * @template T - The original Prisma field type\n * @template Flattened - The flattened relation field type\n */\ntype EnforceArrayRelation<T, Flattened> =\n IsArrayRelation<T> extends true\n ? // Array relation: Extract only array types from the union\n Flattened extends Array<any>\n ? Flattened\n : never\n : // Singular relation: Keep XOR behavior (can be object OR array)\n Exclude<XOR<Flattened, T>, \"AND\">;\n\ntype FlattenRelations<T> = {\n [K in keyof T]: IsRelationField<T[K]> extends true\n ? EnforceArrayRelation<T[K], FlattenRelationField<T[K]>>\n : T[K] extends object\n ? T[K] extends Date | null | undefined\n ? T[K]\n : FlattenRelations<T[K]>\n : T[K];\n};\n/**\n * Flattens Prisma relation inputs into a simpler, developer-friendly format\n *\n * Transforms Prisma's nested relation format:\n * ```typescript\n * { posts: { create: [...], connect: [...], update: [...] } }\n * ```\n *\n * Into a flattened format with optional apiAction discriminators:\n * ```typescript\n * { posts: [\n * { title: \"New Post\" }, // auto-detected as create\n * { id: 1 }, // auto-detected as connect\n * { id: 2, title: \"Updated\", apiAction: \"update\" }\n * ]}\n * ```\n *\n * Features:\n * - Preserves non-relation fields as-is\n * - Automatically detects operation type based on field presence\n * - Supports explicit apiAction for disambiguation\n * - Works recursively for deeply nested relations\n * - Enforces array-only types for array relations (one-to-many, many-to-many)\n * - Enforces mutual exclusivity between flattened and Prisma formats for singular relations\n *\n * @see {@link https://wwww.arkosjs.com/docs/api-reference/arkos-prisma-input}\n * @template T - The Prisma input type (e.g., Prisma.UserCreateInput)\n * @returns A flattened version of the input type with simplified relation handling\n *\n * @example\n * ```typescript\n * import { Prisma } from \"@prisma/client\";\n *\n * type FlatUserInput = ArkosPrismaInput<Prisma.UserCreateInput>;\n *\n * const user: FlatUserInput = {\n * name: \"John\",\n * email: \"john@example.com\",\n * posts: [\n * { title: \"My First Post\" }, // creates new post\n * { id: 1 }, // connects to existing post\n * { id: 2, title: \"Updated\" }, // updates existing post\n * { id: 3, apiAction: \"delete\" } // deletes post\n * ],\n * profile: { bio: \"Software developer\" } // singular relation (can be object or array)\n * };\n * ```\n */\nexport type ArkosPrismaInput<T> = FlattenRelations<T>;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arkos-prisma-input.js","sourceRoot":"","sources":["../../../src/types/arkos-prisma-input.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Helper type to exclude properties from T that exist in U\n * Used internally by XOR to create mutually exclusive types\n */\ntype Without<T, U> = {\n [P in Exclude<keyof T, keyof U>]?: never;\n};\n/**\n * XOR (Exclusive OR) type for mutually exclusive union types\n * Ensures that properties from T and U cannot be mixed together\n * @see https://stackoverflow.com/questions/42123407/does-typescript-support-mutually-exclusive-types\n */\ntype XOR<T, U> = T extends object\n ? U extends object\n ? (Without<T, U> & U) | (Without<U, T> & T)\n : U\n : T;\ntype Unpack<T> = T;\n/**\n * Checks if a field is an array relation (one-to-many or many-to-many)\n * Identified by the presence of createMany property\n */\nexport type IsArrayRelation<T> =\n Exclude<T, undefined> extends never\n ? false\n : Exclude<T, undefined> extends { createMany?: any }\n ? true\n : false;\n/**\n * Checks if a field is an object relation (one-to-one or many-to-one)\n * Identified by the presence of relation operations without being an array\n */\nexport type IsObjectRelation<T> =\n Exclude<T, undefined> extends Array<any>\n ? false\n : Exclude<T, undefined> extends\n | {\n create?: any;\n }\n | {\n connect?: any;\n }\n | {\n connectOrCreate?: any;\n }\n | {\n update?: any;\n }\n | {\n delete?: any;\n }\n | {\n disconnect?: any;\n }\n ? true\n : false;\ntype ExtractCreateTypeArray<T> =\n Exclude<T, undefined> extends {\n create?: infer C;\n }\n ? Extract<C, Array<any>> extends Array<infer U>\n ? U extends Array<infer I>\n ? (Omit<I, \"OR\" | \"AND\" | \"NOT\"> & {\n apiAction?: \"create\";\n })[]\n : (Omit<U, \"OR\" | \"AND\" | \"NOT\"> & {\n apiAction?: \"create\";\n })[]\n : never\n : never;\ntype ExtractConnectTypeArray<\n T,\n A extends\n | \"connect\"\n | \"delete\"\n | \"update\"\n | \"disconnect\"\n | \"deleteMany\"\n | \"set\",\n> =\n Exclude<T, undefined> extends {\n [k in A]?: infer C;\n }\n ? Extract<C, Array<any>> extends Array<infer U>\n ? (Omit<U, \"OR\" | \"AND\" | \"NOT\"> & {\n apiAction?: A;\n })[]\n : never\n : never;\ntype ExtractUpdateTypeArray<T> =\n Exclude<T, undefined> extends Array<infer Item>\n ? Item extends {\n update?: infer U;\n }\n ? U extends Array<infer UpdateItem>\n ? UpdateItem extends {\n where: infer W;\n data: infer D;\n }\n ? ((W & D) & {\n apiAction?: \"update\";\n })[]\n : never\n : U extends {\n where: infer W;\n data: infer D;\n }\n ? ((W & D) & {\n apiAction?: \"update\";\n })[]\n : never\n : never\n : never;\ntype ExtractCreateTypeObject<T> =\n Exclude<T, undefined> extends {\n create?: infer C;\n }\n ? Exclude<\n Extract<Exclude<C, undefined>, object>,\n Array<any>\n > extends infer Obj\n ? Obj extends object\n ? Omit<Obj, \"OR\" | \"AND\" | \"NOT\"> & {\n apiAction?: \"create\";\n }\n : never\n : never\n : never;\ntype ExtractConnectTypeObject<\n T,\n A extends \"connect\" | \"delete\" | \"update\" | \"disconnect\",\n> =\n Exclude<T, undefined> extends {\n [k in A]?: infer C;\n }\n ? Exclude<\n Extract<Exclude<C, undefined>, object>,\n Array<any>\n > extends infer Obj\n ? Obj extends object\n ? Omit<Obj, \"OR\" | \"AND\" | \"NOT\"> & {\n apiAction?: A;\n }\n : never\n : never\n : never;\ntype ExtractUpdateTypeObject<T> =\n Exclude<T, undefined> extends {\n update?: infer U;\n }\n ? U extends {\n where: infer W;\n data: infer D;\n }\n ? (W & D) & {\n apiAction?: \"update\";\n }\n : Exclude<Extract<U, object>, Array<any>> & {\n apiAction?: \"update\";\n }\n : never;\ntype FlattenArrayRelation<T> =\n | (ExtractCreateTypeArray<T> extends never\n ? never\n : FlattenRelations<ExtractCreateTypeArray<T>>)\n | (ExtractConnectTypeArray<T, \"connect\"> extends never\n ? never\n : FlattenRelations<ExtractConnectTypeArray<T, \"connect\">>)\n | (ExtractUpdateTypeArray<T> extends never\n ? never\n : FlattenRelations<ExtractUpdateTypeArray<T>>)\n | (Exclude<T, undefined> extends Array<infer Item>\n ? Item extends {\n delete?: any;\n }\n ? FlattenRelations<ExtractConnectTypeArray<T, \"delete\">> & {\n apiAction: \"delete\";\n }\n : never\n : never)\n | (Exclude<T, undefined> extends Array<infer Item>\n ? Item extends {\n disconnect?: any;\n }\n ? FlattenRelations<ExtractConnectTypeArray<T, \"disconnect\">> & {\n apiAction: \"disconnect\";\n }\n : never\n : never)\n | (Exclude<T, undefined> extends Array<infer Item>\n ? Item extends {\n set?: infer S;\n }\n ? Unpack<S> & {\n apiAction?: \"set\";\n }\n : never\n : never)\n | (Exclude<T, undefined> extends Array<infer Item>\n ? Item extends {\n deleteMany?: any;\n }\n ? FlattenRelations<ExtractConnectTypeArray<T, \"deleteMany\">> & {\n apiAction: \"deleteMany\";\n }\n : never\n : never);\ntype FlattenObjectRelation<T> =\n | (ExtractCreateTypeObject<T> extends never\n ? never\n : FlattenRelations<ExtractCreateTypeObject<T>>)\n | (ExtractConnectTypeObject<T, \"connect\"> extends never\n ? never\n : FlattenRelations<ExtractConnectTypeObject<T, \"connect\">>)\n | (ExtractUpdateTypeObject<T> extends never\n ? never\n : FlattenRelations<ExtractUpdateTypeObject<T>>)\n | (Exclude<T, undefined> extends {\n delete?: any;\n }\n ? FlattenRelations<ExtractConnectTypeObject<T, \"delete\">> & {\n apiAction: \"delete\";\n }\n : never)\n | (Exclude<T, undefined> extends {\n disconnect?: any;\n }\n ? FlattenRelations<ExtractConnectTypeObject<T, \"disconnect\">> & {\n apiAction: \"disconnect\";\n }\n : never)\n | (Exclude<T, undefined> extends {\n set?: infer S;\n }\n ? Unpack<S> & {\n apiAction?: \"set\";\n }\n : never);\ntype StripPrismaFilters<T> = T extends\n | {\n equals?: any;\n }\n | {\n in?: any;\n }\n | {\n notIn?: any;\n }\n | {\n lt?: any;\n }\n | {\n lte?: any;\n }\n | {\n gt?: any;\n }\n | {\n gte?: any;\n }\n | {\n AND?: any;\n }\n | {\n OR?: any;\n }\n | {\n NOT?: any;\n }\n ? never\n : T;\ntype FlattenRelations<T> = {\n [K in keyof T]: IsArrayRelation<T[K]> extends true\n ? FlattenArrayRelation<T[K]>\n : IsObjectRelation<T[K]> extends true\n ? XOR<FlattenObjectRelation<T[K]>, T[K]>\n : StripPrismaFilters<T[K]> extends never\n ? never\n : T[K] extends object\n ? T[K] extends Date | null | undefined\n ? T[K]\n : FlattenRelations<StripPrismaFilters<T[K]>>\n : StripPrismaFilters<T[K]>;\n};\n/**\n * Flattens Prisma relation inputs into a simpler, developer-friendly format\n *\n * Transforms Prisma's nested relation format:\n * ```typescript\n * { posts: { create: [...], connect: [...], update: [...] } }\n * ```\n *\n * Into a flattened format with optional apiAction discriminators:\n * ```typescript\n * { posts: [\n * { title: \"New Post\" }, // auto-detected as create\n * { id: 1 }, // auto-detected as connect\n * { id: 2, title: \"Updated\", apiAction: \"update\" }\n * ]}\n * ```\n *\n * @see {@link https://wwww.arkosjs.com/docs/api-reference/arkos-prisma-input}\n * @template T - The Prisma input type (e.g., Prisma.UserCreateInput)\n * @returns A flattened version of the input type with simplified relation handling\n */\nexport type ArkosPrismaInput<T> = FlattenRelations<T>;\n"]}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const deepmerge_helper_1 = __importDefault(require("../helpers/deepmerge.helper"));
|
|
7
|
+
class ArkosRouterOpenAPIManager {
|
|
8
|
+
addUploadFields(uploadConfig, existingSchema = {}) {
|
|
9
|
+
const uploadSchema = {
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {},
|
|
12
|
+
required: [],
|
|
13
|
+
};
|
|
14
|
+
if (uploadConfig.type === "single") {
|
|
15
|
+
uploadSchema.properties[uploadConfig.field] = {
|
|
16
|
+
type: "string",
|
|
17
|
+
format: "binary",
|
|
18
|
+
...(uploadConfig.maxSize && {
|
|
19
|
+
description: `Max size: ${uploadConfig.maxSize} bytes`,
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
if (uploadConfig.required) {
|
|
23
|
+
uploadSchema.required.push(uploadConfig.field);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else if (uploadConfig.type === "array") {
|
|
27
|
+
uploadSchema.properties[uploadConfig.field] = {
|
|
28
|
+
type: "array",
|
|
29
|
+
items: {
|
|
30
|
+
type: "string",
|
|
31
|
+
format: "binary",
|
|
32
|
+
},
|
|
33
|
+
...(uploadConfig.maxCount && { maxItems: uploadConfig.maxCount }),
|
|
34
|
+
...(uploadConfig.maxSize && {
|
|
35
|
+
description: `Max size per file: ${uploadConfig.maxSize} bytes`,
|
|
36
|
+
}),
|
|
37
|
+
};
|
|
38
|
+
if (uploadConfig.required) {
|
|
39
|
+
uploadSchema.required.push(uploadConfig.field);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (uploadConfig.type === "fields") {
|
|
43
|
+
for (const field of uploadConfig.fields) {
|
|
44
|
+
uploadSchema.properties[field.name] = {
|
|
45
|
+
type: "array",
|
|
46
|
+
items: {
|
|
47
|
+
type: "string",
|
|
48
|
+
format: "binary",
|
|
49
|
+
},
|
|
50
|
+
...(field.maxCount && { maxItems: field.maxCount }),
|
|
51
|
+
...(uploadConfig.maxSize && {
|
|
52
|
+
description: `Max size per file: ${uploadConfig.maxSize} bytes`,
|
|
53
|
+
}),
|
|
54
|
+
};
|
|
55
|
+
if (uploadConfig.required) {
|
|
56
|
+
uploadSchema.required.push(field.name);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (uploadSchema.required.length === 0)
|
|
61
|
+
delete uploadSchema.required;
|
|
62
|
+
return (0, deepmerge_helper_1.default)(existingSchema, uploadSchema);
|
|
63
|
+
}
|
|
64
|
+
validateMultipartFormDocs(userDefinedMultipartSchema, routePath, uploadConfig) {
|
|
65
|
+
const errors = [];
|
|
66
|
+
const properties = userDefinedMultipartSchema?.properties || {};
|
|
67
|
+
const requiredFields = userDefinedMultipartSchema?.required || [];
|
|
68
|
+
const expectedFields = [];
|
|
69
|
+
if (uploadConfig?.type === "single") {
|
|
70
|
+
expectedFields.push({
|
|
71
|
+
name: uploadConfig.field,
|
|
72
|
+
required: uploadConfig.required || false,
|
|
73
|
+
expectedType: "single",
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else if (uploadConfig?.type === "array") {
|
|
77
|
+
expectedFields.push({
|
|
78
|
+
name: uploadConfig.field,
|
|
79
|
+
required: uploadConfig.required || false,
|
|
80
|
+
expectedType: "array",
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else if (uploadConfig?.type === "fields") {
|
|
84
|
+
for (const field of uploadConfig.fields) {
|
|
85
|
+
expectedFields.push({
|
|
86
|
+
name: field.name,
|
|
87
|
+
required: uploadConfig.required || false,
|
|
88
|
+
expectedType: "array",
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
for (const { name, required, expectedType } of expectedFields) {
|
|
93
|
+
const fieldSchema = properties[name];
|
|
94
|
+
if (!fieldSchema) {
|
|
95
|
+
errors.push(`Missing upload field '${name}' in multipart/form-data schema`);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (expectedType === "single") {
|
|
99
|
+
if (fieldSchema.type !== "string")
|
|
100
|
+
errors.push(`Upload field '${name}' must have type 'string', got '${fieldSchema.type}'`);
|
|
101
|
+
if (fieldSchema.format !== "binary")
|
|
102
|
+
errors.push(`Upload field '${name}' must have format 'binary', got '${fieldSchema.format || "undefined"}'`);
|
|
103
|
+
}
|
|
104
|
+
else if (expectedType === "array") {
|
|
105
|
+
if (fieldSchema.type !== "array") {
|
|
106
|
+
errors.push(`Upload field '${name}' must have type 'array', got '${fieldSchema.type}'`);
|
|
107
|
+
}
|
|
108
|
+
else if (!fieldSchema.items ||
|
|
109
|
+
fieldSchema.items.type !== "string" ||
|
|
110
|
+
fieldSchema.items.format !== "binary")
|
|
111
|
+
errors.push(`Upload field '${name}' must have items with type 'string' and format 'binary'`);
|
|
112
|
+
}
|
|
113
|
+
const isMarkedRequired = requiredFields.includes(name);
|
|
114
|
+
if (required && !isMarkedRequired)
|
|
115
|
+
errors.push(`Upload field '${name}' is required in config but not marked as required in schema`);
|
|
116
|
+
if (!required && isMarkedRequired)
|
|
117
|
+
errors.push(`Upload field '${name}' is not required in config but marked as required in schema`);
|
|
118
|
+
}
|
|
119
|
+
if (errors.length > 0) {
|
|
120
|
+
throw new Error(`ValidationError: Invalid multipart/form-data schema for route '${routePath}':\n${errors.map((e) => ` - ${e}`).join("\n")}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const arkosRouterOpenApiManager = new ArkosRouterOpenAPIManager();
|
|
125
|
+
exports.default = arkosRouterOpenApiManager;
|
|
126
|
+
//# sourceMappingURL=arkos-router-openapi-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arkos-router-openapi-manager.js","sourceRoot":"","sources":["../../../../src/utils/arkos-router/arkos-router-openapi-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { OpenAPIV3 } from \"openapi-types\";\nimport deepmerge from \"../helpers/deepmerge.helper\";\nimport { UploadConfig } from \"./types/upload-config\";\n\nclass ArkosRouterOpenAPIManager {\n /**\n * Generates OpenAPI schema for file upload fields in multipart/form-data requests.\n * Converts upload configuration into OpenAPI-compliant schema and merges with existing body schema.\n *\n * @param {UploadConfig} uploadConfig - The upload configuration from config.experimental.uploads\n * @param {any} existingSchema - Existing JSON schema from config.validation.body (optional)\n * @returns {{ schema: any }} OpenAPI schema object for multipart/form-data content type\n *\n * @example\n * // Single file upload\n * addUploadFields({ type: 'single', field: 'avatar', maxSize: 5242880 })\n * // Returns: { schema: { type: 'object', properties: { avatar: { type: 'string', format: 'binary' } } } }\n *\n * @example\n * // Array file upload\n * addUploadFields({ type: 'array', field: 'gallery', maxCount: 10 })\n *\n * @example\n * // Multiple fields upload\n * addUploadFields({ type: 'fields', fields: [{ name: 'avatar', maxCount: 1 }, { name: 'resume', maxCount: 1 }] })\n */\n addUploadFields(\n uploadConfig: UploadConfig,\n existingSchema: OpenAPIV3.SchemaObject = {}\n ): OpenAPIV3.SchemaObject {\n const uploadSchema: any = {\n type: \"object\",\n properties: {},\n required: [],\n };\n\n if (uploadConfig.type === \"single\") {\n uploadSchema.properties[uploadConfig.field] = {\n type: \"string\",\n format: \"binary\",\n ...(uploadConfig.maxSize && {\n description: `Max size: ${uploadConfig.maxSize} bytes`,\n }),\n };\n if (uploadConfig.required) {\n uploadSchema.required.push(uploadConfig.field);\n }\n } else if (uploadConfig.type === \"array\") {\n uploadSchema.properties[uploadConfig.field] = {\n type: \"array\",\n items: {\n type: \"string\",\n format: \"binary\",\n },\n ...(uploadConfig.maxCount && { maxItems: uploadConfig.maxCount }),\n ...(uploadConfig.maxSize && {\n description: `Max size per file: ${uploadConfig.maxSize} bytes`,\n }),\n };\n if (uploadConfig.required) {\n uploadSchema.required.push(uploadConfig.field);\n }\n } else if (uploadConfig.type === \"fields\") {\n for (const field of uploadConfig.fields) {\n uploadSchema.properties[field.name] = {\n type: \"array\",\n items: {\n type: \"string\",\n format: \"binary\",\n },\n ...(field.maxCount && { maxItems: field.maxCount }),\n ...(uploadConfig.maxSize && {\n description: `Max size per file: ${uploadConfig.maxSize} bytes`,\n }),\n };\n if (uploadConfig.required) {\n uploadSchema.required.push(field.name);\n }\n }\n }\n\n // Clean up empty required array\n if (uploadSchema.required.length === 0) delete uploadSchema.required;\n\n return deepmerge(existingSchema as any, uploadSchema);\n }\n\n /**\n * Validates that a user-defined multipart/form-data schema includes all required upload fields\n * with correct types, formats, and required flags.\n *\n * @param {any} userDefinedMultipartSchema - The schema object from openapi.requestBody.content['multipart/form-data'].schema\n * @param {UploadConfig} uploadConfig - The upload configuration from config.experimental.uploads\n * @param {string} routePath - The route path for error context\n * @throws {Error} If upload fields are missing or incorrectly defined\n *\n * @example\n * validateMultipartFormDocs(\n * { type: 'object', properties: { avatar: { type: 'string', format: 'binary' } } },\n * { type: 'single', field: 'avatar', required: true },\n * '/users/:id/avatar'\n * )\n */\n validateMultipartFormDocs(\n userDefinedMultipartSchema: any,\n routePath: string,\n uploadConfig?: UploadConfig\n ): void {\n const errors: string[] = [];\n const properties = userDefinedMultipartSchema?.properties || {};\n const requiredFields = userDefinedMultipartSchema?.required || [];\n\n const expectedFields: Array<{\n name: string;\n required: boolean;\n expectedType: \"single\" | \"array\";\n }> = [];\n\n if (uploadConfig?.type === \"single\") {\n expectedFields.push({\n name: uploadConfig.field,\n required: uploadConfig.required || false,\n expectedType: \"single\",\n });\n } else if (uploadConfig?.type === \"array\") {\n expectedFields.push({\n name: uploadConfig.field,\n required: uploadConfig.required || false,\n expectedType: \"array\",\n });\n } else if (uploadConfig?.type === \"fields\") {\n for (const field of uploadConfig.fields) {\n expectedFields.push({\n name: field.name,\n required: uploadConfig.required || false,\n expectedType: \"array\",\n });\n }\n }\n\n for (const { name, required, expectedType } of expectedFields) {\n const fieldSchema = properties[name];\n\n if (!fieldSchema) {\n errors.push(\n `Missing upload field '${name}' in multipart/form-data schema`\n );\n continue;\n }\n\n if (expectedType === \"single\") {\n if (fieldSchema.type !== \"string\")\n errors.push(\n `Upload field '${name}' must have type 'string', got '${fieldSchema.type}'`\n );\n\n if (fieldSchema.format !== \"binary\")\n errors.push(\n `Upload field '${name}' must have format 'binary', got '${fieldSchema.format || \"undefined\"}'`\n );\n } else if (expectedType === \"array\") {\n if (fieldSchema.type !== \"array\") {\n errors.push(\n `Upload field '${name}' must have type 'array', got '${fieldSchema.type}'`\n );\n } else if (\n !fieldSchema.items ||\n fieldSchema.items.type !== \"string\" ||\n fieldSchema.items.format !== \"binary\"\n )\n errors.push(\n `Upload field '${name}' must have items with type 'string' and format 'binary'`\n );\n }\n\n const isMarkedRequired = requiredFields.includes(name);\n if (required && !isMarkedRequired)\n errors.push(\n `Upload field '${name}' is required in config but not marked as required in schema`\n );\n\n if (!required && isMarkedRequired)\n errors.push(\n `Upload field '${name}' is not required in config but marked as required in schema`\n );\n }\n\n if (errors.length > 0) {\n throw new Error(\n `ValidationError: Invalid multipart/form-data schema for route '${routePath}':\\n${errors.map((e) => ` - ${e}`).join(\"\\n\")}`\n );\n }\n }\n}\n\nconst arkosRouterOpenApiManager = new ArkosRouterOpenAPIManager();\n\nexport default arkosRouterOpenApiManager;\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const remove_dir_1 = require("../remove-dir");
|
|
4
|
+
(async () => {
|
|
5
|
+
if ((0, remove_dir_1.isEntryPoint)()) {
|
|
6
|
+
const folderPath = (0, remove_dir_1.getFolderPathFromArgs)();
|
|
7
|
+
(0, remove_dir_1.removeDir)(folderPath);
|
|
8
|
+
}
|
|
9
|
+
})();
|
|
10
|
+
//# sourceMappingURL=remove-dir-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove-dir-cli.js","sourceRoot":"","sources":["../../../../src/utils/cli/remove-dir-cli.ts"],"names":[],"mappings":";;AAAA,8CAA+E;AAE/E,CAAC,KAAK,IAAI,EAAE;IACV,IAAI,IAAA,yBAAY,GAAE,EAAE,CAAC;QACnB,MAAM,UAAU,GAAG,IAAA,kCAAqB,GAAE,CAAC;QAC3C,IAAA,sBAAS,EAAC,UAAU,CAAC,CAAC;IACxB,CAAC;AACH,CAAC,CAAC,EAAE,CAAC","sourcesContent":["import { getFolderPathFromArgs, isEntryPoint, removeDir } from \"../remove-dir\";\n\n(async () => {\n if (isEntryPoint()) {\n const folderPath = getFolderPathFromArgs();\n removeDir(folderPath);\n }\n})();\n"]}
|