112 lines
3.0 KiB
TypeScript
112 lines
3.0 KiB
TypeScript
/**
|
|
* Thin CLI wrapper for auth-runtime.
|
|
*
|
|
* Copy this file into your skill's src/ directory. It calls the
|
|
* `auth-rt` binary (compiled from auth-runtime), so the skill has
|
|
* zero npm dependency on @clawd/auth-runtime.
|
|
*
|
|
* Prerequisites:
|
|
* ~/.openclaw/bin/auth-rt must exist (run auth-runtime/install.sh)
|
|
*
|
|
* Usage:
|
|
* import { createSkillClient } from './auth-cli.ts';
|
|
* const client = createSkillClient();
|
|
* const res = await client.post('/ecom/tasks/scrape', { url: '...' });
|
|
*/
|
|
|
|
import { spawnSync } from 'child_process';
|
|
import * as path from 'path';
|
|
import * as os from 'os';
|
|
|
|
const home = process.env.HOME || os.homedir();
|
|
const AUTH_RT_BIN = process.env.AUTH_RT_BIN
|
|
|| path.join(home, '.local', 'bin', 'auth-rt');
|
|
|
|
export interface ApiResponse {
|
|
status: number;
|
|
body: string;
|
|
}
|
|
|
|
export interface SessionResponse {
|
|
accessToken: string;
|
|
expiresIn: number;
|
|
ownerSessionToken?: string;
|
|
hookUrl?: string;
|
|
hookToken?: string;
|
|
}
|
|
|
|
export interface SkillClientOptions {
|
|
apiBase?: string;
|
|
dryRun?: boolean;
|
|
}
|
|
|
|
function runCli(...args: string[]): string {
|
|
const result = spawnSync(AUTH_RT_BIN, args, {
|
|
encoding: 'utf-8',
|
|
timeout: 60_000,
|
|
});
|
|
|
|
if (result.error) {
|
|
throw new Error(`auth-rt spawn failed: ${result.error.message}`);
|
|
}
|
|
if (result.status !== 0) {
|
|
throw new Error(`auth-rt failed (exit ${result.status}): ${(result.stderr || '').trim()}`);
|
|
}
|
|
return (result.stdout || '').trim();
|
|
}
|
|
|
|
export class SkillClient {
|
|
private readonly apiBase?: string;
|
|
private readonly dryRun: boolean;
|
|
|
|
constructor(options: SkillClientOptions = {}) {
|
|
this.apiBase = options.apiBase;
|
|
this.dryRun = options.dryRun ?? false;
|
|
}
|
|
|
|
async session(): Promise<SessionResponse> {
|
|
if (this.dryRun) {
|
|
return { accessToken: '<dry-run-token>', expiresIn: 900 };
|
|
}
|
|
return JSON.parse(runCli('session'));
|
|
}
|
|
|
|
async get(urlPath: string): Promise<ApiResponse> {
|
|
return this.request('GET', urlPath);
|
|
}
|
|
|
|
async post(urlPath: string, body?: unknown): Promise<ApiResponse> {
|
|
return this.request('POST', urlPath, body);
|
|
}
|
|
|
|
async put(urlPath: string, body?: unknown): Promise<ApiResponse> {
|
|
return this.request('PUT', urlPath, body);
|
|
}
|
|
|
|
async patch(urlPath: string, body?: unknown): Promise<ApiResponse> {
|
|
return this.request('PATCH', urlPath, body);
|
|
}
|
|
|
|
async delete(urlPath: string, body?: unknown): Promise<ApiResponse> {
|
|
return this.request('DELETE', urlPath, body);
|
|
}
|
|
|
|
private async request(method: string, urlPath: string, body?: unknown): Promise<ApiResponse> {
|
|
if (this.dryRun) {
|
|
return { status: 200, body: JSON.stringify({ dryRun: true, method, path: urlPath }) };
|
|
}
|
|
const args = ['request', method, urlPath];
|
|
if (body != null) {
|
|
args.push('--body', JSON.stringify(body));
|
|
}
|
|
if (this.apiBase) {
|
|
args.push('--api-base', this.apiBase);
|
|
}
|
|
return JSON.parse(runCli(...args));
|
|
}
|
|
}
|
|
|
|
export function createSkillClient(options?: SkillClientOptions): SkillClient {
|
|
return new SkillClient(options);
|
|
}
|