rasengan 1.0.0-beta.35 → 1.0.0-beta.36

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.
@@ -61,28 +61,26 @@ program
61
61
  .command("dev")
62
62
  .option("-p <port>")
63
63
  .description("Start development server")
64
- .action(function (_a) {
65
- var port = _a.p;
66
- return __awaiter(void 0, void 0, void 0, function () {
67
- var convertedPort;
68
- return __generator(this, function (_b) {
69
- convertedPort = Number(port);
70
- // Checking port
71
- if (port &&
72
- (isNaN(convertedPort) || convertedPort < 0 || convertedPort > 65535)) {
73
- console.log("");
74
- console.log(chalk.red("Please provide a valid port number between 0-65535"));
75
- console.log("");
76
- process.exit(1);
77
- }
78
- execa("node", ["node_modules/rasengan/server"], {
79
- stdio: "inherit",
80
- env: __assign(__assign({}, process.env), { PORT: convertedPort ? convertedPort.toString() : undefined }),
81
- });
82
- return [2 /*return*/];
64
+ .action(function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
65
+ var convertedPort;
66
+ var port = _b.p;
67
+ return __generator(this, function (_c) {
68
+ convertedPort = Number(port);
69
+ // Checking port
70
+ if (port &&
71
+ (isNaN(convertedPort) || convertedPort < 0 || convertedPort > 65535)) {
72
+ console.log("");
73
+ console.log(chalk.red("Please provide a valid port number between 0-65535"));
74
+ console.log("");
75
+ process.exit(1);
76
+ }
77
+ execa("node", ["node_modules/rasengan/server"], {
78
+ stdio: "inherit",
79
+ env: __assign(__assign({}, process.env), { PORT: convertedPort ? convertedPort.toString() : undefined }),
83
80
  });
81
+ return [2 /*return*/];
84
82
  });
85
- });
83
+ }); });
86
84
  // Handle the build command
87
85
  program
88
86
  .command("build")
@@ -155,43 +155,41 @@ export var generateStaticRoutes = function (router, isRoot) {
155
155
  var finalProps = __assign(__assign({}, props), { params: params });
156
156
  return _jsx(Layout, __assign({}, finalProps));
157
157
  },
158
- loader: function (_a) {
159
- var params = _a.params, request = _a.request;
160
- return __awaiter(void 0, void 0, void 0, function () {
161
- var response, formData, error_1;
162
- return __generator(this, function (_b) {
163
- switch (_b.label) {
164
- case 0:
165
- _b.trys.push([0, 2, , 3]);
166
- // Check if the loader is defined
167
- if (!Layout.loader) {
168
- throw new Error("Missing loader function");
169
- }
170
- return [4 /*yield*/, Layout.loader({ params: params, request: request })];
171
- case 1:
172
- response = _b.sent();
173
- // Handle redirection
174
- if (response.redirect) {
175
- formData = new FormData();
176
- formData.append("redirect", response.redirect);
177
- return [2 /*return*/, new Response(formData, {
178
- status: 302,
179
- headers: {
180
- Location: response.redirect,
181
- },
182
- })];
183
- }
184
- return [2 /*return*/, response];
185
- case 2:
186
- error_1 = _b.sent();
187
- return [2 /*return*/, {
188
- props: {},
189
- }];
190
- case 3: return [2 /*return*/];
191
- }
192
- });
158
+ loader: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
159
+ var response, formData, error_1;
160
+ var params = _b.params, request = _b.request;
161
+ return __generator(this, function (_c) {
162
+ switch (_c.label) {
163
+ case 0:
164
+ _c.trys.push([0, 2, , 3]);
165
+ // Check if the loader is defined
166
+ if (!Layout.loader) {
167
+ throw new Error("Missing loader function");
168
+ }
169
+ return [4 /*yield*/, Layout.loader({ params: params, request: request })];
170
+ case 1:
171
+ response = _c.sent();
172
+ // Handle redirection
173
+ if (response.redirect) {
174
+ formData = new FormData();
175
+ formData.append("redirect", response.redirect);
176
+ return [2 /*return*/, new Response(formData, {
177
+ status: 302,
178
+ headers: {
179
+ Location: response.redirect,
180
+ },
181
+ })];
182
+ }
183
+ return [2 /*return*/, response];
184
+ case 2:
185
+ error_1 = _c.sent();
186
+ return [2 /*return*/, {
187
+ props: {},
188
+ }];
189
+ case 3: return [2 /*return*/];
190
+ }
193
191
  });
194
- },
192
+ }); },
195
193
  children: [],
196
194
  };
197
195
  // Defining the page not found route
@@ -215,20 +213,20 @@ export var generateStaticRoutes = function (router, isRoot) {
215
213
  return {
216
214
  path: path,
217
215
  loader: function (_a) {
218
- var params = _a.params, request = _a.request;
219
- return __awaiter(this, void 0, void 0, function () {
216
+ return __awaiter(this, arguments, void 0, function (_b) {
220
217
  var response, formData, error_2;
221
- return __generator(this, function (_b) {
222
- switch (_b.label) {
218
+ var params = _b.params, request = _b.request;
219
+ return __generator(this, function (_c) {
220
+ switch (_c.label) {
223
221
  case 0:
224
- _b.trys.push([0, 2, , 3]);
222
+ _c.trys.push([0, 2, , 3]);
225
223
  // Check if the loader is defined
226
224
  if (!Page.loader) {
227
225
  throw new Error("Missing loader function");
228
226
  }
229
227
  return [4 /*yield*/, Page.loader({ params: params, request: request })];
230
228
  case 1:
231
- response = _b.sent();
229
+ response = _c.sent();
232
230
  // Handle redirection
233
231
  if (response.redirect) {
234
232
  formData = new FormData();
@@ -242,7 +240,7 @@ export var generateStaticRoutes = function (router, isRoot) {
242
240
  }
243
241
  return [2 /*return*/, response];
244
242
  case 2:
245
- error_2 = _b.sent();
243
+ error_2 = _c.sent();
246
244
  return [2 /*return*/, {
247
245
  props: {},
248
246
  }];
@@ -52,28 +52,32 @@ import { createFetchRequest } from "rasengan";
52
52
  import { fileTypeFromBuffer } from "file-type";
53
53
  // Create server for production only
54
54
  export default function handler(req, res) {
55
- var _a;
56
55
  return __awaiter(this, void 0, void 0, function () {
57
- var url, host, appPath, err_1, segments, segmentsWithoutOrigin, _i, segments_1, segment, filePath, file, otherFile, result, mimeType, file, templateHtml, serverFilePath, bootstrapDirPath, entry, bootstrap, styles, render, staticRoutes, loadTemplateHtml, handler_1, fetchRequest, context, status_1, redirect, helmetContext, router, rendered, html, e_1;
56
+ var url, host, appPath, filePath, file, err_1, segments, segmentsWithoutOrigin, _i, segments_1, segment, filePath, file, otherFile, result, mimeType, file, templateHtml, serverFilePath, bootstrapDirPath, entry, bootstrap, styles, render, staticRoutes, loadTemplateHtml, handler_1, fetchRequest, context, status_1, redirect, helmetContext, router, rendered, html, e_1;
57
+ var _a;
58
58
  return __generator(this, function (_b) {
59
59
  switch (_b.label) {
60
60
  case 0:
61
- _b.trys.push([0, 14, , 15]);
61
+ _b.trys.push([0, 15, , 16]);
62
62
  url = req.url;
63
63
  host = req.headers.host;
64
64
  appPath = process.cwd();
65
- if (!(url === "/robots.txt")) return [3 /*break*/, 4];
65
+ if (!(url === "/robots.txt")) return [3 /*break*/, 5];
66
66
  _b.label = 1;
67
67
  case 1:
68
- _b.trys.push([1, 3, , 4]);
69
- return [4 /*yield*/, fs.access(path.resolve(join(appPath, "dist/client/robots.txt")))];
68
+ _b.trys.push([1, 4, , 5]);
69
+ filePath = join(appPath, "dist/client/robots.txt");
70
+ return [4 /*yield*/, fs.access(path.resolve(filePath))];
70
71
  case 2:
71
72
  _b.sent();
72
- return [2 /*return*/, res.send(path.resolve(join(appPath, "dist/client/robots.txt")))];
73
+ return [4 /*yield*/, fs.readFile(filePath, "utf-8")];
73
74
  case 3:
75
+ file = _b.sent();
76
+ return [2 /*return*/, res.send(file)];
77
+ case 4:
74
78
  err_1 = _b.sent();
75
79
  return [2 /*return*/, res.send("\n user-agent: *\n disallow: /downloads/\n disallow: /private/\n allow: /\n \n user-agent: magicsearchbot\n disallow: /uploads/\n ")];
76
- case 4:
80
+ case 5:
77
81
  // ! Sitemap Fix
78
82
  if (url === "/sitemap.xml") {
79
83
  return [2 /*return*/, res.send(path.resolve(join(appPath, "dist/client/sitemap.xml")))];
@@ -82,7 +86,7 @@ export default function handler(req, res) {
82
86
  if (url === "/manifest.json") {
83
87
  return [2 /*return*/, res.send(path.resolve(join(appPath, "dist/client/manifest.json")))];
84
88
  }
85
- if (!url.includes("/assets")) return [3 /*break*/, 8];
89
+ if (!url.includes("/assets")) return [3 /*break*/, 9];
86
90
  segments = url.split("/");
87
91
  segmentsWithoutOrigin = __spreadArray([], segments, true);
88
92
  for (_i = 0, segments_1 = segments; _i < segments_1.length; _i++) {
@@ -94,7 +98,7 @@ export default function handler(req, res) {
94
98
  }
95
99
  filePath = join(appPath, "dist/client", segmentsWithoutOrigin.join("/"));
96
100
  return [4 /*yield*/, fs.readFile(filePath, "utf-8")];
97
- case 5:
101
+ case 6:
98
102
  file = _b.sent();
99
103
  if (url.endsWith(".js") || url.endsWith(".css")) {
100
104
  return [2 /*return*/, new Response(file, {
@@ -105,10 +109,10 @@ export default function handler(req, res) {
105
109
  })];
106
110
  }
107
111
  return [4 /*yield*/, fs.readFile(filePath)];
108
- case 6:
112
+ case 7:
109
113
  otherFile = _b.sent();
110
114
  return [4 /*yield*/, fileTypeFromBuffer(otherFile)];
111
- case 7:
115
+ case 8:
112
116
  result = _b.sent();
113
117
  mimeType = result ? result.mime : url.endsWith(".svg") ? "image/svg+xml" : "application/octet-stream";
114
118
  return [2 /*return*/, new Response(otherFile, {
@@ -117,22 +121,22 @@ export default function handler(req, res) {
117
121
  "Cache-Control": "max-age=31536000",
118
122
  },
119
123
  })];
120
- case 8:
121
- if (!(url.endsWith(".js") || url.endsWith(".css"))) return [3 /*break*/, 10];
122
- return [4 /*yield*/, fs.readFile(url, "utf-8")];
123
124
  case 9:
125
+ if (!(url.endsWith(".js") || url.endsWith(".css"))) return [3 /*break*/, 11];
126
+ return [4 /*yield*/, fs.readFile(url, "utf-8")];
127
+ case 10:
124
128
  file = _b.sent();
125
129
  return [2 /*return*/, res
126
130
  .status(200)
127
131
  .setHeader("Content-Type", url.endsWith(".js") ? "text/javascript" : "text/css")
128
132
  .setHeader("Cache-Control", "max-age=31536000")
129
133
  .end(file)];
130
- case 10:
134
+ case 11:
131
135
  templateHtml = "";
132
136
  serverFilePath = join(appPath, "dist/server/entry-server.js");
133
137
  bootstrapDirPath = join(appPath, "dist/client/assets");
134
138
  return [4 /*yield*/, import(serverFilePath)];
135
- case 11:
139
+ case 12:
136
140
  entry = _b.sent();
137
141
  bootstrap = "/assets/" +
138
142
  fsSync
@@ -146,7 +150,7 @@ export default function handler(req, res) {
146
150
  handler_1 = createStaticHandler(staticRoutes);
147
151
  fetchRequest = createFetchRequest(req, host);
148
152
  return [4 /*yield*/, handler_1.query(fetchRequest)];
149
- case 12:
153
+ case 13:
150
154
  context = _b.sent();
151
155
  status_1 = context.status;
152
156
  if (status_1 === 302) {
@@ -157,7 +161,7 @@ export default function handler(req, res) {
157
161
  helmetContext = {};
158
162
  router = createStaticRouter(handler_1.dataRoutes, context);
159
163
  return [4 /*yield*/, render(router, context, helmetContext)];
160
- case 13:
164
+ case 14:
161
165
  rendered = _b.sent();
162
166
  // Load template html
163
167
  if (!templateHtml) {
@@ -170,12 +174,12 @@ export default function handler(req, res) {
170
174
  .setHeader("Content-Type", "text/html")
171
175
  .setHeader("Cache-Control", "max-age=31536000")
172
176
  .end(html)];
173
- case 14:
177
+ case 15:
174
178
  e_1 = _b.sent();
175
179
  console.log(e_1.stack);
176
180
  res.status(500).end(e_1.stack);
177
- return [3 /*break*/, 15];
178
- case 15: return [2 /*return*/];
181
+ return [3 /*break*/, 16];
182
+ case 16: return [2 /*return*/];
179
183
  }
180
184
  });
181
185
  });
@@ -29,6 +29,7 @@ export default function createFetchRequest(req, host) {
29
29
  headers: headers,
30
30
  signal: controller.signal,
31
31
  body: null,
32
+ duplex: 'half'
32
33
  };
33
34
  if (req.method !== "GET" && req.method !== "HEAD") {
34
35
  init.body = req.body;
@@ -51,9 +51,9 @@ import { createStaticHandler, createStaticRouter, } from "react-router-dom/serve
51
51
  import { createFetchRequest } from "rasengan";
52
52
  // Create server for production only
53
53
  export function handleRequest(req, res) {
54
- var _a;
55
54
  return __awaiter(this, void 0, void 0, function () {
56
55
  var url, host, appPath, err_1, segments, segmentsWithoutOrigin, _i, segments_1, segment, filePath, file, file, templateHtml, serverFilePath, bootstrapDirPath, entry, bootstrap, styles, render, staticRoutes, loadTemplateHtml, handler, fetchRequest, context, status_1, redirect, helmetContext, router, rendered, html, e_1;
56
+ var _a;
57
57
  return __generator(this, function (_b) {
58
58
  switch (_b.label) {
59
59
  case 0:
@@ -47,10 +47,10 @@ import { getIP } from "./index.js";
47
47
  * @param {boolean} isProduction Whether the server is running in production mode
48
48
  * @param {boolean} open Whether to open the browser automatically
49
49
  */
50
- export function logServerInfo(port, isProduction, open) {
51
- if (open === void 0) { open = false; }
52
- return __awaiter(this, void 0, void 0, function () {
50
+ export function logServerInfo(port_1, isProduction_1) {
51
+ return __awaiter(this, arguments, void 0, function (port, isProduction, open) {
53
52
  var arrowRight, spinner, packageJson, parsedPackageJson, ipAddress;
53
+ if (open === void 0) { open = false; }
54
54
  return __generator(this, function (_a) {
55
55
  switch (_a.label) {
56
56
  case 0:
@@ -1,4 +1,4 @@
1
- import { Request } from "express";
1
+ import type { Request } from "express";
2
2
  /**
3
3
  * This function is used to create a fetch request from an express request.
4
4
  */
package/package.json CHANGED
@@ -1,129 +1,128 @@
1
1
  {
2
- "name": "rasengan",
3
- "private": false,
4
- "version": "1.0.0-beta.35",
5
- "description": "The modern frontend framework for React",
6
- "type": "module",
7
- "main": "lib/esm/index.js",
8
- "bin": {
9
- "rasengan": "./lib/esm/cli/index.js"
10
- },
11
- "exports": {
12
- ".": {
13
- "import": {
14
- "types": "./lib/types/index.d.ts",
15
- "default": "./lib/esm/index.js"
16
- },
17
- "require": {
18
- "types": "./lib/types/index.d.ts",
19
- "default": "./lib/esm/index.js"
20
- },
21
- "types": "./lib/types/index.d.ts",
22
- "default": "./lib/esm/index.js"
23
- },
24
- "./types/client": {
25
- "types": "./types/client.d.ts"
26
- },
27
- "./package.json": "./package.json"
28
- },
29
- "author": {
30
- "name": "dilane3",
31
- "email": "komboudilane125@gmail.com",
32
- "url": "https://dilane3.com",
33
- "twitter": "https://twitter.com/dilanekombou",
34
- "github": "https://github.com/dilane3"
35
- },
36
- "repository": {
37
- "type": "git",
38
- "url": "https://github.com/rasengan-dev/rasenganjs.git",
39
- "issues": "https://github.com/rasengan-dev/rasenganjs/issues"
40
- },
41
- "homepage": "https://rasengan.dev",
42
- "scripts": {
43
- "dev": "node server",
44
- "preview": "cross-env NODE_ENV=production node server",
45
- "build": "npm run build:client && npm run build:server",
46
- "build:client": "vite build --ssrManifest --outDir dist/client",
47
- "build:server": "vite build --ssr node_modules/rasengan/lib/esm/entries/entry-server.js --outDir dist/server",
48
- "compile": "tsc -b ./tsconfig.esm.json ./tsconfig.types.json",
49
- "build:lib:clean": "rm -rf ./lib",
50
- "build:lib:all": "npm-run-all build:lib:clean compile && node ./src/scripts/copy-extra-files.js",
51
- "deploy": "npm publish --access public",
52
- "deploy:beta": "npm run deploy --tag beta",
53
- "pack": "npm pack --pack-destination ./../packages/rasengan/"
54
- },
55
- "dependencies": {
56
- "@vercel/node": "^3.0.14",
57
- "@vitejs/plugin-react": "^4.2.1",
58
- "chalk": "^5.3.0",
59
- "commander": "^11.1.0",
60
- "compression": "^1.7.4",
61
- "cross-spawn": "^7.0.3",
62
- "execa": "^8.0.1",
63
- "express": "^4.18.2",
64
- "file-type": "^19.0.0",
65
- "inquirer": "^9.2.12",
66
- "keypress": "^0.2.1",
67
- "node-fetch": "^3.3.2",
68
- "open": "^10.1.0",
69
- "ora": "^7.0.1",
70
- "react-helmet-async": "^2.0.4",
71
- "react-router-dom": "^6.20.1",
72
- "sirv": "^2.0.3",
73
- "vite-plugin-css-injected-by-js": "^3.5.0"
74
- },
75
- "peerDependencies": {
76
- "@netlify/functions": "^2.6.0",
77
- "@types/node": "^18.0.0 || >=20.0.0",
78
- "less": "*",
79
- "react": "^18.2.0",
80
- "react-dom": "^18.2.0",
81
- "sass": "*",
82
- "stylus": "*",
83
- "vite": "^5.2.0"
84
- },
85
- "peerDependenciesMeta": {
86
- "@types/node": {
87
- "optional": true
88
- },
89
- "@netlify/functions": {
90
- "optional": true
91
- },
92
- "sass": {
93
- "optional": true
94
- },
95
- "stylus": {
96
- "optional": true
97
- },
98
- "less": {
99
- "optional": true
100
- }
101
- },
102
- "devDependencies": {
103
- "@types/compression": "^1.7.4",
104
- "@types/cross-spawn": "^6.0.4",
105
- "@types/express": "^4.17.19",
106
- "@types/node": "^20.8.6",
107
- "@types/react": "^18.2.28",
108
- "@types/react-dom": "^18.2.13",
109
- "cross-env": "^7.0.3",
110
- "npm-run-all": "^4.1.5",
111
- "typescript": "^5.2.2"
112
- },
113
- "resolutions": {
114
- "@vitejs/plugin-react": "^4.2.1"
115
- },
116
- "license": "MIT",
117
- "engines": {
118
- "node": ">=18.19.0",
119
- "npm": ">=7.0.0"
120
- },
121
- "keywords": [
122
- "rasengan",
123
- "frontend",
124
- "framework",
125
- "react",
126
- "vite",
127
- "ssr"
128
- ]
2
+ "name": "rasengan",
3
+ "private": false,
4
+ "version": "1.0.0-beta.36",
5
+ "description": "The modern frontend framework for React",
6
+ "type": "module",
7
+ "main": "lib/esm/index.js",
8
+ "bin": {
9
+ "rasengan": "./lib/esm/cli/index.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "import": {
14
+ "types": "./lib/types/index.d.ts",
15
+ "default": "./lib/esm/index.js"
16
+ },
17
+ "require": {
18
+ "types": "./lib/types/index.d.ts",
19
+ "default": "./lib/esm/index.js"
20
+ },
21
+ "types": "./lib/types/index.d.ts",
22
+ "default": "./lib/esm/index.js"
23
+ },
24
+ "./types/client": {
25
+ "types": "./types/client.d.ts"
26
+ },
27
+ "./package.json": "./package.json"
28
+ },
29
+ "author": {
30
+ "name": "dilane3",
31
+ "email": "komboudilane125@gmail.com",
32
+ "url": "https://dilane3.com",
33
+ "twitter": "https://twitter.com/dilanekombou",
34
+ "github": "https://github.com/dilane3"
35
+ },
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/rasengan-dev/rasenganjs.git",
39
+ "issues": "https://github.com/rasengan-dev/rasenganjs/issues"
40
+ },
41
+ "homepage": "https://rasengan.dev",
42
+ "scripts": {
43
+ "dev": "node server",
44
+ "preview": "cross-env NODE_ENV=production node server",
45
+ "build": "npm run build:client && npm run build:server",
46
+ "build:client": "vite build --ssrManifest --outDir dist/client",
47
+ "build:server": "vite build --ssr node_modules/rasengan/lib/esm/entries/entry-server.js --outDir dist/server",
48
+ "compile": "tsc -b ./tsconfig.esm.json ./tsconfig.types.json",
49
+ "build:lib:clean": "rm -rf ./lib",
50
+ "build:lib:all": "npm-run-all build:lib:clean compile && node ./src/scripts/copy-extra-files.js",
51
+ "deploy": "npm publish --access public",
52
+ "deploy:beta": "npm run deploy --tag beta",
53
+ "pack": "npm pack --pack-destination ./../packages/rasengan/"
54
+ },
55
+ "dependencies": {
56
+ "@vitejs/plugin-react": "^4.2.1",
57
+ "chalk": "^5.3.0",
58
+ "commander": "^11.1.0",
59
+ "compression": "^1.7.4",
60
+ "cross-spawn": "^7.0.3",
61
+ "execa": "^8.0.1",
62
+ "express": "^4.18.2",
63
+ "file-type": "^19.0.0",
64
+ "inquirer": "^9.2.12",
65
+ "keypress": "^0.2.1",
66
+ "node-fetch": "^3.3.2",
67
+ "open": "^10.1.0",
68
+ "ora": "^7.0.1",
69
+ "react-helmet-async": "^2.0.4",
70
+ "react-router-dom": "^6.20.1",
71
+ "sirv": "^2.0.3"
72
+ },
73
+ "peerDependencies": {
74
+ "@netlify/functions": "^2.6.0",
75
+ "@types/node": "^18.0.0 || >=20.0.0",
76
+ "less": "*",
77
+ "react": "^18.3.0",
78
+ "react-dom": "^18.3.0",
79
+ "sass": "*",
80
+ "stylus": "*",
81
+ "vite": "^5.2.0"
82
+ },
83
+ "peerDependenciesMeta": {
84
+ "@types/node": {
85
+ "optional": true
86
+ },
87
+ "@netlify/functions": {
88
+ "optional": true
89
+ },
90
+ "sass": {
91
+ "optional": true
92
+ },
93
+ "stylus": {
94
+ "optional": true
95
+ },
96
+ "less": {
97
+ "optional": true
98
+ }
99
+ },
100
+ "devDependencies": {
101
+ "@types/compression": "^1.7.4",
102
+ "@types/cross-spawn": "^6.0.4",
103
+ "@types/express": "^4.17.19",
104
+ "@types/node": "^20.8.6",
105
+ "@types/react": "^18.3.3",
106
+ "@types/react-dom": "^18.3.0",
107
+ "@vercel/node": "^3.0.14",
108
+ "cross-env": "^7.0.3",
109
+ "npm-run-all": "^4.1.5",
110
+ "typescript": "^5.2.2"
111
+ },
112
+ "resolutions": {
113
+ "@vitejs/plugin-react": "^4.2.1"
114
+ },
115
+ "license": "MIT",
116
+ "engines": {
117
+ "node": ">=18.19.0",
118
+ "npm": ">=7.0.0"
119
+ },
120
+ "keywords": [
121
+ "rasengan",
122
+ "frontend",
123
+ "framework",
124
+ "react",
125
+ "vite",
126
+ "ssr"
127
+ ]
129
128
  }