spice-js 2.6.70 → 2.6.72
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/build/bootstrap/map.js +17 -29
- package/build/bootstrap/routes.js +45 -9
- package/build/bootstrap/schema_extenders.js +38 -9
- package/build/bootstrap/validation.js +38 -25
- package/build/index.js +72 -6
- package/build/models/SpiceModel.js +214 -49
- package/bun.lock +2281 -0
- package/package.json +1 -1
- package/src/bootstrap/map.js +17 -12
- package/src/bootstrap/routes.js +36 -10
- package/src/bootstrap/schema_extenders.js +33 -10
- package/src/bootstrap/validation.js +38 -19
- package/src/index.js +51 -4
- package/src/models/SpiceModel.js +202 -78
package/build/bootstrap/map.js
CHANGED
|
@@ -6,40 +6,28 @@ var _lodash = _interopRequireDefault(require("lodash"));
|
|
|
6
6
|
|
|
7
7
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
try {
|
|
10
|
+
var resources = ["models", "controllers", "schemas", "cache"];
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
for (var resource of resources) {
|
|
13
|
+
var paths = _path.default.join(spice.root_path, resource);
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
spice[resource] = {};
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
var files = require("fs").readdirSync(paths);
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
for (var file of files) {
|
|
20
|
+
var file_name = file.split(".")[0];
|
|
21
|
+
|
|
22
|
+
var imported = require(_path.default.join(paths, file));
|
|
23
|
+
|
|
24
|
+
var moduleDefault = imported.default || imported; // ⚡ Only store once, create both references to same object
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
spice[resource] = {};
|
|
27
|
-
|
|
28
|
-
for (var file of require("fs").readdirSync(paths)) {
|
|
29
|
-
var file_name = file.split(".")[0];
|
|
30
|
-
spice[resource][file_name.toLowerCase()] = (yield Promise.resolve("" + _path.default.join(paths, file)).then(s => _interopRequireWildcard(require(s)))).default;
|
|
31
|
-
spice[resource][file_name] = (yield Promise.resolve("" + _path.default.join(paths, file)).then(s => _interopRequireWildcard(require(s)))).default;
|
|
32
|
-
|
|
33
|
-
if (resource == "models") {
|
|
34
|
-
new spice[resource][file_name]({});
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
return function (_x) {
|
|
40
|
-
return _ref.apply(this, arguments);
|
|
41
|
-
};
|
|
42
|
-
}());
|
|
26
|
+
spice[resource][file_name] = moduleDefault;
|
|
27
|
+
spice[resource][file_name.toLowerCase()] = moduleDefault; // ⚡ REMOVED: No longer instantiating models at startup
|
|
28
|
+
// Models will be instantiated when needed via `new spice.models[name]({})`
|
|
29
|
+
}
|
|
30
|
+
}
|
|
43
31
|
} catch (error) {
|
|
44
32
|
console.log("Error Happened", error);
|
|
45
33
|
}
|
|
@@ -2,17 +2,53 @@
|
|
|
2
2
|
|
|
3
3
|
var _path = _interopRequireDefault(require("path"));
|
|
4
4
|
|
|
5
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
6
|
+
|
|
7
|
+
var _util = require("util");
|
|
8
|
+
|
|
5
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
12
|
+
|
|
13
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
14
|
+
|
|
15
|
+
var readdir = (0, _util.promisify)(_fs.default.readdir);
|
|
16
|
+
spice.routers = {}; // ⚡ OPTIMIZED: Async file operations for non-blocking route loading
|
|
17
|
+
|
|
18
|
+
function loadRoutes() {
|
|
19
|
+
return _loadRoutes.apply(this, arguments);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function _loadRoutes() {
|
|
23
|
+
_loadRoutes = _asyncToGenerator(function* () {
|
|
24
|
+
var paths = _path.default.join(spice.root_path, 'routes');
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
var files = yield readdir(paths);
|
|
28
|
+
|
|
29
|
+
for (var file of files) {
|
|
30
|
+
if (file !== 'index.js' && file.endsWith('.js')) {
|
|
31
|
+
try {
|
|
32
|
+
var router = require(_path.default.join(paths, file)); // Handle ESM default exports
|
|
33
|
+
|
|
8
34
|
|
|
9
|
-
|
|
35
|
+
if (router.default) {
|
|
36
|
+
router = router.default;
|
|
37
|
+
}
|
|
10
38
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
39
|
+
var routerName = file.split('.')[0];
|
|
40
|
+
spice.routers[routerName] = router;
|
|
41
|
+
spice.app.use(spice.routers[routerName].routes()).use(spice.routers[routerName].allowedMethods());
|
|
42
|
+
} catch (routeError) {
|
|
43
|
+
console.error("Failed to load route " + file + ":", routeError.message);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error('Error loading routes:', error);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return _loadRoutes.apply(this, arguments);
|
|
52
|
+
}
|
|
14
53
|
|
|
15
|
-
|
|
16
|
-
spice.app.use(spice.routers[file.split('.')[0]].routes()).use(spice.routers[file.split('.')[0]].allowedMethods());
|
|
17
|
-
}
|
|
18
|
-
});
|
|
54
|
+
module.exports = loadRoutes;
|
|
@@ -4,22 +4,51 @@ var _path = _interopRequireDefault(require("path"));
|
|
|
4
4
|
|
|
5
5
|
var _fs = _interopRequireDefault(require("fs"));
|
|
6
6
|
|
|
7
|
+
var _util = require("util");
|
|
8
|
+
|
|
7
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
8
10
|
|
|
9
|
-
var
|
|
11
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
12
|
+
|
|
13
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
14
|
+
|
|
15
|
+
var readdir = (0, _util.promisify)(_fs.default.readdir);
|
|
16
|
+
spice.schema_extenders = {}; // ⚡ OPTIMIZED: Async file operations for non-blocking schema extender loading
|
|
17
|
+
|
|
18
|
+
function loadSchemaExtenders() {
|
|
19
|
+
return _loadSchemaExtenders.apply(this, arguments);
|
|
20
|
+
}
|
|
10
21
|
|
|
11
|
-
|
|
22
|
+
function _loadSchemaExtenders() {
|
|
23
|
+
_loadSchemaExtenders = _asyncToGenerator(function* () {
|
|
24
|
+
var paths = _path.default.join(spice.root_path, "schema_extenders");
|
|
12
25
|
|
|
13
|
-
if (_fs.default.existsSync(paths)) {
|
|
14
|
-
_fs.default.readdirSync(paths).forEach(function (file) {
|
|
15
|
-
if (_path.default.extname(file) === ".js" && file !== "index.js") {
|
|
26
|
+
if (_fs.default.existsSync(paths)) {
|
|
16
27
|
try {
|
|
17
|
-
var
|
|
28
|
+
var files = yield readdir(paths);
|
|
18
29
|
|
|
19
|
-
|
|
30
|
+
for (var file of files) {
|
|
31
|
+
if (_path.default.extname(file) === ".js" && file !== "index.js") {
|
|
32
|
+
try {
|
|
33
|
+
var extender = require(_path.default.join(paths, file)); // Handle ESM default exports
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
if (extender.default) {
|
|
37
|
+
extender = extender.default;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
spice.schema_extenders[_path.default.basename(file, ".js")] = extender;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error("Failed to load schema extender " + file + ":", error.message);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
20
46
|
} catch (error) {
|
|
21
|
-
console.error("
|
|
47
|
+
console.error("Error loading schema extenders:", error);
|
|
22
48
|
}
|
|
23
49
|
}
|
|
24
50
|
});
|
|
25
|
-
|
|
51
|
+
return _loadSchemaExtenders.apply(this, arguments);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = loadSchemaExtenders;
|
|
@@ -2,37 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
var _path = _interopRequireDefault(require("path"));
|
|
4
4
|
|
|
5
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
6
|
+
|
|
7
|
+
var _util = require("util");
|
|
8
|
+
|
|
5
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
* Created by chadfraser on 25/02/2017.
|
|
9
|
-
*/
|
|
10
|
-
module.exports = function () {
|
|
11
|
-
return new Promise(function (resolve, reject) {
|
|
12
|
-
try {
|
|
13
|
-
var locations = [spice.module_root_path + '/val', spice.root_path + '/validators'];
|
|
11
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
var files = require('fs').readdirSync(i);
|
|
13
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
if (file != 'index.js') {
|
|
20
|
-
file.split('.')[0];
|
|
15
|
+
var readdir = (0, _util.promisify)(_fs.default.readdir); // ⚡ OPTIMIZED: Async file operations for non-blocking validator loading
|
|
21
16
|
|
|
22
|
-
|
|
17
|
+
module.exports =
|
|
18
|
+
/*#__PURE__*/
|
|
19
|
+
_asyncToGenerator(function* () {
|
|
20
|
+
try {
|
|
21
|
+
var locations = [spice.module_root_path + '/val', spice.root_path + '/validators'];
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
for (var location of locations) {
|
|
24
|
+
// Check if directory exists before trying to read it
|
|
25
|
+
if (_fs.default.existsSync(location)) {
|
|
26
|
+
try {
|
|
27
|
+
var files = yield readdir(location);
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
for (var file of files) {
|
|
30
|
+
if (file !== 'index.js' && file.endsWith('.js')) {
|
|
31
|
+
try {
|
|
32
|
+
require(_path.default.join(location, file));
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
console.log('Loading Validator', _path.default.join(location, file));
|
|
35
|
+
} catch (validatorError) {
|
|
36
|
+
console.error("Failed to load validator " + file + ":", validatorError.message);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.log("Error reading " + location + ":", error.message);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
36
44
|
}
|
|
37
|
-
|
|
38
|
-
};
|
|
45
|
+
|
|
46
|
+
return {};
|
|
47
|
+
} catch (e) {
|
|
48
|
+
console.error('Error in validation bootstrap:', e);
|
|
49
|
+
throw e;
|
|
50
|
+
}
|
|
51
|
+
});
|
package/build/index.js
CHANGED
|
@@ -175,22 +175,88 @@ class Spice {
|
|
|
175
175
|
/* app._io.on("connection", (sock) => {
|
|
176
176
|
console.log("Connection Up", sock);
|
|
177
177
|
}); */
|
|
178
|
-
|
|
179
|
-
|
|
178
|
+
// ⚡ OPTIMIZED: Load routes and models first, then generate docs lazily
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
yield require("./loaders").load(); // ⚡ LAZY DOCS: Generate docs in background after startup to not block server
|
|
182
|
+
|
|
183
|
+
var docsCache = null;
|
|
184
|
+
var docsGenerating = false; // Generate docs asynchronously after startup
|
|
185
|
+
|
|
186
|
+
var generateDocsInBackground =
|
|
187
|
+
/*#__PURE__*/
|
|
188
|
+
function () {
|
|
189
|
+
var _ref = _asyncToGenerator(function* () {
|
|
190
|
+
if (docsCache || docsGenerating) return;
|
|
191
|
+
docsGenerating = true;
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
console.log("Generating API documentation...");
|
|
195
|
+
docsCache = yield (0, _generator.default)();
|
|
196
|
+
console.log("API documentation generated successfully");
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error("Error generating docs:", error);
|
|
199
|
+
docsCache = {
|
|
200
|
+
swagger: "2.0",
|
|
201
|
+
info: {
|
|
202
|
+
title: "API Docs",
|
|
203
|
+
version: "1.0.0"
|
|
204
|
+
},
|
|
205
|
+
paths: {},
|
|
206
|
+
definitions: {}
|
|
207
|
+
};
|
|
208
|
+
} finally {
|
|
209
|
+
docsGenerating = false;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
return function generateDocsInBackground() {
|
|
214
|
+
return _ref.apply(this, arguments);
|
|
215
|
+
};
|
|
216
|
+
}(); // Start generating docs in background (non-blocking)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
setTimeout(generateDocsInBackground, 100); // Middleware to serve docs - will wait if still generating
|
|
220
|
+
|
|
221
|
+
app.use(
|
|
222
|
+
/*#__PURE__*/
|
|
223
|
+
function () {
|
|
224
|
+
var _ref2 = _asyncToGenerator(function* (ctx, next) {
|
|
225
|
+
if (ctx.path === "/docs/spec" || ctx.path === "/docs/spec.json") {
|
|
226
|
+
// Wait for docs to be generated if not ready
|
|
227
|
+
while (docsGenerating && !docsCache) {
|
|
228
|
+
yield new Promise(resolve => setTimeout(resolve, 100));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (!docsCache) {
|
|
232
|
+
yield generateDocsInBackground();
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
ctx.body = docsCache;
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
yield next();
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
return function (_x, _x2) {
|
|
243
|
+
return _ref2.apply(this, arguments);
|
|
244
|
+
};
|
|
245
|
+
}());
|
|
180
246
|
app.use((0, _koa2SwaggerUi.koaSwagger)({
|
|
181
247
|
hideTopbar: true,
|
|
182
248
|
title: "Spice JS",
|
|
183
249
|
routePrefix: "/docs",
|
|
184
|
-
// host at /swagger instead of default /docs
|
|
185
250
|
swaggerOptions: {
|
|
186
|
-
|
|
251
|
+
url: "/docs/spec",
|
|
252
|
+
// Load spec from endpoint instead of inline
|
|
187
253
|
deepLinking: true,
|
|
188
254
|
displayRequestDuration: true,
|
|
189
255
|
jsonEditor: true
|
|
190
256
|
},
|
|
191
|
-
exposeSpec:
|
|
257
|
+
exposeSpec: false // We handle spec serving ourselves
|
|
258
|
+
|
|
192
259
|
}));
|
|
193
|
-
yield require("./loaders").load();
|
|
194
260
|
return spice;
|
|
195
261
|
} catch (e) {
|
|
196
262
|
console.log(e.stack);
|