mirror of
https://github.com/stack-auth/stack.git
synced 2026-07-03 21:02:05 +08:00
## What
Continues the **Stack Auth → Hexclave** rename for a set of safe,
internal-only surfaces. This intentionally avoids public-contract names.
### Changes
- **Examples** — renamed the user-facing config module
`stack.ts`/`stack.tsx` (and the `convex` / `lovable` `stack/`
directories) to `hexclave`, and updated every importer across
`.ts`/`.tsx`/`.jsx`. The public `app/handler/[...stack]/` route segment
is left unchanged.
- **apps/{dashboard,backend,internal-tool}** — renamed app-local
SDK-init symbols `stackClientApp → hexclaveClientApp` and
`getStackServerApp → getHexclaveServerApp`, and the dashboard
`StackCompanion` component → `HexclaveCompanion` (incl.
`useStackCompanion`, context types). The public
`StackClientApp`/`StackServerApp` SDK classes are **unchanged**.
- **packages/stack-shared** — added comments to the crypto / JWT / vault
`stack-*` literals documenting that they must **not** be renamed (key
derivation / JWKS / KMS-alias stability). The literals are
byte-identical.
### Deliberately excluded
- **`STACK_*` → `HEXCLAVE_*` env-var rename** — `HEXCLAVE_*` already
resolves via the dual-read layers (SDK env, dashboard `_inlineEnvVars`,
`getEnvVariable`). The remaining holdout is the docker post-build
sentinel path, which the codebase authors explicitly deferred and which
is tightly coupled to `entrypoint.sh` + untestable here. A blind rename
there risks silently breaking self-host/emulator bootstrap for ~zero
functional gain.
- **All public-contract names** — SDK class names, env vars, HTTP
headers (`x-stack-*`), and the `/handler` route convention.
## Verification
- `pnpm lint` — **29/29 passing**.
- `pnpm typecheck` — **28/29 passing**; the only failure is
`@hexclave/docs` (pre-existing missing fumadocs `.source` codegen,
untouched by this PR).
- Two rounds of adversarial multi-agent review; findings fixed:
string-literal collateral from the symbol sweep (CLI test fixtures + an
AI-prompt template) reverted, and a missed `.jsx` importer in
`examples/cjs-test` corrected.
## Notes
- Based on a `dev` snapshot from when the branch was cut (a couple
commits behind tip); the diff contains only the changes above.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Complete the internal “Stack” → “Hexclave” rename across examples,
app-local code, config tooling, and setup docs, and standardize env
output to HEXCLAVE_* with correct default API URL handling. Public SDK
classes, handler routes, and legacy env names keep working.
- **Refactors**
- Examples/config: `stack.*` files and `stack/` dirs →
`hexclave.*`/`hexclave/`; imports updated; keep `app/handler/[...stack]`
route.
- Apps: backend/dashboard/internal-tool now use `getHexclaveServerApp`
and `hexclaveClientApp`; dashboard `StackCompanion` →
`HexclaveCompanion`. Public `StackClientApp`/`StackServerApp` unchanged.
- Env/setup: Next.js and CLI generators write HEXCLAVE_* and omit API
URL when using https://api.stack-auth.com; CLI `doctor` and auth
resolution prefer HEXCLAVE_* (e.g. `HEXCLAVE_SECRET_SERVER_KEY`,
`HEXCLAVE_PROJECT_ID`) with `STACK_*` fallback.
- Config tooling: `stack-config-file` → `hexclave-config-file`, emitting
`HexclaveConfig`; imports updated across backend/dashboard/tooling.
- Shared/docs: added “do not rename” notes for crypto/JWT/vault
`stack-*` literals; regenerated setup prompt/docs to use
`hexclave.config.ts`, `hexclave dev`, and `src/hexclave/`.
- Tests: updated snapshots/assertions to expect `HexclaveConfig` and
HEXCLAVE_* env names.
- **Migration**
- No action required. SDK and CLI read both HEXCLAVE_* and STACK_*.
<sup>Written for commit 8a891b4f6c.
Summary will update on new commits.</sup>
<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1534?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Renamed internal app/client/server instances and companion/provider
components to the new product name across backend, dashboard, examples,
and tooling; imports updated accordingly.
* Updated generated environment variable names and CLI init/doctor
outputs to prefer the new product prefix.
* **Documentation**
* Added clarifying notes about vault/encryption and JWT/key labels to
avoid breaking existing encrypted data.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
113 lines
3.3 KiB
TypeScript
113 lines
3.3 KiB
TypeScript
import { getPublicEnvVar } from '@/lib/env';
|
|
import { runAsynchronously, wait } from "@hexclave/shared/dist/utils/promises";
|
|
import packageJson from "../../package.json";
|
|
|
|
export type VersionCheckResult = {
|
|
severe: boolean,
|
|
error: string,
|
|
} | null;
|
|
|
|
export type VersionCheckOptions = {
|
|
/** Delay before making the request (in milliseconds) */
|
|
delay?: number,
|
|
/** Whether to silently fail or throw errors */
|
|
silentFailure?: boolean,
|
|
/** Custom error message prefix for logging */
|
|
errorPrefix?: string,
|
|
};
|
|
|
|
/**
|
|
* Hook to check if non-severe version alerts should be shown
|
|
* Based on NEXT_PUBLIC_VERSION_ALERTER_SEVERE_ONLY environment variable
|
|
*/
|
|
export function shouldShowNonSevereVersionCheck(): boolean {
|
|
// IMPORTANT: THIS ENVIRONMENT VARIABLE IS UNDOCUMENTED AND NOT MEANT FOR PRODUCTION USAGE
|
|
// AND YOU SHOULD ALWAYS KEEP STACK AUTH UP TO DATE. WE CAN'T APPLY SECURITY UPDATES IF
|
|
// YOU DON'T UPDATE STACK AUTH REGULARLY.
|
|
return getPublicEnvVar('NEXT_PUBLIC_VERSION_ALERTER_SEVERE_ONLY') !== "true";
|
|
}
|
|
|
|
/**
|
|
* Utility to determine if a version check result should be displayed
|
|
*/
|
|
export function shouldDisplayVersionResult(
|
|
result: VersionCheckResult,
|
|
enableNonSevereCheck: boolean = shouldShowNonSevereVersionCheck()
|
|
): boolean {
|
|
return result !== null && (enableNonSevereCheck || result.severe);
|
|
}
|
|
|
|
/**
|
|
* Common utility function for checking version against Hexclave API
|
|
* Used by both VersionAlerter and HexclaveCompanion components
|
|
*/
|
|
export function checkVersion(
|
|
onResult: (result: VersionCheckResult) => void,
|
|
options: VersionCheckOptions = {}
|
|
) {
|
|
const {
|
|
delay = 1000,
|
|
silentFailure = false,
|
|
errorPrefix = "Version check failed"
|
|
} = options;
|
|
|
|
// Skip check for managed hosting
|
|
if (typeof window !== "undefined" && window.location.origin === "https://app.hexclave.com") {
|
|
return () => {}; // Return cleanup function
|
|
}
|
|
|
|
let cancelled = false;
|
|
|
|
runAsynchronously(async () => {
|
|
try {
|
|
await wait(delay);
|
|
if (cancelled) return;
|
|
|
|
const res = await fetch(`https://api.hexclave.com/api/v1/check-version`, {
|
|
method: "POST",
|
|
body: JSON.stringify({
|
|
clientPackageName: packageJson.name,
|
|
clientVersion: packageJson.version,
|
|
}),
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
|
|
if (res.status !== 200) {
|
|
if (silentFailure) {
|
|
return; // Silently fail
|
|
} else {
|
|
throw new Error(`Version check API call failed with status ${res.status}: ${await res.text()}`);
|
|
}
|
|
}
|
|
|
|
const data = await res.json();
|
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
if (cancelled) return;
|
|
|
|
onResult(data.upToDate ? null : data);
|
|
} catch (e) {
|
|
if (silentFailure) {
|
|
console.warn(`${errorPrefix}:`, e);
|
|
return;
|
|
}
|
|
|
|
// Wait a little bit because the error may have been caused by a page reload
|
|
await wait(5000);
|
|
if (cancelled) return;
|
|
|
|
console.error(`${errorPrefix}`, e);
|
|
onResult({
|
|
severe: true,
|
|
error: `Error checking version, please make sure you're connected to the internet. See the console for more details. \n${e}`
|
|
});
|
|
}
|
|
});
|
|
|
|
// Return cleanup function
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}
|