unplugin-remix-router
Version:
[](https://stand-with-palestine.org)
233 lines (224 loc) • 9.18 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/webpack.ts
var webpack_exports = {};
__export(webpack_exports, {
default: () => webpack_default
});
module.exports = __toCommonJS(webpack_exports);
var import_unplugin2 = require("unplugin");
// src/index.ts
var import_unplugin = require("unplugin");
// src/utils/is-file-exist.ts
var import_node_fs = require("fs");
async function isFileExist(filePath) {
try {
await import_node_fs.promises.stat(filePath);
return true;
} catch (error) {
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT")
return false;
else
throw error;
}
}
// src/utils/list-files.ts
var import_node_fs2 = require("fs");
var import_node_path = __toESM(require("path"), 1);
var import_vite = require("vite");
async function listFiles(directory) {
const topLevelPattern = /\.tsx$/;
const subdirectoryPattern = /^route(\.lazy)?\.tsx$/;
try {
const files = await import_node_fs2.promises.readdir(directory);
const matchingFiles = [];
for (const file of files) {
const filePath = import_node_path.default.join(directory, file);
const stat = await import_node_fs2.promises.stat(filePath);
if (stat.isDirectory()) {
const subdirectoryFiles = await import_node_fs2.promises.readdir(filePath);
const subdirectoryFile = subdirectoryFiles.find((subItem) => subdirectoryPattern.test(subItem));
if (!subdirectoryFile)
continue;
const subFilePath = import_node_path.default.join(filePath, subdirectoryFile);
matchingFiles.push((0, import_vite.normalizePath)(subFilePath).replace((0, import_vite.normalizePath)(`${directory}/`), ""));
} else if (topLevelPattern.test(file)) {
matchingFiles.push((0, import_vite.normalizePath)(filePath).replace((0, import_vite.normalizePath)(`${directory}/`), ""));
}
}
return matchingFiles;
} catch (error) {
console.error("Error:", error);
throw error;
}
}
// src/utils/build-route-maps.ts
function buildRoutesMap(strings, appDirectory, lazyMode = "suffix", level = 0) {
const result = [];
let intenalImports = "";
const firstSegments = new Set(
strings.map((str) => str.split(".")[level].replace("/route", "")).filter((str) => str !== void 0 && str !== "tsx" && str !== "lazy")
);
if (firstSegments.size === 0)
return { routesMap: result };
const reversedSegments = Array.from(firstSegments).reverse();
for (const segment of reversedSegments) {
const filteredStrings = strings.filter((str) => str.split(".")[level] === segment || str.split(".")[level] === `${segment}/route`);
const routePath = segment.replace(/\(([^)]*)\)\??$/, "$1?").replace(/\$+$/, "*").replace(/^\$/, ":");
if (filteredStrings.length === 0)
continue;
const newNode = {};
if (routePath === "_index")
newNode.index = true;
else if (!routePath.startsWith("_"))
newNode.path = routePath;
const page = filteredStrings.find(
(str) => str.endsWith(`${segment}.tsx`) || str.endsWith(`${segment}/route.tsx`)
);
const lazyPage = filteredStrings.find(
(str) => str.endsWith(`${segment}.lazy.tsx`) || str.endsWith(`${segment}/route.lazy.tsx`)
);
if (lazyMode === "always" && page) {
const absolutePath = `${appDirectory}/routes/${page}`;
newNode.lazy = `ImportStart'${absolutePath}'ImportEnd`;
} else if (lazyPage) {
const absolutePath = `${appDirectory}/routes/${lazyPage}`;
newNode.lazy = `ImportStart'${absolutePath}'ImportEnd`;
} else if (page) {
const random = Math.floor(Math.random() * 1e5 + 1);
const absolutePath = `${appDirectory}/routes/${page}`;
intenalImports += `import * as route${random} from '${absolutePath}'
`;
newNode.spread = `SpreadStartroute${random}SpreadEnd`;
}
const { routesMap, imports } = buildRoutesMap(filteredStrings, appDirectory, lazyMode, level + 1);
if (routesMap.length > 0)
newNode.children = routesMap;
if (imports)
intenalImports += imports;
if (segment.endsWith("_")) {
const slicedSegment = segment.slice(0, -1);
routesMap.forEach((node) => {
result.push(__spreadProps(__spreadValues({}, node), { path: node.index ? slicedSegment : `${slicedSegment}/${node.path}` }));
});
} else {
result.push(newNode);
}
}
return { routesMap: result, imports: intenalImports };
}
// src/index.ts
var server;
function routesCode(imports, routesObject) {
return `
${imports}
function moduleFactory(module) {
const { default: Component, clientLoader: loader, clientAction: action, clientMiddleware: middleware, loader: _loader, action: _action, Component: _Component, middleware: _middleware, unstable_middleware: _unstable_middleware, ...rest } = module;
return { Component, loader, action, middleware, unstable_middleware: middleware, ...rest };
}
export const routes = ${routesObject}
`;
}
function invalidateVirtualModule(server2) {
const { moduleGraph, ws } = server2;
const module2 = moduleGraph.getModuleById("virtual:routes");
if (module2) {
moduleGraph.invalidateModule(module2);
if (ws) {
ws.send({
type: "full-reload",
path: "*"
});
}
}
}
var unpluginFactory = (options) => ({
name: "unplugin-remix-router",
async resolveId(source) {
if (source === "virtual:routes")
return source;
},
async load(id) {
const appDirectory = (options == null ? void 0 : options.appDirectory) ? options.appDirectory : "./app";
const lazyMode = (options == null ? void 0 : options.lazy) || "always";
if (id === "virtual:routes") {
const files = await listFiles(`${appDirectory}/routes`);
let { routesMap, imports } = buildRoutesMap(files, appDirectory, lazyMode);
if (await isFileExist(`${appDirectory}/root.lazy.tsx`)) {
const absolutePath = `${appDirectory}/root.lazy.tsx`;
routesMap = [{
path: "/",
lazy: `ImportStart'${absolutePath}'ImportEnd`,
children: routesMap
}];
} else if (await isFileExist(`${appDirectory}/root.tsx`)) {
const absolutePath = `${appDirectory}/root.tsx`;
imports += `import * as root from '${absolutePath}'
`;
routesMap = [{
path: "/",
spread: `SpreadStartrootSpreadEnd`,
children: routesMap
}];
}
const routesObject = JSON.stringify(routesMap).replace(/"ImportStart/g, "() => import(").replace(/ImportEnd"/g, ").then(moduleFactory)").replace(/"spread":"SpreadStart/g, "...moduleFactory(").replace(/SpreadEnd"/g, ")");
return routesCode(imports, routesObject);
}
},
vite: {
configureServer(_server) {
server = _server;
},
watchChange(id, change) {
if (change.event === "update")
return;
invalidateVirtualModule(server);
}
}
});
// src/webpack.ts
var webpack_default = (0, import_unplugin2.createWebpackPlugin)(unpluginFactory);
exports.default = module.exports;