svelte-reflector 1.0.7 → 1.0.9

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/file.d.ts CHANGED
@@ -8,5 +8,5 @@ export declare class Source {
8
8
  save(): Promise<void>;
9
9
  safeSave(): Promise<void>;
10
10
  changeData(data: string): Promise<void>;
11
- buildPath(endpoint: string[]): string;
11
+ buildPath(endpoint: string[]): string | undefined;
12
12
  }
@@ -1,8 +1,8 @@
1
1
  // src/generate-doc.ts
2
2
  import "dotenv/config"; // carrega .env a partir de process.cwd()
3
3
  import axios from "axios";
4
- import fs from "node:fs";
5
- import path from "node:path";
4
+ import * as path from "node:path";
5
+ import * as fs from "node:fs";
6
6
  import { Reflector } from "./main.js";
7
7
  /** ajuda a pegar a 1ª env definida dentre várias chaves possíveis */
8
8
  function pickEnv(...keys) {
@@ -1,4 +1,3 @@
1
- export declare function stripState(attr: string): string;
2
1
  export declare function toCamelCase(str: string): string;
3
2
  export declare function sanitizeKey(name: string): string;
4
3
  export declare function sanitizeNumber(texto: string): string;
@@ -6,6 +5,7 @@ export declare function capitalizeFirstLetter(text: string): string;
6
5
  export declare function splitByUppercase(text: string): string[];
7
6
  export declare function createDangerMessage(text: string): void;
8
7
  export declare function getEndpointAndModuleName(rawEndpoint: string): {
9
- endpoint: string;
8
+ baseEndpoint: string;
10
9
  moduleName: string;
11
10
  };
11
+ export declare function getEndpoint(rawEndpoint: string): string;
@@ -1,21 +1,22 @@
1
- export function stripState(attr) {
2
- // Ex.: "form = $state(newForm(DefaultCreateUserDtoSchema))"
3
- const [lhs, rhsRaw = ""] = attr.split("=");
4
- const rhs = rhsRaw.trim();
5
- // remove apenas UM wrapper $state( ... ) do início ao fim
6
- const cleaned = rhs.startsWith("$state(") && rhs.endsWith(")") ? rhs.slice("$state(".length, -1).trim() : rhs;
7
- return `${lhs.trim()} = ${cleaned}`;
8
- }
1
+ // export function stripState(attr: string): string {
2
+ // // Ex.: "form = $state(newForm(DefaultCreateUserDtoSchema))"
3
+ // const [lhs, rhsRaw = ""] = attr.split("=");
4
+ // const rhs = rhsRaw.trim();
5
+ // // remove apenas UM wrapper $state( ... ) do início ao fim
6
+ // const cleaned = rhs.startsWith("$state(") && rhs.endsWith(")") ? rhs.slice("$state(".length, -1).trim() : rhs;
7
+ // if (!lhs) return "";
8
+ // return `${lhs.trim()} = ${cleaned}`;
9
+ // }
9
10
  export function toCamelCase(str) {
10
11
  return str
11
12
  .split("-")
12
- .map((chunk, i) => (i === 0 ? chunk : chunk[0].toUpperCase() + chunk.slice(1)))
13
+ .map((chunk, i) => (i === 0 ? chunk : chunk.charAt(0).toUpperCase() + chunk.slice(1)))
13
14
  .join("");
14
15
  }
15
16
  export function sanitizeKey(name) {
16
17
  const match = /^\[id(.+)\]$|^\{(.+)\}$/.exec(name);
17
18
  if (match) {
18
- const raw = match[1] || match[2]; // pega o conteúdo entre [] ou {}
19
+ const raw = (match[1] || match[2]) ?? ""; // pega o conteúdo entre [] ou {}
19
20
  const camel = toCamelCase(raw);
20
21
  // Garante que a primeira letra fique minúscula
21
22
  return camel.charAt(0).toLowerCase() + camel.slice(1);
@@ -36,10 +37,18 @@ export function splitByUppercase(text) {
36
37
  export function createDangerMessage(text) {
37
38
  console.log("\x1b[31m%s\x1b[0m", `[!] ${text}`);
38
39
  }
39
- export function getEndpointAndModuleName(rawEndpoint) {
40
+ function getFilteredEntities(rawEndpoint) {
40
41
  const splittedEntitys = rawEndpoint.split("/");
41
- const filteredEntitys = splittedEntitys.filter((item) => item !== "" && !item.includes("{"));
42
+ return splittedEntitys.filter((item) => item !== "" && !item.includes("{"));
43
+ }
44
+ export function getEndpointAndModuleName(rawEndpoint) {
45
+ const filteredEntitys = getFilteredEntities(rawEndpoint);
46
+ // console.log(filteredEntitys);
42
47
  const moduleName = filteredEntitys.map((x) => sanitizeKey(capitalizeFirstLetter(x))).join("");
43
- const endpoint = filteredEntitys.join("/");
44
- return { endpoint, moduleName };
48
+ const baseEndpoint = filteredEntitys.join("/");
49
+ return { baseEndpoint: getEndpoint(baseEndpoint), moduleName };
50
+ }
51
+ export function getEndpoint(rawEndpoint) {
52
+ const filteredEntitys = getFilteredEntities(rawEndpoint);
53
+ return filteredEntitys.join("/");
45
54
  }
package/dist/main.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Source } from "./file.js";
2
2
  import { Schema } from "./schema.js";
3
- import { ComponentsObject, PathsObject, OpenAPIObject } from "./types/open-api-spec.interface.js";
3
+ import type { ComponentsObject, PathsObject, OpenAPIObject } from "./types/open-api-spec.interface.js";
4
4
  import { Module } from "./module.js";
5
5
  export declare class Reflector {
6
6
  readonly components: ComponentsObject;
package/dist/main.js CHANGED
@@ -1,10 +1,10 @@
1
- import path from "node:path";
2
- import fs from "node:fs";
1
+ import * as path from "node:path";
2
+ import * as fs from "node:fs";
3
3
  import { Source } from "./file.js";
4
- import { getEndpointAndModuleName, splitByUppercase } from "./helpers/helpers.js";
4
+ import { getEndpoint, getEndpointAndModuleName, splitByUppercase } from "./helpers/helpers.js";
5
5
  import { Schema } from "./schema.js";
6
6
  import { Module } from "./module.js";
7
- const methods = ["get", "patch", "post", "put", "delete"];
7
+ // const defaultMethods = ["get", "patch", "post", "put", "delete"] as const;
8
8
  export class Reflector {
9
9
  components;
10
10
  paths;
@@ -46,39 +46,37 @@ export class Reflector {
46
46
  }
47
47
  getModules() {
48
48
  const methodsMap = new Map();
49
- const modules = [];
50
- for (const [rawEndpoint, object] of Object.entries(this.paths)) {
51
- let entity;
52
- const operations = [];
53
- const { endpoint, moduleName } = getEndpointAndModuleName(rawEndpoint);
54
- for (const method of methods) {
55
- if (!object[method])
56
- continue;
57
- operations.push({ ...object[method], apiMethod: method });
58
- if (!entity) {
59
- const teste = object[method].operationId.split("_")[0];
60
- const x = splitByUppercase(teste);
61
- const aaa = x.filter((y) => y !== "Controller");
62
- entity = aaa.join("");
63
- }
64
- }
65
- if (!entity)
66
- continue;
67
- const existingOps = methodsMap.get(entity);
68
- if (existingOps) {
69
- existingOps.operations.push(...operations);
49
+ for (const [path, methods] of Object.entries(this.paths)) {
50
+ const rawName = Object.values(methods)[0];
51
+ const a = rawName.operationId?.split("_")[0] ?? "";
52
+ const teste = splitByUppercase(a).filter((x) => x !== "Controller");
53
+ const moduleName = teste.join("");
54
+ const baseEndpoint = getEndpoint(path);
55
+ const operations = Object.entries(methods).map(([apiMethod, attributes]) => {
56
+ return {
57
+ apiMethod,
58
+ endpoint: path,
59
+ ...attributes,
60
+ };
61
+ });
62
+ const existentModule = methodsMap.get(moduleName);
63
+ if (existentModule) {
64
+ methodsMap.set(moduleName, {
65
+ ...existentModule,
66
+ operations: [...existentModule.operations, ...operations],
67
+ });
70
68
  }
71
69
  else {
72
- methodsMap.set(entity, { endpoint, operations, moduleName });
70
+ methodsMap.set(moduleName, { operations, path: baseEndpoint, moduleName });
73
71
  }
74
72
  }
75
- for (const [name, info] of methodsMap) {
76
- modules.push(new Module({
73
+ const modules = Array.from(methodsMap).map(([name, info]) => {
74
+ return new Module({
77
75
  name,
78
76
  ...info,
79
77
  dir: this.generatedDir,
80
- }));
81
- }
78
+ });
79
+ });
82
80
  return modules;
83
81
  }
84
82
  build() {
package/dist/method.d.ts CHANGED
@@ -4,7 +4,8 @@ import type { ReflectorOperation } from "./types/types.js";
4
4
  export declare class Method {
5
5
  name: string;
6
6
  zodProperties: ZodProperty[];
7
- description?: string;
7
+ description: string | undefined;
8
+ endpoint: string;
8
9
  request: Request;
9
10
  constructor(params: {
10
11
  operation: ReflectorOperation;
@@ -13,5 +14,5 @@ export declare class Method {
13
14
  private getParams;
14
15
  private buildCallMethod;
15
16
  private buildDescription;
16
- build(): string | undefined;
17
+ build(): string;
17
18
  }
package/dist/method.js CHANGED
@@ -1,15 +1,17 @@
1
1
  import { Request } from "./request.js";
2
2
  import { ZodProperty } from "./property.js";
3
- import { createDangerMessage } from "./helpers/helpers.js";
3
+ import { createDangerMessage, getEndpoint } from "./helpers/helpers.js";
4
4
  export class Method {
5
5
  name;
6
6
  zodProperties;
7
7
  description;
8
+ endpoint;
8
9
  request;
9
10
  constructor(params) {
10
11
  const { operation } = params;
11
12
  this.request = new Request(operation);
12
13
  this.description = operation.description ?? operation.summary;
14
+ this.endpoint = operation.endpoint;
13
15
  this.name = operation.operationId?.split("_")[1] ?? this.request.apiType;
14
16
  const { parameters } = this.getParams(params);
15
17
  this.zodProperties = parameters;
@@ -33,7 +35,7 @@ export class Method {
33
35
  example: schema.default,
34
36
  schemaObject: schema,
35
37
  type: schema.type,
36
- description,
38
+ description: description ?? "",
37
39
  required: required || true,
38
40
  }));
39
41
  }
@@ -57,23 +59,27 @@ export class Method {
57
59
  }
58
60
  if (this.request.attributeType === "list") {
59
61
  beforeResponse.push(`const {data: { data }, ...params} = response`, "\n\n", `this.list = data`, `repo.intercept.rebuild(this.parameters, params)`);
60
- return `
62
+ const inside = `
61
63
  ${afterResponse.join(";")}
62
64
  const response = await repo.api.get<{data: ${this.request.responseType}}, unknown>({
63
- endpoint: this.endpoint, ${query}
65
+ endpoint,
66
+ ${query}
64
67
  })
65
68
  ${beforeResponse.join(";")}
66
69
  `;
70
+ return { inside, outside: "" };
67
71
  }
68
72
  else if (this.request.attributeType === "entity") {
69
73
  beforeResponse.push(`this.entity = response`);
70
- return `
74
+ const inside = `
71
75
  ${afterResponse.join(";")}
72
76
  const response = await repo.api.get<${this.request.responseType}, unknown>({
73
- endpoint: this.endpoint, ${query}
77
+ endpoint,
78
+ ${query}
74
79
  })
75
80
  ${beforeResponse.join(";")}
76
81
  `;
82
+ return { inside, outside: "" };
77
83
  }
78
84
  }
79
85
  else if (this.request.apiType === "post" || this.request.apiType === "put" || this.request.apiType === "patch") {
@@ -81,66 +87,55 @@ export class Method {
81
87
  if (this.request.bodyType) {
82
88
  data = `const data = repo.intercept.bundle(this.forms.${this.name})`;
83
89
  }
84
- return `
85
- ${data}
86
-
90
+ const outside = ["this.loading = true", data].join("\n");
91
+ const inside = `
87
92
  const response = await repo.api.post<${this.request.responseType}>({
88
- endpoint: this.endpoint,
89
- ${data ? "data" : ""}
93
+ endpoint,
94
+ data
90
95
  })
91
96
  `;
97
+ return { outside, inside };
92
98
  }
93
99
  else if (this.request.apiType === "delete") {
94
100
  const props = this.zodProperties.map((x) => x.name).join(",");
95
101
  const propsString = props.length > 0 ? `const {${props}} = this.parameters` : "";
96
- return `
102
+ const inside = `
97
103
  ${propsString}
98
104
 
99
105
  const response = await repo.api.delete<${this.request.responseType ?? "null"}, unknown>({
100
- endpoint: this.endpoint, ${query}
106
+ endpoint,
107
+ ${query}
101
108
  })
102
109
 
103
110
  this.clearEntity()
104
111
  `;
112
+ const outside = "";
113
+ return { inside, outside };
105
114
  }
106
- return "";
115
+ return { inside: "", outside: "" };
107
116
  }
108
117
  buildDescription() {
109
118
  return `/** ${this.description ?? ""} */`;
110
119
  }
111
120
  build() {
112
- const content = this.buildCallMethod();
113
- if (!content)
114
- return;
121
+ const { inside, outside } = this.buildCallMethod();
115
122
  if (this.name === "list")
116
123
  this.name = "listAll";
117
124
  const hasProprierties = this.zodProperties.length > 0;
118
125
  if (!hasProprierties && this.request.apiType === "delete") {
119
126
  createDangerMessage(`${this.name} não vai funcionar, pois não aceita parâmetros na requisição.`);
120
127
  }
121
- let additionalMethod = "";
122
128
  const description = this.buildDescription();
123
- if (this.request.apiType === "post") {
124
- additionalMethod = `
125
- /** Limpa a entity depois de ser criada com sucesso */
126
- async ${this.name}AndClear(behavior: Behavior = new Behavior()) {
127
- const data = await this.${this.name}(behavior)
128
-
129
- if(data) {
130
- this.clearEntity()
131
- }
132
-
133
- return data
134
- }
135
- `;
136
- }
137
129
  return `
138
130
  ${description}
139
131
  async ${this.name}(behavior: Behavior = new Behavior()) {
140
132
  const {onError, onSuccess} = behavior
133
+ const endpoint = "${getEndpoint(this.endpoint)}"
134
+
135
+ ${outside}
141
136
 
142
137
  try{
143
- ${content}
138
+ ${inside}
144
139
  onSuccess?.()
145
140
 
146
141
  return response
@@ -148,9 +143,9 @@ export class Method {
148
143
  } catch(e) {
149
144
  onError?.()
150
145
  }
146
+
147
+ this.loading = false
151
148
  }
152
-
153
- ${additionalMethod}
154
149
  `;
155
150
  }
156
151
  }
package/dist/module.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { Source } from "./file.js";
2
2
  import { Method } from "./method.js";
3
- import { ReflectorOperation } from "./types/types.js";
3
+ import type { ReflectorOperation } from "./types/types.js";
4
4
  export declare class Module {
5
5
  readonly name: string;
6
- readonly endpoint: string;
6
+ readonly path: string;
7
7
  readonly moduleName: string;
8
8
  readonly src: Source;
9
9
  imports: Set<string>;
@@ -13,11 +13,12 @@ export declare class Module {
13
13
  name: string;
14
14
  moduleName: string;
15
15
  operations: ReflectorOperation[];
16
- endpoint: string;
16
+ path: string;
17
17
  dir: string;
18
18
  });
19
19
  private creator;
20
20
  private getPath;
21
+ private getAdditionalMethod;
21
22
  private buildMethods;
22
23
  private getParameters;
23
24
  private buildImports;
package/dist/module.js CHANGED
@@ -1,18 +1,18 @@
1
- import path from "node:path";
2
- import fs from "node:fs";
1
+ import * as path from "node:path";
2
+ import * as fs from "node:fs";
3
3
  import { Source } from "./file.js";
4
4
  import { capitalizeFirstLetter, createDangerMessage } from "./helpers/helpers.js";
5
5
  import { Method } from "./method.js";
6
6
  export class Module {
7
7
  name;
8
- endpoint;
8
+ path;
9
9
  moduleName;
10
10
  src;
11
11
  imports;
12
12
  parameters;
13
13
  methods;
14
14
  constructor(params) {
15
- const { name, operations, endpoint, dir, moduleName } = params;
15
+ const { name, operations, path, dir, moduleName } = params;
16
16
  this.moduleName = moduleName;
17
17
  this.imports = new Set([
18
18
  "// AUTO GERADO. QUEM ALTERAR GOSTA DE RAPAZES!\n",
@@ -20,7 +20,7 @@ export class Module {
20
20
  'import { Behavior } from "$reflector/reflector.types";',
21
21
  ]);
22
22
  this.name = capitalizeFirstLetter(name);
23
- this.endpoint = endpoint;
23
+ this.path = path;
24
24
  const methods = operations.map((operation) => {
25
25
  return new Method({
26
26
  operation,
@@ -48,7 +48,7 @@ export class Module {
48
48
  }
49
49
  creator() {
50
50
  const buildedModuleTypes = [];
51
- const moduleAttributes = new Set([`endpoint = '${this.endpoint}'`]);
51
+ const moduleAttributes = new Set().add("loading = $state<boolean>(false)");
52
52
  const moduleInit = new Set([]);
53
53
  const moduleClear = new Set([]);
54
54
  if (this.parameters.length > 0) {
@@ -105,15 +105,38 @@ export class Module {
105
105
  };
106
106
  }
107
107
  getPath(dir) {
108
- const fileName = this.endpoint.split("/").slice(-2).join("-");
109
- const inPath = path.join(dir, this.endpoint);
108
+ const fileName = this.path.split("/").slice(-2).join("-");
109
+ const inPath = path.join(dir, this.path);
110
110
  const outPath = path.join(inPath, `${fileName.toLowerCase()}.module.svelte.ts`);
111
111
  fs.mkdirSync(inPath, { recursive: true });
112
112
  return outPath;
113
113
  }
114
+ getAdditionalMethod(params) {
115
+ const { method, canAddClearMethod } = params;
116
+ let additionalMethod = "";
117
+ if (canAddClearMethod && method.request.attributeType === "form") {
118
+ additionalMethod = `
119
+ /** Limpa o form depois do back retornar uma resposta de sucesso */
120
+ async ${method.name}AndClear(behavior: Behavior = new Behavior()) {
121
+ const data = await this.${method.name}(behavior)
122
+
123
+ if (data) {
124
+ this.clearForms()
125
+ }
126
+
127
+ return data
128
+ }
129
+ `;
130
+ }
131
+ return additionalMethod;
132
+ }
114
133
  buildMethods() {
134
+ const hasForm = this.methods.some((m) => m.request.attributeType === "form");
135
+ const hasEntity = this.methods.some((m) => m.request.attributeType === "entity");
136
+ const canAddClearMethod = hasForm && hasEntity;
115
137
  return this.methods.map((method) => {
116
- return method.build();
138
+ let additionalMethod = this.getAdditionalMethod({ canAddClearMethod, method });
139
+ return [method.build(), additionalMethod].join("\n");
117
140
  });
118
141
  }
119
142
  getParameters() {
@@ -152,7 +175,7 @@ export class Module {
152
175
 
153
176
  ${moduleClear.join("\n\n")}
154
177
 
155
- clearAll() {
178
+ reset() {
156
179
  ${moduleInit.join(";")}
157
180
  }
158
181
  }
@@ -1,11 +1,11 @@
1
- import { SchemaObject } from "./types/open-api-spec.interface.js";
2
- import { Example, ReflectorParamType } from "./types/types.js";
1
+ import { type SchemaObject } from "./types/open-api-spec.interface.js";
2
+ import { type Example, type ReflectorParamType } from "./types/types.js";
3
3
  export declare class ZodProperty {
4
4
  name: string;
5
- example: Example;
5
+ example: Example | undefined;
6
6
  type: ReflectorParamType;
7
7
  buildedProp: string;
8
- description: string;
8
+ description?: string;
9
9
  required: boolean;
10
10
  constructor(params: {
11
11
  name: string;
package/dist/property.js CHANGED
@@ -1,21 +1,25 @@
1
1
  import { sanitizeNumber } from "./helpers/helpers.js";
2
2
  import { ReflectorInput } from "./helpers/input.js";
3
+ import {} from "./types/open-api-spec.interface.js";
4
+ import {} from "./types/types.js";
3
5
  const inputs = new ReflectorInput();
4
6
  export class ZodProperty {
5
7
  name;
6
8
  example;
7
9
  type;
8
10
  buildedProp;
9
- description = "";
11
+ description;
10
12
  required;
11
13
  constructor(params) {
12
- const { name, schemaObject, type, example, required } = params;
14
+ const { name, schemaObject, type, example, required, description } = params;
13
15
  const realExample = example ?? schemaObject.example;
14
16
  this.required = required;
15
17
  this.name = name;
16
18
  this.type = type;
17
19
  this.example = this.getExample(realExample);
18
20
  this.buildedProp = this.build(schemaObject);
21
+ if (description)
22
+ this.description = description;
19
23
  }
20
24
  getDtoName(ref) {
21
25
  const cavalos = ref.split("/");
package/dist/request.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ApiType, ReflectorOperation } from "./types/types.js";
1
+ import type { ApiType, ReflectorOperation } from "./types/types.js";
2
2
  type ReflectorRequestType = "entity" | "list" | "pagination" | "form" | "other";
3
3
  export declare class Request {
4
4
  readonly attributeType: ReflectorRequestType;
package/dist/request.js CHANGED
@@ -8,8 +8,12 @@ export class Request {
8
8
  responseType;
9
9
  constructor(operation) {
10
10
  this.apiType = operation.apiMethod;
11
- this.bodyType = this.getTypeFromRequestBody(operation.requestBody);
12
- this.responseType = this.getTypeFromResponses(operation.responses);
11
+ const body = this.getTypeFromRequestBody(operation.requestBody);
12
+ if (body)
13
+ this.bodyType = body;
14
+ const response = this.getTypeFromResponses(operation.responses);
15
+ if (response)
16
+ this.responseType = response;
13
17
  this.attributeType = this.inferAttributeType(operation) ?? "other";
14
18
  }
15
19
  // ============= Derivações principais =======================================
@@ -102,9 +106,9 @@ export class Request {
102
106
  * Se `data` não existir ou não tiver tipo, retorna undefined.
103
107
  */
104
108
  typeFromProperties(properties) {
105
- if (!properties)
109
+ if (!properties?.["data"])
106
110
  return undefined;
107
- const data = properties.data;
111
+ const data = properties["data"];
108
112
  if (isRef(data))
109
113
  return this.componentName(data);
110
114
  if (data.type === "any")
package/dist/schema.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ZodProperty } from "./property.js";
2
- import { SchemaObject, ReferenceObject } from "./types/open-api-spec.interface.js";
2
+ import type { SchemaObject, ReferenceObject } from "./types/open-api-spec.interface.js";
3
3
  export declare class Schema {
4
4
  name: string;
5
5
  properties: ZodProperty[];
@@ -1,11 +1,12 @@
1
- import { OperationObject } from "./open-api-spec.interface.js";
1
+ import type { OperationObject } from "./open-api-spec.interface.js";
2
2
  export type ReflectorParamType = "string" | "boolean" | "number" | "array" | "object";
3
3
  export type ApiType = "get" | "post" | "delete" | "patch" | "put";
4
4
  export type ReflectorOperation = OperationObject & {
5
5
  apiMethod: ApiType;
6
+ endpoint: string;
6
7
  };
7
8
  export type Info = {
8
- endpoint: string;
9
+ path: string;
9
10
  operations: ReflectorOperation[];
10
11
  moduleName: string;
11
12
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-reflector",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Reflects zod types from openAPI schemas",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",