Files
oh-my-pi/packages/natives/scripts/embed-native.ts
T
can1357 9b78a6fa85 refactor(natives): migrated native bindings to NAPI-RS with auto-generated types
- Migrated native bindings from TypeScript wrappers to NAPI-RS generated modules with auto-generated type definitions and runtime enums.
- Replaced chunk tree API with stateful ChunkState class supporting render, edit, and resolve operations with improved error handling.
- Converted callback signatures to error-first pattern (error, result) for shell, PTY, glob, and grep operations.
- Introduced type-safe enums for MacOSAppearance, GrepOutputMode, KeyEventType, ImageFormat, and AstMatchStrictness replacing string literals.
- Refactored chunk tree implementation with dedicated modules for edit, indent, resolve, and state management with comprehensive validation.
- Moved clipboard utilities from native bindings to coding-agent package with improved OSC 52 and Termux compatibility.
2026-04-07 02:00:59 +02:00

122 lines
3.3 KiB
TypeScript

import * as fs from "node:fs/promises";
import * as path from "node:path";
const reset = process.argv.includes("--reset");
const outputPath = path.join(import.meta.dir, "../native/embedded-addon.js");
const packageJsonPath = path.join(import.meta.dir, "../package.json");
const nativeDir = path.join(import.meta.dir, "../native");
const stubContent = `
// AUTOGENERATED FILE -- DO NOT EDIT DIRECTLY
// See scripts/embed-native.ts
/** @typedef {"modern" | "baseline" | "default"} EmbeddedAddonVariant */
/**
* @typedef {Object} EmbeddedAddonFile
* @property {EmbeddedAddonVariant} variant
* @property {string} filename
* @property {string} filePath
*/
/**
* @typedef {Object} EmbeddedAddon
* @property {string} platformTag
* @property {string} version
* @property {EmbeddedAddonFile[]} files
*/
/** @type {EmbeddedAddon|null} */
export const embeddedAddon = null;
`;
if (reset) {
await Bun.write(outputPath, stubContent);
process.exit(0);
}
interface CandidateAddon {
variant: "modern" | "baseline" | "default";
filename: string;
}
async function fileExists(filePath: string): Promise<boolean> {
try {
await fs.stat(filePath);
return true;
} catch (err) {
if ((err as NodeJS.ErrnoException).code === "ENOENT") return false;
throw err;
}
}
const targetPlatform = Bun.env.TARGET_PLATFORM || process.platform;
const targetArch = Bun.env.TARGET_ARCH || process.arch;
const platformTag = `${targetPlatform}-${targetArch}`;
const candidates: CandidateAddon[] =
targetArch === "x64"
? [
{ variant: "modern", filename: `pi_natives.${platformTag}-modern.node` },
{ variant: "baseline", filename: `pi_natives.${platformTag}-baseline.node` },
]
: [{ variant: "default", filename: `pi_natives.${platformTag}.node` }];
const available: CandidateAddon[] = [];
for (const candidate of candidates) {
const candidatePath = path.join(nativeDir, candidate.filename);
if (await fileExists(candidatePath)) {
available.push(candidate);
}
}
if (available.length === 0) {
const expected = candidates.map(candidate => ` - ${candidate.filename}`).join("\n");
throw new Error(`No native addons found for ${platformTag}. Expected one of:\n${expected}`);
}
const packageJson = (await Bun.file(packageJsonPath).json()) as { version: string };
const imports = available
.map(
(candidate, index) =>
`import addonPath${index} from ${JSON.stringify(`../native/${candidate.filename}`)} with { type: "file" };`,
)
.join("\n");
const files = available
.map(
(candidate, index) =>
`\t\t{ variant: ${JSON.stringify(candidate.variant)}, filename: ${JSON.stringify(candidate.filename)}, filePath: addonPath${index} },`,
)
.join("\n");
const content = `
// AUTOGENERATED FILE -- DO NOT EDIT DIRECTLY
// See scripts/embed-native.ts
/** @typedef {"modern" | "baseline" | "default"} EmbeddedAddonVariant */
/**
* @typedef {Object} EmbeddedAddonFile
* @property {EmbeddedAddonVariant} variant
* @property {string} filename
* @property {string} filePath
*/
/**
* @typedef {Object} EmbeddedAddon
* @property {string} platformTag
* @property {string} version
* @property {EmbeddedAddonFile[]} files
*/
${imports}
export const embeddedAddon = {
\tplatformTag: ${JSON.stringify(platformTag)},
\tversion: ${JSON.stringify(packageJson.version)},
\tfiles: [
${files}
\t],
};
`;
await Bun.write(outputPath, content);