nothumanallowed 16.0.40 → 16.0.41
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/package.json +1 -1
- package/src/constants.mjs +1 -1
- package/src/server/routes/webcraft.mjs +73 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.41",
|
|
4
4
|
"description": "Local AI assistant: 80 tools (Gmail, Calendar, Drive, GitHub, Slack, browser, code, files), 38 agents, visual workflows (Studio, AWF, WebCraft). Install with `npm i -g nothumanallowed`, run with `nha ui`. Free tier built-in (Liara), no API key required. Your data stays on your PC — OAuth tokens local, no cloud. Open-source MIT.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/constants.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
7
7
|
|
|
8
|
-
export const VERSION = '16.0.
|
|
8
|
+
export const VERSION = '16.0.41';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -5027,15 +5027,40 @@ function compilePath(p) {
|
|
|
5027
5027
|
}
|
|
5028
5028
|
|
|
5029
5029
|
function createApp() {
|
|
5030
|
-
|
|
5030
|
+
// Flat layer list — each handler is its own layer (matches Express semantics).
|
|
5031
|
+
// Layer types: 'normal' (3-arg) or 'error' (4-arg). Path-mounted layers
|
|
5032
|
+
// ('app.use("/api", router)') get a prefix that must match the URL.
|
|
5033
|
+
const layers = [];
|
|
5031
5034
|
const settings = {};
|
|
5035
|
+
|
|
5036
|
+
function addLayer(method, re, keys, prefix, handler) {
|
|
5037
|
+
const isErrHandler = typeof handler === 'function' && handler.length === 4;
|
|
5038
|
+
layers.push({ method, re, keys, prefix, handler, isErrHandler });
|
|
5039
|
+
}
|
|
5040
|
+
|
|
5032
5041
|
function use(arg, ...rest) {
|
|
5033
|
-
|
|
5034
|
-
|
|
5042
|
+
let prefix = '';
|
|
5043
|
+
let handlers = rest;
|
|
5044
|
+
if (typeof arg === 'function') {
|
|
5045
|
+
handlers = [arg, ...rest];
|
|
5046
|
+
} else {
|
|
5047
|
+
prefix = String(arg).replace(/\\/+$/, '');
|
|
5048
|
+
}
|
|
5049
|
+
for (const h of handlers.flat()) {
|
|
5050
|
+
if (typeof h !== 'function') continue;
|
|
5051
|
+
addLayer('ALL', /.*/, [], prefix, h);
|
|
5052
|
+
}
|
|
5035
5053
|
return app;
|
|
5036
5054
|
}
|
|
5037
5055
|
function addRoute(method) {
|
|
5038
|
-
return (
|
|
5056
|
+
return (p, ...handlers) => {
|
|
5057
|
+
const c = compilePath(p);
|
|
5058
|
+
for (const h of handlers.flat()) {
|
|
5059
|
+
if (typeof h !== 'function') continue;
|
|
5060
|
+
addLayer(method, c.re, c.keys, '', h);
|
|
5061
|
+
}
|
|
5062
|
+
return app;
|
|
5063
|
+
};
|
|
5039
5064
|
}
|
|
5040
5065
|
const app = async function (req, res) {
|
|
5041
5066
|
const parsed = url.parse(req.url, true);
|
|
@@ -5049,30 +5074,52 @@ function createApp() {
|
|
|
5049
5074
|
res.sendStatus = function (n) { this.statusCode = n; this.end(http.STATUS_CODES[n] || ''); return this; };
|
|
5050
5075
|
res.redirect = function (loc) { this.statusCode = 302; this.setHeader('Location', loc); this.end(); return this; };
|
|
5051
5076
|
}
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5077
|
+
|
|
5078
|
+
// Real Express-style routing chain:
|
|
5079
|
+
// - 3-arg handlers run ONLY when err is null/undefined
|
|
5080
|
+
// - 4-arg handlers run ONLY when err is truthy
|
|
5081
|
+
// - Path-mounted middleware ('/api') only runs if req.path matches prefix
|
|
5082
|
+
// - Method-specific layers (GET/POST/...) only run for that method
|
|
5083
|
+
let idx = 0;
|
|
5084
|
+
function nextLayer(err) {
|
|
5085
|
+
while (idx < layers.length) {
|
|
5086
|
+
const layer = layers[idx++];
|
|
5087
|
+
// Method filter
|
|
5057
5088
|
if (layer.method !== 'ALL' && layer.method !== req.method) continue;
|
|
5058
|
-
|
|
5059
|
-
if (
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
}
|
|
5070
|
-
|
|
5089
|
+
// Path filter
|
|
5090
|
+
if (layer.prefix) {
|
|
5091
|
+
if (!req.path.startsWith(layer.prefix)) continue;
|
|
5092
|
+
const remaining = req.path.slice(layer.prefix.length);
|
|
5093
|
+
if (remaining && !remaining.startsWith('/')) continue;
|
|
5094
|
+
} else if (layer.re && layer.method !== 'ALL') {
|
|
5095
|
+
// Specific route — must match
|
|
5096
|
+
const m = req.path.match(layer.re);
|
|
5097
|
+
if (!m) continue;
|
|
5098
|
+
req.params = {};
|
|
5099
|
+
layer.keys.forEach((k, i) => { req.params[k] = m[i + 1]; });
|
|
5100
|
+
}
|
|
5101
|
+
// Error chain filter: skip normal handlers when in error, and skip
|
|
5102
|
+
// error handlers when not in error. THIS is the fix for the MySaaS bug.
|
|
5103
|
+
if (err && !layer.isErrHandler) continue;
|
|
5104
|
+
if (!err && layer.isErrHandler) continue;
|
|
5105
|
+
|
|
5106
|
+
try {
|
|
5107
|
+
if (layer.isErrHandler) {
|
|
5108
|
+
return layer.handler(err, req, res, nextLayer);
|
|
5109
|
+
}
|
|
5110
|
+
return layer.handler(req, res, nextLayer);
|
|
5111
|
+
} catch (e) { return nextLayer(e); }
|
|
5071
5112
|
}
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5113
|
+
// End of chain — default response
|
|
5114
|
+
if (err) {
|
|
5115
|
+
res.statusCode = err.status || err.statusCode || 500;
|
|
5116
|
+
res.end('Error: ' + ((err && err.message) || String(err)));
|
|
5117
|
+
} else {
|
|
5118
|
+
res.statusCode = 404;
|
|
5119
|
+
res.end('Cannot ' + req.method + ' ' + req.path);
|
|
5120
|
+
}
|
|
5121
|
+
}
|
|
5122
|
+
nextLayer();
|
|
5076
5123
|
};
|
|
5077
5124
|
app.use = use;
|
|
5078
5125
|
app.get = addRoute('GET'); app.post = addRoute('POST'); app.put = addRoute('PUT');
|