Replace CDN React/ReactDOM/Babel with local libs; remove Babel and inline scripts Build Tailwind locally, add safelist; switch to assets/tailwind.css Self-host Font Awesome and Inter (CSS + woff2); remove external font CDNs Implement strict CSP (no unsafe-inline/eval; scripts/styles/fonts from self) Extract inline handlers; move PWA scripts to external files Add local QR code generation (qrcode lib) and remove api.qrserver.com Improve SessionTypeSelector visual selection (highlighted background and ring) Keep PWA working with service worker and offline assets Refs: CSP hardening, offline-first, no external dependencies
66 lines
2.7 KiB
JavaScript
66 lines
2.7 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.argsert = void 0;
|
|
const yerror_1 = require("./yerror");
|
|
const parse_command_1 = require("./parse-command");
|
|
const positionName = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth'];
|
|
function argsert(arg1, arg2, arg3) {
|
|
function parseArgs() {
|
|
return typeof arg1 === 'object'
|
|
? [{ demanded: [], optional: [] }, arg1, arg2]
|
|
: [parse_command_1.parseCommand(`cmd ${arg1}`), arg2, arg3];
|
|
}
|
|
// TODO: should this eventually raise an exception.
|
|
try {
|
|
// preface the argument description with "cmd", so
|
|
// that we can run it through yargs' command parser.
|
|
let position = 0;
|
|
let [parsed, callerArguments, length] = parseArgs();
|
|
const args = [].slice.call(callerArguments);
|
|
while (args.length && args[args.length - 1] === undefined)
|
|
args.pop();
|
|
length = length || args.length;
|
|
if (length < parsed.demanded.length) {
|
|
throw new yerror_1.YError(`Not enough arguments provided. Expected ${parsed.demanded.length} but received ${args.length}.`);
|
|
}
|
|
const totalCommands = parsed.demanded.length + parsed.optional.length;
|
|
if (length > totalCommands) {
|
|
throw new yerror_1.YError(`Too many arguments provided. Expected max ${totalCommands} but received ${length}.`);
|
|
}
|
|
parsed.demanded.forEach((demanded) => {
|
|
const arg = args.shift();
|
|
const observedType = guessType(arg);
|
|
const matchingTypes = demanded.cmd.filter(type => type === observedType || type === '*');
|
|
if (matchingTypes.length === 0)
|
|
argumentTypeError(observedType, demanded.cmd, position);
|
|
position += 1;
|
|
});
|
|
parsed.optional.forEach((optional) => {
|
|
if (args.length === 0)
|
|
return;
|
|
const arg = args.shift();
|
|
const observedType = guessType(arg);
|
|
const matchingTypes = optional.cmd.filter(type => type === observedType || type === '*');
|
|
if (matchingTypes.length === 0)
|
|
argumentTypeError(observedType, optional.cmd, position);
|
|
position += 1;
|
|
});
|
|
}
|
|
catch (err) {
|
|
console.warn(err.stack);
|
|
}
|
|
}
|
|
exports.argsert = argsert;
|
|
function guessType(arg) {
|
|
if (Array.isArray(arg)) {
|
|
return 'array';
|
|
}
|
|
else if (arg === null) {
|
|
return 'null';
|
|
}
|
|
return typeof arg;
|
|
}
|
|
function argumentTypeError(observedType, allowedTypes, position) {
|
|
throw new yerror_1.YError(`Invalid ${positionName[position] || 'manyith'} argument. Expected ${allowedTypes.join(' or ')} but received ${observedType}.`);
|
|
}
|