@nanobpm/urban 0.75.0 → 0.75.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.
|
@@ -38,7 +38,7 @@ form .field input[type=checkbox],form .field input[type=radio]{width:auto}
|
|
|
38
38
|
<h1>Task inbox</h1><ul id="tasks"><li>loading…</li></ul>
|
|
39
39
|
<div id="form"></div>
|
|
40
40
|
<script>
|
|
41
|
-
const BASE=location.pathname.replace(
|
|
41
|
+
const BASE=location.pathname.replace(/[/]+$/,'');
|
|
42
42
|
const tasksEl=document.getElementById('tasks');
|
|
43
43
|
const formEl=document.getElementById('form');
|
|
44
44
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nanobpm/urban",
|
|
3
|
-
"version": "0.75.
|
|
3
|
+
"version": "0.75.1",
|
|
4
4
|
"description": "Urban: build and run code-first apps on Nano — runtime, derivation toolkit, and CLI in one. Author durable processes with @nanobpm/workflow (defineFlow), a typed datasource, forms, triggers and surfaces from a nano.app.json manifest, on Node or Deno.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -163,6 +163,24 @@ test("inbox page renders the client-side form fetch + renderer", async () => {
|
|
|
163
163
|
assert.ok(!/const\s+variables\s*=\s*\{\}/.test(rendered), "client must not collect untrusted keys into a plain {} object");
|
|
164
164
|
});
|
|
165
165
|
|
|
166
|
+
test("inbox client script parses — no template-literal backslash collapse", async () => {
|
|
167
|
+
const { page } = inboxRoutes(fakeEngine);
|
|
168
|
+
const rendered = String((await call(page)).body);
|
|
169
|
+
// Extract every inline <script> body and assert each parses. A backslash-bearing regex
|
|
170
|
+
// written inside the page's template literal (e.g. `/\/+$/`) collapses to `//…` at emit
|
|
171
|
+
// time, turning the rest of the statement into a line comment and breaking the parse
|
|
172
|
+
// (issue #433). `new Function(body)` throws on any such SyntaxError.
|
|
173
|
+
const scripts = rendered
|
|
174
|
+
.split("<script>")
|
|
175
|
+
.slice(1)
|
|
176
|
+
.map((chunk) => chunk.split("</scr" + "ipt>")[0]);
|
|
177
|
+
assert.ok(scripts.length > 0, "inbox page has at least one inline script");
|
|
178
|
+
for (const body of scripts) {
|
|
179
|
+
assert.ok(!body.includes("//+$/"), "trailing-slash-strip regex collapsed to a line comment");
|
|
180
|
+
assert.doesNotThrow(() => new Function(body), "inline client script must parse");
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
166
184
|
test("/api/tasks surfaces the resolved form linkage", async () => {
|
|
167
185
|
let seenFilter: unknown;
|
|
168
186
|
const engine: EngineClient = {
|
|
@@ -50,7 +50,7 @@ form .field input[type=checkbox],form .field input[type=radio]{width:auto}
|
|
|
50
50
|
<h1>Task inbox</h1><ul id="tasks"><li>loading…</li></ul>
|
|
51
51
|
<div id="form"></div>
|
|
52
52
|
<script>
|
|
53
|
-
const BASE=location.pathname.replace(
|
|
53
|
+
const BASE=location.pathname.replace(/[/]+$/,'');
|
|
54
54
|
const tasksEl=document.getElementById('tasks');
|
|
55
55
|
const formEl=document.getElementById('form');
|
|
56
56
|
|