This commit is contained in:
Mantra 2026-07-19 18:32:54 -07:00 committed by GitHub
commit 4649bc0b7c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 72 additions and 4 deletions

View File

@ -3,6 +3,31 @@ import * as os from "os";
import * as path from "path";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { assertConfigPullTarget, buildConfigPushSource, resolveConfigFilePathForPull } from "./config-file.js";
import { createConfigFileJiti } from "../lib/config-jiti.js";
describe("createConfigFileJiti", () => {
let tmpDir: string;
beforeEach(() => {
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "hexclave-cli-config-jiti-"));
});
afterEach(() => {
fs.rmSync(tmpDir, { recursive: true, force: true });
});
it("loads config authoring imports when the project has no SDK installed", async () => {
const configPath = path.join(tmpDir, "hexclave.config.ts");
fs.writeFileSync(
configPath,
'import { defineHexclaveConfig } from "@hexclave/js/config";\nexport const config = defineHexclaveConfig({ auth: { allowSignUp: true } });\n',
);
const configModule = await createConfigFileJiti(configPath).import<{ config: { auth: { allowSignUp: boolean } } }>(configPath);
expect(configModule.config).toEqual({ auth: { allowSignUp: true } });
});
});
describe("resolveConfigFilePathForPull", () => {
let tmpDir: string;

View File

@ -287,8 +287,8 @@ export function registerConfigCommand(program: Command) {
throw new CliError("Config file must have a .js or .ts extension.");
}
const { createJiti } = await import("jiti");
const jiti = createJiti(import.meta.url);
const { createConfigFileJiti } = await import("../lib/config-jiti.js");
const jiti = createConfigFileJiti(filePath);
const configModule: { config?: unknown } = await jiti.import(filePath);
const config = parseConfigOverride(configModule.config);

View File

@ -453,8 +453,8 @@ function configFileCheck(): CheckSpec {
if (!foundPath || !foundRel) return null; // skip — config file is optional
try {
const { createJiti } = await import("jiti");
const jiti = createJiti(import.meta.url);
const { createConfigFileJiti } = await import("../lib/config-jiti.js");
const jiti = createConfigFileJiti(foundPath);
const mod = await jiti.import<{ config?: unknown }>(foundPath);
const config = mod.config;
if (config === undefined) {

View File

@ -0,0 +1,43 @@
import { createRequire } from "node:module";
import { createJiti, type Jiti } from "jiti";
const CONFIG_IMPORT_SPECIFIERS = [
"@hexclave/js/config",
"@hexclave/next/config",
"@hexclave/react/config",
"@hexclave/tanstack-start/config",
"@hexclave/template/config",
"@stackframe/js",
"@stackframe/next",
"@stackframe/react",
"@stackframe/stack",
"@stackframe/template",
] as const;
/**
* Loads config authoring imports from the project's SDK when available, while
* allowing bare CI checkouts to use the CLI's bundled SDK copy. Jiti resolves
* imports relative to the config file, so those projects may otherwise fail.
*/
export function createConfigFileJiti(configFilePath: string): Jiti {
const configRequire = createRequire(configFilePath);
const unresolvedSpecifiers: string[] = [];
for (const specifier of CONFIG_IMPORT_SPECIFIERS) {
try {
configRequire.resolve(specifier);
} catch {
unresolvedSpecifiers.push(specifier);
}
}
const configAliases: Record<string, string> = {};
if (unresolvedSpecifiers.length > 0) {
const cliConfigEntrypoint = createRequire(import.meta.url).resolve("@hexclave/js/config");
for (const specifier of unresolvedSpecifiers) {
configAliases[specifier] = cliConfigEntrypoint;
}
}
return createJiti(import.meta.url, { alias: configAliases });
}