radashi-helper
Version:
Help with managing your own Radashi
232 lines (218 loc) • 5.96 kB
JavaScript
import {
dedent
} from "./chunk-V32CUL4H.js";
import {
getRadashiGroups
} from "./chunk-PPHUQN6R.js";
import {
pullRadashi
} from "./chunk-FEUFDYD5.js";
import {
openInEditor
} from "./chunk-CQEIEK2X.js";
import "./chunk-GGEXN2BI.js";
import {
prompt
} from "./chunk-MJC327DM.js";
import {
getEnv
} from "./chunk-DSXY7YVB.js";
import {
EarlyExitError,
RadashiError,
log
} from "./chunk-JLKIE3A2.js";
import "./chunk-VOEQFXI5.js";
// src/fn-create.ts
import { existsSync, readFileSync } from "node:fs";
import { mkdir, writeFile } from "node:fs/promises";
import path, { dirname, join } from "node:path";
// src/util/addExportToBarrel.ts
function addExportToBarrel(content, specifier) {
const addedLine = `export * from '${specifier}'`;
const existingLines = content.split("\n");
let insertIndex = Math.max(existingLines.length - 1, 0);
for (let i = 0; i < existingLines.length; i++) {
if (existingLines[i] && existingLines[i] > addedLine) {
if (i === 0) {
insertIndex = 0;
break;
}
for (let j = i - 1; j >= 0; j--) {
if (existingLines[j].length) {
insertIndex = j + 1;
break;
}
}
break;
}
}
existingLines.splice(insertIndex, 0, addedLine);
return existingLines.join("\n");
}
// src/fn-create.ts
async function createFunction(funcName, options = {}) {
if (funcName == null) {
funcName = await prompt({
type: "text",
name: "funcName",
message: "Enter the name for the new function:"
});
}
if (!funcName) {
throw new RadashiError("Function name cannot be empty");
}
if (funcName.includes("/")) {
throw new RadashiError("Function name cannot include slashes");
}
const env = options.env ?? getEnv(options.dir);
if (env.radashiDir) {
await pullRadashi(env);
}
let { group, description } = options;
if (group == null) {
const groups = await getRadashiGroups(env);
const selectedGroup = await prompt({
type: "autocomplete",
name: "selectedGroup",
message: "Select a group for the function:",
choices: [
{ title: "Create a new group", value: "new" },
...groups.map((g) => ({ title: g, value: g }))
]
});
if (!selectedGroup) {
throw new EarlyExitError("No group selected. Exiting...");
}
if (selectedGroup === "new") {
const newGroup = await prompt({
type: "text",
name: "newGroup",
message: "Enter the name for the new group:"
});
if (!newGroup) {
throw new RadashiError("Group name cannot be empty");
}
group = newGroup;
} else {
group = selectedGroup;
}
}
const directories = {
src: join(env.root, "src", group),
docs: join(env.root, "docs", group),
tests: join(env.root, "tests", group),
benchmarks: join(env.root, "benchmarks", group)
};
const files = {
src: join(directories.src, `${funcName}.ts`),
docs: join(directories.docs, `${funcName}.mdx`),
tests: join(directories.tests, `${funcName}.test.ts`),
benchmarks: join(directories.benchmarks, `${funcName}.bench.ts`)
};
if (!existsSync(files.docs)) {
if (description == null) {
description = await prompt({
type: "text",
name: "description",
message: `Enter a description for ${funcName}:`
});
if (description == null) {
throw new EarlyExitError("No description provided. Exiting...");
}
if (description.trim() === "") {
throw new RadashiError("Function description cannot be empty");
}
}
await createFile(files.docs, generateDocsContent(funcName, description));
} else {
log.error(`Warning: ${files.docs} already exists. Skipping.`);
}
await createFileIfNotExists(files.src, generateSrcContent(group, funcName));
await createFileIfNotExists(files.tests, generateTestsContent(funcName));
await createFileIfNotExists(
files.benchmarks,
generateBenchmarksContent(funcName)
);
if (options.editor !== false) {
await openInEditor(files.src, env, options.editor);
}
if (env.radashiDir) {
const { default: build } = await import("./build-7F3PTR5C.js");
await build({ env });
} else {
log("Updating src/mod.ts");
const barrelFile = join(env.root, "src/mod.ts");
writeFile(
barrelFile,
addExportToBarrel(
readFileSync(barrelFile, "utf8"),
`./${group}/${funcName}.ts`
)
);
}
}
async function createFile(file, content) {
await mkdir(dirname(file), { recursive: true });
await writeFile(file, content);
log(`Created ${path.relative(process.cwd(), file)}`);
}
async function createFileIfNotExists(file, content) {
if (!existsSync(file)) {
await createFile(file, content);
} else {
log.error(`Warning: ${file} already exists. Skipping.`);
}
}
function generateDocsContent(funcName, description) {
return dedent`
---
title: ${funcName}
description: ${description}
---
### Usage
Does a thing. Returns a value.
\`\`\`ts
import * as _ from 'radashi'
_.${funcName}()
\`\`\`
`;
}
function generateSrcContent(group, funcName) {
return dedent`
/**
* Does a thing.
*
* @see https://radashi.js.org/reference/${group}/${funcName}
* @example
* \`\`\`ts
* ${funcName}()
* \`\`\`
*/
export function ${funcName}(): void {}
`;
}
function generateTestsContent(funcName) {
return dedent`
import * as _ from 'radashi'
describe('${funcName}', () => {
test('does a thing', () => {
expect(_.${funcName}()).toBe(undefined)
})
})
`;
}
function generateBenchmarksContent(funcName) {
return dedent`
import * as _ from 'radashi'
import { bench } from 'vitest'
describe('${funcName}', () => {
bench('with no arguments', () => {
_.${funcName}()
})
})
`;
}
export {
createFunction
};