UNPKG

@generouted/react-router

Version:

Generated file-based routes for React Router and Vite

119 lines (108 loc) 5.16 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; 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/plugin/generate.ts var generate_exports = {}; __export(generate_exports, { generate: () => generate }); module.exports = __toCommonJS(generate_exports); var import_child_process = require("child_process"); var import_fs = __toESM(require("fs"), 1); var import_path = __toESM(require("path"), 1); var import_vite = require("vite"); // ../../shared/core/src/index.ts var patterns = { route: [/^.*\/src\/pages\/|^\/pages\/|\.(jsx|tsx|mdx)$/g, ""], splat: [/\[\.{3}\w+\]/g, "*"], param: [/\[([^\]]+)\]/g, ":$1"], slash: [/^index$|\./g, "/"], optional: [/^-(:?[\w-]+|\*)/, "$1?"] }; // src/plugin/generate.ts var import_fast_glob = __toESM(require("fast-glob"), 1); // src/plugin/template.ts var template = `// Generouted, changes to this file will be overriden /* eslint-disable */ import { components, hooks, utils } from '@generouted/react-router/client' // types export const { Link, Navigate } = components<Path, Params>() export const { useModals, useNavigate, useParams } = hooks<Path, Params, ModalPath>() export const { redirect } = utils<Path, Params>() `; // src/plugin/generate.ts var generateRouteTypes = async (options) => { const files = await (0, import_fast_glob.default)(options.source.routes || "./src/pages/**/[\\w[-]*.{jsx,tsx,mdx}", { onlyFiles: true }); const modal = await (0, import_fast_glob.default)(options.source.modals || "./src/pages/**/[+]*.{jsx,tsx,mdx}", { onlyFiles: true }); const filtered = files.filter((key) => !key.includes("/_") && !key.includes("/404")); const params = []; const paths = filtered.map((key) => { const path2 = key.replace(...patterns.route).replace(...patterns.splat).replace(...patterns.param).replace(/\([\w-]+\)\/|\/?_layout/g, "").replace(/\/?index|\./g, "/").replace(/(\w)\/$/g, "$1").split("/").map((segment) => segment.replace(...patterns.optional)).join("/"); if (path2) { const param = path2.split("/").filter((segment) => segment.startsWith(":")); if (param.length || path2.includes("*")) { const dynamic = param.length ? param.map((p) => p.replace(/:(.+)(\?)?/, "$1$2:") + " string") : []; const splat = path2.includes("*") ? ["'*': string"] : []; params.push(`'/${path2}': { ${[...dynamic, ...splat].join("; ")} }`); } return path2.length > 1 ? `/${path2}` : path2; } }); const modals = modal.map( (path2) => `/${path2.replace(...patterns.route).replace(/\+|\([\w-]+\)\//g, "").replace(/(\/)?index/g, "").replace(/\./g, "/")}` ); const types = `export type Path = | "${[...new Set(paths.filter(Boolean))].sort().join('"\n | "')}"`.replace(/"/g, "`") + ` export type Params = { ${params.sort().join("\n ")} } ` + `export type ModalPath = "${modals.sort().join('" | "') || "never"}"`.replace(/"/g, modals.length ? "`" : ""); const content = template.replace("// types", types); const count = paths.length + modals.length; return { content, count }; }; var logger = (0, import_vite.createLogger)("info", { prefix: "[generouted]" }); var latestContent = ""; var generate = async (options) => { const start = Date.now(); const { content, count } = await generateRouteTypes(options); logger.info(`scanned ${count} routes in ${Date.now() - start} ms`, { timestamp: true }); if (latestContent === content) return; latestContent = content; await import_fs.default.promises.writeFile(options.output, content); if (!options.format) return; const prettier = import_path.default.resolve("./node_modules/.bin/prettier"); if (import_fs.default.existsSync(prettier)) (0, import_child_process.execSync)(`${prettier} --write --cache ${options.output}`); }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { generate });