部署优化
This commit is contained in:
21
app.js
21
app.js
@@ -796,6 +796,25 @@ const I18N = {
|
|||||||
const $ = (selector, root = document) => root.querySelector(selector);
|
const $ = (selector, root = document) => root.querySelector(selector);
|
||||||
const $$ = (selector, root = document) => [...root.querySelectorAll(selector)];
|
const $$ = (selector, root = document) => [...root.querySelectorAll(selector)];
|
||||||
|
|
||||||
|
function createUuid() {
|
||||||
|
if (typeof window.crypto?.randomUUID === "function") {
|
||||||
|
return window.crypto.randomUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
const bytes = new Uint8Array(16);
|
||||||
|
if (typeof window.crypto?.getRandomValues === "function") {
|
||||||
|
window.crypto.getRandomValues(bytes);
|
||||||
|
} else {
|
||||||
|
for (let index = 0; index < bytes.length; index += 1) {
|
||||||
|
bytes[index] = Math.floor(Math.random() * 256);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
||||||
|
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
||||||
|
const hex = [...bytes].map(byte => byte.toString(16).padStart(2, "0")).join("");
|
||||||
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
||||||
|
}
|
||||||
|
|
||||||
function mapApiOwner(record) {
|
function mapApiOwner(record) {
|
||||||
return {
|
return {
|
||||||
id: record.id,
|
id: record.id,
|
||||||
@@ -1654,7 +1673,7 @@ function calculateForm() {
|
|||||||
|
|
||||||
function resetStayForm(ownerId = owners[0]?.id || "") {
|
function resetStayForm(ownerId = owners[0]?.id || "") {
|
||||||
$("#stayForm").reset();
|
$("#stayForm").reset();
|
||||||
stayIdempotencyKey = IS_API_MODE ? window.crypto.randomUUID() : null;
|
stayIdempotencyKey = IS_API_MODE ? createUuid() : null;
|
||||||
$("#ownerSelect").value = String(ownerId);
|
$("#ownerSelect").value = String(ownerId);
|
||||||
$("#confirmationInput").value = "";
|
$("#confirmationInput").value = "";
|
||||||
$("#checkinInput").value = "2026-08-01";
|
$("#checkinInput").value = "2026-08-01";
|
||||||
|
|||||||
@@ -337,6 +337,6 @@
|
|||||||
<script src="runtime-config.js?v=20260802-login"></script>
|
<script src="runtime-config.js?v=20260802-login"></script>
|
||||||
<script src="owners-data.js"></script>
|
<script src="owners-data.js"></script>
|
||||||
<script src="api-client.js?v=20260802-login"></script>
|
<script src="api-client.js?v=20260802-login"></script>
|
||||||
<script src="app.js?v=20260803-accounts-fill-1"></script>
|
<script src="app.js?v=20260803-uuid-fallback"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
48
tests/browser-uuid.test.mjs
Normal file
48
tests/browser-uuid.test.mjs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import assert from "node:assert/strict";
|
||||||
|
import { readFile } from "node:fs/promises";
|
||||||
|
import test from "node:test";
|
||||||
|
import vm from "node:vm";
|
||||||
|
|
||||||
|
const appSource = await readFile(new URL("../app.js", import.meta.url), "utf8");
|
||||||
|
const helperStart = appSource.indexOf("function createUuid");
|
||||||
|
const helperEnd = appSource.indexOf("\n\nfunction mapApiOwner", helperStart);
|
||||||
|
assert.notEqual(helperStart, -1, "createUuid helper should exist");
|
||||||
|
assert.notEqual(helperEnd, -1, "createUuid helper should end before API mappers");
|
||||||
|
|
||||||
|
function loadCreateUuid(windowObject) {
|
||||||
|
const context = { window: windowObject };
|
||||||
|
vm.runInNewContext(`${appSource.slice(helperStart, helperEnd)}\nglobalThis.createUuid = createUuid;`, context);
|
||||||
|
return context.createUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
test("UUID generation falls back when crypto.randomUUID is unavailable", () => {
|
||||||
|
let next = 0;
|
||||||
|
const createUuid = loadCreateUuid({
|
||||||
|
crypto: {
|
||||||
|
getRandomValues(bytes) {
|
||||||
|
for (let index = 0; index < bytes.length; index += 1) {
|
||||||
|
bytes[index] = next;
|
||||||
|
next = (next + 17) % 256;
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.match(
|
||||||
|
createUuid(),
|
||||||
|
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("UUID generation uses native randomUUID when it is available", () => {
|
||||||
|
const createUuid = loadCreateUuid({
|
||||||
|
crypto: {
|
||||||
|
randomUUID() {
|
||||||
|
return "00000000-0000-4000-8000-000000000123";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(createUuid(), "00000000-0000-4000-8000-000000000123");
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user