svelte-reflector 1.0.1 → 1.0.3

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/cli.js CHANGED
@@ -1,12 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
  import { reflector } from "./generate-doc.js";
3
- // (async () => {
4
- // try {
5
- // console.log("[reflector] Finalizado com sucesso.");
6
- // process.exit(0);
7
- // } catch (err) {
8
- // console.error("[reflector] Falha:", err instanceof Error ? err.message : err);
9
- // process.exit(1);
10
- // }
11
- // })();
12
3
  await reflector(true);
@@ -1,4 +1,4 @@
1
1
  import "dotenv/config";
2
2
  export declare function reflector(manual?: boolean): Promise<{
3
3
  name: string;
4
- } | undefined>;
4
+ }>;
@@ -35,7 +35,6 @@ function getParams() {
35
35
  }
36
36
  export async function reflector(manual = false) {
37
37
  const { BACKEND_URL, ENVIRONMENT } = getParams();
38
- console.warn("opa");
39
38
  if (ENVIRONMENT === "DEV" && !manual) {
40
39
  console.warn("[reflector] Ambiente DEV: para regerar os schemas manualmente, use: npx reflect");
41
40
  return breakReflector();
@@ -54,12 +53,12 @@ export async function reflector(manual = false) {
54
53
  const { components, paths } = data;
55
54
  if (!components) {
56
55
  console.warn("[reflector] OpenAPI sem components; abortando.");
57
- return { name: "vite-plugin-generate-doc" };
56
+ return breakReflector();
58
57
  }
59
58
  const r = new Reflector({ components, paths });
60
59
  r.build();
61
60
  r.localSave(data);
62
- breakReflector();
61
+ return breakReflector();
63
62
  }
64
63
  function breakReflector() {
65
64
  return {
@@ -0,0 +1,11 @@
1
+ export declare function stripState(attr: string): string;
2
+ export declare function toCamelCase(str: string): string;
3
+ export declare function sanitizeKey(name: string): string;
4
+ export declare function sanitizeNumber(texto: string): string;
5
+ export declare function capitalizeFirstLetter(text: string): string;
6
+ export declare function splitByUppercase(text: string): string[];
7
+ export declare function createDangerMessage(text: string): void;
8
+ export declare function getEndpointAndModuleName(rawEndpoint: string): {
9
+ endpoint: string;
10
+ moduleName: string;
11
+ };
@@ -0,0 +1,45 @@
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
+ }
9
+ export function toCamelCase(str) {
10
+ return str
11
+ .split("-")
12
+ .map((chunk, i) => (i === 0 ? chunk : chunk[0].toUpperCase() + chunk.slice(1)))
13
+ .join("");
14
+ }
15
+ export function sanitizeKey(name) {
16
+ const match = /^\[id(.+)\]$|^\{(.+)\}$/.exec(name);
17
+ if (match) {
18
+ const raw = match[1] || match[2]; // pega o conteúdo entre [] ou {}
19
+ const camel = toCamelCase(raw);
20
+ // Garante que a primeira letra fique minúscula
21
+ return camel.charAt(0).toLowerCase() + camel.slice(1);
22
+ }
23
+ return toCamelCase(name);
24
+ }
25
+ export function sanitizeNumber(texto) {
26
+ return texto.replace(/["']/g, "");
27
+ }
28
+ export function capitalizeFirstLetter(text) {
29
+ if (!text)
30
+ return "";
31
+ return text.charAt(0).toUpperCase() + text.slice(1);
32
+ }
33
+ export function splitByUppercase(text) {
34
+ return text.split(/(?=[A-Z])/);
35
+ }
36
+ export function createDangerMessage(text) {
37
+ console.log("\x1b[31m%s\x1b[0m", `[!] ${text}`);
38
+ }
39
+ export function getEndpointAndModuleName(rawEndpoint) {
40
+ const splittedEntitys = rawEndpoint.split("/");
41
+ const filteredEntitys = splittedEntitys.filter((item) => item !== "" && !item.includes("{"));
42
+ const moduleName = filteredEntitys.map((x) => sanitizeKey(capitalizeFirstLetter(x))).join("");
43
+ const endpoint = filteredEntitys.join("/");
44
+ return { endpoint, moduleName };
45
+ }
@@ -0,0 +1,3 @@
1
+ export declare class ReflectorInput {
2
+ password: string;
3
+ }
@@ -0,0 +1,14 @@
1
+ export class ReflectorInput {
2
+ password = `z
3
+ .string()
4
+ .regex(/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,}$/, {
5
+ message: 'A senha deve conter pelo menos ',
6
+ })
7
+ .min(8, { message: '8 caracteres, ' })
8
+ .regex(/[A-Z]/, { message: 'uma letra maiúscula, ' })
9
+ .regex(/[a-z]/, { message: 'uma letra minúscula, ' })
10
+ .regex(/[0-9]/, { message: 'um número, ' })
11
+ .regex(/[^A-Za-z0-9]/, { message: 'um caracter especial.' })
12
+ .default('Senha123!@#')
13
+ `;
14
+ }
package/dist/main.d.ts CHANGED
@@ -18,7 +18,7 @@ export declare class Reflector {
18
18
  paths: PathsObject;
19
19
  });
20
20
  private getSchemas;
21
- getModules(): Module[];
21
+ private getModules;
22
22
  build(): {};
23
23
  localSave(data: OpenAPIObject): void;
24
24
  private clearSrc;
package/dist/main.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import path from "node:path";
2
2
  import fs from "node:fs";
3
3
  import { Source } from "./file.js";
4
- import { sanitizeKey, capitalizeFirstLetter } from "./helpers.js";
4
+ import { 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
8
  export class Reflector {
8
9
  components;
9
10
  paths;
@@ -11,7 +12,7 @@ export class Reflector {
11
12
  generatedDir = `${this.dir}/reflector`;
12
13
  localDoc = new Source({ path: path.resolve(process.cwd(), `${this.dir}/backup.json`) });
13
14
  src = new Source({ path: path.resolve(process.cwd(), this.generatedDir) });
14
- schemaFile = new Source({ path: path.resolve(process.cwd(), `${this.dir}/schemas.ts`) });
15
+ schemaFile = new Source({ path: path.resolve(process.cwd(), `${this.generatedDir}/schemas.ts`) });
15
16
  files;
16
17
  schemas;
17
18
  modules;
@@ -29,16 +30,16 @@ export class Reflector {
29
30
  if (!componentSchemas)
30
31
  return [];
31
32
  const schemas = [];
32
- Object.entries(componentSchemas).forEach(([key, object]) => {
33
+ for (const [key, object] of Object.entries(componentSchemas)) {
33
34
  if ("$ref" in object || !object.properties)
34
- return;
35
+ continue;
35
36
  const properties = object.properties;
36
37
  schemas.push(new Schema({
37
38
  properties,
38
39
  name: key,
39
40
  requireds: object.required || [],
40
41
  }));
41
- });
42
+ }
42
43
  console.log(`${schemas.length} schemas gerados com sucesso.`);
43
44
  return schemas;
44
45
  }
@@ -46,22 +47,21 @@ export class Reflector {
46
47
  const methodsMap = new Map();
47
48
  const modules = [];
48
49
  for (const [rawEndpoint, object] of Object.entries(this.paths)) {
49
- const methods = ["get", "patch", "post", "put", "delete"];
50
50
  let entity;
51
51
  const operations = [];
52
- const splittedEntitys = rawEndpoint.split("/");
53
- const filteredEntitys = splittedEntitys.filter((item) => item !== "" && !item.includes("{"));
54
- const moduleName = filteredEntitys.map((x) => sanitizeKey(capitalizeFirstLetter(x))).join("");
55
- const endpoint = filteredEntitys.join("/");
52
+ const { endpoint, moduleName } = getEndpointAndModuleName(rawEndpoint);
56
53
  for (const method of methods) {
57
54
  if (!object[method])
58
55
  continue;
59
56
  operations.push({ ...object[method], apiMethod: method });
60
- const tags = object[method].tags;
61
- if (!entity && tags) {
62
- entity = tags.join("").split("/").join("");
57
+ if (!entity) {
58
+ const teste = object[method].operationId.split("_")[0];
59
+ const x = splitByUppercase(teste);
60
+ const aaa = x.filter((y) => y !== "Controller");
61
+ entity = aaa.join("");
63
62
  }
64
63
  }
64
+ // console.warn(entity)
65
65
  if (!entity)
66
66
  continue;
67
67
  const existingOps = methodsMap.get(entity);
@@ -84,9 +84,9 @@ export class Reflector {
84
84
  build() {
85
85
  this.schemaFile.changeData([`import z from 'zod';`, ...this.schemas.map((s) => `${s.schema} ${s.type}`)].join("\n\n"));
86
86
  this.schemaFile.save();
87
- this.modules.forEach((module) => {
87
+ for (const module of this.modules) {
88
88
  module.src.save();
89
- });
89
+ }
90
90
  return {};
91
91
  }
92
92
  localSave(data) {
package/dist/method.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Request } from "./request.js";
2
2
  import { ZodProperty } from "./property.js";
3
- import { createDangerMessage } from "./helpers.js";
3
+ import { createDangerMessage } from "./helpers/helpers.js";
4
4
  export class Method {
5
5
  name;
6
6
  zodProperties;
@@ -20,15 +20,15 @@ export class Method {
20
20
  return { parameters: [] };
21
21
  }
22
22
  const parameters = [];
23
- operation.parameters.forEach((object) => {
23
+ for (const object of operation.parameters) {
24
24
  if ("$ref" in object)
25
- return;
25
+ continue;
26
26
  if (!object.schema)
27
- return;
27
+ continue;
28
28
  const { required, name, description, schema } = object;
29
29
  if ("$ref" in schema)
30
- return;
31
- return parameters.push(new ZodProperty({
30
+ continue;
31
+ parameters.push(new ZodProperty({
32
32
  name,
33
33
  example: schema.default,
34
34
  schemaObject: schema,
@@ -36,7 +36,7 @@ export class Method {
36
36
  description,
37
37
  required: required || true,
38
38
  }));
39
- });
39
+ }
40
40
  return { parameters };
41
41
  }
42
42
  buildCallMethod() {
@@ -56,23 +56,29 @@ export class Method {
56
56
  beforeResponse.push(`\n`);
57
57
  }
58
58
  if (this.request.attributeType === "list") {
59
- beforeResponse.push(`const {data, ...params} = response`);
60
- beforeResponse.push("\n\n");
61
- beforeResponse.push(`this.list = data`);
62
- beforeResponse.push(`repo.intercept.rebuild(this.parameters, params)`);
59
+ beforeResponse.push(`const {data, ...params} = response`, "\n\n", `this.list = data`, `repo.intercept.rebuild(this.parameters, params)`);
60
+ return `
61
+ ${afterResponse.join(";")}
62
+ const response = await repo.api.get<{data: ${this.request.responseType}[]}, unknown>({
63
+ endpoint: this.endpoint, ${query}
64
+ })
65
+ ${beforeResponse.join(";")}
66
+
67
+ return response
68
+ `;
63
69
  }
64
70
  else if (this.request.attributeType === "entity") {
65
71
  beforeResponse.push(`this.entity = response`);
66
- }
67
- return `
68
- ${afterResponse.join(";")}
69
- const response = await repo.api.get<${this.request.responseType}, unknown>({
70
- endpoint: this.endpoint, ${query}
71
- })
72
- ${beforeResponse.join(";")}
72
+ return `
73
+ ${afterResponse.join(";")}
74
+ const response = await repo.api.get<${this.request.responseType}, unknown>({
75
+ endpoint: this.endpoint, ${query}
76
+ })
77
+ ${beforeResponse.join(";")}
73
78
 
74
- return response
75
- `;
79
+ return response
80
+ `;
81
+ }
76
82
  }
77
83
  else if (this.request.apiType === "post" || this.request.apiType === "put") {
78
84
  let data = "";
package/dist/module.d.ts CHANGED
@@ -3,16 +3,12 @@ import { Method } from "./method.js";
3
3
  import { ReflectorOperation } from "./types/types.js";
4
4
  export declare class Module {
5
5
  readonly name: string;
6
- readonly src: Source;
7
6
  readonly endpoint: string;
8
7
  readonly moduleName: string;
8
+ readonly src: Source;
9
9
  imports: string[];
10
10
  parameters: string[];
11
11
  methods: Method[];
12
- types: {
13
- raw: string[];
14
- constructor: string[];
15
- }[];
16
12
  constructor(params: {
17
13
  name: string;
18
14
  moduleName: string;
package/dist/module.js CHANGED
@@ -1,27 +1,20 @@
1
1
  import path from "node:path";
2
2
  import fs from "node:fs";
3
3
  import { Source } from "./file.js";
4
- import { capitalizeFirstLetter, createDangerMessage, stripState } from "./helpers.js";
4
+ import { capitalizeFirstLetter, stripState } from "./helpers/helpers.js";
5
5
  import { Method } from "./method.js";
6
6
  export class Module {
7
7
  name;
8
- src;
9
8
  endpoint;
10
9
  moduleName;
10
+ src;
11
11
  imports;
12
12
  parameters;
13
13
  methods;
14
- types;
15
14
  constructor(params) {
16
15
  const { name, operations, endpoint, dir, moduleName } = params;
17
16
  this.moduleName = moduleName;
18
17
  this.imports = ["// AUTO GERADO. QUEM ALTERAR GOSTA DE RAPAZES!\n", 'import repo from "$repository/main"'];
19
- this.types = [
20
- {
21
- raw: [],
22
- constructor: [],
23
- },
24
- ];
25
18
  this.name = capitalizeFirstLetter(name);
26
19
  this.endpoint = endpoint;
27
20
  const methods = operations.map((operation) => {
@@ -32,9 +25,9 @@ export class Module {
32
25
  });
33
26
  // não vão entrar metodos que não tiverem uma resposta tipada
34
27
  this.methods = methods.filter((op) => {
35
- if (!op.request.responseType) {
36
- createDangerMessage(`Método [ ${op.name} ] do módulo [ ${this.moduleName} ] sem tipagem na resposta.`);
37
- }
28
+ // if (!op.request.responseType) {
29
+ // createDangerMessage(`Método [ ${op.name} ] do módulo [ ${this.moduleName} ] sem tipagem na resposta.`);
30
+ // }
38
31
  return op.request.responseType;
39
32
  });
40
33
  this.parameters = this.getParameters();
@@ -53,7 +46,7 @@ export class Module {
53
46
  moduleAtributes.add(`parameters = $state(repo.newForm(ParametersSchema))`);
54
47
  }
55
48
  const form = [];
56
- this.methods.forEach((method) => {
49
+ for (const method of this.methods) {
57
50
  const { bodyType, responseType, attributeType } = method.request;
58
51
  if (attributeType === "form" && bodyType) {
59
52
  form.push({
@@ -61,15 +54,18 @@ export class Module {
61
54
  type: bodyType,
62
55
  });
63
56
  }
57
+ console.warn(attributeType);
64
58
  if (attributeType === "entity") {
65
- moduleAtributes.add(`list = $state<${responseType}[]>([])`);
66
59
  moduleAtributes.add(`entity = $state<${responseType} | undefined>()`);
67
60
  }
68
- });
61
+ else if (attributeType === "list") {
62
+ moduleAtributes.add(`list = $state<${responseType}[]>([])`);
63
+ }
64
+ }
69
65
  const formSet = new Set();
70
- form.forEach((f) => {
66
+ for (const f of form) {
71
67
  formSet.add(`${f.name}: repo.newForm(${f.type}Schema)`);
72
- });
68
+ }
73
69
  moduleAtributes.add(`
74
70
  forms = $state({
75
71
  ${Array.from(formSet)}
@@ -94,14 +90,16 @@ export class Module {
94
90
  }
95
91
  getParameters() {
96
92
  const set = new Set();
97
- this.methods.forEach((method) => {
98
- method.zodProperties.forEach((param) => set.add(param.buildedProp));
99
- });
93
+ for (const method of this.methods) {
94
+ for (const param of method.zodProperties) {
95
+ set.add(param.buildedProp);
96
+ }
97
+ }
100
98
  return Array.from(set);
101
99
  }
102
100
  buildImports() {
103
101
  const entries = new Set();
104
- this.methods.forEach((method) => {
102
+ for (const method of this.methods) {
105
103
  const { bodyType, responseType, apiType } = method.request;
106
104
  if (bodyType)
107
105
  entries.add(`${bodyType}Schema`);
@@ -110,11 +108,11 @@ export class Module {
110
108
  entries.add(`${responseType}Schema`);
111
109
  entries.add(`type ${responseType}`);
112
110
  }
113
- });
111
+ }
114
112
  const cleanEntries = Array.from(entries).filter((x) => x != "type any");
115
113
  if (cleanEntries.length === 0)
116
114
  return "";
117
- return `import { ${cleanEntries} } from '$api/schemas';`;
115
+ return `import { ${cleanEntries} } from '$reflector/schemas';`;
118
116
  }
119
117
  buildClass(modulesAttributes) {
120
118
  const initAssignments = modulesAttributes.map((attr) => `this.${stripState(attr)}`).join(";");
@@ -136,13 +134,13 @@ export class Module {
136
134
  }
137
135
  buildFile(modulesAttributes, moduleTypes) {
138
136
  return `
139
- ${this.imports.join(";")}
140
- import z from "zod";
141
- ${this.buildImports()}
137
+ ${this.imports.join(";")}
138
+ import z from "zod";
139
+ ${this.buildImports()}
142
140
 
143
- ${moduleTypes.join(";")}
141
+ ${moduleTypes.join(";")}
144
142
 
145
- ${this.buildClass(modulesAttributes)}
143
+ ${this.buildClass(modulesAttributes)}
146
144
  `;
147
145
  }
148
146
  }
package/dist/property.js CHANGED
@@ -1,4 +1,5 @@
1
- import { ReflectorInput } from "./input.js";
1
+ import { sanitizeNumber } from "./helpers/helpers.js";
2
+ import { ReflectorInput } from "./helpers/input.js";
2
3
  const inputs = new ReflectorInput();
3
4
  export class ZodProperty {
4
5
  name;
@@ -64,13 +65,14 @@ export class ZodProperty {
64
65
  return `${x}.default(${this.example})`;
65
66
  case "number": {
66
67
  const number = JSON.stringify(this.example) ?? 1;
67
- return `${x}.default(${number})`;
68
+ return `${x}.default(${sanitizeNumber(number)})`;
68
69
  }
69
70
  case "array": {
70
- if (!value.items || !("$ref" in value.items))
71
- return `${x}.default([])`;
71
+ if (!value.items || !("$ref" in value.items)) {
72
+ return `${this.name}: z.${this.type}(z.${value.items?.type || "string"}())${this.isNullable()}.default([])`;
73
+ }
72
74
  const dto = this.getDtoName(value.items.$ref);
73
- return `${this.name}: z.array(${dto}Schema).default(Array(10).fill(${dto}Schema.parse({})))`;
75
+ return `${this.name}: z.array(${dto}Schema).default(new Array(10).fill(${dto}Schema.parse({})))`;
74
76
  }
75
77
  case "object":
76
78
  return `${this.name}: z.any()`;
package/dist/schema.js CHANGED
@@ -7,9 +7,9 @@ export class Schema {
7
7
  constructor(params) {
8
8
  const { name, properties, requireds } = params;
9
9
  this.name = name;
10
- Object.entries(properties).forEach(([key, value]) => {
10
+ for (const [key, value] of Object.entries(properties)) {
11
11
  if ("$ref" in value || !value?.type)
12
- return;
12
+ continue;
13
13
  const required = requireds.includes(key);
14
14
  this.properties.push(new ZodProperty({
15
15
  name: key,
@@ -18,7 +18,7 @@ export class Schema {
18
18
  example: value.example,
19
19
  required,
20
20
  }));
21
- });
21
+ }
22
22
  this.type = `export type ${name} = z.infer<typeof ${name}Schema>;`;
23
23
  this.schema = `export const ${name}Schema = z.object({
24
24
  ${this.properties.map((p) => p.buildedProp)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-reflector",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Reflects zod types from openAPI schemas",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",