Problem: the hexagonal refactor churns the backend tree for nine more phases; the UI delivery stack (web/ SPA, cmd/desktop Wails wrapper, compose/web image) must move to its own repo first so doc/layout rewrites land once on a backend-only tree. Change: - New repo git.hubris.network/dtoro/oikos-web (v0.33.0): web/, desktop/ (updateURL repointed to oikos-web releases), compose/, own CI (web + desktop jobs), own deploy script (CI-green gate, TOCTOU guard, version-tagged images, prune-to-3), own webhook receiver on :9798 + launchd unit, own compose project publishing the same 8091:80. - Cutover executed on mac-mini in order: oikos stack's web service stopped+removed, oikos-web project brought up on 8091; outer Caddy untouched (targets the published port) — serving + Authentik flow + /wails 404 quirk verified post-cutover. - Stripped from oikos: web/, cmd/desktop/, compose/web/, desktop CI workflow, ci.yml web job, Makefile ui/desktop/desktop-package/install targets, the compose web service, oikos-web from deploy.sh's fallback prune list; wails + go-keyring dropped from go.mod, vendor synced. - README / CONTRIBUTING / AGENTS.md / .agents dev+operations docs now point at the new repo; mbse + mascot design docs carry a path note. Risk: production SPA serving depends on the new pipeline now; rollback is versioned-image re-up of the old web service from a pre-split checkout (port 8091). Desktop builds installed before the split still check dtoro/oikos releases — one manual reinstall, noted in the oikos-web release notes. Verification: go vet, make test (race), make generate-check, golangci (no new findings; baseline down 400→365); post-cutover curls — localhost:8091 200, /wails/runtime.js 404, outer Caddy 302 Authentik.
202 lines
6.3 KiB
JavaScript
202 lines
6.3 KiB
JavaScript
'use strict';
|
|
|
|
var fs = require('node:fs');
|
|
var node_module = require('node:module');
|
|
var node_url = require('node:url');
|
|
var pathe = require('pathe');
|
|
|
|
const isWindows = process.platform === "win32";
|
|
const drive = isWindows ? process.cwd()[0] : null;
|
|
const driveOpposite = drive ? drive === drive.toUpperCase() ? drive.toLowerCase() : drive.toUpperCase() : null;
|
|
const driveRegexp = drive ? new RegExp(`(?:^|/@fs/)${drive}(:[\\/])`) : null;
|
|
const driveOppositeRegext = driveOpposite ? new RegExp(`(?:^|/@fs/)${driveOpposite}(:[\\/])`) : null;
|
|
function slash(str) {
|
|
return str.replace(/\\/g, "/");
|
|
}
|
|
const VALID_ID_PREFIX = "/@id/";
|
|
function normalizeRequestId(id, base) {
|
|
if (base && id.startsWith(withTrailingSlash(base))) {
|
|
id = `/${id.slice(base.length)}`;
|
|
}
|
|
if (driveRegexp && !(driveRegexp == null ? void 0 : driveRegexp.test(id)) && (driveOppositeRegext == null ? void 0 : driveOppositeRegext.test(id))) {
|
|
id = id.replace(driveOppositeRegext, `${drive}$1`);
|
|
}
|
|
return id.replace(/^\/@id\/__x00__/, "\0").replace(/^\/@id\//, "").replace(/^__vite-browser-external:/, "").replace(/^file:(\/+)/, isWindows ? "" : "/").replace(/\?v=\w+/, "?").replace(/&v=\w+/, "").replace(/\?t=\w+/, "?").replace(/&t=\w+/, "").replace(/\?import/, "?").replace(/&import/, "").replace(/\?&/, "?").replace(/\?+$/, "");
|
|
}
|
|
const postfixRE = /[?#].*$/;
|
|
function cleanUrl(url) {
|
|
return url.replace(postfixRE, "");
|
|
}
|
|
const internalRequests = ["@vite/client", "@vite/env"];
|
|
const internalRequestRegexp = new RegExp(
|
|
`^/?(?:${internalRequests.join("|")})$`
|
|
);
|
|
function isInternalRequest(id) {
|
|
return internalRequestRegexp.test(id);
|
|
}
|
|
const prefixedBuiltins = /* @__PURE__ */ new Set(["node:test"]);
|
|
const builtins = /* @__PURE__ */ new Set([
|
|
...node_module.builtinModules,
|
|
"assert/strict",
|
|
"diagnostics_channel",
|
|
"dns/promises",
|
|
"fs/promises",
|
|
"path/posix",
|
|
"path/win32",
|
|
"readline/promises",
|
|
"stream/consumers",
|
|
"stream/promises",
|
|
"stream/web",
|
|
"timers/promises",
|
|
"util/types",
|
|
"wasi"
|
|
]);
|
|
function normalizeModuleId(id) {
|
|
if (prefixedBuiltins.has(id)) {
|
|
return id;
|
|
}
|
|
return id.replace(/\\/g, "/").replace(/^\/@fs\//, isWindows ? "" : "/").replace(/^file:\//, "/").replace(/^node:/, "").replace(/^\/+/, "/");
|
|
}
|
|
function isPrimitive(v) {
|
|
return v !== Object(v);
|
|
}
|
|
function toFilePath(id, root) {
|
|
let { absolute, exists } = (() => {
|
|
if (id.startsWith("/@fs/")) {
|
|
return { absolute: id.slice(4), exists: true };
|
|
}
|
|
if (!id.startsWith(withTrailingSlash(root)) && id.startsWith("/")) {
|
|
const resolved = pathe.resolve(root, id.slice(1));
|
|
if (fs.existsSync(cleanUrl(resolved))) {
|
|
return { absolute: resolved, exists: true };
|
|
}
|
|
} else if (id.startsWith(withTrailingSlash(root)) && fs.existsSync(cleanUrl(id))) {
|
|
return { absolute: id, exists: true };
|
|
}
|
|
return { absolute: id, exists: false };
|
|
})();
|
|
if (absolute.startsWith("//")) {
|
|
absolute = absolute.slice(1);
|
|
}
|
|
return {
|
|
path: isWindows && absolute.startsWith("/") ? slash(node_url.fileURLToPath(node_url.pathToFileURL(absolute.slice(1)).href)) : absolute,
|
|
exists
|
|
};
|
|
}
|
|
const NODE_BUILTIN_NAMESPACE = "node:";
|
|
function isNodeBuiltin(id) {
|
|
if (prefixedBuiltins.has(id)) {
|
|
return true;
|
|
}
|
|
return builtins.has(
|
|
id.startsWith(NODE_BUILTIN_NAMESPACE) ? id.slice(NODE_BUILTIN_NAMESPACE.length) : id
|
|
);
|
|
}
|
|
function toArray(array) {
|
|
if (array === null || array === void 0) {
|
|
array = [];
|
|
}
|
|
if (Array.isArray(array)) {
|
|
return array;
|
|
}
|
|
return [array];
|
|
}
|
|
function getCachedData(cache, basedir, originalBasedir) {
|
|
const pkgData = cache.get(getFnpdCacheKey(basedir));
|
|
if (pkgData) {
|
|
traverseBetweenDirs(originalBasedir, basedir, (dir) => {
|
|
cache.set(getFnpdCacheKey(dir), pkgData);
|
|
});
|
|
return pkgData;
|
|
}
|
|
}
|
|
function setCacheData(cache, data, basedir, originalBasedir) {
|
|
cache.set(getFnpdCacheKey(basedir), data);
|
|
traverseBetweenDirs(originalBasedir, basedir, (dir) => {
|
|
cache.set(getFnpdCacheKey(dir), data);
|
|
});
|
|
}
|
|
function getFnpdCacheKey(basedir) {
|
|
return `fnpd_${basedir}`;
|
|
}
|
|
function traverseBetweenDirs(longerDir, shorterDir, cb) {
|
|
while (longerDir !== shorterDir) {
|
|
cb(longerDir);
|
|
longerDir = pathe.dirname(longerDir);
|
|
}
|
|
}
|
|
function withTrailingSlash(path) {
|
|
if (path[path.length - 1] !== "/") {
|
|
return `${path}/`;
|
|
}
|
|
return path;
|
|
}
|
|
function createImportMetaEnvProxy() {
|
|
const booleanKeys = ["DEV", "PROD", "SSR"];
|
|
return new Proxy(process.env, {
|
|
get(_, key) {
|
|
if (typeof key !== "string") {
|
|
return void 0;
|
|
}
|
|
if (booleanKeys.includes(key)) {
|
|
return !!process.env[key];
|
|
}
|
|
return process.env[key];
|
|
},
|
|
set(_, key, value) {
|
|
if (typeof key !== "string") {
|
|
return true;
|
|
}
|
|
if (booleanKeys.includes(key)) {
|
|
process.env[key] = value ? "1" : "";
|
|
} else {
|
|
process.env[key] = value;
|
|
}
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
const packageCache = /* @__PURE__ */ new Map();
|
|
async function findNearestPackageData(basedir) {
|
|
var _a;
|
|
const originalBasedir = basedir;
|
|
while (basedir) {
|
|
const cached = getCachedData(packageCache, basedir, originalBasedir);
|
|
if (cached) {
|
|
return cached;
|
|
}
|
|
const pkgPath = pathe.join(basedir, "package.json");
|
|
if ((_a = await fs.promises.stat(pkgPath).catch(() => {
|
|
})) == null ? void 0 : _a.isFile()) {
|
|
const pkgData = JSON.parse(await fs.promises.readFile(pkgPath, "utf8"));
|
|
if (packageCache) {
|
|
setCacheData(packageCache, pkgData, basedir, originalBasedir);
|
|
}
|
|
return pkgData;
|
|
}
|
|
const nextBasedir = pathe.dirname(basedir);
|
|
if (nextBasedir === basedir) {
|
|
break;
|
|
}
|
|
basedir = nextBasedir;
|
|
}
|
|
return {};
|
|
}
|
|
|
|
exports.VALID_ID_PREFIX = VALID_ID_PREFIX;
|
|
exports.cleanUrl = cleanUrl;
|
|
exports.createImportMetaEnvProxy = createImportMetaEnvProxy;
|
|
exports.findNearestPackageData = findNearestPackageData;
|
|
exports.getCachedData = getCachedData;
|
|
exports.isInternalRequest = isInternalRequest;
|
|
exports.isNodeBuiltin = isNodeBuiltin;
|
|
exports.isPrimitive = isPrimitive;
|
|
exports.isWindows = isWindows;
|
|
exports.normalizeModuleId = normalizeModuleId;
|
|
exports.normalizeRequestId = normalizeRequestId;
|
|
exports.setCacheData = setCacheData;
|
|
exports.slash = slash;
|
|
exports.toArray = toArray;
|
|
exports.toFilePath = toFilePath;
|
|
exports.withTrailingSlash = withTrailingSlash;
|