svelte-reflector 1.1.21 → 1.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/README.md +518 -518
  2. package/dist/core/method/generators/MethodApiCallBuilder.js +24 -24
  3. package/dist/core/method/generators/MethodGenerator.js +35 -35
  4. package/dist/core/method/generators/MethodPropsBuilder.js +3 -3
  5. package/dist/core/module/ModuleClassBuilder.js +36 -36
  6. package/dist/core/module/ModuleConstructorBuilder.js +13 -13
  7. package/dist/core/module/ModuleFileBuilder.js +24 -24
  8. package/dist/helpers/input.js +11 -11
  9. package/dist/interface.js +4 -4
  10. package/dist/main.js +16 -16
  11. package/dist/module.js +6 -6
  12. package/dist/props/array.property.js +4 -4
  13. package/dist/props/primitive.property.js +2 -2
  14. package/dist/reflector.js +184 -184
  15. package/dist/schema.js +13 -13
  16. package/package.json +39 -39
  17. package/dist/array.property.d.ts +0 -22
  18. package/dist/array.property.js +0 -68
  19. package/dist/constructor.d.ts +0 -2
  20. package/dist/constructor.js +0 -2
  21. package/dist/core/Method.d.ts +0 -41
  22. package/dist/core/Method.js +0 -19
  23. package/dist/core/MethodApiTypeAnalyzer.d.ts +0 -9
  24. package/dist/core/MethodApiTypeAnalyzer.js +0 -19
  25. package/dist/core/MethodBodyAnalyzer.d.ts +0 -11
  26. package/dist/core/MethodBodyAnalyzer.js +0 -78
  27. package/dist/core/MethodBuilder.d.ts +0 -11
  28. package/dist/core/MethodBuilder.js +0 -50
  29. package/dist/core/MethodEndpointBuilder.d.ts +0 -6
  30. package/dist/core/MethodEndpointBuilder.js +0 -21
  31. package/dist/core/MethodRequestAnalyzer.d.ts +0 -16
  32. package/dist/core/MethodRequestAnalyzer.js +0 -62
  33. package/dist/core/MethodResponseAnalyzer.d.ts +0 -12
  34. package/dist/core/MethodResponseAnalyzer.js +0 -96
  35. package/dist/core/Module.d.ts +0 -16
  36. package/dist/core/Module.js +0 -14
  37. package/dist/core/ModuleBuilder.d.ts +0 -11
  38. package/dist/core/ModuleBuilder.js +0 -45
  39. package/dist/core/ModuleClassBuilder.d.ts +0 -12
  40. package/dist/core/ModuleClassBuilder.js +0 -78
  41. package/dist/core/ModuleConstructorBuilder.d.ts +0 -7
  42. package/dist/core/ModuleConstructorBuilder.js +0 -20
  43. package/dist/core/ModuleFileBuilder.d.ts +0 -19
  44. package/dist/core/ModuleFileBuilder.js +0 -49
  45. package/dist/core/ModuleFormBuilder.d.ts +0 -13
  46. package/dist/core/ModuleFormBuilder.js +0 -34
  47. package/dist/core/ModuleImports.d.ts +0 -16
  48. package/dist/core/ModuleImports.js +0 -47
  49. package/dist/core/ModuleMethodProcessor.d.ts +0 -28
  50. package/dist/core/ModuleMethodProcessor.js +0 -75
  51. package/dist/core/ModuleParamProcessor.d.ts +0 -24
  52. package/dist/core/ModuleParamProcessor.js +0 -42
  53. package/dist/core/ModuleParameterProcessor.d.ts +0 -19
  54. package/dist/core/ModuleParameterProcessor.js +0 -68
  55. package/dist/core/ModuleStateBuilder.d.ts +0 -10
  56. package/dist/core/ModuleStateBuilder.js +0 -21
  57. package/dist/enum-property.d.ts +0 -17
  58. package/dist/enum-property.js +0 -29
  59. package/dist/enum.class.d.ts +0 -10
  60. package/dist/enum.class.js +0 -15
  61. package/dist/generators/MethodApiCallBuilder.d.ts +0 -13
  62. package/dist/generators/MethodApiCallBuilder.js +0 -80
  63. package/dist/generators/MethodGenerator.d.ts +0 -10
  64. package/dist/generators/MethodGenerator.js +0 -75
  65. package/dist/generators/MethodPropsBuilder.d.ts +0 -5
  66. package/dist/generators/MethodPropsBuilder.js +0 -19
  67. package/dist/generators/ModuleGenerator.d.ts +0 -16
  68. package/dist/generators/ModuleGenerator.js +0 -133
  69. package/dist/generators/QueryBuilderGenerator.d.ts +0 -3
  70. package/dist/generators/QueryBuilderGenerator.js +0 -26
  71. package/dist/generators/ReflectorClasses.d.ts +0 -3
  72. package/dist/generators/ReflectorClasses.js +0 -46
  73. package/dist/generators/ReflectorFileGenerator.d.ts +0 -8
  74. package/dist/generators/ReflectorFileGenerator.js +0 -32
  75. package/dist/generators/ReflectorFunctions.d.ts +0 -3
  76. package/dist/generators/ReflectorFunctions.js +0 -58
  77. package/dist/generators/ReflectorTypes.d.ts +0 -3
  78. package/dist/generators/ReflectorTypes.js +0 -21
  79. package/dist/generators/index.d.ts +0 -3
  80. package/dist/generators/index.js +0 -3
  81. package/dist/helpers.d.ts +0 -6
  82. package/dist/helpers.js +0 -35
  83. package/dist/input.d.ts +0 -3
  84. package/dist/input.js +0 -14
  85. package/dist/models/ArrayProperty.d.ts +0 -23
  86. package/dist/models/ArrayProperty.js +0 -62
  87. package/dist/models/EnumClass.d.ts +0 -10
  88. package/dist/models/EnumClass.js +0 -15
  89. package/dist/models/EnumProperty.d.ts +0 -19
  90. package/dist/models/EnumProperty.js +0 -41
  91. package/dist/models/ObjectProperty.d.ts +0 -15
  92. package/dist/models/ObjectProperty.js +0 -25
  93. package/dist/models/PrimitiveProperty.d.ts +0 -20
  94. package/dist/models/PrimitiveProperty.js +0 -64
  95. package/dist/models/Property.d.ts +0 -19
  96. package/dist/models/Property.js +0 -24
  97. package/dist/models/PropertyBuilder.d.ts +0 -22
  98. package/dist/models/PropertyBuilder.js +0 -89
  99. package/dist/models/index.d.ts +0 -7
  100. package/dist/models/index.js +0 -7
  101. package/dist/module.imports.d.ts +0 -2
  102. package/dist/module.imports.js +0 -2
  103. package/dist/object.property.d.ts +0 -17
  104. package/dist/object.property.js +0 -33
  105. package/dist/primitive-property.d.ts +0 -28
  106. package/dist/primitive-property.js +0 -102
  107. package/dist/property.d.ts +0 -1
  108. package/dist/property.js +0 -116
  109. package/dist/reflector/controllers/admin/account/admin-account.module.svelte.d.ts +0 -7
  110. package/dist/reflector/controllers/admin/account/admin-account.module.svelte.js +0 -28
  111. package/dist/reflector/controllers/admin/account/owner/account-owner.module.svelte.d.ts +0 -15
  112. package/dist/reflector/controllers/admin/account/owner/account-owner.module.svelte.js +0 -79
  113. package/dist/reflector/controllers/admin/kyc/config/kyc-config.module.svelte.d.ts +0 -49
  114. package/dist/reflector/controllers/admin/kyc/config/kyc-config.module.svelte.js +0 -303
  115. package/dist/reflector/controllers/admin/policy/system/policy-system.module.svelte.d.ts +0 -9
  116. package/dist/reflector/controllers/admin/policy/system/policy-system.module.svelte.js +0 -36
  117. package/dist/reflector/controllers/admin/smtp/config/smtp-config.module.svelte.d.ts +0 -19
  118. package/dist/reflector/controllers/admin/smtp/config/smtp-config.module.svelte.js +0 -82
  119. package/dist/reflector/controllers/customer/kyc/file-upload/kyc-file-upload.module.svelte.d.ts +0 -37
  120. package/dist/reflector/controllers/customer/kyc/file-upload/kyc-file-upload.module.svelte.js +0 -228
  121. package/dist/reflector/controllers/member/account/member-account.module.svelte.d.ts +0 -11
  122. package/dist/reflector/controllers/member/account/member-account.module.svelte.js +0 -54
  123. package/dist/reflector/controllers/owner/account/owner-account.module.svelte.d.ts +0 -11
  124. package/dist/reflector/controllers/owner/account/owner-account.module.svelte.js +0 -54
  125. package/dist/reflector/controllers/owner/kyc/config/kyc-config.module.svelte.d.ts +0 -49
  126. package/dist/reflector/controllers/owner/kyc/config/kyc-config.module.svelte.js +0 -303
  127. package/dist/reflector/controllers/owner/kyc/self/create-or-update/self-create-or-update.module.svelte.d.ts +0 -33
  128. package/dist/reflector/controllers/owner/kyc/self/create-or-update/self-create-or-update.module.svelte.js +0 -197
  129. package/dist/reflector/controllers/owner/policy/owner-policy.module.svelte.d.ts +0 -9
  130. package/dist/reflector/controllers/owner/policy/owner-policy.module.svelte.js +0 -36
  131. package/dist/reflector/controllers/owner/smtp/config/smtp-config.module.svelte.d.ts +0 -19
  132. package/dist/reflector/controllers/owner/smtp/config/smtp-config.module.svelte.js +0 -82
  133. package/dist/reflector/controllers/public/auth/sign-in-firebase/auth-sign-in-firebase.module.svelte.d.ts +0 -29
  134. package/dist/reflector/controllers/public/auth/sign-in-firebase/auth-sign-in-firebase.module.svelte.js +0 -223
  135. package/dist/reflector/controllers/public/reset-password/tenant/send-recovery-email/tenant-send-recovery-email.module.svelte.d.ts +0 -13
  136. package/dist/reflector/controllers/public/reset-password/tenant/send-recovery-email/tenant-send-recovery-email.module.svelte.js +0 -49
  137. package/dist/reflector/controllers/restricted/account/avatar-file-upload/account-avatar-file-upload.module.svelte.d.ts +0 -19
  138. package/dist/reflector/controllers/restricted/account/avatar-file-upload/account-avatar-file-upload.module.svelte.js +0 -114
  139. package/dist/reflector/controllers/restricted/bank/restricted-bank.module.svelte.d.ts +0 -15
  140. package/dist/reflector/controllers/restricted/bank/restricted-bank.module.svelte.js +0 -78
  141. package/dist/reflector/controllers/restricted/files/presigned-url/files-presigned-url.module.svelte.d.ts +0 -11
  142. package/dist/reflector/controllers/restricted/files/presigned-url/files-presigned-url.module.svelte.js +0 -56
  143. package/dist/reflector/controllers/restricted/notification/restricted-notification.module.svelte.d.ts +0 -9
  144. package/dist/reflector/controllers/restricted/notification/restricted-notification.module.svelte.js +0 -36
  145. package/dist/reflector/controllers/restricted/two-factor-auth/status/two-factor-auth-status.module.svelte.d.ts +0 -15
  146. package/dist/reflector/controllers/restricted/two-factor-auth/status/two-factor-auth-status.module.svelte.js +0 -68
  147. package/dist/reflector/reflector.types.d.ts +0 -4
  148. package/dist/reflector/reflector.types.js +0 -4
  149. package/dist/reflector/schemas.d.ts +0 -357
  150. package/dist/reflector/schemas.js +0 -1709
  151. package/dist/request.d.ts +0 -32
  152. package/dist/request.js +0 -125
  153. package/dist/utils/EndpointUtils.d.ts +0 -4
  154. package/dist/utils/EndpointUtils.js +0 -34
  155. package/dist/utils/EnumUtils.d.ts +0 -2
  156. package/dist/utils/EnumUtils.js +0 -9
  157. package/dist/utils/FileUtils.d.ts +0 -3
  158. package/dist/utils/FileUtils.js +0 -20
  159. package/dist/utils/NamingUtils.d.ts +0 -4
  160. package/dist/utils/NamingUtils.js +0 -19
  161. package/dist/utils/SchemaUtils.d.ts +0 -4
  162. package/dist/utils/SchemaUtils.js +0 -18
  163. package/dist/utils/StringUtils.d.ts +0 -5
  164. package/dist/utils/StringUtils.js +0 -41
  165. package/dist/utils/ValidatorUtils.d.ts +0 -6
  166. package/dist/utils/ValidatorUtils.js +0 -70
  167. package/dist/utils/index.d.ts +0 -7
  168. package/dist/utils/index.js +0 -7
  169. package/dist/zodProperty.d.ts +0 -32
  170. package/dist/zodProperty.js +0 -123
package/README.md CHANGED
@@ -1,518 +1,518 @@
1
- # Svelte Reflector
2
-
3
- **Turn your OpenAPI into a first-class Svelte 5 DX.**
4
-
5
- Svelte Reflector is a **developer-experience-first code generator** that converts OpenAPI specs into fully typed, reactive Svelte 5 modules — ready for production, forms included.
6
-
7
- [![npm version](https://img.shields.io/npm/v/svelte-reflector.svg)](https://www.npmjs.com/package/svelte-reflector)
8
- [![npm downloads](https://img.shields.io/npm/dm/svelte-reflector.svg)](https://www.npmjs.com/package/svelte-reflector)
9
- [![npm total downloads](https://img.shields.io/npm/dt/svelte-reflector.svg)](https://www.npmjs.com/package/svelte-reflector)
10
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.9+-blue.svg)](https://www.typescriptlang.org/)
11
- [![Svelte](https://img.shields.io/badge/Svelte-5+-orange.svg)](https://svelte.dev/)
12
-
13
- A TypeScript code generator that creates type-safe Svelte 5 modules from OpenAPI specifications. It transforms your backend's OpenAPI/Swagger docs into fully-typed Svelte stores with built-in form handling, validation, and API integration.
14
-
15
- ## Features
16
-
17
- - **Automatic Type Generation** - Generates TypeScript interfaces and classes from OpenAPI schemas
18
- - **Svelte 5 Runes Integration** - Uses `$state` and `$derived` for reactive state management
19
- - **Form Handling** - Auto-generates form schemas with validation support
20
- - **Type-Safe API Calls** - Full TypeScript support for all API operations
21
- - **Query Parameter Sync** - `QueryBuilder` and `EnumQueryBuilder` keep state synced with URL searchParams
22
- - **Enum Support** - Auto-generates enum types and array enum query builders
23
- - **OpenAPI/Swagger Compatible** - Works with any backend that exposes OpenAPI specs
24
- - **Development Mode** - Smart regeneration based on environment
25
- - **Validation Ready** - Built-in support for custom field validators
26
- - **Vite Plugin** - Can be used as a Vite plugin for automatic generation on build
27
-
28
- ## Installation
29
-
30
- ```bash
31
- npm install svelte-reflector
32
- # or
33
- yarn add svelte-reflector
34
- # or
35
- pnpm add svelte-reflector
36
- ```
37
-
38
- ## Quick Start
39
-
40
- ### 1. Configure Environment Variables
41
-
42
- Create a `.env` file in your project root:
43
-
44
- ```env
45
- # Required - Your backend URL
46
- BACKEND_URL=https://api.example.com/
47
- # or
48
- PUBLIC_BACKEND=https://api.example.com/
49
-
50
- # Optional - Environment (defaults to PROD)
51
- ENVIRONMENT=DEV
52
- # or
53
- VITE_ENVIRONMENT=DEV
54
- ```
55
-
56
- ### 2. Create Reflector Config (Optional)
57
-
58
- Create a `src/reflector.config.ts` to define custom validators:
59
-
60
- ```typescript
61
- export const validators = [
62
- {
63
- fields: ["email", "userEmail"],
64
- validator: "validateEmail",
65
- },
66
- {
67
- fields: ["phone", "mobile"],
68
- validator: "validatePhone",
69
- },
70
- {
71
- fields: ["cpf", "cnpj"],
72
- validator: "validateDocument",
73
- },
74
- ];
75
- ```
76
-
77
- ### 3. Run the Generator
78
-
79
- ```bash
80
- # Manual generation (recommended for DEV environment)
81
- npx reflect
82
-
83
- # Or programmatically as a Vite plugin
84
- import { reflector } from "svelte-reflector";
85
- await reflector(true); // true = force generation
86
- ```
87
-
88
- ### 4. Use Generated Modules
89
-
90
- The generator creates files in `src/reflector/`:
91
-
92
- ```typescript
93
- import { UserModule } from "$reflector/controllers/user/user.module.svelte";
94
- import type { User } from "$reflector/schemas.svelte";
95
-
96
- // Create module instance
97
- const userModule = new UserModule();
98
-
99
- // Access reactive state
100
- console.log(userModule.loading); // $state<boolean>
101
- console.log(userModule.list); // $state<User[]>
102
-
103
- // Call API methods
104
- await userModule.listAll({
105
- behavior: {
106
- onSuccess: (response) => console.log(response),
107
- onError: (error) => console.error(error),
108
- },
109
- });
110
-
111
- // Work with forms
112
- const userForm = userModule.forms.createUser;
113
- userForm.name.value = "John Doe";
114
- userForm.email.value = "john@example.com";
115
-
116
- // Submit form
117
- await userModule.createUser();
118
- ```
119
-
120
- ## Generated Structure
121
-
122
- ```
123
- src/reflector/
124
- ├── controllers/
125
- │ └── user/
126
- │ └── user.module.svelte.ts # API module with methods
127
- ├── schemas.svelte.ts # Generated schemas & types
128
- ├── reflector.svelte.ts # Core utilities (build, isFormValid, QueryBuilder, etc.)
129
- ├── fields.ts # Field name constants
130
- ├── enums.ts # Enum type definitions
131
- ├── mocked-params.svelte.ts # Mocked path parameters ($state)
132
- └── backup.json # Cached OpenAPI spec
133
- ```
134
-
135
- ## Generated Module API
136
-
137
- Each generated module provides:
138
-
139
- ### State Properties
140
-
141
- | Property | Type | Description |
142
- |----------|------|-------------|
143
- | `loading` | `$state<boolean>` | Request loading state |
144
- | `list` | `$state<T[]>` | List results (for list endpoints) |
145
- | `forms` | `$state<Record<string, T>>` | Form instances |
146
- | `querys` | `Querys` | Query parameter state (QueryBuilder instances) |
147
- | `headers` | `Headers` | Header state |
148
- | `paths` | `Paths` | Path parameter state |
149
-
150
- ### Methods
151
-
152
- ```typescript
153
- // List all items (GET with page parameter)
154
- async listAll(params?: { behavior?: Behavior }): Promise<T[]>
155
-
156
- // Get single entity (GET without page parameter)
157
- async get(params?: { behavior?: Behavior }): Promise<T>
158
-
159
- // Create/Update (POST/PUT/PATCH)
160
- async create(params?: { behavior?: Behavior }): Promise<T>
161
- async update(params?: { behavior?: Behavior }): Promise<T>
162
-
163
- // Delete (DELETE)
164
- async delete(params?: { behavior?: Behavior }): Promise<void>
165
-
166
- // Reset all state
167
- reset(): void
168
-
169
- // Clear forms
170
- clearForms(): void
171
- ```
172
-
173
- ### QueryBuilder
174
-
175
- Query parameters are wrapped in `QueryBuilder` instances that sync with URL searchParams:
176
-
177
- ```typescript
178
- // Single value query parameter
179
- const querys = module.querys;
180
- querys.status.update("active"); // Updates URL searchParam and internal state
181
-
182
- // Array enum query parameter
183
- const enumQuery = module.querys.roles; // EnumQueryBuilder<RoleType>
184
- enumQuery.selected = "admin";
185
- enumQuery.add(); // Adds to URL searchParams
186
- enumQuery.remove(0); // Removes from URL searchParams
187
- enumQuery.values; // $derived from URL - always in sync
188
- ```
189
-
190
- ## Configuration
191
-
192
- ### Environment Variables
193
-
194
- | Variable | Required | Description |
195
- |----------|----------|-------------|
196
- | `BACKEND_URL` | Yes | Backend API URL |
197
- | `PUBLIC_BACKEND` | Yes | Alternative to BACKEND_URL |
198
- | `ENVIRONMENT` | No | DEV/PROD (defaults to PROD) |
199
- | `VITE_ENVIRONMENT` | No | Vite-specific env var |
200
- | `NODE_ENV` | No | Node environment |
201
-
202
- ### Behavior Pattern
203
-
204
- All API methods accept a `Behavior` object for callbacks:
205
-
206
- ```typescript
207
- interface Behavior<TSuccess, TError> {
208
- onSuccess?: (value: TSuccess) => Promise<void> | void;
209
- onError?: (error: TError) => Promise<void> | void;
210
- }
211
-
212
- // Usage
213
- await userModule.createUser({
214
- behavior: {
215
- onSuccess: (user) => console.log("Created:", user),
216
- onError: (err) => console.error("Failed:", err),
217
- },
218
- });
219
- ```
220
-
221
- ### Form Validation
222
-
223
- Forms use `BuildedInput` class with validation:
224
-
225
- ```typescript
226
- class BuildedInput<T> {
227
- value: T; // Current value ($state)
228
- display: T; // Display value ($state)
229
- required: boolean; // Is field required
230
- placeholder: T; // Placeholder/example value
231
- readonly kind: 'builded';
232
- validator?: (v: T) => string | null; // Validation function
233
- validate(): string | null; // Run validation
234
- }
235
-
236
- // Check if all form fields are valid
237
- import { isFormValid } from "$reflector/reflector.svelte";
238
-
239
- if (isFormValid(userModule.forms.createUser)) {
240
- await userModule.createUser();
241
- }
242
- ```
243
-
244
- ## TypeScript Configuration
245
-
246
- Add path aliases to your `tsconfig.json`:
247
-
248
- ```json
249
- {
250
- "compilerOptions": {
251
- "paths": {
252
- "$reflector/*": ["./src/reflector/*"],
253
- "$lib/*": ["./src/lib/*"]
254
- }
255
- }
256
- }
257
- ```
258
-
259
- For Vite projects, also update `vite.config.ts`:
260
-
261
- ```typescript
262
- export default defineConfig({
263
- resolve: {
264
- alias: {
265
- $reflector: path.resolve("./src/reflector"),
266
- $lib: path.resolve("./src/lib"),
267
- },
268
- },
269
- });
270
- ```
271
-
272
- ## Workflow
273
-
274
- ### Development Mode
275
-
276
- In `ENVIRONMENT=DEV`:
277
- - Schemas are **NOT** auto-regenerated on build
278
- - Use `npx reflect` to manually regenerate
279
- - Faster builds, manual control
280
-
281
- ### Production Mode
282
-
283
- In `ENVIRONMENT=PROD`:
284
- - Schemas are auto-regenerated on each build
285
- - Fresh types from latest OpenAPI spec
286
- - Fallback to `backup.json` if backend is unavailable
287
-
288
- ## Advanced Usage
289
-
290
- ### Custom Validators
291
-
292
- Define validators in `src/reflector.config.ts`:
293
-
294
- ```typescript
295
- export const validators = [
296
- {
297
- fields: ["email", "userEmail", "contactEmail"],
298
- validator: "validateEmail",
299
- },
300
- {
301
- fields: ["phone", "mobile", "whatsapp"],
302
- validator: "validatePhone",
303
- },
304
- {
305
- fields: ["cpf", "cnpj", "document"],
306
- validator: "validateDocument",
307
- },
308
- {
309
- fields: ["password", "newPassword"],
310
- validator: "validatePassword",
311
- },
312
- {
313
- fields: ["birthDate", "startDate", "endDate"],
314
- validator: "validateDate",
315
- },
316
- {
317
- fields: ["zipcode", "cep"],
318
- validator: "validateZipcode",
319
- },
320
- {
321
- fields: ["url", "website", "avatarUrl"],
322
- validator: "validateUrl",
323
- },
324
- ];
325
- ```
326
-
327
- Then implement in your app at `$lib/sanitizers/validateFormats.ts`:
328
-
329
- ```typescript
330
- // Email validation
331
- export function validateEmail(value: string): string | null {
332
- if (!value) return null; // Let required handle empty
333
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
334
- return emailRegex.test(value) ? null : "Invalid email format";
335
- }
336
-
337
- // Phone validation
338
- export function validatePhone(value: string): string | null {
339
- if (!value) return null;
340
- const phoneRegex = /^(\+?55\s?)?(\(?\d{2}\)?\s?)?(\d{4,5}-?\d{4})$/;
341
- return phoneRegex.test(value) ? null : "Invalid phone number";
342
- }
343
-
344
- // CPF/CNPJ validation (Brazilian documents)
345
- export function validateDocument(value: string): string | null {
346
- if (!value) return null;
347
- const cleaned = value.replace(/\D/g, '');
348
-
349
- if (cleaned.length === 11) {
350
- return validateCPF(cleaned) ? null : "Invalid CPF";
351
- } else if (cleaned.length === 14) {
352
- return validateCNPJ(cleaned) ? null : "Invalid CNPJ";
353
- }
354
- return "Invalid document format";
355
- }
356
-
357
- function validateCPF(cpf: string): boolean {
358
- if (/^(\d)\1{10}$/.test(cpf)) return false;
359
-
360
- let sum = 0;
361
- for (let i = 0; i < 9; i++) sum += parseInt(cpf[i]) * (10 - i);
362
- let rev = 11 - (sum % 11);
363
- if (rev === 10 || rev === 11) rev = 0;
364
- if (rev !== parseInt(cpf[9])) return false;
365
-
366
- sum = 0;
367
- for (let i = 0; i < 10; i++) sum += parseInt(cpf[i]) * (11 - i);
368
- rev = 11 - (sum % 11);
369
- if (rev === 10 || rev === 11) rev = 0;
370
- return rev === parseInt(cpf[10]);
371
- }
372
-
373
- function validateCNPJ(cnpj: string): boolean {
374
- if (/^(\d)\1{13}$/.test(cnpj)) return false;
375
-
376
- const weights1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
377
- const weights2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
378
-
379
- let sum = 0;
380
- for (let i = 0; i < 12; i++) sum += parseInt(cnpj[i]) * weights1[i];
381
- let rev = sum % 11 < 2 ? 0 : 11 - (sum % 11);
382
- if (rev !== parseInt(cnpj[12])) return false;
383
-
384
- sum = 0;
385
- for (let i = 0; i < 13; i++) sum += parseInt(cnpj[i]) * weights2[i];
386
- rev = sum % 11 < 2 ? 0 : 11 - (sum % 11);
387
- return rev === parseInt(cnpj[13]);
388
- }
389
-
390
- // Password strength validation
391
- export function validatePassword(value: string): string | null {
392
- if (!value) return null;
393
- if (value.length < 8) return "Password must be at least 8 characters";
394
- if (!/[A-Z]/.test(value)) return "Password must contain an uppercase letter";
395
- if (!/[a-z]/.test(value)) return "Password must contain a lowercase letter";
396
- if (!/[0-9]/.test(value)) return "Password must contain a number";
397
- if (!/[!@#$%^&*]/.test(value)) return "Password must contain a special character";
398
- return null;
399
- }
400
-
401
- // Date validation
402
- export function validateDate(value: string): string | null {
403
- if (!value) return null;
404
- const date = new Date(value);
405
- if (isNaN(date.getTime())) return "Invalid date";
406
- if (date > new Date()) return "Date cannot be in the future";
407
- return null;
408
- }
409
-
410
- // Brazilian ZIP code (CEP) validation
411
- export function validateZipcode(value: string): string | null {
412
- if (!value) return null;
413
- const cepRegex = /^\d{5}-?\d{3}$/;
414
- return cepRegex.test(value) ? null : "Invalid ZIP code format";
415
- }
416
-
417
- // URL validation
418
- export function validateUrl(value: string): string | null {
419
- if (!value) return null;
420
- try {
421
- new URL(value);
422
- return null;
423
- } catch {
424
- return "Invalid URL format";
425
- }
426
- }
427
-
428
- // Min/max length validator factory
429
- export function minLength(min: number) {
430
- return (value: string): string | null => {
431
- if (!value) return null;
432
- return value.length >= min ? null : `Must be at least ${min} characters`;
433
- };
434
- }
435
-
436
- export function maxLength(max: number) {
437
- return (value: string): string | null => {
438
- if (!value) return null;
439
- return value.length <= max ? null : `Must be at most ${max} characters`;
440
- };
441
- }
442
-
443
- // Number range validator factory
444
- export function numberRange(min: number, max: number) {
445
- return (value: number): string | null => {
446
- if (value === null || value === undefined) return null;
447
- return value >= min && value <= max ? null : `Must be between ${min} and ${max}`;
448
- };
449
- }
450
-
451
- // Required field validator
452
- export function required(value: string | number | boolean | null): string | null {
453
- if (value === null || value === undefined || value === '') {
454
- return "This field is required";
455
- }
456
- return null;
457
- }
458
- ```
459
-
460
- ### Manual Schema Access
461
-
462
- ```typescript
463
- import { User } from "$reflector/schemas.svelte";
464
-
465
- // Create instance
466
- const user = new User({ name: "John", email: "john@example.com" });
467
-
468
- // Get data bundle
469
- const data = user.bundle(); // { name: "John", email: "john@example.com" }
470
- ```
471
-
472
- ### Batch Query Updates
473
-
474
- ```typescript
475
- import { setQueryGroup } from "$reflector/reflector.svelte";
476
-
477
- // Update multiple query params at once
478
- setQueryGroup([
479
- { key: "page", value: 1 },
480
- { key: "status", value: "active" },
481
- { key: "roles", value: ["admin", "editor"] }, // Array params supported
482
- ]);
483
- ```
484
-
485
- ## Troubleshooting
486
-
487
- ### "BACKEND_URL vazio" Error
488
-
489
- Ensure you have set `BACKEND_URL` or `PUBLIC_BACKEND` in your `.env` file.
490
-
491
- ### Schemas Not Updating
492
-
493
- In DEV mode, run `npx reflect` manually. Check that your backend's OpenAPI spec is accessible at `{BACKEND_URL}openapi.json`.
494
-
495
- ### Type Errors After Generation
496
-
497
- 1. Restart your TypeScript language server
498
- 2. Check path aliases in `tsconfig.json`
499
- 3. Ensure `$reflector/*` alias is configured
500
-
501
- ## License
502
-
503
- MIT License - see [LICENSE](LICENSE) for details.
504
-
505
- ## Contributing
506
-
507
- Contributions are welcome! Please feel free to submit a Pull Request.
508
-
509
- ## Links
510
-
511
- - [npm](https://www.npmjs.com/package/svelte-reflector)
512
- - [GitHub](https://github.com/aleleppy/reflector)
513
- - [Svelte](https://svelte.dev/)
514
- - [OpenAPI Specification](https://swagger.io/specification/)
515
-
516
- ---
517
-
518
- Built with by the Pináculo Digital team.
1
+ # Svelte Reflector
2
+
3
+ **Turn your OpenAPI into a first-class Svelte 5 DX.**
4
+
5
+ Svelte Reflector is a **developer-experience-first code generator** that converts OpenAPI specs into fully typed, reactive Svelte 5 modules — ready for production, forms included.
6
+
7
+ [![npm version](https://img.shields.io/npm/v/svelte-reflector.svg)](https://www.npmjs.com/package/svelte-reflector)
8
+ [![npm downloads](https://img.shields.io/npm/dm/svelte-reflector.svg)](https://www.npmjs.com/package/svelte-reflector)
9
+ [![npm total downloads](https://img.shields.io/npm/dt/svelte-reflector.svg)](https://www.npmjs.com/package/svelte-reflector)
10
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.9+-blue.svg)](https://www.typescriptlang.org/)
11
+ [![Svelte](https://img.shields.io/badge/Svelte-5+-orange.svg)](https://svelte.dev/)
12
+
13
+ A TypeScript code generator that creates type-safe Svelte 5 modules from OpenAPI specifications. It transforms your backend's OpenAPI/Swagger docs into fully-typed Svelte stores with built-in form handling, validation, and API integration.
14
+
15
+ ## Features
16
+
17
+ - **Automatic Type Generation** - Generates TypeScript interfaces and classes from OpenAPI schemas
18
+ - **Svelte 5 Runes Integration** - Uses `$state` and `$derived` for reactive state management
19
+ - **Form Handling** - Auto-generates form schemas with validation support
20
+ - **Type-Safe API Calls** - Full TypeScript support for all API operations
21
+ - **Query Parameter Sync** - `QueryBuilder` and `EnumQueryBuilder` keep state synced with URL searchParams
22
+ - **Enum Support** - Auto-generates enum types and array enum query builders
23
+ - **OpenAPI/Swagger Compatible** - Works with any backend that exposes OpenAPI specs
24
+ - **Development Mode** - Smart regeneration based on environment
25
+ - **Validation Ready** - Built-in support for custom field validators
26
+ - **Vite Plugin** - Can be used as a Vite plugin for automatic generation on build
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ npm install svelte-reflector
32
+ # or
33
+ yarn add svelte-reflector
34
+ # or
35
+ pnpm add svelte-reflector
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ### 1. Configure Environment Variables
41
+
42
+ Create a `.env` file in your project root:
43
+
44
+ ```env
45
+ # Required - Your backend URL
46
+ BACKEND_URL=https://api.example.com/
47
+ # or
48
+ PUBLIC_BACKEND=https://api.example.com/
49
+
50
+ # Optional - Environment (defaults to PROD)
51
+ ENVIRONMENT=DEV
52
+ # or
53
+ VITE_ENVIRONMENT=DEV
54
+ ```
55
+
56
+ ### 2. Create Reflector Config (Optional)
57
+
58
+ Create a `src/reflector.config.ts` to define custom validators:
59
+
60
+ ```typescript
61
+ export const validators = [
62
+ {
63
+ fields: ["email", "userEmail"],
64
+ validator: "validateEmail",
65
+ },
66
+ {
67
+ fields: ["phone", "mobile"],
68
+ validator: "validatePhone",
69
+ },
70
+ {
71
+ fields: ["cpf", "cnpj"],
72
+ validator: "validateDocument",
73
+ },
74
+ ];
75
+ ```
76
+
77
+ ### 3. Run the Generator
78
+
79
+ ```bash
80
+ # Manual generation (recommended for DEV environment)
81
+ npx reflect
82
+
83
+ # Or programmatically as a Vite plugin
84
+ import { reflector } from "svelte-reflector";
85
+ await reflector(true); // true = force generation
86
+ ```
87
+
88
+ ### 4. Use Generated Modules
89
+
90
+ The generator creates files in `src/reflector/`:
91
+
92
+ ```typescript
93
+ import { UserModule } from "$reflector/controllers/user/user.module.svelte";
94
+ import type { User } from "$reflector/schemas.svelte";
95
+
96
+ // Create module instance
97
+ const userModule = new UserModule();
98
+
99
+ // Access reactive state
100
+ console.log(userModule.loading); // $state<boolean>
101
+ console.log(userModule.list); // $state<User[]>
102
+
103
+ // Call API methods
104
+ await userModule.listAll({
105
+ behavior: {
106
+ onSuccess: (response) => console.log(response),
107
+ onError: (error) => console.error(error),
108
+ },
109
+ });
110
+
111
+ // Work with forms
112
+ const userForm = userModule.forms.createUser;
113
+ userForm.name.value = "John Doe";
114
+ userForm.email.value = "john@example.com";
115
+
116
+ // Submit form
117
+ await userModule.createUser();
118
+ ```
119
+
120
+ ## Generated Structure
121
+
122
+ ```
123
+ src/reflector/
124
+ ├── controllers/
125
+ │ └── user/
126
+ │ └── user.module.svelte.ts # API module with methods
127
+ ├── schemas.svelte.ts # Generated schemas & types
128
+ ├── reflector.svelte.ts # Core utilities (build, isFormValid, QueryBuilder, etc.)
129
+ ├── fields.ts # Field name constants
130
+ ├── enums.ts # Enum type definitions
131
+ ├── mocked-params.svelte.ts # Mocked path parameters ($state)
132
+ └── backup.json # Cached OpenAPI spec
133
+ ```
134
+
135
+ ## Generated Module API
136
+
137
+ Each generated module provides:
138
+
139
+ ### State Properties
140
+
141
+ | Property | Type | Description |
142
+ |----------|------|-------------|
143
+ | `loading` | `$state<boolean>` | Request loading state |
144
+ | `list` | `$state<T[]>` | List results (for list endpoints) |
145
+ | `forms` | `$state<Record<string, T>>` | Form instances |
146
+ | `querys` | `Querys` | Query parameter state (QueryBuilder instances) |
147
+ | `headers` | `Headers` | Header state |
148
+ | `paths` | `Paths` | Path parameter state |
149
+
150
+ ### Methods
151
+
152
+ ```typescript
153
+ // List all items (GET with page parameter)
154
+ async listAll(params?: { behavior?: Behavior }): Promise<T[]>
155
+
156
+ // Get single entity (GET without page parameter)
157
+ async get(params?: { behavior?: Behavior }): Promise<T>
158
+
159
+ // Create/Update (POST/PUT/PATCH)
160
+ async create(params?: { behavior?: Behavior }): Promise<T>
161
+ async update(params?: { behavior?: Behavior }): Promise<T>
162
+
163
+ // Delete (DELETE)
164
+ async delete(params?: { behavior?: Behavior }): Promise<void>
165
+
166
+ // Reset all state
167
+ reset(): void
168
+
169
+ // Clear forms
170
+ clearForms(): void
171
+ ```
172
+
173
+ ### QueryBuilder
174
+
175
+ Query parameters are wrapped in `QueryBuilder` instances that sync with URL searchParams:
176
+
177
+ ```typescript
178
+ // Single value query parameter
179
+ const querys = module.querys;
180
+ querys.status.update("active"); // Updates URL searchParam and internal state
181
+
182
+ // Array enum query parameter
183
+ const enumQuery = module.querys.roles; // EnumQueryBuilder<RoleType>
184
+ enumQuery.selected = "admin";
185
+ enumQuery.add(); // Adds to URL searchParams
186
+ enumQuery.remove(0); // Removes from URL searchParams
187
+ enumQuery.values; // $derived from URL - always in sync
188
+ ```
189
+
190
+ ## Configuration
191
+
192
+ ### Environment Variables
193
+
194
+ | Variable | Required | Description |
195
+ |----------|----------|-------------|
196
+ | `BACKEND_URL` | Yes | Backend API URL |
197
+ | `PUBLIC_BACKEND` | Yes | Alternative to BACKEND_URL |
198
+ | `ENVIRONMENT` | No | DEV/PROD (defaults to PROD) |
199
+ | `VITE_ENVIRONMENT` | No | Vite-specific env var |
200
+ | `NODE_ENV` | No | Node environment |
201
+
202
+ ### Behavior Pattern
203
+
204
+ All API methods accept a `Behavior` object for callbacks:
205
+
206
+ ```typescript
207
+ interface Behavior<TSuccess, TError> {
208
+ onSuccess?: (value: TSuccess) => Promise<void> | void;
209
+ onError?: (error: TError) => Promise<void> | void;
210
+ }
211
+
212
+ // Usage
213
+ await userModule.createUser({
214
+ behavior: {
215
+ onSuccess: (user) => console.log("Created:", user),
216
+ onError: (err) => console.error("Failed:", err),
217
+ },
218
+ });
219
+ ```
220
+
221
+ ### Form Validation
222
+
223
+ Forms use `BuildedInput` class with validation:
224
+
225
+ ```typescript
226
+ class BuildedInput<T> {
227
+ value: T; // Current value ($state)
228
+ display: T; // Display value ($state)
229
+ required: boolean; // Is field required
230
+ placeholder: T; // Placeholder/example value
231
+ readonly kind: 'builded';
232
+ validator?: (v: T) => string | null; // Validation function
233
+ validate(): string | null; // Run validation
234
+ }
235
+
236
+ // Check if all form fields are valid
237
+ import { isFormValid } from "$reflector/reflector.svelte";
238
+
239
+ if (isFormValid(userModule.forms.createUser)) {
240
+ await userModule.createUser();
241
+ }
242
+ ```
243
+
244
+ ## TypeScript Configuration
245
+
246
+ Add path aliases to your `tsconfig.json`:
247
+
248
+ ```json
249
+ {
250
+ "compilerOptions": {
251
+ "paths": {
252
+ "$reflector/*": ["./src/reflector/*"],
253
+ "$lib/*": ["./src/lib/*"]
254
+ }
255
+ }
256
+ }
257
+ ```
258
+
259
+ For Vite projects, also update `vite.config.ts`:
260
+
261
+ ```typescript
262
+ export default defineConfig({
263
+ resolve: {
264
+ alias: {
265
+ $reflector: path.resolve("./src/reflector"),
266
+ $lib: path.resolve("./src/lib"),
267
+ },
268
+ },
269
+ });
270
+ ```
271
+
272
+ ## Workflow
273
+
274
+ ### Development Mode
275
+
276
+ In `ENVIRONMENT=DEV`:
277
+ - Schemas are **NOT** auto-regenerated on build
278
+ - Use `npx reflect` to manually regenerate
279
+ - Faster builds, manual control
280
+
281
+ ### Production Mode
282
+
283
+ In `ENVIRONMENT=PROD`:
284
+ - Schemas are auto-regenerated on each build
285
+ - Fresh types from latest OpenAPI spec
286
+ - Fallback to `backup.json` if backend is unavailable
287
+
288
+ ## Advanced Usage
289
+
290
+ ### Custom Validators
291
+
292
+ Define validators in `src/reflector.config.ts`:
293
+
294
+ ```typescript
295
+ export const validators = [
296
+ {
297
+ fields: ["email", "userEmail", "contactEmail"],
298
+ validator: "validateEmail",
299
+ },
300
+ {
301
+ fields: ["phone", "mobile", "whatsapp"],
302
+ validator: "validatePhone",
303
+ },
304
+ {
305
+ fields: ["cpf", "cnpj", "document"],
306
+ validator: "validateDocument",
307
+ },
308
+ {
309
+ fields: ["password", "newPassword"],
310
+ validator: "validatePassword",
311
+ },
312
+ {
313
+ fields: ["birthDate", "startDate", "endDate"],
314
+ validator: "validateDate",
315
+ },
316
+ {
317
+ fields: ["zipcode", "cep"],
318
+ validator: "validateZipcode",
319
+ },
320
+ {
321
+ fields: ["url", "website", "avatarUrl"],
322
+ validator: "validateUrl",
323
+ },
324
+ ];
325
+ ```
326
+
327
+ Then implement in your app at `$lib/sanitizers/validateFormats.ts`:
328
+
329
+ ```typescript
330
+ // Email validation
331
+ export function validateEmail(value: string): string | null {
332
+ if (!value) return null; // Let required handle empty
333
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
334
+ return emailRegex.test(value) ? null : "Invalid email format";
335
+ }
336
+
337
+ // Phone validation
338
+ export function validatePhone(value: string): string | null {
339
+ if (!value) return null;
340
+ const phoneRegex = /^(\+?55\s?)?(\(?\d{2}\)?\s?)?(\d{4,5}-?\d{4})$/;
341
+ return phoneRegex.test(value) ? null : "Invalid phone number";
342
+ }
343
+
344
+ // CPF/CNPJ validation (Brazilian documents)
345
+ export function validateDocument(value: string): string | null {
346
+ if (!value) return null;
347
+ const cleaned = value.replace(/\D/g, '');
348
+
349
+ if (cleaned.length === 11) {
350
+ return validateCPF(cleaned) ? null : "Invalid CPF";
351
+ } else if (cleaned.length === 14) {
352
+ return validateCNPJ(cleaned) ? null : "Invalid CNPJ";
353
+ }
354
+ return "Invalid document format";
355
+ }
356
+
357
+ function validateCPF(cpf: string): boolean {
358
+ if (/^(\d)\1{10}$/.test(cpf)) return false;
359
+
360
+ let sum = 0;
361
+ for (let i = 0; i < 9; i++) sum += parseInt(cpf[i]) * (10 - i);
362
+ let rev = 11 - (sum % 11);
363
+ if (rev === 10 || rev === 11) rev = 0;
364
+ if (rev !== parseInt(cpf[9])) return false;
365
+
366
+ sum = 0;
367
+ for (let i = 0; i < 10; i++) sum += parseInt(cpf[i]) * (11 - i);
368
+ rev = 11 - (sum % 11);
369
+ if (rev === 10 || rev === 11) rev = 0;
370
+ return rev === parseInt(cpf[10]);
371
+ }
372
+
373
+ function validateCNPJ(cnpj: string): boolean {
374
+ if (/^(\d)\1{13}$/.test(cnpj)) return false;
375
+
376
+ const weights1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
377
+ const weights2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
378
+
379
+ let sum = 0;
380
+ for (let i = 0; i < 12; i++) sum += parseInt(cnpj[i]) * weights1[i];
381
+ let rev = sum % 11 < 2 ? 0 : 11 - (sum % 11);
382
+ if (rev !== parseInt(cnpj[12])) return false;
383
+
384
+ sum = 0;
385
+ for (let i = 0; i < 13; i++) sum += parseInt(cnpj[i]) * weights2[i];
386
+ rev = sum % 11 < 2 ? 0 : 11 - (sum % 11);
387
+ return rev === parseInt(cnpj[13]);
388
+ }
389
+
390
+ // Password strength validation
391
+ export function validatePassword(value: string): string | null {
392
+ if (!value) return null;
393
+ if (value.length < 8) return "Password must be at least 8 characters";
394
+ if (!/[A-Z]/.test(value)) return "Password must contain an uppercase letter";
395
+ if (!/[a-z]/.test(value)) return "Password must contain a lowercase letter";
396
+ if (!/[0-9]/.test(value)) return "Password must contain a number";
397
+ if (!/[!@#$%^&*]/.test(value)) return "Password must contain a special character";
398
+ return null;
399
+ }
400
+
401
+ // Date validation
402
+ export function validateDate(value: string): string | null {
403
+ if (!value) return null;
404
+ const date = new Date(value);
405
+ if (isNaN(date.getTime())) return "Invalid date";
406
+ if (date > new Date()) return "Date cannot be in the future";
407
+ return null;
408
+ }
409
+
410
+ // Brazilian ZIP code (CEP) validation
411
+ export function validateZipcode(value: string): string | null {
412
+ if (!value) return null;
413
+ const cepRegex = /^\d{5}-?\d{3}$/;
414
+ return cepRegex.test(value) ? null : "Invalid ZIP code format";
415
+ }
416
+
417
+ // URL validation
418
+ export function validateUrl(value: string): string | null {
419
+ if (!value) return null;
420
+ try {
421
+ new URL(value);
422
+ return null;
423
+ } catch {
424
+ return "Invalid URL format";
425
+ }
426
+ }
427
+
428
+ // Min/max length validator factory
429
+ export function minLength(min: number) {
430
+ return (value: string): string | null => {
431
+ if (!value) return null;
432
+ return value.length >= min ? null : `Must be at least ${min} characters`;
433
+ };
434
+ }
435
+
436
+ export function maxLength(max: number) {
437
+ return (value: string): string | null => {
438
+ if (!value) return null;
439
+ return value.length <= max ? null : `Must be at most ${max} characters`;
440
+ };
441
+ }
442
+
443
+ // Number range validator factory
444
+ export function numberRange(min: number, max: number) {
445
+ return (value: number): string | null => {
446
+ if (value === null || value === undefined) return null;
447
+ return value >= min && value <= max ? null : `Must be between ${min} and ${max}`;
448
+ };
449
+ }
450
+
451
+ // Required field validator
452
+ export function required(value: string | number | boolean | null): string | null {
453
+ if (value === null || value === undefined || value === '') {
454
+ return "This field is required";
455
+ }
456
+ return null;
457
+ }
458
+ ```
459
+
460
+ ### Manual Schema Access
461
+
462
+ ```typescript
463
+ import { User } from "$reflector/schemas.svelte";
464
+
465
+ // Create instance
466
+ const user = new User({ name: "John", email: "john@example.com" });
467
+
468
+ // Get data bundle
469
+ const data = user.bundle(); // { name: "John", email: "john@example.com" }
470
+ ```
471
+
472
+ ### Batch Query Updates
473
+
474
+ ```typescript
475
+ import { setQueryGroup } from "$reflector/reflector.svelte";
476
+
477
+ // Update multiple query params at once
478
+ setQueryGroup([
479
+ { key: "page", value: 1 },
480
+ { key: "status", value: "active" },
481
+ { key: "roles", value: ["admin", "editor"] }, // Array params supported
482
+ ]);
483
+ ```
484
+
485
+ ## Troubleshooting
486
+
487
+ ### "BACKEND_URL vazio" Error
488
+
489
+ Ensure you have set `BACKEND_URL` or `PUBLIC_BACKEND` in your `.env` file.
490
+
491
+ ### Schemas Not Updating
492
+
493
+ In DEV mode, run `npx reflect` manually. Check that your backend's OpenAPI spec is accessible at `{BACKEND_URL}openapi.json`.
494
+
495
+ ### Type Errors After Generation
496
+
497
+ 1. Restart your TypeScript language server
498
+ 2. Check path aliases in `tsconfig.json`
499
+ 3. Ensure `$reflector/*` alias is configured
500
+
501
+ ## License
502
+
503
+ MIT License - see [LICENSE](LICENSE) for details.
504
+
505
+ ## Contributing
506
+
507
+ Contributions are welcome! Please feel free to submit a Pull Request.
508
+
509
+ ## Links
510
+
511
+ - [npm](https://www.npmjs.com/package/svelte-reflector)
512
+ - [GitHub](https://github.com/aleleppy/reflector)
513
+ - [Svelte](https://svelte.dev/)
514
+ - [OpenAPI Specification](https://swagger.io/specification/)
515
+
516
+ ---
517
+
518
+ Built with by the Pináculo Digital team.