first commit
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import { join, resolve } from "node:path";
|
||||
import { runMobileCommand } from "./mobile-command.ts";
|
||||
|
||||
interface CapabilityPackage {
|
||||
browser: string;
|
||||
capacitor?: string;
|
||||
expo?: string;
|
||||
}
|
||||
|
||||
export const nativeCatalog: Record<string, CapabilityPackage> = {
|
||||
camera: {
|
||||
browser: "MediaDevices / file input",
|
||||
capacitor: "@capacitor/camera",
|
||||
expo: "expo-camera",
|
||||
},
|
||||
clipboard: {
|
||||
browser: "Clipboard API",
|
||||
capacitor: "@capacitor/clipboard",
|
||||
expo: "expo-clipboard",
|
||||
},
|
||||
device: {
|
||||
browser: "Browser device information",
|
||||
capacitor: "@capacitor/device",
|
||||
expo: "expo-device",
|
||||
},
|
||||
filesystem: {
|
||||
browser: "File System Access API",
|
||||
capacitor: "@capacitor/filesystem",
|
||||
expo: "expo-file-system",
|
||||
},
|
||||
geolocation: {
|
||||
browser: "Geolocation API",
|
||||
capacitor: "@capacitor/geolocation",
|
||||
expo: "expo-location",
|
||||
},
|
||||
haptics: { browser: "Vibration API", capacitor: "@capacitor/haptics", expo: "expo-haptics" },
|
||||
network: {
|
||||
browser: "Navigator online status",
|
||||
capacitor: "@capacitor/network",
|
||||
expo: "expo-network",
|
||||
},
|
||||
notifications: {
|
||||
browser: "Notifications API",
|
||||
capacitor: "@capacitor/local-notifications",
|
||||
expo: "expo-notifications",
|
||||
},
|
||||
share: { browser: "Web Share API", capacitor: "@capacitor/share" },
|
||||
storage: {
|
||||
browser: "Web Storage",
|
||||
capacitor: "@capacitor/preferences",
|
||||
expo: "expo-secure-store",
|
||||
},
|
||||
};
|
||||
|
||||
function mode(root: string): "webview" | "native" {
|
||||
const file = join(root, "mobile", "package.json");
|
||||
if (!existsSync(file))
|
||||
throw new Error("No mobile project found. Run `wrnexus generate mobile` first.");
|
||||
return (
|
||||
(JSON.parse(readFileSync(file, "utf8")) as { wrnexus?: { mode?: "webview" | "native" } })
|
||||
.wrnexus?.mode ?? "webview"
|
||||
);
|
||||
}
|
||||
|
||||
export async function runNativeCommand(
|
||||
appRoot: string,
|
||||
subcommand?: string,
|
||||
args: string[] = [],
|
||||
): Promise<void> {
|
||||
if (subcommand === "list" || !subcommand) {
|
||||
console.log("WrNexus native capabilities:\n");
|
||||
for (const [name, entry] of Object.entries(nativeCatalog)) {
|
||||
console.log(
|
||||
` ${name.padEnd(14)} browser: ${entry.browser}; Capacitor: ${entry.capacitor ?? "built in"}; Expo: ${entry.expo ?? "built in"}`,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (subcommand === "add") {
|
||||
const names = args.filter((arg) => !arg.startsWith("--"));
|
||||
if (!names.length) throw new Error("Usage: wrnexus native add <capability...>");
|
||||
const unknown = names.filter((name) => !nativeCatalog[name]);
|
||||
if (unknown.length)
|
||||
throw new Error(
|
||||
`Unknown native capability: ${unknown.join(", ")}. Run \`wrnexus native list\`.`,
|
||||
);
|
||||
const root = resolve(appRoot);
|
||||
const target = mode(root);
|
||||
const packages = names
|
||||
.map((name) => nativeCatalog[name]![target === "native" ? "expo" : "capacitor"])
|
||||
.filter((value): value is string => !!value);
|
||||
if (!packages.length) {
|
||||
console.log(` ✓ ${names.join(", ")} use built-in APIs; no package installation required`);
|
||||
return;
|
||||
}
|
||||
await runMobileCommand(root, "add", packages);
|
||||
return;
|
||||
}
|
||||
throw new Error("Usage: wrnexus native <list|add <capability...>>");
|
||||
}
|
||||
Reference in New Issue
Block a user