Pending changes to add API example
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
"tasks": {
|
"tasks": {
|
||||||
"check": "deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx",
|
"check": "deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx",
|
||||||
"cli": "echo \"import '\\$fresh/src/dev/cli.ts'\" | deno run --unstable -A -",
|
"cli": "echo \"import '\\$fresh/src/dev/cli.ts'\" | deno run --unstable -A -",
|
||||||
|
"pmpr": "deno run -A toolbox/cli.ts",
|
||||||
"manifest": "deno task cli manifest $(pwd)",
|
"manifest": "deno task cli manifest $(pwd)",
|
||||||
"start": "deno run -A --unstable-ffi --watch=static/,routes/ dev.ts",
|
"start": "deno run -A --unstable-ffi --watch=static/,routes/ dev.ts",
|
||||||
"build": "deno run -A --unstable-ffi dev.ts build",
|
"build": "deno run -A --unstable-ffi dev.ts build",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
import * as $_apps_layout from "./routes/(apps)/_layout.tsx";
|
import * as $_apps_layout from "./routes/(apps)/_layout.tsx";
|
||||||
import * as $_apps_mobility_index from "./routes/(apps)/mobility/index.tsx";
|
import * as $_apps_mobility_index from "./routes/(apps)/mobility/index.tsx";
|
||||||
import * as $_apps_mobility_partials_index from "./routes/(apps)/mobility/partials/index.tsx";
|
import * as $_apps_mobility_partials_index from "./routes/(apps)/mobility/partials/index.tsx";
|
||||||
|
import * as $_apps_notes_api_example from "./routes/(apps)/notes/api/example.ts";
|
||||||
import * as $_apps_notes_index from "./routes/(apps)/notes/index.tsx";
|
import * as $_apps_notes_index from "./routes/(apps)/notes/index.tsx";
|
||||||
import * as $_apps_notes_partials_admin_courses from "./routes/(apps)/notes/partials/(admin)/courses.tsx";
|
import * as $_apps_notes_partials_admin_courses from "./routes/(apps)/notes/partials/(admin)/courses.tsx";
|
||||||
import * as $_apps_notes_partials_admin_students from "./routes/(apps)/notes/partials/(admin)/students.tsx";
|
import * as $_apps_notes_partials_admin_students from "./routes/(apps)/notes/partials/(admin)/students.tsx";
|
||||||
@@ -28,6 +29,7 @@ const manifest = {
|
|||||||
"./routes/(apps)/mobility/index.tsx": $_apps_mobility_index,
|
"./routes/(apps)/mobility/index.tsx": $_apps_mobility_index,
|
||||||
"./routes/(apps)/mobility/partials/index.tsx":
|
"./routes/(apps)/mobility/partials/index.tsx":
|
||||||
$_apps_mobility_partials_index,
|
$_apps_mobility_partials_index,
|
||||||
|
"./routes/(apps)/notes/api/example.ts": $_apps_notes_api_example,
|
||||||
"./routes/(apps)/notes/index.tsx": $_apps_notes_index,
|
"./routes/(apps)/notes/index.tsx": $_apps_notes_index,
|
||||||
"./routes/(apps)/notes/partials/(admin)/courses.tsx":
|
"./routes/(apps)/notes/partials/(admin)/courses.tsx":
|
||||||
$_apps_notes_partials_admin_courses,
|
$_apps_notes_partials_admin_courses,
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { Handlers } from "$fresh/server.ts";
|
||||||
|
|
||||||
|
export const handler: Handlers = {
|
||||||
|
async GET(request, context) {
|
||||||
|
return new Response({
|
||||||
|
test: await request.json(),
|
||||||
|
context,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
+65
-21
@@ -1,8 +1,11 @@
|
|||||||
import { parseArgs, type ParseOptions } from "@std/cli/parse-args";
|
import { parseArgs, type ParseOptions } from "@std/cli/parse-args";
|
||||||
import { createModule } from "$root/toolbox/module.ts";
|
import { createModule } from "$root/toolbox/module/create.ts";
|
||||||
|
import { listModules } from "$root/toolbox/module/list.ts";
|
||||||
|
|
||||||
|
type CLICommand = (...args: Array<string>) => void;
|
||||||
|
type CLIAsyncCommand = (...args: Array<string>) => Promise<void>;
|
||||||
interface CLI {
|
interface CLI {
|
||||||
[command: string]: CLI | (() => void) | (() => Promise<void>);
|
[command: string]: CLI | CLICommand | CLIAsyncCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
const argSpec: ParseOptions = {};
|
const argSpec: ParseOptions = {};
|
||||||
@@ -10,51 +13,92 @@ const argSpec: ParseOptions = {};
|
|||||||
const cli: CLI = {
|
const cli: CLI = {
|
||||||
help: () => displayHelp(cli),
|
help: () => displayHelp(cli),
|
||||||
module: {
|
module: {
|
||||||
create: createModule,
|
list: () => listModules(),
|
||||||
|
create: (name: string) => createModule(name),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function displayHelp(cli: CLI, errorMessage?: string): never {
|
function displayHelp(
|
||||||
|
cli: CLI | CLICommand | CLIAsyncCommand,
|
||||||
|
errorMessage?: string,
|
||||||
|
): never {
|
||||||
const loggingFunction = errorMessage ? console.error : console.log;
|
const loggingFunction = errorMessage ? console.error : console.log;
|
||||||
if (errorMessage) {
|
if (errorMessage) {
|
||||||
console.error(errorMessage);
|
console.error(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
loggingFunction("Commands:");
|
if (typeof cli == "function") {
|
||||||
|
loggingFunction("Usage:");
|
||||||
|
displayFunctionHelp(cli, loggingFunction);
|
||||||
|
} else {
|
||||||
|
loggingFunction("Commands:");
|
||||||
|
displayObjectHelp(cli, loggingFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
Deno.exit(errorMessage ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function runCommand(commands: Array<string | number>, cli: CLI): never | void | Promise<void> {
|
function displayObjectHelp(
|
||||||
|
cli: CLI,
|
||||||
|
loggingFunction: typeof console.log,
|
||||||
|
level: number = 1,
|
||||||
|
) {
|
||||||
|
for (const [key, value] of Object.entries(cli)) {
|
||||||
|
if (typeof value == "function") {
|
||||||
|
displayFunctionHelp(value, loggingFunction, level);
|
||||||
|
} else {
|
||||||
|
loggingFunction(`${" ".repeat(level * 2)}${key}`);
|
||||||
|
displayObjectHelp(value, loggingFunction, level + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayFunctionHelp(
|
||||||
|
cli: CLICommand | CLIAsyncCommand,
|
||||||
|
loggingFunction: typeof console.log,
|
||||||
|
level: number = 1,
|
||||||
|
) {
|
||||||
|
const command = cli.name;
|
||||||
|
const matched = cli.toString().match(/(?<=^\()[^\)]+(?=\))/);
|
||||||
|
const args = matched?.[0].split(",").map((arg) => `<${arg.trim()}>`);
|
||||||
|
loggingFunction(
|
||||||
|
`${" ".repeat(level * 2)}${command} ${args?.join(" ") ?? ""}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function runCommand(
|
||||||
|
commands: Array<string | number>,
|
||||||
|
cli: CLI,
|
||||||
|
): never | {
|
||||||
|
command: CLICommand | CLIAsyncCommand;
|
||||||
|
args: Array<string | number>;
|
||||||
|
} {
|
||||||
if (commands.length == 0) {
|
if (commands.length == 0) {
|
||||||
console.error(
|
displayHelp(cli, `No command provided.`);
|
||||||
`No command provided. Available commands are ${
|
|
||||||
JSON.stringify(Object.keys(cli))
|
|
||||||
}.`,
|
|
||||||
);
|
|
||||||
Deno.exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const command = commands.shift()!.toString();
|
const command = commands.shift()!.toString();
|
||||||
|
|
||||||
if (cli[command] == undefined) {
|
if (cli[command] == undefined) {
|
||||||
console.error(
|
displayHelp(cli, `Command "${command}" doesn't exist.`);
|
||||||
`Command "${command}" doesn't exist. Available commands are ${
|
|
||||||
JSON.stringify(Object.keys(cli))
|
|
||||||
}.`,
|
|
||||||
);
|
|
||||||
Deno.exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof cli[command] == "object") {
|
if (typeof cli[command] == "object") {
|
||||||
return runCommand(commands, cli[command]);
|
return runCommand(commands, cli[command]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cli[command]();
|
if (cli[command].length != commands.length) {
|
||||||
|
displayHelp(cli[command], `Wrong usage of command "${command}".`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { command: cli[command], args: commands };
|
||||||
}
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
const args = parseArgs(Deno.args, argSpec);
|
const argv = parseArgs(Deno.args, argSpec);
|
||||||
runCommand(args._, cli);
|
const { command, args } = runCommand(argv._, cli);
|
||||||
|
|
||||||
|
command(...args.map((element) => element.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
export async function createModule() {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
export async function createModule(name: string): Promise<void> {
|
||||||
|
console.log(`Checking for module ${name}...`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Deno.mkdir(`routes/(apps)/${name}`);
|
||||||
|
} catch (error) {
|
||||||
|
if (!(error instanceof Deno.errors.AlreadyExists)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(`Some module is already named ${name}, aborting.`);
|
||||||
|
Deno.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const capitalizedName = `${name[0].toUpperCase()}${
|
||||||
|
name.substring(1).toLowerCase()
|
||||||
|
}`;
|
||||||
|
|
||||||
|
Promise.allSettled([
|
||||||
|
createDir(`routes/(apps)/${name}/(_props)`),
|
||||||
|
createDir(`routes/(apps)/${name}/partials`),
|
||||||
|
createDir(`routes/(apps)/${name}/(_islands)`),
|
||||||
|
createDir(`routes/(apps)/${name}/(_components)`),
|
||||||
|
createDir(`routes/(apps)/${name}/api`),
|
||||||
|
]);
|
||||||
|
|
||||||
|
Promise.allSettled([
|
||||||
|
createFile(
|
||||||
|
`routes/(apps)/${name}/index.tsx`,
|
||||||
|
getIndexContent(capitalizedName),
|
||||||
|
),
|
||||||
|
createFile(
|
||||||
|
`routes/(apps)/${name}/(_props)/props.ts`,
|
||||||
|
getPropsContent(capitalizedName),
|
||||||
|
),
|
||||||
|
createFile(
|
||||||
|
`routes/(apps)/${name}/partials/index.tsx`,
|
||||||
|
getPartialIndexContent(capitalizedName),
|
||||||
|
),
|
||||||
|
createFile(
|
||||||
|
`routes/(apps)/${name}/api/example.ts`,
|
||||||
|
getApiExampleContent(capitalizedName),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const formatter = new Deno.Command(Deno.execPath(), {
|
||||||
|
args: [
|
||||||
|
"fmt",
|
||||||
|
`routes/(apps)/${name}`,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
formatter.output();
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFile(path: string, content: string): Promise<void> {
|
||||||
|
console.log(`Creating file ${path}...`);
|
||||||
|
return Deno.writeTextFile(path, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDir(path: string): Promise<void> {
|
||||||
|
console.log(`Creating directory ${path}...`);
|
||||||
|
return Deno.mkdir(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIndexContent(_name: string) {
|
||||||
|
return `
|
||||||
|
import makeIndex from "$root/defaults/makeIndex.ts";
|
||||||
|
export default makeIndex(import.meta.dirname!);
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPartialIndexContent(name: string) {
|
||||||
|
return `
|
||||||
|
import { EmptyObject } from "$root/defaults/interfaces.ts";
|
||||||
|
import {
|
||||||
|
getPartialsConfig,
|
||||||
|
makePartials,
|
||||||
|
} from "$root/defaults/makePartials.tsx";
|
||||||
|
|
||||||
|
type ${name}IndexProps = EmptyObject;
|
||||||
|
|
||||||
|
export function Index(_props: ${name}IndexProps) {
|
||||||
|
return <h2>Welcome to ${name}.</h2>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const config = getPartialsConfig();
|
||||||
|
export default makePartials(Index);
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPropsContent(name: string) {
|
||||||
|
return `
|
||||||
|
import { AppProperties } from "$root/defaults/interfaces.ts";
|
||||||
|
|
||||||
|
const properties: AppProperties = {
|
||||||
|
name: "${name}",
|
||||||
|
icon: "school",
|
||||||
|
pages: {
|
||||||
|
index: "Homepage",
|
||||||
|
},
|
||||||
|
adminOnly: [],
|
||||||
|
hint: "PolyMPR module",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default properties;
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getApiExampleContent(name: string) {
|
||||||
|
return `
|
||||||
|
import { AppProperties } from "$root/defaults/interfaces.ts";
|
||||||
|
|
||||||
|
const properties: AppProperties = {
|
||||||
|
name: "${name}",
|
||||||
|
icon: "school",
|
||||||
|
pages: {
|
||||||
|
index: "Homepage",
|
||||||
|
},
|
||||||
|
adminOnly: [],
|
||||||
|
hint: "PolyMPR module",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default properties;
|
||||||
|
`;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export async function listModules(): Promise<void> {
|
||||||
|
for await (const path of Deno.readDir("routes/(apps)")) {
|
||||||
|
if (path.isDirectory) {
|
||||||
|
console.log(path.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user