svelte-reflector 1.0.7 → 1.0.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.
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;
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
  }
@@ -60,7 +62,8 @@ export class Method {
60
62
  return `
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,7 +73,8 @@ export class Method {
70
73
  return `
71
74
  ${afterResponse.join(";")}
72
75
  const response = await repo.api.get<${this.request.responseType}, unknown>({
73
- endpoint: this.endpoint, ${query}
76
+ endpoint,
77
+ ${query}
74
78
  })
75
79
  ${beforeResponse.join(";")}
76
80
  `;
@@ -85,7 +89,7 @@ export class Method {
85
89
  ${data}
86
90
 
87
91
  const response = await repo.api.post<${this.request.responseType}>({
88
- endpoint: this.endpoint,
92
+ endpoint,
89
93
  ${data ? "data" : ""}
90
94
  })
91
95
  `;
@@ -97,7 +101,8 @@ export class Method {
97
101
  ${propsString}
98
102
 
99
103
  const response = await repo.api.delete<${this.request.responseType ?? "null"}, unknown>({
100
- endpoint: this.endpoint, ${query}
104
+ endpoint,
105
+ ${query}
101
106
  })
102
107
 
103
108
  this.clearEntity()
@@ -110,34 +115,22 @@ export class Method {
110
115
  }
111
116
  build() {
112
117
  const content = this.buildCallMethod();
113
- if (!content)
118
+ if (!content) {
119
+ createDangerMessage(`Método ${this.name} (${this.request.apiType}) não foi gerado: buildCallMethod vazio`);
114
120
  return;
121
+ }
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)}"
141
134
 
142
135
  try{
143
136
  ${content}
@@ -149,8 +142,6 @@ export class Method {
149
142
  onError?.()
150
143
  }
151
144
  }
152
-
153
- ${additionalMethod}
154
145
  `;
155
146
  }
156
147
  }
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();
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() {
@@ -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.8",
4
4
  "description": "Reflects zod types from openAPI schemas",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",