svelte-reflector 1.3.6 → 1.3.8
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.
|
@@ -67,6 +67,9 @@ export class ModuleClassBuilder {
|
|
|
67
67
|
]);
|
|
68
68
|
}
|
|
69
69
|
`;
|
|
70
|
+
if (bundle.length > 0) {
|
|
71
|
+
this.imports.addReflectorImport("bundleStrict");
|
|
72
|
+
}
|
|
70
73
|
return `
|
|
71
74
|
class ${outputName} {
|
|
72
75
|
${attributes.join(";")}
|
|
@@ -75,9 +78,9 @@ export class ModuleClassBuilder {
|
|
|
75
78
|
|
|
76
79
|
${bundle.length > 0 ? `
|
|
77
80
|
bundle() {
|
|
78
|
-
return {
|
|
81
|
+
return bundleStrict({
|
|
79
82
|
${bundle.join(",")}
|
|
80
|
-
}
|
|
83
|
+
})
|
|
81
84
|
}
|
|
82
85
|
` : ""}
|
|
83
86
|
}
|
|
@@ -92,12 +95,15 @@ export class ModuleClassBuilder {
|
|
|
92
95
|
bundle.push(prop.bundleBuild());
|
|
93
96
|
});
|
|
94
97
|
}
|
|
98
|
+
if (bundle.length > 0) {
|
|
99
|
+
this.imports.addReflectorImport("bundleStrict");
|
|
100
|
+
}
|
|
95
101
|
const bundleBuild = bundle.length > 0
|
|
96
102
|
? `
|
|
97
103
|
bundle() {
|
|
98
|
-
return {
|
|
104
|
+
return bundleStrict({
|
|
99
105
|
${bundle.join(",")}
|
|
100
|
-
}
|
|
106
|
+
})
|
|
101
107
|
}
|
|
102
108
|
`
|
|
103
109
|
: "";
|
|
@@ -18,7 +18,7 @@ export class ModuleSchemaFileBuilder {
|
|
|
18
18
|
}
|
|
19
19
|
const treatedSchemas = schemas.map((s) => `${s.interface};\n${s.schema};`);
|
|
20
20
|
const imports = [
|
|
21
|
-
`import { build, BuildedInput } from "${config.reflectorAlias}/reflector.svelte";`,
|
|
21
|
+
`import { build, BuildedInput, bundleStrict } from "${config.reflectorAlias}/reflector.svelte";`,
|
|
22
22
|
`import { validateInputs } from "${config.validatorsImport}";`,
|
|
23
23
|
];
|
|
24
24
|
if (enumDeps.size > 0) {
|
|
@@ -34,20 +34,20 @@ export class SchemaClassRenderer {
|
|
|
34
34
|
keys.push(prop.classBuild());
|
|
35
35
|
bundleParams.push(prop.bundleBuild());
|
|
36
36
|
});
|
|
37
|
-
const constructorCode = `constructor(params?: { data?: ${name}Interface | undefined, empty?: boolean }) {
|
|
38
|
-
${constructorThis.join(";\n")}
|
|
37
|
+
const constructorCode = `constructor(params?: { data?: ${name}Interface | undefined, empty?: boolean }) {
|
|
38
|
+
${constructorThis.join(";\n")}
|
|
39
39
|
}`;
|
|
40
|
-
const schema = `
|
|
41
|
-
export class ${name} {
|
|
42
|
-
${keys.join(";")}
|
|
43
|
-
|
|
44
|
-
${constructorCode}
|
|
45
|
-
|
|
46
|
-
${staticMethod}
|
|
47
|
-
|
|
48
|
-
bundle(){
|
|
49
|
-
return { ${bundleParams.join(",")} }
|
|
50
|
-
}
|
|
40
|
+
const schema = `
|
|
41
|
+
export class ${name} {
|
|
42
|
+
${keys.join(";")}
|
|
43
|
+
|
|
44
|
+
${constructorCode}
|
|
45
|
+
|
|
46
|
+
${staticMethod}
|
|
47
|
+
|
|
48
|
+
bundle(){
|
|
49
|
+
return bundleStrict({ ${bundleParams.join(",")} })
|
|
50
|
+
}
|
|
51
51
|
};`;
|
|
52
52
|
return { interface: reflectorInterface.builded, schema };
|
|
53
53
|
}
|
|
@@ -103,8 +103,9 @@ export class PrimitiveProp {
|
|
|
103
103
|
else if (this.customType) {
|
|
104
104
|
typeParam = `<${this.effectiveType}>`;
|
|
105
105
|
}
|
|
106
|
+
const nullableParam = this.isNullable ? "nullable: true, " : "";
|
|
106
107
|
return `
|
|
107
|
-
build${typeParam}({ key: ${keyExpr}, placeholder: ${this.example}, example: ${buildedExample}, required: ${required}, ${buildedValidator()}})
|
|
108
|
+
build${typeParam}({ key: ${keyExpr}, placeholder: ${this.example}, example: ${buildedExample}, required: ${required}, ${nullableParam}${buildedValidator()}})
|
|
108
109
|
`;
|
|
109
110
|
}
|
|
110
111
|
thisDot() {
|
|
@@ -1,210 +1,221 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import toast from "$lib/utils/toast.svelte";
|
|
3
|
-
import { goto } from "$app/navigation";
|
|
4
|
-
import { page } from "$app/state";
|
|
5
|
-
import { browser } from "$app/environment";
|
|
6
|
-
import { SvelteURL } from "svelte/reactivity";
|
|
7
|
-
|
|
8
|
-
type ValidatorResult = string | null;
|
|
9
|
-
type ValidatorFn<T> = (v: T) => ValidatorResult;
|
|
10
|
-
type BundleResult<T> = T extends { bundle: () => infer R } ? R : T;
|
|
11
|
-
|
|
12
|
-
export type ApiCallParams<TResponse, TPaths = void> = TPaths extends void
|
|
13
|
-
? { behavior?: Behavior<TResponse, ApiErrorResponse> }
|
|
14
|
-
: { behavior?: Behavior<TResponse, ApiErrorResponse>; paths?: TPaths };
|
|
15
|
-
|
|
16
|
-
type PartialBuildedInput<T> = {
|
|
17
|
-
[K in Exclude<keyof T, "bundle">]?: BuildedInput<T[K]>;
|
|
18
|
-
} & {
|
|
19
|
-
bundle: unknown;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export interface QueryContract {
|
|
23
|
-
event: string;
|
|
24
|
-
key: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
type SeiLa = HTMLInputElement | HTMLButtonElement;
|
|
28
|
-
export type SvelteEvent = {
|
|
29
|
-
currentTarget: EventTarget & SeiLa;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export interface ApiErrorResponse {
|
|
33
|
-
error: string;
|
|
34
|
-
message: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export class Behavior<TSuccess = unknown, TError = unknown> {
|
|
38
|
-
onError?: (e: TError) => Promise<void> | void;
|
|
39
|
-
onSuccess?: (v: TSuccess) => Promise<void> | void;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export class BuildedInput<T> {
|
|
43
|
-
value = $state<T>(null as any);
|
|
44
|
-
display = $state<T>(null as any);
|
|
45
|
-
required: boolean;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
readonly
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
this.
|
|
64
|
-
this.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
this.selected
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
export function genericArrayBundler
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import toast from "$lib/utils/toast.svelte";
|
|
3
|
+
import { goto } from "$app/navigation";
|
|
4
|
+
import { page } from "$app/state";
|
|
5
|
+
import { browser } from "$app/environment";
|
|
6
|
+
import { SvelteURL } from "svelte/reactivity";
|
|
7
|
+
|
|
8
|
+
type ValidatorResult = string | null;
|
|
9
|
+
type ValidatorFn<T> = (v: T) => ValidatorResult;
|
|
10
|
+
type BundleResult<T> = T extends { bundle: () => infer R } ? R : T;
|
|
11
|
+
|
|
12
|
+
export type ApiCallParams<TResponse, TPaths = void> = TPaths extends void
|
|
13
|
+
? { behavior?: Behavior<TResponse, ApiErrorResponse> }
|
|
14
|
+
: { behavior?: Behavior<TResponse, ApiErrorResponse>; paths?: TPaths };
|
|
15
|
+
|
|
16
|
+
type PartialBuildedInput<T> = {
|
|
17
|
+
[K in Exclude<keyof T, "bundle">]?: BuildedInput<T[K]>;
|
|
18
|
+
} & {
|
|
19
|
+
bundle: unknown;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export interface QueryContract {
|
|
23
|
+
event: string;
|
|
24
|
+
key: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type SeiLa = HTMLInputElement | HTMLButtonElement;
|
|
28
|
+
export type SvelteEvent = {
|
|
29
|
+
currentTarget: EventTarget & SeiLa;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export interface ApiErrorResponse {
|
|
33
|
+
error: string;
|
|
34
|
+
message: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class Behavior<TSuccess = unknown, TError = unknown> {
|
|
38
|
+
onError?: (e: TError) => Promise<void> | void;
|
|
39
|
+
onSuccess?: (v: TSuccess) => Promise<void> | void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class BuildedInput<T> {
|
|
43
|
+
value = $state<T>(null as any);
|
|
44
|
+
display = $state<T>(null as any);
|
|
45
|
+
required: boolean;
|
|
46
|
+
nullable: boolean;
|
|
47
|
+
placeholder: T;
|
|
48
|
+
readonly kind = "builded";
|
|
49
|
+
readonly validator?: ValidatorFn<T>;
|
|
50
|
+
|
|
51
|
+
constructor(params: {
|
|
52
|
+
key?: T | undefined;
|
|
53
|
+
example: T;
|
|
54
|
+
required: boolean;
|
|
55
|
+
nullable?: boolean;
|
|
56
|
+
placeholder: T;
|
|
57
|
+
validator?: ValidatorFn<T>;
|
|
58
|
+
}) {
|
|
59
|
+
const { example, required, nullable, key, validator, placeholder } = params;
|
|
60
|
+
|
|
61
|
+
const initial = key === undefined ? example : key;
|
|
62
|
+
|
|
63
|
+
this.value = initial;
|
|
64
|
+
this.display = initial;
|
|
65
|
+
this.required = required;
|
|
66
|
+
this.nullable = nullable ?? false;
|
|
67
|
+
this.placeholder = placeholder;
|
|
68
|
+
|
|
69
|
+
if (validator) {
|
|
70
|
+
this.validator = validator;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
validate(): ValidatorResult {
|
|
75
|
+
if (!this.validator) return null;
|
|
76
|
+
return this.validator(this.value);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export class EnumQueryBuilder<T> {
|
|
81
|
+
readonly key: string = "";
|
|
82
|
+
values = $derived(page.url.searchParams.getAll(this.key)) as T[];
|
|
83
|
+
selected = $state<T | null>(null);
|
|
84
|
+
|
|
85
|
+
constructor(params: { key: string }) {
|
|
86
|
+
const { key } = params;
|
|
87
|
+
|
|
88
|
+
this.key = key;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
add = () => {
|
|
92
|
+
if (!this.selected) return;
|
|
93
|
+
const values = [...this.values, this.selected] as string[];
|
|
94
|
+
changeArrayParam({ key: this.key, values });
|
|
95
|
+
this.selected = null;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
remove = (index: number) => {
|
|
99
|
+
const values = [
|
|
100
|
+
...this.values.slice(0, index),
|
|
101
|
+
...this.values.slice(index + 1),
|
|
102
|
+
] as string[];
|
|
103
|
+
return changeArrayParam({ key: this.key, values });
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function build<T>(params: {
|
|
108
|
+
key?: T | undefined;
|
|
109
|
+
example: T;
|
|
110
|
+
placeholder: T;
|
|
111
|
+
required: boolean;
|
|
112
|
+
nullable?: boolean;
|
|
113
|
+
validator?: ValidatorFn<T>;
|
|
114
|
+
}): BuildedInput<T> {
|
|
115
|
+
return new BuildedInput(params);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function isFormValid<T>(schema: PartialBuildedInput<T>): boolean {
|
|
119
|
+
delete (schema as { bundle?: unknown }).bundle;
|
|
120
|
+
|
|
121
|
+
const arrayOfBuildedInputs = Object.values(schema) as BuildedInput<unknown>[];
|
|
122
|
+
|
|
123
|
+
const isValid = arrayOfBuildedInputs.every((a) => {
|
|
124
|
+
const result = a?.validate?.() ?? null;
|
|
125
|
+
|
|
126
|
+
if (result) {
|
|
127
|
+
throw new Error(`O valor ${a.value} do campo está incorreto. ${result}`);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return result === null;
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
if (!isValid) {
|
|
134
|
+
toast.error({
|
|
135
|
+
title: "Erro ao fazer a requisição",
|
|
136
|
+
description: "Um ou mais campos preenchidos estão incorretos.",
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return isValid;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function genericArrayBundler(data: string[]): string[];
|
|
144
|
+
export function genericArrayBundler<T extends { bundle: () => BundleResult<T> }>(
|
|
145
|
+
data: T[],
|
|
146
|
+
): BundleResult<T>[];
|
|
147
|
+
export function genericArrayBundler<T extends { bundle: () => BundleResult<T> }>(
|
|
148
|
+
data: T[] | string[],
|
|
149
|
+
) {
|
|
150
|
+
if (data.length === 0) return [];
|
|
151
|
+
if (typeof data[0] === "string") return data;
|
|
152
|
+
return (data as T[]).map((item) => item.bundle());
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function changeParam({ event, key }: QueryContract) {
|
|
156
|
+
const newValue = event;
|
|
157
|
+
const url = new SvelteURL(page.url);
|
|
158
|
+
url.searchParams.set(key, String(newValue));
|
|
159
|
+
goto(url, { replaceState: true, keepFocus: true });
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
type StringOrNumber = string | number;
|
|
163
|
+
|
|
164
|
+
type QueryWithArrayType = {
|
|
165
|
+
key: string;
|
|
166
|
+
value: string | number | null | StringOrNumber[];
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export class QueryBuilder {
|
|
170
|
+
readonly key: string = "";
|
|
171
|
+
value = $state<string | null>(null);
|
|
172
|
+
readonly kind = "query";
|
|
173
|
+
|
|
174
|
+
constructor(params: { key: string }) {
|
|
175
|
+
const { key } = params;
|
|
176
|
+
this.key = key;
|
|
177
|
+
|
|
178
|
+
const urlValue = page.url.searchParams.get(key);
|
|
179
|
+
this.value = urlValue !== null ? urlValue : null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
update(event: string | number | null) {
|
|
183
|
+
if (event === null || event === undefined) return;
|
|
184
|
+
this.value = String(event);
|
|
185
|
+
return changeParam({ key: this.key, event: this.value });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function setQueryGroup(group: QueryWithArrayType[]) {
|
|
190
|
+
if (!browser) return;
|
|
191
|
+
|
|
192
|
+
const url = new SvelteURL(page.url);
|
|
193
|
+
|
|
194
|
+
for (const p of group) {
|
|
195
|
+
const { key, value } = p;
|
|
196
|
+
|
|
197
|
+
if (Array.isArray(value)) {
|
|
198
|
+
url.searchParams.delete(key);
|
|
199
|
+
value.forEach((v) => url.searchParams.append(key, String(v)));
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
url.searchParams.set(key, String(value));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
goto(url, { replaceState: true, keepFocus: false });
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function changeArrayParam({ values, key }: { values: string[]; key: string }) {
|
|
210
|
+
const url = new SvelteURL(page.url);
|
|
211
|
+
url.searchParams.delete(key);
|
|
212
|
+
values.forEach((value) => url.searchParams.append(key, value));
|
|
213
|
+
goto(url, { replaceState: true, keepFocus: true });
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export function bundleStrict<T extends Record<string, unknown>>(
|
|
217
|
+
payload: T,
|
|
218
|
+
): { [K in keyof T as Exclude<T[K], undefined> extends never ? never : K]: Exclude<T[K], undefined> };
|
|
219
|
+
export function bundleStrict(payload: Record<string, unknown>): Record<string, unknown> {
|
|
220
|
+
return Object.fromEntries(Object.entries(payload).filter(([, v]) => v !== undefined));
|
|
221
|
+
}
|