sparkzen 1.1.1 → 1.2.0

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