From c9be34f2f1f5966dee53c4771cac6c18393cca0c Mon Sep 17 00:00:00 2001 From: Angga7Togk Date: Mon, 20 Apr 2026 21:32:43 +0700 Subject: [PATCH 1/4] feat(kame): initialize @gaman/kame --- packages/kame/.npmignore | 4 + packages/kame/README.md | 21 ++++ packages/kame/package.json | 41 +++++++ packages/kame/src/commands/buntest-cmd.ts | 37 +++++++ packages/kame/src/commands/fetch.ts | 77 +++++++++++++ packages/kame/src/commands/gen-controller.ts | 34 ++++++ packages/kame/src/commands/gen-exception.ts | 37 +++++++ packages/kame/src/commands/gen-middleware.ts | 36 +++++++ packages/kame/src/commands/gen-module.ts | 59 ++++++++++ packages/kame/src/commands/gen-router.ts | 32 ++++++ packages/kame/src/commands/gen-service.ts | 104 ++++++++++++++++++ packages/kame/src/commands/registry.ts | 95 ++++++++++++++++ packages/kame/src/compose/index.ts | 21 ++++ packages/kame/src/index.ts | 8 ++ packages/kame/src/input-parser.ts | 41 +++++++ packages/kame/src/repl.ts | 63 +++++++++++ packages/kame/src/templates/module.ts | 108 +++++++++++++++++++ packages/kame/src/templates/service.ts | 18 ++++ packages/kame/src/utils.ts | 17 +++ packages/kame/tsconfig.dts.json | 60 +++++++++++ packages/kame/tsconfig.json | 8 ++ 21 files changed, 921 insertions(+) create mode 100644 packages/kame/.npmignore create mode 100644 packages/kame/README.md create mode 100644 packages/kame/package.json create mode 100644 packages/kame/src/commands/buntest-cmd.ts create mode 100644 packages/kame/src/commands/fetch.ts create mode 100644 packages/kame/src/commands/gen-controller.ts create mode 100644 packages/kame/src/commands/gen-exception.ts create mode 100644 packages/kame/src/commands/gen-middleware.ts create mode 100644 packages/kame/src/commands/gen-module.ts create mode 100644 packages/kame/src/commands/gen-router.ts create mode 100644 packages/kame/src/commands/gen-service.ts create mode 100644 packages/kame/src/commands/registry.ts create mode 100644 packages/kame/src/compose/index.ts create mode 100644 packages/kame/src/index.ts create mode 100644 packages/kame/src/input-parser.ts create mode 100644 packages/kame/src/repl.ts create mode 100644 packages/kame/src/templates/module.ts create mode 100644 packages/kame/src/templates/service.ts create mode 100644 packages/kame/src/utils.ts create mode 100644 packages/kame/tsconfig.dts.json create mode 100644 packages/kame/tsconfig.json diff --git a/packages/kame/.npmignore b/packages/kame/.npmignore new file mode 100644 index 0000000..123ec67 --- /dev/null +++ b/packages/kame/.npmignore @@ -0,0 +1,4 @@ +src +test +node_modules +log \ No newline at end of file diff --git a/packages/kame/README.md b/packages/kame/README.md new file mode 100644 index 0000000..d7dfca1 --- /dev/null +++ b/packages/kame/README.md @@ -0,0 +1,21 @@ +# @gaman/static +**Secure, Lightweight & High-Performance Static File Server for GamanJS**. Built for Bun, optimized for speed with non-blocking I/O, built-in compression, and ETag caching. + +## Installation +```bash +bun add @gaman/static +``` + +## Quick Used +By default, this middleware will serve files from the `public/` folder in the root of your project. +```ts +import { defineBootstrap } from "gaman"; +import { StaticServe } from "@gaman/static"; + +defineBootstrap((app) => { + // Mount the static server + app.mount(StaticServe()); + + app.mountServer(...) +}); +``` \ No newline at end of file diff --git a/packages/kame/package.json b/packages/kame/package.json new file mode 100644 index 0000000..03cdc9c --- /dev/null +++ b/packages/kame/package.json @@ -0,0 +1,41 @@ +{ + "name": "@gaman/kame", + "version": "0.1.0", + "author": "angga7togk", + "license": "MIT", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "require": "./dist/index.js", + "import": "./dist/index.mjs" + }, + "./compose": { + "types": "./dist/compose/index.d.ts", + "require": "./dist/compose/index.js", + "import": "./dist/compose/index.mjs" + } + }, + "keywords": [ + "gamanjs", + "gaman", + "gaman cli", + "kame", + "cli", + "repl", + "bun" + ], + "repository": { + "url": "git+https://github.com/7TogkID/gaman.git", + "directory": "packages/kame" + }, + "bugs": { + "url": "https://github.com/7TogkID/gaman/issues" + }, + "homepage": "https://gaman.7togk.id", + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "gitHead": "8d1bf3bbac4b72847e9157e2c95d75b5e90c89cf" +} diff --git a/packages/kame/src/commands/buntest-cmd.ts b/packages/kame/src/commands/buntest-cmd.ts new file mode 100644 index 0000000..1800319 --- /dev/null +++ b/packages/kame/src/commands/buntest-cmd.ts @@ -0,0 +1,37 @@ +import { $ } from 'bun'; +import { Logger } from 'gaman/utils'; +import { registerCommand } from './registry'; + +const handler = async (args: string[]): Promise => { + Logger.info("Starting Bun test suite..."); + + try { + const result = await $`bun test ${args}`.quiet().text(); + + result.split('\n').forEach((line) => { + if (line.trim()) { + Logger.info(line); + } + }); + + Logger.info("All tests passed successfully."); + } catch (err: any) { + const errorOutput = err.stderr?.toString() || err.stdout?.toString() || ""; + + errorOutput.split('\n').forEach((line: string) => { + if (line.trim()) { + Logger.error(line); + } + }); + + Logger.error("Test suite failed."); + } +}; + +registerCommand({ + name: 'test', + description: 'Run project tests.', + usage: 'test [filter]', + aliases: ['t'], + handler, +}); \ No newline at end of file diff --git a/packages/kame/src/commands/fetch.ts b/packages/kame/src/commands/fetch.ts new file mode 100644 index 0000000..cd51d95 --- /dev/null +++ b/packages/kame/src/commands/fetch.ts @@ -0,0 +1,77 @@ +import { Logger } from 'gaman/utils'; +import { registerCommand } from './registry'; + +const handler = async (args: string[]): Promise => { + const method = args[0]?.toUpperCase(); + const url = args[1]; + + if (!method || !url) { + Logger.error("Usage: fetch [-h Header] [-b Body]"); + return; + } + + // Parsing manual untuk -h dan -b + const headerIndex = args.indexOf("-h"); + const bodyIndex = args.indexOf("-b"); + + const headers: Record = { + "Content-Type": "application/json", + }; + + // Ambil value setelah -h (Format "Key:Value") + if (headerIndex !== -1 && args[headerIndex + 1]) { + const headerRaw = args[headerIndex + 1]; + const splitIndex = headerRaw?.indexOf(":") || -1; + if (splitIndex !== -1) { + const key = headerRaw?.slice(0, splitIndex).trim() || ''; + const value = headerRaw?.slice(splitIndex + 1).trim() || ''; + headers[key] = value; + } + } + + // Ambil value setelah -b + let body = null; + if (bodyIndex !== -1 && args[bodyIndex + 1]) { + body = args[bodyIndex + 1]; + } + + Logger.info(`Sending ${method} request to: ${url}`); + + try { + const response = await fetch(url, { + method, + headers, + body: ["GET", "HEAD"].includes(method) ? null : body, + }); + + const resText = await response.text(); + let resData; + + try { + resData = JSON.parse(resText); + } catch { + resData = resText; + } + + if (response.ok) { + Logger.info(`Status: ${response.status}`); + console.log(typeof resData === "object" + ? JSON.stringify(resData, null, 2) + : resData + ); + } else { + Logger.error(`Status: ${response.status}`); + console.log(resData); + } + } catch (err: any) { + Logger.error(`Fetch failed: ${err.message}`); + } +}; + +registerCommand({ + name: 'fetch', + description: 'Request internal/external API via CLI', + usage: 'fetch [-h "Key: Value"] [-b "Body"]', + aliases: ['req'], + handler, +}); \ No newline at end of file diff --git a/packages/kame/src/commands/gen-controller.ts b/packages/kame/src/commands/gen-controller.ts new file mode 100644 index 0000000..4c546f0 --- /dev/null +++ b/packages/kame/src/commands/gen-controller.ts @@ -0,0 +1,34 @@ +import { Logger } from 'gaman/utils'; +import { join, relative } from 'node:path'; +import { registerCommand } from './registry'; +import { controllerTemplate } from '../templates/module'; +import { capitalize } from '../utils'; + +const handler = async (args: string[]): Promise => { + const [name, module = 'app'] = args; + if (!name || !module) { + Logger.error("Usage: gen:controller "); + return; + } + + const nameCapitalized = capitalize(name); + const cwd = process.cwd(); + // Support nested paths like "v2/user" + const controllerDir = join(cwd, 'src', 'modules', module, 'controllers'); + const filePath = join(controllerDir, `${nameCapitalized}Controller.ts`); + + await Bun.$`mkdir -p ${controllerDir}`.quiet(); + await Bun.write(filePath, controllerTemplate(name) + '\n'); + Logger.info(`created ${relative(cwd, filePath)}`); + Logger.info( + `Controller "${nameCapitalized}Controller" generated successfully.`, + ); +}; + +registerCommand({ + name: 'gen:controller', + description: 'Generate a new Controller inside an existing module', + usage: "gen:controller ", + aliases: ['gen:co'], + handler, +}); diff --git a/packages/kame/src/commands/gen-exception.ts b/packages/kame/src/commands/gen-exception.ts new file mode 100644 index 0000000..e2bf59a --- /dev/null +++ b/packages/kame/src/commands/gen-exception.ts @@ -0,0 +1,37 @@ +import { Logger, TextFormat } from 'gaman/utils'; +import { join, relative } from 'node:path'; +import { registerCommand } from './registry'; +import { exceptionTemplate } from '../templates/module'; +import { capitalize } from '../utils'; + +const handler = async (args: string[]): Promise => { + const [name, module = 'app'] = args; + if (!name || !module) { + Logger.error("Usage: gen:exception "); + return; + } + + const nameCapitalized = capitalize(name); + const cwd = process.cwd(); + + // Support nested paths like "v2/user" + const exceptionDir = join(cwd, 'src', 'modules', module, 'exceptions'); + const filePath = join(exceptionDir, `${nameCapitalized}Exception.ts`); + + await Bun.$`mkdir -p ${exceptionDir}`.quiet(); + await Bun.write(filePath, exceptionTemplate() + '\n'); + Logger.info( + `created ${TextFormat.UNDERLINE}${relative(cwd, filePath)}${TextFormat.RESET}`, + ); + Logger.info( + `Exception "${nameCapitalized}Exception" generated successfully.`, + ); +}; + +registerCommand({ + name: 'gen:exception', + description: 'Generate a new Exception inside an existing module', + usage: "gen:exception ", + aliases: ['gen:ex'], + handler, +}); diff --git a/packages/kame/src/commands/gen-middleware.ts b/packages/kame/src/commands/gen-middleware.ts new file mode 100644 index 0000000..f2e27ca --- /dev/null +++ b/packages/kame/src/commands/gen-middleware.ts @@ -0,0 +1,36 @@ +import { Logger, TextFormat } from 'gaman/utils'; +import { join, relative } from 'node:path'; +import { registerCommand } from './registry'; +import { middlewareTemplate } from '../templates/module'; +import { capitalize } from '../utils'; + +const handler = async (args: string[]): Promise => { + const [name, module = 'app'] = args; + if (!name || !module) { + Logger.error("Usage: gen:middleware "); + return; + } + + const nameCapitalized = capitalize(name); + const cwd = process.cwd(); + // Support nested paths like "v2/user" + const middlewareDir = join(cwd, 'src', 'modules', module, 'middlewares'); + const filePath = join(middlewareDir, `${nameCapitalized}Middleware.ts`); + + await Bun.$`mkdir -p ${middlewareDir}`.quiet(); + await Bun.write(filePath, middlewareTemplate() + '\n'); + Logger.info( + `created ${TextFormat.UNDERLINE}${relative(cwd, filePath)}${TextFormat.RESET}`, + ); + Logger.info( + `Middleware "${nameCapitalized}Middleware" generated successfully.`, + ); +}; + +registerCommand({ + name: 'gen:middleware', + description: 'Generate a new Middleware inside an existing module', + usage: "gen:middleware ", + aliases: ['gen:mi'], + handler, +}); diff --git a/packages/kame/src/commands/gen-module.ts b/packages/kame/src/commands/gen-module.ts new file mode 100644 index 0000000..192300b --- /dev/null +++ b/packages/kame/src/commands/gen-module.ts @@ -0,0 +1,59 @@ +import { Logger } from 'gaman/utils'; +import { join, basename, relative, dirname } from 'node:path'; +import { registerCommand } from './registry'; +import { + controllerTemplate, + routerTemplate, + serviceTemplate, +} from '../templates/module'; +import { capitalize } from '../utils'; + +const handler = async (args: string[]): Promise => { + const modulePath = args[0]; + if (!modulePath) { + Logger.error('Usage: gen:module '); + return; + } + + // Support nested paths like "v2/user" — use last segment for file naming + const name = basename(modulePath); + const nameCapitalized = capitalize(name); + const cwd = process.cwd(); + const moduleDir = join(cwd, 'src', 'modules', modulePath); + + const files: { filePath: string; content: string }[] = [ + { + filePath: join( + moduleDir, + 'controllers', + `${nameCapitalized}Controller.ts`, + ), + content: controllerTemplate(name), + }, + { + filePath: join(moduleDir, 'services', `${nameCapitalized}Service.ts`), + content: serviceTemplate(name), + }, + { + filePath: join(moduleDir, `${nameCapitalized}Router.ts`), + content: routerTemplate(name), + }, + ]; + + for (const { filePath, content } of files) { + const dir = dirname(filePath); + await Bun.$`mkdir -p ${dir}`.quiet(); + await Bun.write(filePath, content + '\n'); + Logger.info(`created ${relative(cwd, filePath)}`); + } + + Logger.info(`Module "${nameCapitalized}" generated successfully.`); +}; + +registerCommand({ + name: 'gen:module', + description: 'Generate a new module with Controller, Service, and Router', + usage: 'gen:module ', + aliases: ['gen:mo'], + handler, +}); diff --git a/packages/kame/src/commands/gen-router.ts b/packages/kame/src/commands/gen-router.ts new file mode 100644 index 0000000..9178782 --- /dev/null +++ b/packages/kame/src/commands/gen-router.ts @@ -0,0 +1,32 @@ +import { Logger } from 'gaman/utils'; +import { join, relative } from 'node:path'; +import { registerCommand } from './registry'; +import { routerBlankTemplate } from '../templates/module'; +import { capitalize } from '../utils'; + +const handler = async (args: string[]): Promise => { + const [name, module = 'app'] = args; + if (!name || !module) { + Logger.error("Usage: gen:router "); + return; + } + + const nameCapitalized = capitalize(name); + const cwd = process.cwd(); + // Support nested paths like "v2/user" + const routerDir = join(cwd, 'src', 'modules', module); + const filePath = join(routerDir, `${nameCapitalized}Router.ts`); + + await Bun.$`mkdir -p ${routerDir}`.quiet(); + await Bun.write(filePath, routerBlankTemplate() + '\n'); + Logger.info(`created ${relative(cwd, filePath)}`); + Logger.info(`Router "${nameCapitalized}Router" generated successfully.`); +}; + +registerCommand({ + name: 'gen:router', + description: 'Generate a new Router inside an existing module', + usage: "gen:router ", + aliases: ['gen:ro'], + handler, +}); diff --git a/packages/kame/src/commands/gen-service.ts b/packages/kame/src/commands/gen-service.ts new file mode 100644 index 0000000..8f8ecd4 --- /dev/null +++ b/packages/kame/src/commands/gen-service.ts @@ -0,0 +1,104 @@ +import { Logger } from 'gaman/utils'; +import { join, relative, basename } from 'node:path'; +import { registerCommand } from './registry'; +import { standaloneServiceTemplate } from '../templates/service'; +import { capitalize, toCamelCase } from '../utils'; + +/** + * Inject the new service into the module Router file. + * Adds the import statement and an entry inside r.mountService({...}). + */ +const patchRouter = async ( + routerPath: string, + serviceName: string, +): Promise => { + const file = Bun.file(routerPath); + if (!(await file.exists())) { + Logger.warn(`Router not found at ${routerPath}, skipping auto-register.`); + return; + } + + const nameCapitalized = capitalize(serviceName); + const camelName = toCamelCase(serviceName); + const importLine = `import { ${nameCapitalized}Service } from './services/${nameCapitalized}Service';`; + const mountEntry = `\t\t${camelName}Service: ${nameCapitalized}Service(),`; + + let source = await file.text(); + + // --- 1. Add import if not already present --- + if (!source.includes(importLine)) { + // Insert after the last import line + const lastImportIdx = source.lastIndexOf('\nimport '); + const insertAfter = + lastImportIdx !== -1 + ? source.indexOf('\n', lastImportIdx + 1) + : source.indexOf('\n'); + source = + source.slice(0, insertAfter) + + '\n' + + importLine + + source.slice(insertAfter); + } + + if (!source.includes(`${camelName}Service:`)) { + const mountStart = source.indexOf('r.mountService({'); + if (mountStart !== -1) { + // Find the closing }) of mountService + const closingIdx = source.indexOf('\t});', mountStart); + if (closingIdx !== -1) { + source = + source.slice(0, closingIdx) + + mountEntry + + '\n' + + source.slice(closingIdx); + } + } else { + Logger.warn( + `r.mountService block not found in ${routerPath}, skipping auto-register.`, + ); + } + } + + await Bun.write(routerPath, source); +}; + +const handler = async (args: string[]): Promise => { + const [name, module = 'app'] = args; + if (!name || !module) { + Logger.error("Usage: gen:service "); + return; + } + + const nameCapitalized = capitalize(name); + // Support nested paths like "v2/user" — use last segment for Router filename + const moduleSegment = basename(module); + const moduleCapitalized = capitalize(moduleSegment); + const cwd = process.cwd(); + const serviceDir = join(cwd, 'src', 'modules', module, 'services'); + const filePath = join(serviceDir, `${nameCapitalized}Service.ts`); + + await Bun.$`mkdir -p ${serviceDir}`.quiet(); + await Bun.write(filePath, standaloneServiceTemplate(name) + '\n'); + Logger.info(`created ${relative(cwd, filePath)}`); + + // Auto-register in module router (named after last segment, e.g. UserRouter.ts) + const routerPath = join( + cwd, + 'src', + 'modules', + module, + `${moduleCapitalized}Router.ts`, + ); + await patchRouter(routerPath, name); + Logger.info(`updated ${relative(cwd, routerPath)}`); + + Logger.info(`Service "${nameCapitalized}Service" generated successfully.`); +}; + +registerCommand({ + name: 'gen:service', + description: 'Generate a new Service and register it in the module Router', + usage: "gen:service ", + aliases: ['gen:se'], + handler, +}); diff --git a/packages/kame/src/commands/registry.ts b/packages/kame/src/commands/registry.ts new file mode 100644 index 0000000..ff0aae8 --- /dev/null +++ b/packages/kame/src/commands/registry.ts @@ -0,0 +1,95 @@ +export type CommandHandler = ( + args: string[], + flags: Record, +) => Promise | void; + +export class Command { + private _name: string; + private _handler: CommandHandler; + private _description: string = ''; + private _usage: string = ''; + private _aliases: string[] = []; + + constructor(name: string, handler: CommandHandler) { + this._name = name; + this._handler = handler; + } + + description(description: string): this { + this._description = description; + return this; + } + + usage(usage: string): this { + this._usage = usage; + return this; + } + + aliases(aliases: string[]): this { + this._aliases = aliases; + return this; + } + + getName(): string { + return this._name; + } + + getHandler(): CommandHandler { + return this._handler; + } + + getDescription(): string { + return this._description; + } + + getUsage(): string { + return this._usage; + } + + getAliases(): string[] { + return this._aliases; + } +} + +const commands = new Map(); +const aliases = new Map(); + +export const registerCommand = ( + cmd: + | Command + | { + name: string; + handler: CommandHandler; + description?: string; + usage?: string; + aliases?: string[]; + }, +): void => { + let _cmd: Command; + if (cmd instanceof Command) { + _cmd = cmd; + } else { + _cmd = new Command(cmd.name, cmd.handler) + .description(cmd.description ?? '') + .usage(cmd.usage ?? '') + .aliases(cmd.aliases ?? []); + } + + commands.set(_cmd.getName(), _cmd); + + // register aliases + for (const alias of _cmd.getAliases()) { + aliases.set(alias, _cmd.getName()); + } +}; + +export const getCommand = (name: string): Command | undefined => { + const cmd = commands.get(name); + if (cmd) return cmd; + + // search by alias + const aliasCmdName = aliases.get(name); + if (aliasCmdName) return commands.get(aliasCmdName); +}; + +export const getAllCommands = (): Command[] => Array.from(commands.values()); diff --git a/packages/kame/src/compose/index.ts b/packages/kame/src/compose/index.ts new file mode 100644 index 0000000..d1bbf42 --- /dev/null +++ b/packages/kame/src/compose/index.ts @@ -0,0 +1,21 @@ +import { + Command, + registerCommand, + type CommandHandler, +} from '../commands/registry'; + +export interface KameConsole { + command(name: string, handler: CommandHandler): Command; +} + +export function composeConsole( + handler: (kame: KameConsole) => Promise | void, +) { + handler({ + command(name, handler) { + const cmdClass = new Command(name, handler); + registerCommand(cmdClass); + return cmdClass; + }, + }); +} diff --git a/packages/kame/src/index.ts b/packages/kame/src/index.ts new file mode 100644 index 0000000..2b0d178 --- /dev/null +++ b/packages/kame/src/index.ts @@ -0,0 +1,8 @@ +export { startKame } from './repl'; + +import { Gaman } from 'gaman'; +import { startKame } from './repl'; + +export function startKameWithGaman(gaman: Gaman) { + return startKame(); +} diff --git a/packages/kame/src/input-parser.ts b/packages/kame/src/input-parser.ts new file mode 100644 index 0000000..3c5d8c0 --- /dev/null +++ b/packages/kame/src/input-parser.ts @@ -0,0 +1,41 @@ +export interface ParsedInput { + args: string[]; + flags: Record; +} + +export function parseInput(argv: string[]): ParsedInput { + const args: string[] = []; + const flags: Record = {}; + + for (let i = 0; i < argv.length; i++) { + const token = argv[i]; + if (token === undefined) continue; + + if (token.startsWith('--')) { + const key = token.slice(2); + const next = argv[i + 1]; + + // --force (boolean) vs --name value + if (!next || next.startsWith('--') || next.startsWith('-')) { + flags[key] = true; + } else { + flags[key] = next; + i++; // skip next token + } + } else if (token.startsWith('-') && token.length === 2) { + const key = token.slice(1); + const next = argv[i + 1]; + + if (!next || next.startsWith('--') || next.startsWith('-')) { + flags[key] = true; + } else { + flags[key] = next; + i++; + } + } else { + args.push(token); + } + } + + return { args, flags }; +} diff --git a/packages/kame/src/repl.ts b/packages/kame/src/repl.ts new file mode 100644 index 0000000..7e15a03 --- /dev/null +++ b/packages/kame/src/repl.ts @@ -0,0 +1,63 @@ +import * as readline from 'node:readline'; +import { Logger, TextFormat } from 'gaman/utils'; +import { getAllCommands, getCommand } from './commands/registry'; +import { parseInput } from './input-parser'; + +/* -------------------------------------------------------------------------- */ +/* REGISTER COMMANDS */ +/* -------------------------------------------------------------------------- */ +import './commands/gen-module'; +import './commands/gen-router'; +import './commands/gen-controller'; +import './commands/gen-service'; +import './commands/gen-middleware'; +import './commands/gen-exception'; +import './commands/buntest-cmd'; +import './commands/fetch'; + +export function startKame() { + if (!process.env.KAME_CLI) return; + Logger.info( + `${TextFormat.BG_CYAN} ${TextFormat.BOLD}Kame ${TextFormat.RESET} System active. Type "help" for commands.`, + ); + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + terminal: true, + }); + + rl.setPrompt('> '); + rl.prompt(); + rl.write('help'); + + rl.on('line', async (line) => { + const _argv = line.trim().split(' '); + const commandName = _argv[0]; + if (commandName === undefined) return; + + const { args, flags } = parseInput(_argv.slice(1)); + + if (commandName === 'help') { + const commands = getAllCommands(); + Logger.info(`${TextFormat.BOLD}Available commands:${TextFormat.RESET}`); + for (const cmd of commands) { + Logger.info( + `${TextFormat.YELLOW}- ${TextFormat.RESET}${cmd.getUsage().padEnd(40)} ${TextFormat.GRAY}${cmd.getDescription()}${TextFormat.RESET}`, + ); + } + rl.prompt(); + return; + } + + const cmd = getCommand(commandName); + if (!cmd) { + Logger.error( + `Unknown command: "${commandName}". Run "help" to see available commands.`, + ); + } else { + await cmd.getHandler()(args, flags); + } + + rl.prompt(); + }); +} diff --git a/packages/kame/src/templates/module.ts b/packages/kame/src/templates/module.ts new file mode 100644 index 0000000..867d344 --- /dev/null +++ b/packages/kame/src/templates/module.ts @@ -0,0 +1,108 @@ +import { capitalize, toCamelCase } from '../utils'; + +export const serviceTemplate = (name: string) => { + const nameCapitalized = capitalize(name); + return ` +import { composeService } from 'gaman/compose'; +import type { RT } from 'gaman/types'; + +export const ${nameCapitalized}Service = composeService(() => { + + // TODO: Implement your service logic here + + return { + WelcomeMessage() { + return 'Welcome to ${nameCapitalized} Service!'; + }, + }; +}); + +export type ${nameCapitalized}Service = RT; +`.trim(); +}; + +export const controllerTemplate = (name: string) => { + const nameCapitalized = capitalize(name); + return ` +import { composeController } from 'gaman/compose'; +import { Res } from 'gaman/responder'; +import { ${nameCapitalized}Service } from '../services/${nameCapitalized}Service'; + +export type Deps = { + ${toCamelCase(name)}Service: ${nameCapitalized}Service; +} + +export default composeController(({ ${toCamelCase(name)}Service }: Deps) => { + + // TODO: Implement your controller logic here + + return { + index(ctx) { + return Res.json({ + message: ${toCamelCase(name)}Service.WelcomeMessage(), + }); + }, + }; +}); +`.trim(); +}; + +export const routerTemplate = (name: string) => { + const nameCapitalized = capitalize(name); + const camelCaseName = toCamelCase(name); + + return ` +import { composeRouter } from 'gaman/compose'; +import ${nameCapitalized}Controller from './controllers/${nameCapitalized}Controller'; +import { ${nameCapitalized}Service } from './services/${nameCapitalized}Service'; + +export default composeRouter((r) => { + r.mountService({ + ${camelCaseName}Service: ${nameCapitalized}Service(), + }); + + r.get('/', [${nameCapitalized}Controller, 'index']); +}); +`.trim(); +}; + +export const routerBlankTemplate = () => { + return ` +import { composeRouter } from 'gaman/compose'; + +export default composeRouter((r) => { + r.mountService({ + + }); + + // TODO: Implement your routers +}); +`.trim(); +}; + +export const middlewareTemplate = () => { + return ` +import { composeMiddleware } from 'gaman/compose'; + +export default composeMiddleware(async (ctx, next) => { + + // TODO: Implement your middleware logic here + + return next(); +}); +`.trim(); +}; + +export const exceptionTemplate = () => { + return ` +import { composeException } from 'gaman/compose'; +import { Res } from 'gaman/responder'; + +export default composeException((err, ctx) => { + + // TODO: Implement your exception handler logic here + + return Res.internalServerError(); +}); + `.trim(); +}; diff --git a/packages/kame/src/templates/service.ts b/packages/kame/src/templates/service.ts new file mode 100644 index 0000000..c1c6bb5 --- /dev/null +++ b/packages/kame/src/templates/service.ts @@ -0,0 +1,18 @@ +import { capitalize } from '../utils'; + +export const standaloneServiceTemplate = (name: string): string => { + const nameCapitalized = capitalize(name); + return ` +import { composeService } from 'gaman/compose'; +import type { RT } from 'gaman/types'; + +export const ${nameCapitalized}Service = composeService(() => { + + // TODO: Implement ${nameCapitalized}Service logic here + + return {}; +}); + +export type ${nameCapitalized}Service = RT; +`.trim(); +}; diff --git a/packages/kame/src/utils.ts b/packages/kame/src/utils.ts new file mode 100644 index 0000000..2e999fa --- /dev/null +++ b/packages/kame/src/utils.ts @@ -0,0 +1,17 @@ +/** + * Mengubah karakter pertama menjadi huruf besar + * Contoh: userCreator -> UserCreator + */ +export const capitalize = (str: string): string => { + if (!str) return str; + return str.charAt(0).toUpperCase() + str.slice(1); +}; + +/** + * Mengubah karakter pertama menjadi huruf kecil + * Contoh: UserProfile -> userProfile + */ +export const toCamelCase = (str: string): string => { + if (!str) return str; + return str.charAt(0).toLowerCase() + str.slice(1); +}; \ No newline at end of file diff --git a/packages/kame/tsconfig.dts.json b/packages/kame/tsconfig.dts.json new file mode 100644 index 0000000..abdb0f0 --- /dev/null +++ b/packages/kame/tsconfig.dts.json @@ -0,0 +1,60 @@ +{ + "compilerOptions": { + "preserveSymlinks": true, + "target": "ES2021", + "lib": [ + "ESNext" + ], + "module": "ES2022", + "rootDir": "./src", + "outDir": "./dist", + + "moduleResolution": "node", + "resolveJsonModule": true, + "skipLibCheck": true, + "declaration": true, + "emitDeclarationOnly": true, + "baseUrl": ".", + "paths": { + "gaman": [ + "../../dist/index.d.ts" + ], + "gaman/types": [ + "../../dist/types.d.ts" + ], + "gaman/responder": [ + "../../dist/responder.d.ts" + ], + "gaman/compose": [ + "../../dist/compose/index.d.ts" + ], + "gaman/utils": [ + "../../dist/utils/index.d.ts" + ], + "gaman/formdata": [ + "../../dist/context/formdata/index.d.ts" + ], + "gaman/header": [ + "../../dist/context/header/index.d.ts" + ], + "gaman/enums": [ + "../../dist/enums/index.d.ts" + ] + } + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "test", + "example", + "dist", + "build.ts", + "old", + "src-test", + "**/*.test.*", + "benchmark", + "**/*.benchmark.*" + ] +} \ No newline at end of file diff --git a/packages/kame/tsconfig.json b/packages/kame/tsconfig.json new file mode 100644 index 0000000..14dba04 --- /dev/null +++ b/packages/kame/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} From 0896861fe7c95a2b5a3cb97170aede41d246c33f Mon Sep 17 00:00:00 2001 From: Angga7Togk Date: Mon, 20 Apr 2026 21:34:31 +0700 Subject: [PATCH 2/4] feat: add Res method on global feat: can bootstrap app with new Gaman() --- src/gaman.ts | 21 +++++++++++++++++---- src/global.ts | 3 +++ src/index.ts | 2 +- src/utils/logger.ts | 12 +++++------- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/gaman.ts b/src/gaman.ts index 92f5be2..407b1a5 100644 --- a/src/gaman.ts +++ b/src/gaman.ts @@ -26,7 +26,6 @@ import type { Router, } from './compose/index'; import { TextFormat } from './utils/textformat'; -import type { BodyInit } from 'bun'; export class Gaman { private michi = new Michi(); @@ -176,7 +175,8 @@ export class Gaman { fn = handlers[idx++]; } - if (typeof fn !== 'function') return new Response(undefined, { status: 404 }); + if (typeof fn !== 'function') + return new Response(undefined, { status: 404 }); return await fn(ctx, next); } catch (error) { if (routeExceptionHandler) @@ -266,10 +266,10 @@ export class Gaman { public mountServer(config?: GamanServerConfig) { Logger.log( - `${TextFormat.BOLD}${TextFormat.LIGHT_PURPLE}GamanJS Framework v2`, + `${TextFormat.BOLD}${TextFormat.LIGHT_PURPLE}GamanJS Framework`, ); Logger.info( - `${TextFormat.ITALIC}The Universal Transport Layer for Your Logic.`, + `${TextFormat.ITALIC}A Lean Framework for Enterprise Scalability.`, ); Logger.log(`${TextFormat.GRAY} —————————————————————————————————————— `); @@ -285,6 +285,19 @@ export class Gaman { Logger.info( `${TextFormat.LIGHT_BLUE}HTTP${TextFormat.RESET} : Listening at ${TextFormat.LIGHT_GREEN}http://${host}:${port}`, ); + + const defaultFetch = fetch; + // @ts-ignore + globalThis.fetch = (input, init) => { + const baseUrl = 'http://localhost:' + port; + + if (typeof input === 'string' && !input.startsWith('http')) { + const formattedPath = input.startsWith('/') ? input : `/${input}`; + input = `${baseUrl}${formattedPath}`; + } + return defaultFetch(input, init); + }; + this.listenHttp(config.http); } // this.listenIPC(); diff --git a/src/global.ts b/src/global.ts index 3d73f35..52453c7 100644 --- a/src/global.ts +++ b/src/global.ts @@ -1,9 +1,12 @@ import { Logger } from './utils/logger.js'; +import { Res } from './responder.js'; globalThis.Log = Logger; +globalThis.Res = Res; declare global { var Log: typeof import('./utils/logger.js').Logger; + var Res: typeof import('./responder.js').Res; namespace Bun { interface Env extends Gaman.Env {} diff --git a/src/index.ts b/src/index.ts index 630cf19..8a7b4ea 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ +export { Gaman } from './gaman'; import { Gaman } from './gaman'; export function defineBootstrap(fn: (app: Gaman) => void) { @@ -5,4 +6,3 @@ export function defineBootstrap(fn: (app: Gaman) => void) { fn(gaman); } - diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 0c1c2a0..22a3fee 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -21,9 +21,9 @@ export const Logger = { const time = Logger.getShortTime(); const colorPrefix: Record = { - info: TextFormat.GREEN + '[INFO~]', + info: TextFormat.GREEN + '[INFO]', debug: TextFormat.CYAN + '[DEBUG]', - warn: TextFormat.YELLOW + '[WARN~]', + warn: TextFormat.YELLOW + '[WARN]', error: TextFormat.RED + '[ERROR]', }; @@ -34,7 +34,7 @@ export const Logger = { error: TextFormat.RED, }; - const text = `${colorPrefix[type]} ${TextFormat.GRAY}[${time}]`; + const text = `${TextFormat.GRAY}${time} ${colorPrefix[type]}`; msg = [ text + color[type], @@ -76,8 +76,6 @@ export const Logger = { return Logger.levels[level] <= Logger.levels[Logger.level]; }, - setRequestId(requestId: string) { }, - setRoute(route: string) { }, setStatus(status: number | null) { }, @@ -86,9 +84,9 @@ export const Logger = { getShortTime: () => { const now = new Date(); - const date = now.toISOString().slice(0, 10); // YYYY-MM-DD + // const date = now.toISOString().slice(0, 10); // YYYY-MM-DD const time = now.toTimeString().split(' ')[0]; // HH:MM:SS - return `${date} ${time}`; + return `${time}`; }, }; From 0afee74f68db48b637fb318b23f88037118d2fd3 Mon Sep 17 00:00:00 2001 From: Angga7Togk Date: Mon, 20 Apr 2026 21:34:48 +0700 Subject: [PATCH 3/4] test: update --- test/AppController.ts | 5 +---- test/AppServices.ts | 4 ++-- test/console.ts | 8 ++++++++ test/test.ts | 38 +++++++++++++++++--------------------- 4 files changed, 28 insertions(+), 27 deletions(-) create mode 100644 test/console.ts diff --git a/test/AppController.ts b/test/AppController.ts index be0a52d..7627e76 100644 --- a/test/AppController.ts +++ b/test/AppController.ts @@ -9,10 +9,7 @@ export type AppController = { export default composeController(({ appService }: AppController) => { return { async ANu(ctx) { - - return Res.render('index', { - message: appService.Welcome().message, - }); + return Res.json({ message: 'anajy' }); }, }; }); diff --git a/test/AppServices.ts b/test/AppServices.ts index 5b25b03..7abf6bf 100644 --- a/test/AppServices.ts +++ b/test/AppServices.ts @@ -1,10 +1,10 @@ import { composeService } from "../src/compose"; -import { RT } from "../src/types"; +import type { RT } from "../src/types"; export const AppService = composeService(() => ({ Welcome() { return { - message: "Welcome tu gaman ji es" + message: "Welcome to gaman ji es" } } })); diff --git a/test/console.ts b/test/console.ts new file mode 100644 index 0000000..9910319 --- /dev/null +++ b/test/console.ts @@ -0,0 +1,8 @@ +import { Logger } from 'gaman/utils'; +import { composeConsole } from '../packages/kame/src/compose'; + +export default composeConsole((kame) => { + kame.command('anu', async (args, flags) => { + Logger.info('anjay', flags['f']); + }).usage('anu '); +}); diff --git a/test/test.ts b/test/test.ts index fcafbd6..71e9ead 100644 --- a/test/test.ts +++ b/test/test.ts @@ -1,10 +1,11 @@ import { composeRouter } from '../src/compose'; -import { defineBootstrap } from '../src/index'; +import { defineBootstrap, Gaman } from '../src/index'; import { Cors } from '../packages/cors/src'; import { StaticServe } from '../packages/static/src'; import AppController from './AppController'; import { AppService } from './AppServices'; -import { Edge } from './lib/edge'; +import { startKameWithGaman } from '../packages/kame/src/index'; +import './console'; const childRouter = composeRouter((r) => { r.mountMiddleware((ctx, next) => { @@ -26,26 +27,21 @@ const routes = composeRouter((r) => { r.get('/', [AppController, 'ANu']); }); -defineBootstrap((app) => { - // app.mount(Cors({ - // allowHeaders: ['content-type'] - // })); - // app.mount(Edge()) - - app.mount( - StaticServe({ - publicPath: 'test/public', - }), - ); - app.mount(Cors()); - app.mount(routes); - app.mountServer({ - http: { - port: 3431, - }, - }); -}); +const app = new Gaman(); +app.mount( + StaticServe({ + publicPath: 'test/public', + }), +); +app.mount(Cors()); +app.mount(routes); +app.mountServer({ + http: { + port: 3431, + }, +}); +startKameWithGaman(app); // client // Bun.connect({ // unix: '/tmp/gaman.sock', From 256492745f43233a23f2f2a1f4b58c670c9996fe Mon Sep 17 00:00:00 2001 From: Angga7Togk Date: Mon, 20 Apr 2026 21:35:25 +0700 Subject: [PATCH 4/4] fix(script): build.ts --- .gitignore | 3 + build.ts | 2 +- bun.lock | 161 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 3 +- tsconfig.dts.json | 96 +++++++++++---------------- tsconfig.json | 5 +- 6 files changed, 207 insertions(+), 63 deletions(-) diff --git a/.gitignore b/.gitignore index 1df818b..10df4e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # dependencies (bun install) node_modules +# test folders +src/modules + # output out dist diff --git a/build.ts b/build.ts index ce4d999..88bc2fd 100644 --- a/build.ts +++ b/build.ts @@ -46,7 +46,7 @@ build({ cjsInterop: false, clean: true, bundle: false, - external: ['michi', 'gaman', 'gaman/types', 'gaman/responder', 'gaman/compose', 'gaman/utils', 'gaman/formdata', 'gaman/header', 'gaman/enums'], + external: ['node:path', 'node:readline', 'michi', 'gaman', 'gaman/types', 'gaman/responder', 'gaman/compose', 'gaman/utils', 'gaman/formdata', 'gaman/header', 'gaman/enums'], esbuildPlugins: [ fixImportsPlugin() ], diff --git a/bun.lock b/bun.lock index 0b4d513..ec9582a 100644 --- a/bun.lock +++ b/bun.lock @@ -6,10 +6,17 @@ "name": "gaman", "devDependencies": { "@types/bun": "latest", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "edge.js": "^6.5.0", "esbuild-fix-imports-plugin": "^1.0.23", "prettier": "^3.8.1", + "react": "^19.2.4", + "react-dom": "^19.2.4", "tsup": "^8.5.1", "typescript": "^5.9.3", + "vite": "^8.0.3", }, "peerDependencies": { "@gaman/michi": "^0.1.3", @@ -17,10 +24,20 @@ }, "packages/cors": { "name": "@gaman/cors", - "version": "1.0.8", + "version": "1.0.9", + }, + "packages/static": { + "name": "@gaman/static", + "version": "1.0.6", }, }, "packages": { + "@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="], + + "@emnapi/runtime": ["@emnapi/runtime@1.9.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw=="], + + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q=="], "@esbuild/android-arm": ["@esbuild/android-arm@0.27.4", "", { "os": "android", "cpu": "arm" }, "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ=="], @@ -77,6 +94,8 @@ "@gaman/michi": ["@gaman/michi@0.1.3", "", {}, "sha512-vNkpTEfUa9F8KkpU1OwuY8mKEYmFcpILirsAD7S31IiEThx9inADI/ASO612miX1K6oGWOTqbNXAO09j5I1Hug=="], + "@gaman/static": ["@gaman/static@workspace:packages/static"], + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], @@ -85,6 +104,56 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.2", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw=="], + + "@oxc-project/types": ["@oxc-project/types@0.122.0", "", {}, "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA=="], + + "@poppinss/exception": ["@poppinss/exception@1.2.3", "", {}, "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw=="], + + "@poppinss/inspect": ["@poppinss/inspect@1.0.1", "", {}, "sha512-kLeEaBSGhlleyYvKc7c9s3uE6xv7cwyulE0EgHf4jU/CL96h0yC4mkdw1wvC1l1PYYQozCGy46FwMBAAMOobCA=="], + + "@poppinss/macroable": ["@poppinss/macroable@1.1.2", "", {}, "sha512-FAVBRzzWhYP5mA3lCwLH1A0fKBqq5anyjGet90Z81aRK5c/+LTGUE1zJhZrErjaenBSOOI9BVUs3WVmotneFQA=="], + + "@poppinss/object-builder": ["@poppinss/object-builder@1.1.0", "", {}, "sha512-FOrOq52l7u8goR5yncX14+k+Ewi5djnrt1JwXeS/FvnwAPOiveFhiczCDuvXdssAwamtrV2hp5Rw9v+n2T7hQg=="], + + "@poppinss/string": ["@poppinss/string@1.7.1", "", { "dependencies": { "@types/pluralize": "^0.0.33", "case-anything": "^3.1.2", "pluralize": "^8.0.0", "slugify": "^1.6.6" } }, "sha512-OrLzv/nGDU6l6dLXIQHe8nbNSWWfuSbpB/TW5nRpZFf49CLuQlIHlSPN9IdSUv2vG+59yGM6LoibsaHn8B8mDw=="], + + "@poppinss/types": ["@poppinss/types@1.2.1", "", {}, "sha512-qUYnzl0m9HJTWsXtr8Xo7CwDx6wcjrvo14bOVbIMIlKJCzKrm3LX55dRTDr1/x4PpSvKVgmxvC6Ly2YiqXKOvQ=="], + + "@poppinss/utils": ["@poppinss/utils@7.0.1", "", { "dependencies": { "@poppinss/exception": "^1.2.3", "@poppinss/object-builder": "^1.1.0", "@poppinss/string": "^1.7.1", "@poppinss/types": "^1.2.1", "flattie": "^1.1.1" } }, "sha512-mveSvLI2YPC114mK5HCuSYfUtjpClf1wHG1VCqZJCp4U2ypPhIt62Iku5urh0kPAFvnvCVHx2bXBSH14qMTOlQ=="], + + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.12", "", { "os": "android", "cpu": "arm64" }, "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA=="], + + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg=="], + + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw=="], + + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q=="], + + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12", "", { "os": "linux", "cpu": "arm" }, "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q=="], + + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg=="], + + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw=="], + + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g=="], + + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og=="], + + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "x64" }, "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg=="], + + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.12", "", { "os": "linux", "cpu": "x64" }, "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig=="], + + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.12", "", { "os": "none", "cpu": "arm64" }, "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA=="], + + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.12", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg=="], + + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q=="], + + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.12", "", { "os": "win32", "cpu": "x64" }, "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw=="], + + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.7", "", {}, "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="], "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q=="], @@ -135,22 +204,36 @@ "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + "@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="], "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "@types/node": ["@types/node@25.4.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw=="], + "@types/pluralize": ["@types/pluralize@0.0.33", "", {}, "sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg=="], + + "@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], + + "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], + + "@vitejs/plugin-react": ["@vitejs/plugin-react@6.0.1", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-rc.7" }, "peerDependencies": { "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", "babel-plugin-react-compiler": "^1.0.0", "vite": "^8.0.0" }, "optionalPeers": ["@rolldown/plugin-babel", "babel-plugin-react-compiler"] }, "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ=="], + "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], + "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], + "bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="], "bundle-require": ["bundle-require@5.1.0", "", { "dependencies": { "load-tsconfig": "^0.2.3" }, "peerDependencies": { "esbuild": ">=0.18" } }, "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA=="], "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], + "case-anything": ["case-anything@3.1.2", "", {}, "sha512-wljhAjDDIv/hM2FzgJnYQg90AWmZMNtESCjTeLH680qTzdo0nErlCxOmgzgX4ZsZAtIvqHyD87ES8QyriXB+BQ=="], + "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], "commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], @@ -159,20 +242,64 @@ "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + + "edge-error": ["edge-error@4.0.2", "", {}, "sha512-jB76VYn8wapDHKHSOmP3vbKLoa77RJYsTLNmfl8+cuCD69uxZtP3h+kqV+Prw/YkYmN7yHyp4IApE15pDByk0A=="], + + "edge-lexer": ["edge-lexer@6.0.4", "", { "dependencies": { "edge-error": "^4.0.2" } }, "sha512-rHlTSZUQfBu/fwnAjoaLCGGmDzpRPgUC8FEqNdJtpPEjBRCqU3a4Le7iJ8KSQfY2WvWx6NTGAwti62xj3eIz1w=="], + + "edge-parser": ["edge-parser@9.1.0", "", { "dependencies": { "acorn": "^8.15.0", "astring": "^1.9.0", "edge-error": "^4.0.2", "edge-lexer": "^6.0.4", "js-stringify": "^1.0.2" } }, "sha512-Z7sEbRNjjGuUVch3ELHMbjgksVjQlAjUASCwUWe+1I+nJ0mVBmUD2rn6zyes/+EjLssvEGQcIWMjLMNn1ChXgQ=="], + + "edge.js": ["edge.js@6.5.0", "", { "dependencies": { "@poppinss/inspect": "^1.0.1", "@poppinss/macroable": "^1.1.0", "@poppinss/utils": "^7.0.0-next.4", "edge-error": "^4.0.2", "edge-lexer": "^6.0.4", "edge-parser": "^9.0.4", "he": "^1.2.0", "property-information": "^7.1.0", "stringify-attributes": "^4.0.0" } }, "sha512-WEXNseOSK6n5+Maf6dBPCMgsOuw4mpOqItMniXmdILVCH5PcjQ/CZDfw8IYyMwAjhshoznG+8WjsERy4+56xhA=="], + "esbuild": ["esbuild@0.27.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.4", "@esbuild/android-arm": "0.27.4", "@esbuild/android-arm64": "0.27.4", "@esbuild/android-x64": "0.27.4", "@esbuild/darwin-arm64": "0.27.4", "@esbuild/darwin-x64": "0.27.4", "@esbuild/freebsd-arm64": "0.27.4", "@esbuild/freebsd-x64": "0.27.4", "@esbuild/linux-arm": "0.27.4", "@esbuild/linux-arm64": "0.27.4", "@esbuild/linux-ia32": "0.27.4", "@esbuild/linux-loong64": "0.27.4", "@esbuild/linux-mips64el": "0.27.4", "@esbuild/linux-ppc64": "0.27.4", "@esbuild/linux-riscv64": "0.27.4", "@esbuild/linux-s390x": "0.27.4", "@esbuild/linux-x64": "0.27.4", "@esbuild/netbsd-arm64": "0.27.4", "@esbuild/netbsd-x64": "0.27.4", "@esbuild/openbsd-arm64": "0.27.4", "@esbuild/openbsd-x64": "0.27.4", "@esbuild/openharmony-arm64": "0.27.4", "@esbuild/sunos-x64": "0.27.4", "@esbuild/win32-arm64": "0.27.4", "@esbuild/win32-ia32": "0.27.4", "@esbuild/win32-x64": "0.27.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ=="], "esbuild-fix-imports-plugin": ["esbuild-fix-imports-plugin@1.0.23", "", {}, "sha512-zDn2Mq3OnW9qNm9FrHDeE0FePgIRIaH9EWpHOGsJZFPfyPSNqzvCK/x9EZJ5eHEEyXe8ZGdb5CjDpzqkyAqcCg=="], + "escape-goat": ["escape-goat@4.0.0", "", {}, "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg=="], + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], "fix-dts-default-cjs-exports": ["fix-dts-default-cjs-exports@1.0.1", "", { "dependencies": { "magic-string": "^0.30.17", "mlly": "^1.7.4", "rollup": "^4.34.8" } }, "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg=="], + "flattie": ["flattie@1.1.1", "", {}, "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ=="], + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + "he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="], + "joycon": ["joycon@3.1.1", "", {}, "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw=="], + "js-stringify": ["js-stringify@1.0.2", "", {}, "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g=="], + + "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], + + "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], + + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], + + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], + + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], + + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], + + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], + + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], + + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], + + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], + + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], + + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], + "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], @@ -187,30 +314,52 @@ "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="], "pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], + "pluralize": ["pluralize@8.0.0", "", {}, "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA=="], + + "postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], + "postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["jiti", "postcss", "tsx", "yaml"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="], "prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="], + "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], + + "react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], + + "react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], + "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + "rolldown": ["rolldown@1.0.0-rc.12", "", { "dependencies": { "@oxc-project/types": "=0.122.0", "@rolldown/pluginutils": "1.0.0-rc.12" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.12", "@rolldown/binding-darwin-arm64": "1.0.0-rc.12", "@rolldown/binding-darwin-x64": "1.0.0-rc.12", "@rolldown/binding-freebsd-x64": "1.0.0-rc.12", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A=="], + "rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="], + "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], + + "slugify": ["slugify@1.6.9", "", {}, "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg=="], + "source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "stringify-attributes": ["stringify-attributes@4.0.0", "", { "dependencies": { "escape-goat": "^4.0.0" } }, "sha512-6Hq3K153wTTfhEHb4V/viuqmb0DRn08JCrRnmqc4Q/tmoNuvd4DEyqkiiJXtvVz8ZSUhlCQr7zCpCVTgrelesg=="], + "sucrase": ["sucrase@3.35.1", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw=="], "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], @@ -225,6 +374,8 @@ "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="], + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "tsup": ["tsup@8.5.1", "", { "dependencies": { "bundle-require": "^5.1.0", "cac": "^6.7.14", "chokidar": "^4.0.3", "consola": "^3.4.0", "debug": "^4.4.0", "esbuild": "^0.27.0", "fix-dts-default-cjs-exports": "^1.0.0", "joycon": "^3.1.1", "picocolors": "^1.1.1", "postcss-load-config": "^6.0.1", "resolve-from": "^5.0.0", "rollup": "^4.34.8", "source-map": "^0.7.6", "sucrase": "^3.35.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.11", "tree-kill": "^1.2.2" }, "peerDependencies": { "@microsoft/api-extractor": "^7.36.0", "@swc/core": "^1", "postcss": "^8.4.12", "typescript": ">=4.5.0" }, "optionalPeers": ["@microsoft/api-extractor", "@swc/core", "postcss", "typescript"], "bin": { "tsup": "dist/cli-default.js", "tsup-node": "dist/cli-node.js" } }, "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing=="], "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], @@ -232,5 +383,11 @@ "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="], "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], + + "vite": ["vite@8.0.3", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.12", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ=="], + + "rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.12", "", {}, "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw=="], + + "tinyglobby/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], } } diff --git a/package.json b/package.json index 4ad366f..ce02c01 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,8 @@ "framework" ], "scripts": { - "release": "bun build.ts && bun test && npm publish --access public" + "release": "bun build.ts && bun test && npm publish --access public", + "kame": "bun packages/kame/src/index.ts" }, "devDependencies": { "@types/bun": "latest", diff --git a/tsconfig.dts.json b/tsconfig.dts.json index d40549b..928adcb 100644 --- a/tsconfig.dts.json +++ b/tsconfig.dts.json @@ -1,58 +1,40 @@ { - "compilerOptions": { - "preserveSymlinks": true, - "target": "ES2021", - "lib": [ - "ESNext" - ], - "module": "ES2022", - "rootDir": "./src", - "outDir": "./dist", - "moduleResolution": "node", - "resolveJsonModule": true, - "skipLibCheck": true, - "declaration": true, - "emitDeclarationOnly": true, - "paths": { - "gaman": [ - "./src/index.ts" - ], - "gaman/types": [ - "./src/types.ts" - ], - "gaman/responder": [ - "./src/responder.ts" - ], - "gaman/compose": [ - "./src/compose/index.ts" - ], - "gaman/utils": [ - "./src/utils/index.ts" - ], - "gaman/formdata": [ - "./src/context/formdata/index.ts" - ], - "gaman/header": [ - "./src/context/header/index.ts" - ], - "gaman/enums": [ - "./src/enums/index.ts" - ] - } - }, - "include": [ - "src/*" - ], - "exclude": [ - "node_modules", - "test", - "example", - "dist", - "build.ts", - "old", - "src-test", - "**/*.test.*", - "benchmark", - "**/*.benchmark.*" - ] -} \ No newline at end of file + "compilerOptions": { + "preserveSymlinks": true, + "target": "ES2021", + "lib": ["ESNext"], + "module": "ES2022", + "rootDir": "./src", + "outDir": "./dist", + "moduleResolution": "node", + "resolveJsonModule": true, + "skipLibCheck": true, + "declaration": true, + "emitDeclarationOnly": true, + "isolatedModules": true, + "allowSyntheticDefaultImports": true, + "paths": { + "gaman": ["./src/index.ts"], + "gaman/types": ["./src/types.ts"], + "gaman/responder": ["./src/responder.ts"], + "gaman/compose": ["./src/compose/index.ts"], + "gaman/utils": ["./src/utils/index.ts"], + "gaman/formdata": ["./src/context/formdata/index.ts"], + "gaman/header": ["./src/context/header/index.ts"], + "gaman/enums": ["./src/enums/index.ts"] + } + }, + "include": ["src/**/*"], + "exclude": [ + "node_modules", + "test", + "example", + "dist", + "build.ts", + "old", + "src-test", + "**/*.test.*", + "benchmark", + "**/*.benchmark.*" + ] +} diff --git a/tsconfig.json b/tsconfig.json index 2ea8655..8c1f694 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,6 +24,7 @@ "noUnusedLocals": false, "noUnusedParameters": false, "noPropertyAccessFromIndexSignature": false, + "allowSyntheticDefaultImports": true, "baseUrl": ".", "paths": { "gaman": [ @@ -53,8 +54,8 @@ } }, "include": [ - "src/*" - ], + "src/**/*" +, "test/console.ts" ], "exclude": [ "**/*.test.ts", "tests",