init project
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import type { AdapterCommand, FrameworkAdapter } from './types.js';
|
||||
import {
|
||||
detectJsPackageManager,
|
||||
installCommandFor,
|
||||
readPackageJson,
|
||||
runScriptCommandFor,
|
||||
type JsPackageManager,
|
||||
type PackageJson,
|
||||
} from './packageManager.js';
|
||||
|
||||
/**
|
||||
* Fallback adapter for any project that isn't recognized as Laravel,
|
||||
* CodeIgniter, or React. Drives everything off `package.json` scripts when
|
||||
* one exists; otherwise tool calls fail with a clear, actionable message
|
||||
* instead of guessing.
|
||||
*/
|
||||
export class GenericAdapter implements FrameworkAdapter {
|
||||
readonly kind = 'generic' as const;
|
||||
readonly label: string;
|
||||
readonly packageManager?: JsPackageManager;
|
||||
private readonly pkg: PackageJson | null;
|
||||
|
||||
constructor(readonly root: string) {
|
||||
this.pkg = readPackageJson(root);
|
||||
this.packageManager = this.pkg ? detectJsPackageManager(root) : undefined;
|
||||
this.label = this.pkg ? `Generic Node project (${this.packageManager})` : 'Unrecognized project';
|
||||
}
|
||||
|
||||
installCommand(): AdapterCommand {
|
||||
if (!this.packageManager) {
|
||||
throw new Error(
|
||||
`No package.json found at "${this.root}" and no recognized framework detected. ` +
|
||||
`Nothing for run_install to do here.`,
|
||||
);
|
||||
}
|
||||
const { command, args } = installCommandFor(this.packageManager);
|
||||
return { command, args, cwd: this.root };
|
||||
}
|
||||
|
||||
devCommand(): AdapterCommand {
|
||||
return this.scriptCommand(['dev', 'start', 'serve']);
|
||||
}
|
||||
|
||||
buildCommand(): AdapterCommand | null {
|
||||
return this.scriptCommandOrNull(['build']);
|
||||
}
|
||||
|
||||
testCommand(extraArgs: string[] = []): AdapterCommand | null {
|
||||
return this.scriptCommandOrNull(['test'], extraArgs);
|
||||
}
|
||||
|
||||
lintCommand(fix = false): AdapterCommand | null {
|
||||
return this.scriptCommandOrNull(fix ? ['format', 'lint:fix'] : ['lint']);
|
||||
}
|
||||
|
||||
readyPattern(): RegExp {
|
||||
return /(https?:\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0)[:\d]*\S*)|ready|listening/i;
|
||||
}
|
||||
|
||||
describe(): Record<string, unknown> {
|
||||
return {
|
||||
kind: this.kind,
|
||||
label: this.label,
|
||||
root: this.root,
|
||||
packageManager: this.packageManager ?? null,
|
||||
scripts: this.pkg?.scripts ?? {},
|
||||
};
|
||||
}
|
||||
|
||||
private scriptCommand(candidates: string[]): AdapterCommand {
|
||||
const result = this.scriptCommandOrNull(candidates);
|
||||
if (!result) {
|
||||
throw new Error(
|
||||
`No package.json script found for any of [${candidates.join(', ')}] in "${this.root}". ` +
|
||||
`Add one of these scripts, or use run_script with an explicit script name.`,
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private scriptCommandOrNull(candidates: string[], extraArgs: string[] = []): AdapterCommand | null {
|
||||
if (!this.pkg?.scripts || !this.packageManager) return null;
|
||||
const script = candidates.find((name) => this.pkg?.scripts?.[name]);
|
||||
if (!script) return null;
|
||||
const { command, args } = runScriptCommandFor(this.packageManager, script, extraArgs);
|
||||
return { command, args, cwd: this.root };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user