route-sage-react
Version:
A TypeScript utility for managing and configuring routes with type safety and nested route support
179 lines (178 loc) • 8.35 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateFromFolder = void 0;
const fs_1 = require("fs");
const path = __importStar(require("path"));
const helpers_1 = require("./helpers");
const micromatch_1 = __importDefault(require("micromatch"));
const rootUsingCwd = process.cwd();
const config = require(path.join(rootUsingCwd, "route-sage.config.json"));
const baseIndent = " ";
/**
* Generates a JSON representation of a folder and its files structure.
*
* @param {string} dirPath The root path of the folder to analyze.
* @returns {Promise<IFileSystemEntry | null>} A promise that resolves to a IFileSystemEntry
* representing the folder structure, or null if
* the path is not a directory.
*/
function generateFolderJson(dirPath) {
return __awaiter(this, void 0, void 0, function* () {
try {
const stats = yield fs_1.promises.stat(dirPath);
if (!stats.isDirectory()) {
return null; // Not a directory
}
const folderEntry = {
name: path.basename(dirPath),
// @ts-expect-error
originalUrl: () => `/${path.basename(dirPath)}`,
type: "folder",
children: [],
};
const entries = yield fs_1.promises.readdir(dirPath);
// Use Promise.all to concurrently process all child entries
const childPromises = entries.map((entryName) => __awaiter(this, void 0, void 0, function* () {
const entryPath = path.join(dirPath, entryName);
const entryStats = yield fs_1.promises.stat(entryPath);
if (entryStats.isDirectory()) {
const subFolder = yield generateFolderJson(entryPath);
if (subFolder) {
folderEntry.children.push(subFolder);
}
}
else {
folderEntry.children.push({
name: entryName,
type: "file",
});
}
}));
yield Promise.all(childPromises); // Wait for all children to be processed
// Sort children for consistent output (optional)
if (folderEntry.children) {
folderEntry.children.sort((a, b) => {
if (a.type === "folder" && b.type === "file")
return -1; // Folders first
if (a.type === "file" && b.type === "folder")
return 1;
return a.name.localeCompare(b.name); // Then alphabetically
});
}
return folderEntry;
}
catch (error) {
console.log("error", error);
if (error.code === "ENOENT") {
console.error(`Error: Path not found - ${dirPath}`);
}
else {
console.error(`An unexpected error occurred: ${error.message}`);
}
return null;
}
});
}
const transformFolderJsonToPathConfig = (folderJson) => {
console.log("route-sage.config.json", config);
function addUrlsToFolders(node, indentLevel = 1) {
const indent = baseIndent.repeat(indentLevel);
let value = "";
const nameRegex = /\[([^\]]+)\]/g; // The 'g' flag makes it global, replacing all occurrences.
const name = node.name.split(".")[0].replace(nameRegex, "$$$1");
const varregex = /\$(\w+)/g;
const varName = name.replace(varregex, "${$1}");
const argsRegex = /\$(\w+)/g;
// Use matchAll to find all occurrences
const matches = name.matchAll(argsRegex);
// Map the matches to an array of the captured words
const args = Array.from(matches, (match) => match[1]);
console.log("varName", { varName, name, node, args, matches });
if (node.type === "folder") {
// If the folder has children, process them recursively
value += `${indent}${name}: (${args.join(",")}) => ({\n`;
value += `${indent}${baseIndent}` + "url: `" + `/${varName}` + "`,\n";
if (node.children && Array.isArray(node.children)) {
node.children.forEach((child) => {
console.log("Should add chld", child);
value += addUrlsToFolders(child, indentLevel + 1);
});
}
value += `${indent}}),\n`;
}
else if (config.useFiles) {
const fileInInclude = (config === null || config === void 0 ? void 0 : config.includeFileNames)
? config.includeFileNames.find((fileName) => {
const files = (0, micromatch_1.default)([node.name], fileName);
return files.length > 0;
})
: true;
const fileInExclude = (config === null || config === void 0 ? void 0 : config.excludeFileNames)
? !!config.excludeFileNames.find((fileName) => {
const files = (0, micromatch_1.default)([node.name], fileName);
return files.length > 0;
})
: false;
console.log("fileInInclude", {
fileInInclude,
fileInExclude,
node,
regex: (0, helpers_1.escapeRegExp)(config === null || config === void 0 ? void 0 : config.excludeFileNames[0]),
});
if (fileInInclude && !fileInExclude) {
value += `${indent}${name}: (${args.join(",")}) => ({\n`;
value += `${indent}${baseIndent}` + "url: `" + `/${varName}` + "`,\n";
value += `${indent}}),\n`;
}
}
return value;
}
const transformedResult = addUrlsToFolders(folderJson);
return transformedResult;
};
const generateFromFolder = (folderRootPath) => __awaiter(void 0, void 0, void 0, function* () {
const folderPath = folderRootPath || config.rootFolder;
const folderStructure = yield generateFolderJson(folderPath);
const paths = folderStructure.children.map((child) => transformFolderJsonToPathConfig(child));
//create a json file and inject result
yield fs_1.promises.writeFile(path.join(rootUsingCwd, "route-sage.js"), `export default {
${paths.join(`\n`)}
}`);
});
exports.generateFromFolder = generateFromFolder;
// main().catch(console.error);