sparkzen 1.1.2 → 1.2.1

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/index.js CHANGED
@@ -1,16 +1,74 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli/index.ts
4
- import { Command as Command4 } from "commander";
4
+ import { Command as Command5 } from "commander";
5
5
 
6
- // src/cli/commands/init.ts
7
- import { execSync } from "child_process";
6
+ // package.json
7
+ var name = "sparkzen";
8
+ var version = "1.2.1";
9
+
10
+ // src/cli/commands/app/build.ts
8
11
  import { Command } from "commander";
12
+ import { bgGreenBright, bold } from "logfy-x";
13
+ import { execSync } from "child_process";
14
+ var build = new Command().name("build").description("Build the project").action(() => {
15
+ process.env.NODE_ENV = "production";
16
+ const projectPath = process.cwd();
17
+ console.log(`${bgGreenBright(bold(" \u{1F4E6} BUILD "))} Building the project...
18
+ `);
19
+ execSync(`npx tsup`, {
20
+ cwd: projectPath,
21
+ stdio: "inherit",
22
+ shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh"
23
+ });
24
+ console.log(`
25
+ ${bgGreenBright(bold(" \u2705 BUILD "))} Build completed successfully!
26
+ `);
27
+ });
28
+ var build_default = build;
29
+
30
+ // src/cli/commands/app/dev.ts
31
+ import { Command as Command2 } from "commander";
32
+ import { bgBlue, bold as bold2 } from "logfy-x";
33
+ import { execSync as execSync2 } from "child_process";
34
+ import path from "path";
35
+ var dev = new Command2().name("dev").description("Run the project in development mode").action(() => {
36
+ process.env.NODE_ENV = "dev";
37
+ const projectPath = process.cwd();
38
+ const tsxPath = path.join(projectPath, "node_modules", ".bin", process.platform === "win32" ? "tsx.cmd" : "tsx");
39
+ console.log(`
40
+ ${bgBlue(bold2(" \u{1F680} DEV "))} Starting development server...
41
+ `);
42
+ execSync2(`${tsxPath} watch src/index.ts`, {
43
+ cwd: projectPath,
44
+ stdio: "inherit",
45
+ shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh"
46
+ });
47
+ });
48
+ var dev_default = dev;
49
+
50
+ // src/cli/commands/app/start.ts
51
+ import { Command as Command3 } from "commander";
52
+ import { execSync as execSync3 } from "child_process";
53
+ var start = new Command3().name("start").description("Run the project in production mode").action(() => {
54
+ process.env.NODE_ENV = "production";
55
+ const projectPath = process.cwd();
56
+ execSync3(`node dist/index.js`, {
57
+ cwd: projectPath,
58
+ stdio: "inherit",
59
+ shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh"
60
+ });
61
+ });
62
+ var start_default = start;
63
+
64
+ // src/cli/commands/init.ts
65
+ import { Command as Command4 } from "commander";
9
66
  import degit from "degit";
10
67
  import enquirer from "enquirer";
11
68
  import fs from "fs-extra";
12
- import { bgBlue, blue, bold, error, logfy, success } from "logfy-x";
13
- import path from "path";
69
+ import { bgBlue as bgBlue2, blue, bold as bold3, error, logfy, success } from "logfy-x";
70
+ import { execSync as execSync4 } from "child_process";
71
+ import path2 from "path";
14
72
  var { prompt } = enquirer;
15
73
  var promptOptions = async () => {
16
74
  const terminalWidth = process.stdout.columns || 80;
@@ -21,7 +79,7 @@ var promptOptions = async () => {
21
79
  const half = Math.floor(available / 2);
22
80
  const left = " ".repeat(half);
23
81
  const right = " ".repeat(available - half);
24
- return bgBlue(left) + text + bgBlue(right);
82
+ return bgBlue2(left) + text + bgBlue2(right);
25
83
  };
26
84
  logfy(`
27
85
  ${padFor(line1)}
@@ -33,7 +91,7 @@ ${padFor(line2)}
33
91
  name: "projectName",
34
92
  message: "Project name:",
35
93
  required: true,
36
- validate: (v) => v && v.trim() ? true : "Please enter a project name"
94
+ validate: (v) => v?.trim() ? true : "Please enter a project name"
37
95
  },
38
96
  {
39
97
  type: "select",
@@ -53,10 +111,10 @@ ${padFor(line2)}
53
111
  };
54
112
  var cloneProjectTemplate = async (projectName, targetPath) => {
55
113
  console.log(`
56
- ${bgBlue(bold(" \u{1F4C1} CREATING "))} ${projectName}`);
57
- await fs.mkdirp(path.dirname(targetPath));
114
+ ${bgBlue2(bold3(" \u{1F4C1} CREATING "))} ${projectName}`);
115
+ await fs.mkdirp(path2.dirname(targetPath));
58
116
  console.log(`
59
- ${bgBlue(bold(" \u{1F501} COPYING "))} Default template`);
117
+ ${bgBlue2(bold3(" \u{1F501} COPYING "))} Default template`);
60
118
  const template = degit("MatheusSantos360/sparkzen-templates/default", {
61
119
  cache: false,
62
120
  force: true
@@ -66,7 +124,7 @@ ${bgBlue(bold(" \u{1F501} COPYING "))} Default template`);
66
124
  } catch (err) {
67
125
  throw new Error(`Failed to clone template: ${err.message}`);
68
126
  }
69
- const pkgJsonPath = path.join(targetPath, "package.json");
127
+ const pkgJsonPath = path2.join(targetPath, "package.json");
70
128
  if (!await fs.pathExists(pkgJsonPath)) {
71
129
  error("NOT FOUND", "package.json not found in the template.");
72
130
  return;
@@ -81,10 +139,10 @@ ${bgBlue(bold(" \u{1F501} COPYING "))} Default template`);
81
139
  };
82
140
  var installDependencies = (packageManager, targetPath) => {
83
141
  console.log(`
84
- ${bgBlue(bold(" \u26A1 DEPENDENCIES "))} Installing with ${blue(packageManager)}:
142
+ ${bgBlue2(bold3(" \u26A1 DEPENDENCIES "))} Installing with ${blue(packageManager)}:
85
143
  `);
86
144
  try {
87
- execSync(`${packageManager} install`, {
145
+ execSync4(`${packageManager} install`, {
88
146
  cwd: targetPath,
89
147
  stdio: "inherit",
90
148
  shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh"
@@ -93,10 +151,10 @@ ${bgBlue(bold(" \u26A1 DEPENDENCIES "))} Installing with ${blue(packageManager)}
93
151
  throw new Error(`Dependency install failed: ${err.message}`);
94
152
  }
95
153
  };
96
- var init = new Command().name("init").description("Initialize a new SparkZen project").action(async () => {
154
+ var init = new Command4().name("init").description("Initialize a new SparkZen project").action(async () => {
97
155
  try {
98
156
  const { projectName, packageManager, installNow } = await promptOptions();
99
- const targetPath = path.resolve(process.cwd(), projectName);
157
+ const targetPath = path2.resolve(process.cwd(), projectName);
100
158
  await cloneProjectTemplate(projectName, targetPath);
101
159
  if (installNow) {
102
160
  installDependencies(packageManager, targetPath);
@@ -104,7 +162,7 @@ var init = new Command().name("init").description("Initialize a new SparkZen pro
104
162
  console.log();
105
163
  success("CREATED!", `Project "${blue(projectName)}" has been created successfully.`);
106
164
  console.log(`
107
- ${bgBlue(bold(" \u{1F525} NEXT STEPS "))} To get started:
165
+ ${bgBlue2(bold3(" \u{1F525} NEXT STEPS "))} To get started:
108
166
  `);
109
167
  console.log(` cd ${blue(projectName)}`);
110
168
  console.log(` ${blue(packageManager)} run ${blue("dev")}
@@ -116,57 +174,16 @@ ${bgBlue(bold(" \u{1F525} NEXT STEPS "))} To get started:
116
174
  });
117
175
  var init_default = init;
118
176
 
119
- // src/cli/commands/dev.ts
120
- import { execSync as execSync2 } from "child_process";
121
- import { Command as Command2 } from "commander";
122
- import { bgBlue as bgBlue2, bold as bold2 } from "logfy-x";
123
- import path2 from "path";
124
- var dev = new Command2().name("dev").description("Run the project in development mode").action(() => {
125
- const projectPath = process.cwd();
126
- const tsxPath = path2.join(projectPath, "node_modules", ".bin", process.platform === "win32" ? "tsx.cmd" : "tsx");
127
- console.log(`
128
- ${bgBlue2(bold2(" \u{1F680} DEV "))} Starting development server...
129
- `);
130
- execSync2(`${tsxPath} watch src/index.ts`, {
131
- cwd: projectPath,
132
- stdio: "inherit",
133
- shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh"
134
- });
135
- });
136
- var dev_default = dev;
137
-
138
- // src/cli/commands/build.ts
139
- import { execSync as execSync3 } from "child_process";
140
- import { Command as Command3 } from "commander";
141
- import { bgGreenBright, bold as bold3 } from "logfy-x";
142
- var build = new Command3().name("build").description("Build the project").action(() => {
143
- const projectPath = process.cwd();
144
- console.log(`${bgGreenBright(bold3(" \u{1F4E6} BUILD "))} Building the project...
145
- `);
146
- execSync3(`npx tsup`, {
147
- cwd: projectPath,
148
- stdio: "inherit",
149
- shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh"
150
- });
151
- console.log(`
152
- ${bgGreenBright(bold3(" \u2705 BUILD "))} Build completed successfully!
153
- `);
154
- });
155
- var build_default = build;
156
-
157
177
  // src/cli/commands.ts
158
178
  function registerCommands(program2) {
159
179
  program2.addCommand(init_default);
160
180
  program2.addCommand(dev_default);
161
181
  program2.addCommand(build_default);
182
+ program2.addCommand(start_default);
162
183
  }
163
184
 
164
- // package.json
165
- var name = "sparkzen";
166
- var version = "1.1.2";
167
-
168
185
  // src/cli/index.ts
169
- var program = new Command4();
186
+ var program = new Command5();
170
187
  program.name(name).description("SparkZen CLI").version(version);
171
188
  registerCommands(program);
172
189
  program.parse();
package/dist/index.d.ts CHANGED
@@ -37,4 +37,9 @@ type MiddlewareFunction<Schema extends RouteSchema = RouteSchema> = (request: Fa
37
37
  }>, reply: TypedReply<Schema>, done: () => void) => void | Promise<void>;
38
38
  type Middleware<Schema extends RouteSchema = RouteSchema> = MiddlewareFunction<Schema> | MiddlewareFunction<Schema>[];
39
39
 
40
- export { type Handler, type Middleware, type MiddlewareFunction, sparkzen as default };
40
+ type Config = {
41
+ routePrefix?: string;
42
+ errorMessage?: string;
43
+ };
44
+
45
+ export { type Config, type Handler, type Middleware, type MiddlewareFunction, sparkzen as default };
package/dist/index.js CHANGED
@@ -1,36 +1,128 @@
1
1
  // src/core/sparkzen.ts
2
2
  import fastify from "fastify";
3
- import { bgBlueBright as bgBlueBright2, bgGreenBright, blue, bold as bold3, dim as dim3, error } from "logfy-x";
3
+ import { bgBlueBright as bgBlueBright2, bgGreenBright as bgGreenBright2 } from "logfy-x";
4
+
5
+ // src/core/functions/errorHandler.ts
6
+ import { dim, error } from "logfy-x";
7
+ var errorHandler = (err, _request, reply) => {
8
+ reply.status(500).send({ error: "Internal Server Error", message: "There was an error. Please, try again." });
9
+ const failedRoutePath = err.stack?.split("(")[1].split(")")[0] || "(No path identified)";
10
+ error(`${err.name} ${dim(failedRoutePath)}`, [`Route Path: ${failedRoutePath}`, `Message: ${err.message}`, `Stack: ${err.stack}`]);
11
+ };
12
+
13
+ // src/core/functions/getConfig.ts
14
+ import { exists } from "fs-extra";
15
+ import path from "path";
16
+ import { pathToFileURL } from "url";
17
+
18
+ // src/core/defaultConfig.ts
19
+ var defaultConfig = {
20
+ routePrefix: "/",
21
+ errorMessage: "Something went wrong. Please, try again later."
22
+ };
23
+
24
+ // src/core/package.ts
25
+ var packageConfigs = {
26
+ configFileName: `sparkzen.config.${process.env.NODE_ENV === "production" ? "js" : "ts"}`
27
+ };
28
+
29
+ // src/core/functions/getConfig.ts
30
+ var config = defaultConfig;
31
+ var isDev = process.env.NODE_ENV !== "production";
32
+ var getConfig = async () => {
33
+ return config;
34
+ };
35
+ var setConfig = async () => {
36
+ if (await configFileExists()) {
37
+ const configPath = isDev ? path.resolve(process.cwd(), packageConfigs.configFileName.replace(".js", ".ts")) : path.resolve(process.cwd(), "dist", packageConfigs.configFileName);
38
+ const fileConfig = await import(pathToFileURL(configPath).href);
39
+ config = { ...defaultConfig, ...fileConfig.config };
40
+ }
41
+ };
42
+ var configFileExists = async () => {
43
+ const filePath = isDev ? path.resolve(process.cwd(), packageConfigs.configFileName.replace(".js", ".ts")) : path.resolve(process.cwd(), "dist", packageConfigs.configFileName);
44
+ return await exists(filePath);
45
+ };
46
+
47
+ // src/core/functions/manageListen.ts
48
+ import { bgGreenBright, blue, bold as bold2, error as error2 } from "logfy-x";
49
+
50
+ // src/core/functions/sparkzenBanner.ts
51
+ import { bold, dim as dim2 } from "logfy-x";
52
+ var sparkzenBanner = (message, color) => {
53
+ const tag = color(bold(" SPARKZEN "));
54
+ const line = dim2("\u2500".repeat(10 * 2 + message.length + 2));
55
+ console.log(`
56
+ ${tag} ${bold(message)} ${tag}
57
+ ${line}`);
58
+ };
59
+
60
+ // src/core/functions/manageListen.ts
61
+ var manageListen = (app) => {
62
+ const originalListen = app.listen.bind(app);
63
+ app.listen = async function(options) {
64
+ try {
65
+ sparkzenBanner("STARTING SERVER", bgGreenBright);
66
+ const result = await originalListen(options);
67
+ const runningAt = `http://localhost:${options?.port}`;
68
+ console.log(`${bgGreenBright(bold2(" SERVER "))} Running at: ${blue(runningAt)}
69
+ `);
70
+ return result;
71
+ } catch (err) {
72
+ error2("ERROR", err.name + `: ${err.message}
73
+
74
+ ${err.stack}`);
75
+ }
76
+ };
77
+ };
78
+
79
+ // src/core/loadRoutes.ts
80
+ import fs from "fs/promises";
81
+ import path3 from "path";
82
+
83
+ // src/core/routing/processFile.ts
84
+ import { bgRedBright, bold as bold4, dim as dim5, red } from "logfy-x";
85
+ import { pathToFileURL as pathToFileURL2 } from "url";
86
+
87
+ // src/core/routing/dynamicImport.ts
88
+ var dynamicImport = async (modulePath) => {
89
+ return await import(modulePath);
90
+ };
4
91
 
5
92
  // src/core/routing/isValidRoute.ts
6
93
  var isValidRoute = (routeModule) => {
7
94
  return routeModule && typeof routeModule === "object" && typeof routeModule.default === "function";
8
95
  };
9
96
 
97
+ // src/core/routing/registerRoute.ts
98
+ import * as colors from "logfy-x";
99
+ import { bgBlueBright, dim as dim4, error as error3 } from "logfy-x";
100
+
10
101
  // src/core/routing/getRouteURL.ts
11
- import path from "path";
12
- var getRouteUrl = (filePath) => {
102
+ import path2 from "path";
103
+ var getRouteUrl = async (filePath) => {
104
+ const { routePrefix } = await getConfig();
13
105
  const production = process.env.NODE_ENV === "production";
14
- const basePath = production ? process.cwd() : path.join(process.cwd(), "src", "routes");
106
+ const basePath = production ? process.cwd() : path2.join(process.cwd(), "src", "routes");
15
107
  let routePath = filePath.replace(basePath, "").replaceAll("\\", "/").replace(/\.(js|ts)$/, "");
16
108
  const segments = routePath.split("/");
17
109
  segments.pop();
18
110
  routePath = segments.join("/");
19
- routePath = routePath.replace(/\[(\w+)\]/g, ":$1");
20
- return `/api${routePath}`.replace(/\/+/g, "/").replaceAll("dist/routes/", "");
111
+ routePath = routePath.replaceAll(/\[(\w+)\]/g, ":$1");
112
+ return `${routePrefix}${routePath}`.replaceAll(/\/+/g, "/").replaceAll("dist/routes/", "");
21
113
  };
22
114
 
23
115
  // src/core/routing/registerRoute.ts
24
- import { bgBlueBright } from "logfy-x";
25
- import * as colors from "logfy-x";
26
- var registerRoute = (app, routeModule, method, finalPath) => {
27
- const routeURL = getRouteUrl(finalPath);
116
+ var registerRoute = async (app, routeModule, method, finalPath) => {
117
+ const routeURL = await getRouteUrl(finalPath);
28
118
  const methodColors = {
29
119
  get: "green",
30
120
  post: "yellow",
31
121
  put: "blue",
32
122
  delete: "red",
33
- patch: "magenta"
123
+ patch: "magentaBright",
124
+ head: "green",
125
+ options: "magentaBright"
34
126
  };
35
127
  const routeOptions = {
36
128
  ...routeModule,
@@ -39,73 +131,64 @@ var registerRoute = (app, routeModule, method, finalPath) => {
39
131
  handler: routeModule.default,
40
132
  preHandler: routeModule.middlewares
41
133
  };
42
- app.route(routeOptions);
134
+ try {
135
+ app.route(routeOptions);
136
+ } catch (err) {
137
+ const routeError = err;
138
+ console.log();
139
+ error3(`${routeError.name} ${dim4(finalPath)}`, [
140
+ `Route Path: ${finalPath}`,
141
+ `API Path: ${colors.blue(routeURL)}`,
142
+ `Message: ${routeError.message}`,
143
+ `Code: ${routeError.code}`,
144
+ `Stack: ${routeError.stack}`
145
+ ]);
146
+ }
43
147
  console.log(bgBlueBright(colors.bold(` ROUTE `)) + ` ${colors[methodColors[method]](method.toUpperCase())} ${routeURL} ${colors.dim(finalPath)}`);
44
148
  };
45
149
 
46
- // src/core/loadRoutes.ts
47
- import { pathToFileURL } from "url";
48
- import fs from "fs/promises";
49
-
50
- // src/core/routing/dynamicImport.ts
51
- var dynamicImport = async (modulePath) => {
52
- return await import(modulePath);
150
+ // src/core/routing/processFile.ts
151
+ var processFile = async (app, item, filePath) => {
152
+ const production = process.env.NODE_ENV === "production";
153
+ const ext = production ? ".js" : ".ts";
154
+ const finalPath = production ? filePath.replace(/\.ts$/, ".js") : filePath;
155
+ const modulePath = pathToFileURL2(finalPath).href;
156
+ const modulePathWithQuery = production ? modulePath : `${modulePath}?t=${Date.now()}`;
157
+ const routeModule = await dynamicImport(modulePathWithQuery);
158
+ if (isValidRoute(routeModule)) {
159
+ const method = item.name.replace(new RegExp(`${ext}$`), "").toLowerCase();
160
+ await registerRoute(app, routeModule, method, finalPath);
161
+ } else {
162
+ console.log(bgRedBright(bold4(` ROUTE `)) + ` ${red("Invalid Route (No handler exported)")} ${dim5(finalPath)}`);
163
+ }
53
164
  };
54
165
 
55
166
  // src/core/loadRoutes.ts
56
- import { bgRedBright, bold as bold2, dim as dim2, red } from "logfy-x";
57
- import path2 from "path";
58
167
  var loadRoutes = async (app, directory) => {
59
168
  const production = process.env.NODE_ENV === "production";
60
- const ext = production ? ".js" : ".ts";
61
169
  const currentDir = process.cwd();
62
- const routesPath = directory || (production ? path2.join(currentDir, "dist", "routes") : path2.join(currentDir, "src", "routes"));
170
+ const routesPath = directory || (production ? path3.join(currentDir, "dist", "routes") : path3.join(currentDir, "src", "routes"));
63
171
  const items = await fs.readdir(routesPath, { withFileTypes: true });
64
172
  for (const item of items) {
65
- const itemPath = path2.join(routesPath, item.name);
173
+ const itemPath = path3.join(routesPath, item.name);
66
174
  if (item.isDirectory()) {
67
175
  await loadRoutes(app, itemPath);
68
176
  } else if (item.isFile() && item.name.endsWith(production ? ".js" : ".ts")) {
69
- const finalPath = production ? itemPath.replace(/\.ts$/, ".js") : itemPath;
70
- const modulePath = pathToFileURL(finalPath).href;
71
- const modulePathWithQuery = production ? modulePath : `${modulePath}?t=${Date.now()}`;
72
- const routeModule = await dynamicImport(modulePathWithQuery);
73
- if (isValidRoute(routeModule)) {
74
- const method = item.name.replace(new RegExp(`${ext}$`), "").toLowerCase();
75
- registerRoute(app, routeModule, method, finalPath);
76
- } else {
77
- console.log(bgRedBright(bold2(` ROUTE `)) + ` ${red("Invalid Route (No handler exported)")} ${dim2(finalPath)}`);
78
- }
177
+ await processFile(app, item, itemPath);
79
178
  }
80
179
  }
81
180
  };
82
181
 
83
182
  // src/core/sparkzen.ts
84
- function sparkzenBanner(message, color) {
85
- const tag = color(bold3(" SPARKZEN "));
86
- const line = dim3("\u2500".repeat(10 * 2 + message.length + 2));
87
- console.log(`
88
- ${tag} ${bold3(message)} ${tag}
89
- ${line}`);
90
- }
91
183
  async function sparkzen() {
184
+ await setConfig();
92
185
  sparkzenBanner("INITIALIZING API", bgBlueBright2);
93
186
  const app = fastify().withTypeProvider();
94
- sparkzenBanner("LOADING ROUTES", bgGreenBright);
187
+ sparkzenBanner("LOADING ROUTES", bgGreenBright2);
95
188
  await loadRoutes(app);
96
189
  console.log();
97
- const originalListen = app.listen.bind(app);
98
- app.listen = async function(opts) {
99
- try {
100
- sparkzenBanner("STARTING SERVER", bgGreenBright);
101
- const result = await originalListen(opts);
102
- console.log(`${bgGreenBright(bold3(" SERVER "))} Running at: ${blue(`http://localhost:${opts.port}`)}
103
- `);
104
- return result;
105
- } catch (err) {
106
- error("ERROR", err.message);
107
- }
108
- };
190
+ manageListen(app);
191
+ app.setErrorHandler(errorHandler);
109
192
  return app;
110
193
  }
111
194
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sparkzen",
3
- "version": "1.1.2",
3
+ "version": "1.2.1",
4
4
  "license": "MIT",
5
5
  "author": "Matheus dos Santos Paixão",
6
6
  "type": "module",