sparkzen 0.0.3 → 1.0.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.
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli/index.ts
4
+ import { Command as Command4 } from "commander";
5
+
6
+ // src/cli/commands/init.ts
7
+ import { execSync } from "child_process";
8
+ import { Command } from "commander";
9
+ import degit from "degit";
10
+ import enquirer from "enquirer";
11
+ import fs from "fs-extra";
12
+ import { bgBlue, blue, bold, error, logfy, success } from "logfy-x";
13
+ import path from "path";
14
+ var { prompt } = enquirer;
15
+ var promptOptions = async () => {
16
+ const terminalWidth = process.stdout.columns || 80;
17
+ const line1 = " \u{1F680} Welcome to SparkZen! \u{1F680} ";
18
+ const line2 = " Let's set up your new project. ";
19
+ const padFor = (text) => {
20
+ const available = Math.max(0, terminalWidth - text.length);
21
+ const half = Math.floor(available / 2);
22
+ const left = " ".repeat(half);
23
+ const right = " ".repeat(available - half);
24
+ return bgBlue(left) + text + bgBlue(right);
25
+ };
26
+ logfy(`
27
+ ${padFor(line1)}
28
+ ${padFor(line2)}
29
+ `, { style: "bold blue -underline" });
30
+ const answers = await prompt([
31
+ {
32
+ type: "input",
33
+ name: "projectName",
34
+ message: "Project name:",
35
+ required: true,
36
+ validate: (v) => v && v.trim() ? true : "Please enter a project name"
37
+ },
38
+ {
39
+ type: "select",
40
+ name: "packageManager",
41
+ message: "Package manager:",
42
+ choices: ["npm", "pnpm", "yarn", "bun"],
43
+ initial: 0
44
+ },
45
+ {
46
+ type: "confirm",
47
+ name: "installNow",
48
+ message: "Do you want to install dependencies now?",
49
+ initial: true
50
+ }
51
+ ]);
52
+ return answers;
53
+ };
54
+ var cloneProjectTemplate = async (projectName, targetPath) => {
55
+ console.log(`
56
+ ${bgBlue(bold(" \u{1F4C1} CREATING "))} ${projectName}`);
57
+ await fs.mkdirp(path.dirname(targetPath));
58
+ console.log(`
59
+ ${bgBlue(bold(" \u{1F501} COPYING "))} Default template`);
60
+ const template = degit("MatheusSantos360/sparkzen-templates/default", {
61
+ cache: false,
62
+ force: true
63
+ });
64
+ try {
65
+ await template.clone(targetPath);
66
+ } catch (err) {
67
+ throw new Error(`Failed to clone template: ${err.message}`);
68
+ }
69
+ const pkgJsonPath = path.join(targetPath, "package.json");
70
+ if (!await fs.pathExists(pkgJsonPath)) {
71
+ error("NOT FOUND", "package.json not found in the template.");
72
+ return;
73
+ }
74
+ try {
75
+ const pkgJson = JSON.parse(await fs.readFile(pkgJsonPath, "utf-8"));
76
+ pkgJson.name = projectName;
77
+ await fs.writeFile(pkgJsonPath, JSON.stringify(pkgJson, null, 2));
78
+ } catch (err) {
79
+ error("ERROR", `Failed to update package.json: ${err.message}`);
80
+ }
81
+ };
82
+ var installDependencies = (packageManager, targetPath) => {
83
+ console.log(`
84
+ ${bgBlue(bold(" \u26A1 DEPENDENCIES "))} Installing with ${blue(packageManager)}:
85
+ `);
86
+ try {
87
+ execSync(`${packageManager} install`, {
88
+ cwd: targetPath,
89
+ stdio: "inherit",
90
+ shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh"
91
+ });
92
+ } catch (err) {
93
+ throw new Error(`Dependency install failed: ${err.message}`);
94
+ }
95
+ };
96
+ var init = new Command().name("init").description("Initialize a new SparkZen project").action(async () => {
97
+ try {
98
+ const { projectName, packageManager, installNow } = await promptOptions();
99
+ const targetPath = path.resolve(process.cwd(), projectName);
100
+ await cloneProjectTemplate(projectName, targetPath);
101
+ if (installNow) {
102
+ installDependencies(packageManager, targetPath);
103
+ }
104
+ console.log();
105
+ success("CREATED!", `Project "${blue(projectName)}" has been created successfully.`);
106
+ console.log(`
107
+ ${bgBlue(bold(" \u{1F525} NEXT STEPS "))} To get started:
108
+ `);
109
+ console.log(` cd ${blue(projectName)}`);
110
+ console.log(` ${blue(packageManager)} run ${blue("dev")}
111
+ `);
112
+ } catch (err) {
113
+ error("ERROR", err.message);
114
+ process.exit(1);
115
+ }
116
+ });
117
+ var init_default = init;
118
+
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
+ import path3 from "path";
143
+ var build = new Command3().name("build").description("Build the project").action(() => {
144
+ const projectPath = process.cwd();
145
+ console.log(`${bgGreenBright(bold3(" \u{1F4E6} BUILD "))} Building the project...
146
+ `);
147
+ const tsupPath = path3.join(process.cwd(), "node_modules", ".bin", "tsup");
148
+ execSync3(`${tsupPath} src/index.ts --format esm --dts --out-dir dist`, {
149
+ cwd: projectPath,
150
+ stdio: "inherit",
151
+ shell: process.platform === "win32" ? "cmd.exe" : "/bin/sh"
152
+ });
153
+ console.log(`
154
+ ${bgGreenBright(bold3(" \u2705 BUILD "))} Build completed successfully!
155
+ `);
156
+ });
157
+ var build_default = build;
158
+
159
+ // src/cli/commands.ts
160
+ function registerCommands(program2) {
161
+ program2.addCommand(init_default);
162
+ program2.addCommand(dev_default);
163
+ program2.addCommand(build_default);
164
+ }
165
+
166
+ // package.json
167
+ var name = "sparkzen";
168
+ var version = "1.0.1";
169
+
170
+ // src/cli/index.ts
171
+ var program = new Command4();
172
+ program.name(name).description("SparkZen CLI").version(version);
173
+ registerCommands(program);
174
+ program.parse();
package/dist/index.d.ts CHANGED
@@ -1,3 +1,40 @@
1
- declare const add: (a: number, b: number) => number;
1
+ import * as fastify from 'fastify';
2
+ import { FastifyRequest, FastifyReply } from 'fastify';
3
+ import * as http from 'http';
4
+ import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox';
5
+ import { TSchema, Static } from '@sinclair/typebox';
6
+ export { Static, Type as T } from '@sinclair/typebox';
2
7
 
3
- export { add };
8
+ declare function sparkzen(): Promise<fastify.FastifyInstance<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>, http.IncomingMessage, http.ServerResponse<http.IncomingMessage>, fastify.FastifyBaseLogger, TypeBoxTypeProvider>>;
9
+
10
+ type RouteSchema = {
11
+ params?: TSchema;
12
+ body?: TSchema;
13
+ querystring?: TSchema;
14
+ headers?: TSchema;
15
+ response?: Record<number, TSchema>;
16
+ };
17
+ type ResponsePayload<Schema extends RouteSchema, Status extends number> = Schema["response"] extends Record<number, TSchema> ? Status extends keyof Schema["response"] ? Static<Schema["response"][Status]> : unknown : unknown;
18
+ type ResponseKeys<Schema extends RouteSchema> = Schema["response"] extends Record<number, TSchema> ? keyof Schema["response"] & number : number;
19
+ type TypedReply<Schema extends RouteSchema> = Omit<FastifyReply, "send" | "status"> & {
20
+ status: <Status extends ResponseKeys<Schema>>(statusCode: Status) => {
21
+ send: (payload: ResponsePayload<Schema, Status>) => FastifyReply;
22
+ };
23
+ };
24
+ type Handler<Schema extends RouteSchema = {}> = (request: FastifyRequest<{
25
+ Params: Schema["params"] extends TSchema ? Static<Schema["params"]> : {};
26
+ Body: Schema["body"] extends TSchema ? Static<Schema["body"]> : {};
27
+ Querystring: Schema["querystring"] extends TSchema ? Static<Schema["querystring"]> : {};
28
+ Headers: Schema["headers"] extends TSchema ? Static<Schema["headers"]> : {};
29
+ }>, reply: TypedReply<Schema>) => void | Promise<void>;
30
+
31
+ type EnsureSchema<S> = S extends TSchema ? S : never;
32
+ type MiddlewareFunction<Schema extends RouteSchema = RouteSchema> = (request: FastifyRequest<{
33
+ Params: Schema["params"] extends TSchema ? Static<EnsureSchema<Schema["params"]>> : {};
34
+ Body: Schema["body"] extends TSchema ? Static<EnsureSchema<Schema["body"]>> : {};
35
+ Querystring: Schema["querystring"] extends TSchema ? Static<EnsureSchema<Schema["querystring"]>> : {};
36
+ Headers: Schema["headers"] extends TSchema ? Static<EnsureSchema<Schema["headers"]>> : {};
37
+ }>, reply: TypedReply<Schema>, done: () => void) => void | Promise<void>;
38
+ type Middleware<Schema extends RouteSchema = RouteSchema> = MiddlewareFunction<Schema> | MiddlewareFunction<Schema>[];
39
+
40
+ export { type Handler, type Middleware, type MiddlewareFunction, sparkzen as default };
package/dist/index.js CHANGED
@@ -1,30 +1,118 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
1
+ // src/core/sparkzen.ts
2
+ import fastify from "fastify";
3
+ import { bgBlueBright as bgBlueBright2, bgGreenBright, blue, bold as bold3, dim as dim3, error } from "logfy-x";
4
+
5
+ // src/core/routing/isValidRoute.ts
6
+ var isValidRoute = (routeModule) => {
7
+ return routeModule && typeof routeModule === "object" && typeof routeModule.default === "function";
8
+ };
9
+
10
+ // src/core/routing/getRouteURL.ts
11
+ import path from "path";
12
+ var getRouteUrl = (filePath) => {
13
+ 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)$/, "");
16
+ const segments = routePath.split("/");
17
+ segments.pop();
18
+ routePath = segments.join("/");
19
+ routePath = routePath.replace(/\[(\w+)\]/g, ":$1");
20
+ return `/api${routePath}`.replace(/\/+/g, "/");
9
21
  };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
22
+
23
+ // 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);
28
+ const methodColors = {
29
+ get: "green",
30
+ post: "yellow",
31
+ put: "blue",
32
+ delete: "red",
33
+ patch: "magenta"
34
+ };
35
+ const routeOptions = {
36
+ ...routeModule,
37
+ method,
38
+ url: routeURL,
39
+ handler: routeModule.default,
40
+ preHandler: routeModule.middlewares
41
+ };
42
+ app.route(routeOptions);
43
+ console.log(bgBlueBright(colors.bold(` ROUTE `)) + ` ${colors[methodColors[method]](method.toUpperCase())} ${routeURL} ${colors.dim(finalPath)}`);
44
+ };
45
+
46
+ // src/core/loadRoutes.ts
47
+ import { pathToFileURL } from "url";
48
+ import fs from "fs/promises";
49
+ import path2 from "path";
50
+
51
+ // src/core/routing/dynamicImport.ts
52
+ var dynamicImport = async (modulePath) => {
53
+ return await import(modulePath);
54
+ };
55
+
56
+ // src/core/loadRoutes.ts
57
+ import { bgRedBright, bold as bold2, dim as dim2, red } from "logfy-x";
58
+ var loadRoutes = async (app, directory) => {
59
+ const production = process.env.NODE_ENV === "production";
60
+ const ext = production ? ".js" : ".ts";
61
+ const currentDir = process.cwd();
62
+ const routesPath = directory || (production ? path2.join(currentDir) : path2.join(currentDir, "src", "routes"));
63
+ const items = await fs.readdir(routesPath, { withFileTypes: true });
64
+ for (const item of items) {
65
+ const itemPath = path2.join(routesPath, item.name);
66
+ if (item.isDirectory()) {
67
+ await loadRoutes(app, itemPath);
68
+ } 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
+ }
79
+ }
15
80
  }
16
- return to;
17
81
  };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
82
+
83
+ // 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
+ async function sparkzen() {
92
+ sparkzenBanner("INITIALIZING API", bgBlueBright2);
93
+ const app = fastify().withTypeProvider();
94
+ sparkzenBanner("LOADING ROUTES", bgGreenBright);
95
+ await loadRoutes(app);
96
+ 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
+ };
109
+ return app;
110
+ }
19
111
 
20
112
  // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- add: () => add
24
- });
25
- module.exports = __toCommonJS(index_exports);
26
- var add = (a, b) => a + b;
27
- // Annotate the CommonJS export names for ESM import in node:
28
- 0 && (module.exports = {
29
- add
30
- });
113
+ import { Type } from "@sinclair/typebox";
114
+ var index_default = sparkzen;
115
+ export {
116
+ Type as T,
117
+ index_default as default
118
+ };
package/package.json CHANGED
@@ -1,22 +1,43 @@
1
1
  {
2
2
  "name": "sparkzen",
3
+ "version": "1.0.1",
3
4
  "license": "MIT",
4
- "version": "0.0.3",
5
- "main": "dist/index.js",
6
- "module": "dist/index.mjs",
7
- "types": "dist/index.d.ts",
5
+ "author": "Matheus dos Santos Paixão",
6
+ "type": "module",
8
7
  "private": false,
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "bin": "./dist/cli/index.js",
11
+ "files": [
12
+ "dist"
13
+ ],
9
14
  "publishConfig": {
10
15
  "access": "public"
11
16
  },
17
+ "dependencies": {
18
+ "@fastify/type-provider-typebox": "^6.1.0",
19
+ "@sinclair/typebox": "^0.34.41",
20
+ "commander": "^14.0.2",
21
+ "degit": "^2.8.4",
22
+ "enquirer": "^2.4.1",
23
+ "fastify": "^5.6.1",
24
+ "fs-extra": "^11.3.2",
25
+ "logfy-x": "^1.0.3"
26
+ },
12
27
  "devDependencies": {
13
28
  "@changesets/cli": "^2.29.7",
29
+ "@types/degit": "^2.8.6",
30
+ "@types/fs-extra": "^11.0.4",
31
+ "@types/node": "^24.9.2",
14
32
  "tsup": "^8.5.0",
15
- "typescript": "^5.9.3"
33
+ "typescript": "^5.6.3",
34
+ "vitest": "^4.0.6"
16
35
  },
17
36
  "scripts": {
18
- "build": "tsup src/index.ts --format cjs,esm --dts",
19
- "release": "pnpm run build && changeset publish",
20
- "lint": "tsc"
37
+ "build": "tsup src/index.ts src/cli/index.ts --format esm --dts --out-dir dist",
38
+ "dev": "tsup src/index.ts src/cli/index.ts --format esm --dts --watch --out-dir dist",
39
+ "lint": "tsc --noEmit",
40
+ "test": "vitest",
41
+ "release": "pnpm run build && changeset publish"
21
42
  }
22
43
  }
@@ -1,8 +0,0 @@
1
- # Changesets
2
-
3
- Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4
- with multi-package repos, or single-package repos to help you version and publish your code. You can
5
- find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6
-
7
- We have a quick list of common questions to get you started engaging with this project in
8
- [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
@@ -1,11 +0,0 @@
1
- {
2
- "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
3
- "changelog": "@changesets/cli/changelog",
4
- "commit": false,
5
- "fixed": [],
6
- "linked": [],
7
- "access": "restricted",
8
- "baseBranch": "main",
9
- "updateInternalDependencies": "patch",
10
- "ignore": []
11
- }
@@ -1,35 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches:
6
- - "**"
7
- pull_request:
8
-
9
- jobs:
10
- build:
11
- runs-on: ubuntu-latest
12
-
13
- steps:
14
- - name: Checkout code
15
- uses: actions/checkout@v4
16
-
17
- - name: Setup pnpm
18
- uses: pnpm/action-setup@v4
19
- with:
20
- version: 9
21
-
22
- - name: Setup Node.js
23
- uses: actions/setup-node@v4
24
- with:
25
- node-version: 20
26
- cache: pnpm
27
-
28
- - name: Install dependencies
29
- run: pnpm install --frozen-lockfile
30
-
31
- - name: Lint
32
- run: pnpm run lint
33
-
34
- - name: Build
35
- run: pnpm run build
@@ -1,45 +0,0 @@
1
- name: Publish
2
-
3
- on:
4
- workflow_run:
5
- workflows: ["CI"]
6
- branches: [main]
7
- types: [completed]
8
-
9
- concurrency: ${{ github.workflow }}-${{ github.ref }}
10
-
11
- permissions:
12
- contents: write
13
- pull-requests: write
14
-
15
- jobs:
16
- publish:
17
- if: ${{ github.event.workflow_run.conclusion == 'success' }}
18
- runs-on: ubuntu-latest
19
-
20
- steps:
21
- - name: Checkout code
22
- uses: actions/checkout@v4
23
-
24
- - name: Setup pnpm
25
- uses: pnpm/action-setup@v4
26
- with:
27
- version: 9
28
-
29
- - name: Setup Node.js
30
- uses: actions/setup-node@v4
31
- with:
32
- node-version: 20
33
- cache: pnpm
34
-
35
- - name: Install dependencies
36
- run: pnpm install --frozen-lockfile
37
-
38
- - name: Create Release Pull Request or Publish
39
- id: changesets
40
- uses: changesets/action@v1
41
- with:
42
- publish: pnpm run release
43
- env:
44
- GITHUB_TOKEN: ${{ secrets.MY_GITHUB_TOKEN }}
45
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
package/CHANGELOG.md DELETED
@@ -1,13 +0,0 @@
1
- # my-package
2
-
3
- ## 0.0.3
4
-
5
- ### Patch Changes
6
-
7
- - ec69145: Publish!
8
-
9
- ## 0.0.2
10
-
11
- ### Patch Changes
12
-
13
- - 59c2b5e: Added the add function.
package/dist/index.d.mts DELETED
@@ -1,3 +0,0 @@
1
- declare const add: (a: number, b: number) => number;
2
-
3
- export { add };
package/dist/index.mjs DELETED
@@ -1,5 +0,0 @@
1
- // src/index.ts
2
- var add = (a, b) => a + b;
3
- export {
4
- add
5
- };
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export const add = (a: number, b: number) => a + b; // Publish!!
package/tsconfig.json DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "esModuleInterop": true,
4
- "skipLibCheck": true,
5
- "target": "es2022",
6
- "verbatimModuleSyntax": true,
7
- "allowJs": true,
8
- "resolveJsonModule": true,
9
- "moduleDetection": "force",
10
- "strict": true,
11
- "noUncheckedIndexedAccess": true,
12
- "moduleResolution": "Bundler",
13
- "module": "ESNext",
14
- "noEmit": true
15
- }
16
- }