mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-19 21:00:40 +08:00
Merge remote-tracking branch 'origin/dev' into fix/config-parsing-rde-error
# Conflicts: # docs-mintlify/guides/getting-started/setup.mdx # docs-mintlify/snippets/home-prompt-island.jsx
This commit is contained in:
commit
7ae99459eb
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -41,6 +41,7 @@
|
||||
"geoip",
|
||||
"glassmorphic",
|
||||
"healthcheck",
|
||||
"hexclave",
|
||||
"hookform",
|
||||
"hostable",
|
||||
"INBUCKET",
|
||||
@ -114,6 +115,7 @@
|
||||
"upserted",
|
||||
"Upvotes",
|
||||
"upvoting",
|
||||
"vite",
|
||||
"webapi",
|
||||
"webauthn",
|
||||
"Whitespaces",
|
||||
|
||||
@ -2,6 +2,12 @@
|
||||
|
||||
---
|
||||
|
||||
## 6/5/26
|
||||
|
||||
- CLI improvements: local dashboard in remote SSH and Codespaces, auto-update via npx re-exec, and ~154 MB bundle reduction.
|
||||
- Fixes for sign-out handling, nested cross-domain auth, subscription switching, and email preview theme blanking.
|
||||
- New Python & REST API setup docs, product prices clarified as decimal strings, and pnpm v11 upgrade.
|
||||
|
||||
## 5/29/26
|
||||
|
||||
- Per-provider OAuth callback URLs with host-derived JWT issuer and redirect URIs.
|
||||
|
||||
@ -33,6 +33,14 @@ Setting up Hexclave is one prompt. Paste this into your coding agent of choice:
|
||||
Read skill.hexclave.com and help me setup hexclave in this project
|
||||
```
|
||||
|
||||
## For AI agents
|
||||
|
||||
If you're an AI coding agent, use your web fetch tool or curl the skill documentation for up-to-date integration instructions:
|
||||
|
||||
```
|
||||
curl -sSL "https://skill.hexclave.com?question=<your-question>&context=<your-context>"
|
||||
```
|
||||
|
||||
## What's included
|
||||
|
||||
Hexclave ships as a catalog of apps you switch on as your product needs them.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/backend",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/dashboard",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/dev-launchpad",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/e2e-tests",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@hexclave/hosted-components",
|
||||
"private": true,
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite dev --port ${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}09",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@hexclave/internal-tool",
|
||||
"private": true,
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "node scripts/pre-dev.mjs && next dev --turbopack --port ${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}41",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/mcp",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/mock-oauth-server",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"main": "index.js",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/skills",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@ -104,6 +104,23 @@ export const hexclaveClientApp = new HexclaveClientApp({
|
||||
|
||||
`maskAllInputs` defaults to `true`, so form fields are masked unless you explicitly disable it.
|
||||
|
||||
### Disabling Analytics Capture in the SDK
|
||||
|
||||
SDK-managed analytics capture is enabled by default. If you don't want the SDK to collect any analytics, pass `analytics: { enabled: false }` when creating your client app:
|
||||
|
||||
```ts
|
||||
import { HexclaveClientApp } from "@hexclave/next";
|
||||
|
||||
export const hexclaveClientApp = new HexclaveClientApp({
|
||||
projectId: process.env.NEXT_PUBLIC_STACK_PROJECT_ID!,
|
||||
publishableClientKey: process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY!,
|
||||
tokenStore: "nextjs-cookie",
|
||||
analytics: { enabled: false },
|
||||
});
|
||||
```
|
||||
|
||||
This stops the SDK from sending `$page-view` and `$click` events. It also resolves the `ANALYTICS_NOT_ENABLED` warning the SDK logs to the browser console when it tries to send events to a project that hasn't enabled the Analytics app — with capture disabled, the SDK never makes those requests. If you'd rather keep analytics, enable the Analytics app in your dashboard (**Apps -> Analytics**) instead.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use Tables for quick incident triage**: the Tables UI is the fastest way to inspect recent `events` rows without writing SQL.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -18,6 +18,7 @@ Below are some reminders on Hexclave and how to learn more about it. If you're s
|
||||
- Language, framework, and library-specific details:
|
||||
- JavaScript & TypeScript:
|
||||
- Hexclave has different SDK packages for different frameworks and languages. As of the time of writing these reminders, they are: @hexclave/js (JavaScript/TypeScript), @hexclave/next (Next.js), @hexclave/react (React), @hexclave/tanstack-start (TanStack Start). You can find all of these on npm. They are all versioned together, meaning that vX.Y.Z of one SDK was released at the same time as vX.Y.Z of another SDK. For the most part, they are the same, although each has platform-specific features and differences.
|
||||
- The Hexclave/Stack Auth SDK constructor accepts a `urls` option that tells the SDK where auth pages and post-auth redirects live. When you add a custom auth page such as a `sign-in`, `sign-up`, `forgot-password`, `account-settings`, etc., update the corresponding `urls` key to point to that route; also set redirect targets such as `afterSignIn`, `afterSignUp`, `afterSignOut`, and `home` when those destinations are customized. The `urls` option is the source of truth for redirect helpers such as `redirectToSignIn()`, hosted or handler-page flows, and post-auth navigation; if it is left pointing at the default pages after custom pages are added, users can hit extra redirects, land on the wrong auth page, or return to an unexpected page after signing in or out.
|
||||
- The `Result<T, E>` type is `{ status: "ok", data: T } | { status: "error", error: E }`.
|
||||
- `KnownErrors[KNOWN_ERROR_CODE]` refers to a specific known error type. Each KnownError may have its own properties, but they all inherit from `Error & { statusCode: number, humanReadableMessage: string, details?: Json }`.
|
||||
- React & Next.js:
|
||||
@ -183,6 +184,10 @@ The frameworks and languages with explicit SDK support are:
|
||||
});
|
||||
```
|
||||
|
||||
<Note>
|
||||
The SDK auto-captures page-view and click analytics. To turn this off (and silence the `ANALYTICS_NOT_ENABLED` console warning that appears until you enable the Analytics app in your dashboard), pass `analytics: { enabled: false }`.
|
||||
</Note>
|
||||
|
||||
In a backend where you can keep a secret key safe, you can use the `HexclaveServerApp`, which provides access to more sensitive APIs compared to `HexclaveClientApp`:
|
||||
|
||||
```ts src/hexclave/server.ts
|
||||
@ -253,6 +258,8 @@ The frameworks and languages with explicit SDK support are:
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`hexclave dev` injects all necessary environment variables into the app process automatically, so the app is ready to use without any extra environment variable setup.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Option 2: Connecting to a production project hosted in the cloud">
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/docs-mintlify",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "mint dev --port ${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}04 --no-open",
|
||||
|
||||
@ -86,6 +86,10 @@ If you're building a client-only app and don't have a `SECRET_SERVER_KEY`, you c
|
||||
Redirect URL configuration.
|
||||
</ParamField>
|
||||
|
||||
<ParamField body="analytics" type="object">
|
||||
Analytics capture configuration. SDK-managed capture is enabled by default; pass `{ enabled: false }` to disable it entirely (which also avoids the `ANALYTICS_NOT_ENABLED` console warning on projects that haven't enabled the Analytics app), or `{ replays: { enabled: true } }` to record session replays.
|
||||
</ParamField>
|
||||
|
||||
<ParamField body="noAutomaticPrefetch" type="boolean">
|
||||
Disable automatic prefetching.
|
||||
</ParamField>
|
||||
@ -106,6 +110,7 @@ If you're building a client-only app and don't have a `SECRET_SERVER_KEY`, you c
|
||||
projectId?: string;
|
||||
publishableClientKey?: string;
|
||||
urls?: object;
|
||||
analytics?: object;
|
||||
noAutomaticPrefetch?: boolean;
|
||||
});
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/docs",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/example-cjs-test",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/convex-example",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/example-demo-app",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"description": "",
|
||||
"private": true,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/docs-examples",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"description": "",
|
||||
"private": true,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/e-commerce-demo",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/js-example",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"description": "",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@hexclave/lovable-react-18-example",
|
||||
"private": true,
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/example-middleware-demo",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "react-example",
|
||||
"private": true,
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/example-supabase",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/example-tanstack-start-demo",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"description": "TanStack Start demo app for Hexclave",
|
||||
"private": true,
|
||||
@ -20,13 +20,13 @@
|
||||
"@tanstack/react-router": "^1.168.23",
|
||||
"@tanstack/react-start": "^1.167.42",
|
||||
"nitro": "^3.0.0",
|
||||
"react": "19.2.1",
|
||||
"react-dom": "19.2.1"
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.13.0",
|
||||
"@types/react": "19.2.1",
|
||||
"@types/react-dom": "19.2.1",
|
||||
"@types/react": "19.2.7",
|
||||
"@types/react-dom": "19.2.3",
|
||||
"@vitejs/plugin-react": "^5.0.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.47",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { StackClientApp } from "@hexclave/tanstack-start";
|
||||
import { HexclaveClientApp } from "@hexclave/tanstack-start";
|
||||
|
||||
function getPortPrefix(): string {
|
||||
return import.meta.env.NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX ?? "81";
|
||||
@ -14,9 +14,7 @@ function getStackApiUrl(): string {
|
||||
}
|
||||
|
||||
export function createStackApp() {
|
||||
return new StackClientApp({
|
||||
projectId: import.meta.env.VITE_STACK_PROJECT_ID ?? "internal",
|
||||
publishableClientKey: import.meta.env.VITE_STACK_PUBLISHABLE_CLIENT_KEY ?? "this-publishable-client-key-is-for-local-development-only",
|
||||
return new HexclaveClientApp({
|
||||
baseUrl: getStackApiUrl(),
|
||||
tokenStore: "cookie",
|
||||
redirectMethod: "window",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/cli",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"description": "The CLI for Hexclave. https://hexclave.com",
|
||||
"main": "dist/index.js",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/dashboard-ui-components",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
|
||||
"name": "@hexclave/js",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
@ -49,8 +49,12 @@
|
||||
"typecheck": "tsc --noEmit",
|
||||
"clean": "rimraf dist && rimraf node_modules",
|
||||
"lint": "eslint --ext .tsx,.ts .",
|
||||
"build": "rimraf dist && tsdown",
|
||||
"dev": "tsdown --watch"
|
||||
"codegen": "pnpm run env",
|
||||
"codegen:watch": "concurrently -n \"env\" -k \"pnpm run env:watch\"",
|
||||
"build": "rimraf dist && pnpm run codegen && tsdown",
|
||||
"dev": "concurrently -n \"build,codegen\" -k \"tsdown --watch\" \"pnpm run codegen:watch\"",
|
||||
"env": "tsx ./scripts/generate-env.ts",
|
||||
"env:watch": "chokidar --silent './scripts/generate-env.ts' -c 'pnpm run env' --throttle 2000"
|
||||
},
|
||||
"files": [
|
||||
"README.md",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
|
||||
"name": "@hexclave/next",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
@ -49,10 +49,12 @@
|
||||
"typecheck": "tsc --noEmit",
|
||||
"clean": "rimraf dist && rimraf node_modules",
|
||||
"lint": "eslint --ext .tsx,.ts .",
|
||||
"build": "rimraf dist && pnpm run css && tsdown",
|
||||
"codegen": "pnpm run env && pnpm run css",
|
||||
"codegen:watch": "concurrently -n \"env,css\" -k \"pnpm run env:watch\" \"pnpm run css:watch\"",
|
||||
"build": "rimraf dist && pnpm run codegen && tsdown",
|
||||
"dev": "concurrently -n \"build,codegen\" -k \"tsdown --watch\" \"pnpm run codegen:watch\"",
|
||||
"codegen": "pnpm run css",
|
||||
"codegen:watch": "pnpm run css:watch",
|
||||
"env": "tsx ./scripts/generate-env.ts",
|
||||
"env:watch": "chokidar --silent './scripts/generate-env.ts' -c 'pnpm run env' --throttle 2000",
|
||||
"css": "pnpm run css-tw && pnpm run css-sc",
|
||||
"css:watch": "concurrently -n \"tw,sc\" -k \"pnpm run css-tw:watch\" \"pnpm run css-sc:watch\"",
|
||||
"css-tw:watch": "tailwindcss -i ./src/global.css -o ./src/generated/tailwind.css --watch",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
|
||||
"name": "@hexclave/react",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
@ -49,10 +49,12 @@
|
||||
"typecheck": "tsc --noEmit",
|
||||
"clean": "rimraf dist && rimraf node_modules",
|
||||
"lint": "eslint --ext .tsx,.ts .",
|
||||
"build": "rimraf dist && pnpm run css && tsdown",
|
||||
"codegen": "pnpm run env && pnpm run css",
|
||||
"codegen:watch": "concurrently -n \"env,css\" -k \"pnpm run env:watch\" \"pnpm run css:watch\"",
|
||||
"build": "rimraf dist && pnpm run codegen && tsdown",
|
||||
"dev": "concurrently -n \"build,codegen\" -k \"tsdown --watch\" \"pnpm run codegen:watch\"",
|
||||
"codegen": "pnpm run css",
|
||||
"codegen:watch": "pnpm run css:watch",
|
||||
"env": "tsx ./scripts/generate-env.ts",
|
||||
"env:watch": "chokidar --silent './scripts/generate-env.ts' -c 'pnpm run env' --throttle 2000",
|
||||
"css": "pnpm run css-tw && pnpm run css-sc",
|
||||
"css:watch": "concurrently -n \"tw,sc\" -k \"pnpm run css-tw:watch\" \"pnpm run css-sc:watch\"",
|
||||
"css-tw:watch": "tailwindcss -i ./src/global.css -o ./src/generated/tailwind.css --watch",
|
||||
@ -95,9 +97,14 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": ">=18.0.0",
|
||||
"@types/react-dom": ">=18.0.0",
|
||||
"react-dom": ">=18.0.0",
|
||||
"react": ">=18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/sc",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"exports": {
|
||||
"./force-react-server": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/shared",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"scripts": {
|
||||
"build": "rimraf dist && tsdown",
|
||||
|
||||
@ -18,6 +18,7 @@ export const remindersPrompt = deindent`
|
||||
- Language, framework, and library-specific details:
|
||||
- JavaScript & TypeScript:
|
||||
- Hexclave has different SDK packages for different frameworks and languages. As of the time of writing these reminders, they are: @hexclave/js (JavaScript/TypeScript), @hexclave/next (Next.js), @hexclave/react (React), @hexclave/tanstack-start (TanStack Start). You can find all of these on npm. They are all versioned together, meaning that vX.Y.Z of one SDK was released at the same time as vX.Y.Z of another SDK. For the most part, they are the same, although each has platform-specific features and differences.
|
||||
- The Hexclave/Stack Auth SDK constructor accepts a \`urls\` option that tells the SDK where auth pages and post-auth redirects live. When you add a custom auth page such as a \`sign-in\`, \`sign-up\`, \`forgot-password\`, \`account-settings\`, etc., update the corresponding \`urls\` key to point to that route; also set redirect targets such as \`afterSignIn\`, \`afterSignUp\`, \`afterSignOut\`, and \`home\` when those destinations are customized. The \`urls\` option is the source of truth for redirect helpers such as \`redirectToSignIn()\`, hosted or handler-page flows, and post-auth navigation; if it is left pointing at the default pages after custom pages are added, users can hit extra redirects, land on the wrong auth page, or return to an unexpected page after signing in or out.
|
||||
- The \`Result<T, E>\` type is \`{ status: "ok", data: T } | { status: "error", error: E }\`.
|
||||
- \`KnownErrors[KNOWN_ERROR_CODE]\` refers to a specific known error type. Each KnownError may have its own properties, but they all inherit from \`Error & { statusCode: number, humanReadableMessage: string, details?: Json }\`.
|
||||
- React & Next.js:
|
||||
|
||||
@ -664,6 +664,10 @@ export function getSdkSetupPrompt(mainType: "ai-prompt" | "nextjs" | "react" | "
|
||||
},
|
||||
});
|
||||
\`\`\`
|
||||
|
||||
<Note>
|
||||
The SDK auto-captures page-view and click analytics. To turn this off (and silence the \`ANALYTICS_NOT_ENABLED\` console warning that appears until you enable the Analytics app in your dashboard), pass \`analytics: { enabled: false }\`.
|
||||
</Note>
|
||||
` : ""}
|
||||
|
||||
${isMaybeBackend ? deindent`
|
||||
@ -748,6 +752,8 @@ export function getSdkSetupPrompt(mainType: "ai-prompt" | "nextjs" | "react" | "
|
||||
}
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
\`hexclave dev\` injects all necessary environment variables into the app process automatically, so the app is ready to use without any extra environment variable setup.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Option 2: Connecting to a production project hosted in the cloud">
|
||||
|
||||
@ -786,14 +786,14 @@ export class HexclaveClientInterface {
|
||||
if (res.ok) {
|
||||
return Result.ok(res);
|
||||
} else if (res.status === 429) {
|
||||
// Rate limited, so retry if we can
|
||||
const retryAfter = res.headers.get("Retry-After");
|
||||
if (retryAfter !== null) {
|
||||
console.log(`Rate limited while sending request to ${url}. Will retry after ${retryAfter} seconds...`);
|
||||
await wait(Number(retryAfter) * 1000);
|
||||
return Result.error(new Error(`Rate limited, retrying after ${retryAfter} seconds`));
|
||||
}
|
||||
console.log(`Rate limited while sending request to ${url}, no retry-after header received. Retrying...`);
|
||||
|
||||
console.log(`Rate limited while sending request to ${url}, no retry-after header received. Retrying with default backoff...`);
|
||||
return Result.error(new Error("Rate limited, no retry-after header received"));
|
||||
} else {
|
||||
const error = await res.text();
|
||||
|
||||
147
packages/shared/src/sessions.test.ts
Normal file
147
packages/shared/src/sessions.test.ts
Normal file
@ -0,0 +1,147 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { InternalSession } from "./sessions";
|
||||
|
||||
/**
|
||||
* Builds a decodable (unsigned) access-token JWT with a valid payload. `refreshTokenId` controls the
|
||||
* `refresh_token_id` claim (the session identifier); `iatOffsetSeconds` lets two tokens for the same session
|
||||
* differ as strings while sharing a `refresh_token_id`.
|
||||
*/
|
||||
function createAccessTokenString(refreshTokenId: string, options?: { iatOffsetSeconds?: number, sub?: string }): string {
|
||||
const encode = (value: unknown) => Buffer.from(JSON.stringify(value)).toString("base64url");
|
||||
const nowSeconds = Math.floor(Date.now() / 1000) + (options?.iatOffsetSeconds ?? 0);
|
||||
return [
|
||||
encode({ alg: "none", typ: "JWT" }),
|
||||
encode({
|
||||
sub: options?.sub ?? "user-id",
|
||||
exp: nowSeconds + 60,
|
||||
iat: nowSeconds,
|
||||
iss: "https://api.example.test",
|
||||
aud: "project-id",
|
||||
project_id: "project-id",
|
||||
branch_id: "main",
|
||||
refresh_token_id: refreshTokenId,
|
||||
role: "authenticated",
|
||||
name: null,
|
||||
email: null,
|
||||
email_verified: false,
|
||||
selected_team_id: null,
|
||||
signed_up_at: nowSeconds,
|
||||
is_anonymous: false,
|
||||
is_restricted: false,
|
||||
restricted_reason: null,
|
||||
requires_totp_mfa: false,
|
||||
}),
|
||||
"",
|
||||
].join(".");
|
||||
}
|
||||
|
||||
function createAccessOnlySession(accessToken: string): InternalSession {
|
||||
return new InternalSession({
|
||||
refreshAccessTokenCallback: async () => null,
|
||||
refreshToken: null,
|
||||
accessToken,
|
||||
});
|
||||
}
|
||||
|
||||
const currentToken = (session: InternalSession) => session.getAccessTokenIfNotExpiredYet(20_000, null)?.token;
|
||||
|
||||
describe("InternalSession.calculateSessionKey", () => {
|
||||
it("keys by the refresh token when one is present (ignoring any access token)", () => {
|
||||
expect(InternalSession.calculateSessionKey({ refreshToken: "rt-abc" })).toBe("refresh-rt-abc");
|
||||
expect(InternalSession.calculateSessionKey({ refreshToken: "rt-abc", accessToken: createAccessTokenString("rtid-1") }))
|
||||
.toBe("refresh-rt-abc");
|
||||
});
|
||||
|
||||
it("returns not-logged-in when neither token is present", () => {
|
||||
expect(InternalSession.calculateSessionKey({ refreshToken: null })).toBe("not-logged-in");
|
||||
expect(InternalSession.calculateSessionKey({ refreshToken: null, accessToken: null })).toBe("not-logged-in");
|
||||
});
|
||||
|
||||
it("keys an access-only session by its refresh_token_id", () => {
|
||||
expect(InternalSession.calculateSessionKey({ refreshToken: null, accessToken: createAccessTokenString("rtid-1") }))
|
||||
.toBe("access-session-rtid-1");
|
||||
});
|
||||
|
||||
it("is stable across re-minted access tokens for the same session (the regression this fixes)", () => {
|
||||
const first = createAccessTokenString("rtid-1", { iatOffsetSeconds: 0 });
|
||||
const second = createAccessTokenString("rtid-1", { iatOffsetSeconds: 1 });
|
||||
expect(second).not.toBe(first);
|
||||
expect(InternalSession.calculateSessionKey({ refreshToken: null, accessToken: second }))
|
||||
.toBe(InternalSession.calculateSessionKey({ refreshToken: null, accessToken: first }));
|
||||
});
|
||||
|
||||
it("distinguishes access-only sessions with different refresh_token_ids", () => {
|
||||
expect(InternalSession.calculateSessionKey({ refreshToken: null, accessToken: createAccessTokenString("rtid-1") }))
|
||||
.not.toBe(InternalSession.calculateSessionKey({ refreshToken: null, accessToken: createAccessTokenString("rtid-2") }));
|
||||
});
|
||||
|
||||
it("falls back to the raw token when the access token can't be decoded", () => {
|
||||
expect(InternalSession.calculateSessionKey({ refreshToken: null, accessToken: "not-a-jwt" })).toBe("access-not-a-jwt");
|
||||
});
|
||||
});
|
||||
|
||||
describe("InternalSession#updateAccessToken", () => {
|
||||
it("installs a fresh token for the same access-only session in place", () => {
|
||||
const initial = createAccessTokenString("rtid-1", { iatOffsetSeconds: 0 });
|
||||
const refreshed = createAccessTokenString("rtid-1", { iatOffsetSeconds: 1 });
|
||||
const session = createAccessOnlySession(initial);
|
||||
|
||||
session.updateAccessToken({ accessToken: refreshed, refreshToken: null });
|
||||
expect(currentToken(session)).toBe(refreshed);
|
||||
// identity is unchanged — same session key, same object
|
||||
expect(session.sessionKey).toBe("access-session-rtid-1");
|
||||
});
|
||||
|
||||
it("rejects a token pair belonging to a different access-only session", () => {
|
||||
const initial = createAccessTokenString("rtid-1");
|
||||
const foreign = createAccessTokenString("rtid-2", { sub: "other-user" });
|
||||
const session = createAccessOnlySession(initial);
|
||||
|
||||
session.updateAccessToken({ accessToken: foreign, refreshToken: null });
|
||||
expect(currentToken(session)).toBe(initial);
|
||||
});
|
||||
|
||||
it("is a no-op for an unchanged, null, or undecodable token", () => {
|
||||
const initial = createAccessTokenString("rtid-1");
|
||||
const session = createAccessOnlySession(initial);
|
||||
|
||||
session.updateAccessToken({ accessToken: initial, refreshToken: null });
|
||||
session.updateAccessToken({ accessToken: null, refreshToken: null });
|
||||
session.updateAccessToken({ accessToken: "not-a-jwt", refreshToken: null });
|
||||
expect(currentToken(session)).toBe(initial);
|
||||
});
|
||||
|
||||
it("never revives an invalidated session", () => {
|
||||
const session = createAccessOnlySession(createAccessTokenString("rtid-1"));
|
||||
session.markInvalid();
|
||||
|
||||
session.updateAccessToken({ accessToken: createAccessTokenString("rtid-1", { iatOffsetSeconds: 1 }), refreshToken: null });
|
||||
expect(session.isKnownToBeInvalid()).toBe(true);
|
||||
expect(currentToken(session)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("updates a refresh-token-backed session's access token in place when the refresh token matches", () => {
|
||||
const session = new InternalSession({
|
||||
refreshAccessTokenCallback: async () => null,
|
||||
refreshToken: "rt-abc",
|
||||
accessToken: createAccessTokenString("rtid-1"),
|
||||
});
|
||||
const refreshed = createAccessTokenString("rtid-2", { iatOffsetSeconds: 1 });
|
||||
|
||||
session.updateAccessToken({ accessToken: refreshed, refreshToken: "rt-abc" });
|
||||
expect(currentToken(session)).toBe(refreshed);
|
||||
expect(session.sessionKey).toBe("refresh-rt-abc");
|
||||
});
|
||||
|
||||
it("rejects a token pair carrying a different refresh token for a refresh-backed session", () => {
|
||||
const initial = createAccessTokenString("rtid-1");
|
||||
const session = new InternalSession({
|
||||
refreshAccessTokenCallback: async () => null,
|
||||
refreshToken: "rt-abc",
|
||||
accessToken: initial,
|
||||
});
|
||||
|
||||
session.updateAccessToken({ accessToken: createAccessTokenString("rtid-2"), refreshToken: "rt-other" });
|
||||
expect(currentToken(session)).toBe(initial);
|
||||
});
|
||||
});
|
||||
@ -124,6 +124,14 @@ export class InternalSession {
|
||||
if (ofTokens.refreshToken) {
|
||||
return `refresh-${ofTokens.refreshToken}`;
|
||||
} else if (ofTokens.accessToken) {
|
||||
// Access-only sessions (no refresh token) are keyed by the underlying session's `refresh_token_id`, not the
|
||||
// access token string: access tokens get re-minted frequently, and keying by the raw token would spawn a new
|
||||
// session (and cold-invalidate every session-scoped cache) on each refresh. Falls back to the raw token if
|
||||
// the JWT can't be decoded.
|
||||
const refreshTokenId = decodeAccessTokenIfValid(ofTokens.accessToken)?.refresh_token_id;
|
||||
if (refreshTokenId) {
|
||||
return `access-session-${refreshTokenId}`;
|
||||
}
|
||||
return `access-${ofTokens.accessToken}`;
|
||||
} else {
|
||||
return "not-logged-in";
|
||||
@ -210,6 +218,24 @@ export class InternalSession {
|
||||
return accessToken ? { accessToken, refreshToken: this._refreshToken } : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs a freshly obtained token pair's access token into this session in place, keeping the session object
|
||||
* (and therefore every session-scoped cache) stable instead of constructing a new InternalSession. No-op if the
|
||||
* session is invalid, the access token can't be decoded, it's unchanged, or the pair doesn't map to this session
|
||||
* (so a foreign token can never be written into this object's cache); never clears an existing token.
|
||||
*/
|
||||
updateAccessToken(tokens: { accessToken: string | null, refreshToken: string | null }) {
|
||||
if (this._knownToBeInvalid.get()) return;
|
||||
if (!tokens.accessToken) return;
|
||||
const newAccessToken = AccessToken.createIfValid(tokens.accessToken);
|
||||
if (!newAccessToken) return;
|
||||
// Self-enforce the "a session never changes which session it belongs to" invariant: only install a token pair
|
||||
// that maps to this same session key (validated against the incoming pair, not this session's existing tokens).
|
||||
if (InternalSession.calculateSessionKey(tokens) !== this.sessionKey) return;
|
||||
if (this._accessToken.get()?.token === newAccessToken.token) return;
|
||||
this._accessToken.set(newAccessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually mark the access token as expired, even if the date on its payload may still be valid.
|
||||
*
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
|
||||
"name": "@hexclave/tanstack-start",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
@ -60,10 +60,12 @@
|
||||
"typecheck": "tsc --noEmit",
|
||||
"clean": "rimraf dist && rimraf node_modules",
|
||||
"lint": "eslint --ext .tsx,.ts .",
|
||||
"build": "rimraf dist && pnpm run css && tsdown",
|
||||
"codegen": "pnpm run env && pnpm run css",
|
||||
"codegen:watch": "concurrently -n \"env,css\" -k \"pnpm run env:watch\" \"pnpm run css:watch\"",
|
||||
"build": "rimraf dist && pnpm run codegen && tsdown",
|
||||
"dev": "concurrently -n \"build,codegen\" -k \"tsdown --watch\" \"pnpm run codegen:watch\"",
|
||||
"codegen": "pnpm run css",
|
||||
"codegen:watch": "pnpm run css:watch",
|
||||
"env": "tsx ./scripts/generate-env.ts",
|
||||
"env:watch": "chokidar --silent './scripts/generate-env.ts' -c 'pnpm run env' --throttle 2000",
|
||||
"css": "pnpm run css-tw && pnpm run css-sc",
|
||||
"css:watch": "concurrently -n \"tw,sc\" -k \"pnpm run css-tw:watch\" \"pnpm run css-sc:watch\"",
|
||||
"css-tw:watch": "tailwindcss -i ./src/global.css -o ./src/generated/tailwind.css --watch",
|
||||
@ -106,11 +108,16 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": ">=18.0.0",
|
||||
"@types/react-dom": ">=18.0.0",
|
||||
"react-dom": ">=18.0.0",
|
||||
"@tanstack/react-router": ">=1.100.0",
|
||||
"@tanstack/react-start": ">=1.100.0",
|
||||
"react": ">=18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
|
||||
@ -14,16 +14,8 @@ module.exports = {
|
||||
{
|
||||
"object": "process",
|
||||
"property": "env",
|
||||
"message": "Use envVars from src/lib/env.ts instead of reading process.env directly.",
|
||||
"message": "Use envVars from src/generated/env.ts instead of reading process.env directly.",
|
||||
},
|
||||
],
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["src/lib/env.ts"],
|
||||
"rules": {
|
||||
"no-restricted-properties": "off",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
};
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
"//": "NEXT_LINE_PLATFORM template",
|
||||
"private": true,
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
@ -76,16 +76,19 @@
|
||||
"lint": "eslint --ext .tsx,.ts .",
|
||||
|
||||
"//": "IF_PLATFORM template react-like",
|
||||
"build": "rimraf dist && pnpm run css && tsdown",
|
||||
"dev": "concurrently -n \"build,codegen\" -k \"tsdown --watch\" \"pnpm run codegen:watch\"",
|
||||
"codegen": "pnpm run css",
|
||||
"codegen:watch": "pnpm run css:watch"
|
||||
,"//": "ELSE_PLATFORM",
|
||||
"build": "rimraf dist && tsdown",
|
||||
"dev": "tsdown --watch"
|
||||
,"//": "END_PLATFORM",
|
||||
"codegen": "pnpm run env && pnpm run css",
|
||||
"codegen:watch": "concurrently -n \"env,css\" -k \"pnpm run env:watch\" \"pnpm run css:watch\"",
|
||||
"//": "ELSE_PLATFORM",
|
||||
"codegen": "pnpm run env",
|
||||
"codegen:watch": "concurrently -n \"env\" -k \"pnpm run env:watch\"",
|
||||
"//": "END_PLATFORM",
|
||||
|
||||
"//": "IF_PLATFORM template react-like"
|
||||
"build": "rimraf dist && pnpm run codegen && tsdown",
|
||||
"dev": "concurrently -n \"build,codegen\" -k \"tsdown --watch\" \"pnpm run codegen:watch\"",
|
||||
"env": "tsx ./scripts/generate-env.ts",
|
||||
"env:watch": "chokidar --silent './scripts/generate-env.ts' -c 'pnpm run env' --throttle 2000"
|
||||
|
||||
,"//": "IF_PLATFORM template react-like"
|
||||
,"css": "pnpm run css-tw && pnpm run css-sc",
|
||||
"css:watch": "concurrently -n \"tw,sc\" -k \"pnpm run css-tw:watch\" \"pnpm run css-sc:watch\"",
|
||||
"css-tw:watch": "tailwindcss -i ./src/global.css -o ./src/generated/tailwind.css --watch",
|
||||
@ -95,9 +98,7 @@
|
||||
,"//": "END_PLATFORM",
|
||||
|
||||
"//": "IF_PLATFORM template"
|
||||
,"codegen": "pnpm run css",
|
||||
"codegen:watch": "concurrently -n \"css\" -k \"pnpm run css:watch\"",
|
||||
"override-env-local-for-quetzal": "echo \"\\n$STACK_ENV_LOCAL_PACKAGE_BUILD_OVERRIDE_FOR_QUETZAL\\n\" >> .env.local",
|
||||
,"override-env-local-for-quetzal": "echo \"\\n$STACK_ENV_LOCAL_PACKAGE_BUILD_OVERRIDE_FOR_QUETZAL\\n\" >> .env.local",
|
||||
"quetzal": "rimraf quetzal-translations && pnpm run override-env-local-for-quetzal && quetzal-process-translations && tsx ./scripts/merge-quetzal-translations.ts",
|
||||
"quetzal:ignore-errors": "pnpm run quetzal || echo Quetzal failed, probably because the API key is missing. We will just ignore it",
|
||||
"quetzal:watch": "chokidar --silent \"src/**/*\" -i \"src/generated/quetzal-translations.ts\" -c 'pnpm run quetzal:ignore-errors' --throttle 2000"
|
||||
@ -151,9 +152,9 @@
|
||||
"//": "IF_PLATFORM react-like",
|
||||
"peerDependencies": {
|
||||
"@types/react": ">=18.0.0",
|
||||
"//": "IF_PLATFORM next",
|
||||
"@types/react-dom": ">=18.0.0",
|
||||
"react-dom": ">=18.0.0",
|
||||
"//": "IF_PLATFORM next",
|
||||
"next": ">=14.1 || >=15.0.0-canary.0 || >=15.0.0-rc.0",
|
||||
"//": "END_PLATFORM",
|
||||
"//": "IF_PLATFORM tanstack-start",
|
||||
@ -165,11 +166,9 @@
|
||||
"//": "END_PLATFORM",
|
||||
"//": "IF_PLATFORM react-like",
|
||||
"peerDependenciesMeta": {
|
||||
"//": "IF_PLATFORM next",
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
},
|
||||
"//": "END_PLATFORM",
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"//": "THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template (FOR package.json FILES, PLEASE EDIT package-template.json)",
|
||||
"name": "@hexclave/template",
|
||||
"private": true,
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"sideEffects": false,
|
||||
"main": "./dist/index.js",
|
||||
@ -61,10 +61,12 @@
|
||||
"typecheck": "tsc --noEmit",
|
||||
"clean": "rimraf dist && rimraf node_modules",
|
||||
"lint": "eslint --ext .tsx,.ts .",
|
||||
"build": "rimraf dist && pnpm run css && tsdown",
|
||||
"codegen": "pnpm run env && pnpm run css",
|
||||
"codegen:watch": "concurrently -n \"env,css\" -k \"pnpm run env:watch\" \"pnpm run css:watch\"",
|
||||
"build": "rimraf dist && pnpm run codegen && tsdown",
|
||||
"dev": "concurrently -n \"build,codegen\" -k \"tsdown --watch\" \"pnpm run codegen:watch\"",
|
||||
"codegen": "pnpm run css",
|
||||
"codegen:watch": "concurrently -n \"css\" -k \"pnpm run css:watch\"",
|
||||
"env": "tsx ./scripts/generate-env.ts",
|
||||
"env:watch": "chokidar --silent './scripts/generate-env.ts' -c 'pnpm run env' --throttle 2000",
|
||||
"css": "pnpm run css-tw && pnpm run css-sc",
|
||||
"css:watch": "concurrently -n \"tw,sc\" -k \"pnpm run css-tw:watch\" \"pnpm run css-sc:watch\"",
|
||||
"css-tw:watch": "tailwindcss -i ./src/global.css -o ./src/generated/tailwind.css --watch",
|
||||
|
||||
91
packages/template/scripts/generate-env.ts
Normal file
91
packages/template/scripts/generate-env.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import { writeFileSyncIfChanged } from "@hexclave/shared/dist/utils/fs";
|
||||
import { deindent } from "@hexclave/shared/dist/utils/strings";
|
||||
|
||||
const envVarsConfig: Record<string, { allowPublic?: boolean, deprecatedLegacyNames?: string[] }> = {
|
||||
HEXCLAVE_PORT_PREFIX: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_PROJECT_ID: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_PUBLISHABLE_CLIENT_KEY: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_SECRET_SERVER_KEY: {},
|
||||
HEXCLAVE_SUPER_SECRET_ADMIN_KEY: {},
|
||||
HEXCLAVE_EXTRA_REQUEST_HEADERS: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_API_URL_BROWSER: {
|
||||
allowPublic: true,
|
||||
deprecatedLegacyNames: ["BROWSER_STACK_API_URL", "BROWSER_HEXCLAVE_API_URL"],
|
||||
},
|
||||
HEXCLAVE_API_URL_SERVER: {
|
||||
allowPublic: true,
|
||||
deprecatedLegacyNames: ["SERVER_STACK_API_URL", "SERVER_HEXCLAVE_API_URL"],
|
||||
},
|
||||
HEXCLAVE_API_URL: {
|
||||
allowPublic: true,
|
||||
deprecatedLegacyNames: ["HEXCLAVE_URL", "STACK_URL"],
|
||||
},
|
||||
HEXCLAVE_HOSTED_HANDLER_DOMAIN_SUFFIX: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_HOSTED_HANDLER_URL_TEMPLATE: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_STRIPE_PUBLISHABLE_KEY: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_BOT_CHALLENGE_SITE_KEY: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_BOT_CHALLENGE_INVISIBLE_SITE_KEY: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_IS_LOCAL_EMULATOR: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_POSTHOG_KEY: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_SVIX_SERVER_URL: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_SENTRY_DSN: {
|
||||
allowPublic: true,
|
||||
},
|
||||
HEXCLAVE_VERSION_ALERTER_SEVERE_ONLY: {
|
||||
allowPublic: true,
|
||||
},
|
||||
NODE_ENV: {
|
||||
allowPublic: false,
|
||||
},
|
||||
};
|
||||
|
||||
function generateEnvVarsConstSnippet() {
|
||||
const getters: string[] = [];
|
||||
for (const [key, config] of Object.entries(envVarsConfig)) {
|
||||
const allVariables = [key, ...(config.deprecatedLegacyNames ?? [])]
|
||||
.flatMap(k => k.startsWith("HEXCLAVE_") ? [k, k.replace("HEXCLAVE_", "STACK_")] : [k])
|
||||
.flatMap(k => config.allowPublic ? [k, `NEXT_PUBLIC_${k}`, `VITE_${k}`] : [k]);
|
||||
getters.push(deindent`
|
||||
get ${key}() {
|
||||
return ${allVariables.map(variableName => deindent`
|
||||
((typeof process !== "undefined" ? process.env.${variableName} : undefined) ?? import.meta.env?.${variableName})
|
||||
`).join("\n ?? ")} ?? undefined;
|
||||
},
|
||||
`);
|
||||
}
|
||||
return deindent`
|
||||
// THIS FILE IS AUTO-GENERATED BY THE \`generate-env.ts\` SCRIPT.
|
||||
// DO NOT EDIT IT BY HAND.
|
||||
/* eslint-disable no-restricted-properties */
|
||||
|
||||
export const envVars = {
|
||||
${getters.join("\n")}
|
||||
};
|
||||
` + "\n";
|
||||
}
|
||||
|
||||
writeFileSyncIfChanged("src/generated/env.ts", generateEnvVarsConstSnippet());
|
||||
@ -7,7 +7,7 @@ import { CardElement, Elements, useElements, useStripe } from "@stripe/react-str
|
||||
import { loadStripe } from "@stripe/stripe-js";
|
||||
import { useMemo, useState } from "react";
|
||||
import { useStackApp } from "../../..";
|
||||
import { envVars } from "../../../lib/env";
|
||||
import { envVars } from "../../../generated/env";
|
||||
import { useTranslation } from "../../../lib/translations";
|
||||
import { Section } from "../section";
|
||||
import { Result } from "@hexclave/shared/dist/utils/results";
|
||||
@ -245,7 +245,7 @@ function RealPaymentsPanel(props: { title?: string, customer: CustomerLike, cust
|
||||
|
||||
const stripePromise = useMemo(() => {
|
||||
if (!setupIntentStripeAccountId) return null;
|
||||
const publishableKey = envVars.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY;
|
||||
const publishableKey = envVars.HEXCLAVE_STRIPE_PUBLISHABLE_KEY;
|
||||
if (!publishableKey) return null;
|
||||
return loadStripe(publishableKey, { stripeAccount: setupIntentStripeAccountId });
|
||||
}, [setupIntentStripeAccountId]);
|
||||
|
||||
@ -4,7 +4,7 @@ import type { RequestLogEntry } from "@hexclave/shared/dist/interface/client-int
|
||||
import { runAsynchronously } from "@hexclave/shared/dist/utils/promises";
|
||||
import { isLocalhost } from "@hexclave/shared/dist/utils/urls";
|
||||
import type { StackClientApp } from "../lib/hexclave-app";
|
||||
import { envVars } from "../lib/env";
|
||||
import { envVars } from "../generated/env";
|
||||
import { getBaseUrl } from "../lib/hexclave-app/apps/implementations/common";
|
||||
import type { HandlerUrlOptions, HandlerUrls, HandlerUrlTarget } from "../lib/hexclave-app/common";
|
||||
import { hexclaveAppInternalsSymbol } from "../lib/hexclave-app/common";
|
||||
@ -208,7 +208,7 @@ function resolveApiBaseUrl(app: StackClientApp<true>): string {
|
||||
}
|
||||
|
||||
function shouldShowDashboardTab(app: StackClientApp<true>): boolean {
|
||||
return envVars.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR === "true" && isLocalhost(resolveApiBaseUrl(app));
|
||||
return envVars.HEXCLAVE_IS_LOCAL_EMULATOR === "true" && isLocalhost(resolveApiBaseUrl(app));
|
||||
}
|
||||
|
||||
function getTabsForApp(app: StackClientApp<true>): { id: TabId; label: string; icon: string }[] {
|
||||
|
||||
2
packages/template/src/generated/.gitignore
vendored
2
packages/template/src/generated/.gitignore
vendored
@ -1,3 +1,3 @@
|
||||
/*
|
||||
!.gitignore
|
||||
!quetzal-translations.ts
|
||||
!/quetzal-translations.ts
|
||||
|
||||
9
packages/template/src/global.d.ts
vendored
9
packages/template/src/global.d.ts
vendored
@ -1 +1,8 @@
|
||||
import type {} from "react/canary";
|
||||
import type { } from "react/canary";
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
||||
interface ImportMeta {
|
||||
readonly env?: Record<string, string | undefined>,
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,19 +96,6 @@ function getTanStackStartServerContext() {
|
||||
setCookie,
|
||||
};
|
||||
}
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
||||
interface ImportMetaEnv {
|
||||
SSR: boolean,
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv,
|
||||
}
|
||||
}
|
||||
|
||||
// END_PLATFORM
|
||||
|
||||
function ensureClient() {
|
||||
@ -159,7 +146,7 @@ export async function createCookieHelper(): Promise<CookieHelper> {
|
||||
await rscHeaders(),
|
||||
);
|
||||
// ELSE_IF_PLATFORM tanstack-start
|
||||
if (import.meta.env.SSR) {
|
||||
if (import.meta.env?.SSR) {
|
||||
const cookieHelperPromise = tanStackStartCookieHelperPromise
|
||||
?? Promise.resolve(createTanStackStartCookieHelper(getTanStackStartServerContext()));
|
||||
tanStackStartCookieHelperPromise = cookieHelperPromise;
|
||||
@ -377,7 +364,7 @@ export async function isSecure(): Promise<boolean> {
|
||||
// IF_PLATFORM next
|
||||
return determineSecureFromServerContext(await rscCookies(), await rscHeaders());
|
||||
// ELSE_IF_PLATFORM tanstack-start
|
||||
if (import.meta.env.SSR) {
|
||||
if (import.meta.env?.SSR) {
|
||||
return determineSecureFromTanStackStartContext(getTanStackStartServerContext());
|
||||
}
|
||||
// END_PLATFORM
|
||||
|
||||
@ -1,89 +0,0 @@
|
||||
/**
|
||||
* Centralized environment-variable reads for the SDK.
|
||||
*
|
||||
* Keep each key explicit and reference `process.env.KEY` directly so bundlers
|
||||
* like Next.js can inline values at build time.
|
||||
*
|
||||
* Hexclave rebrand: each getter prefers the HEXCLAVE_*-prefixed literal and
|
||||
* falls back to the legacy STACK_* literal(s). Both operands stay literal
|
||||
* `process.env.X` references so bundlers can inline them. The port-prefix var
|
||||
* is a straight rename (no dual-read).
|
||||
*/
|
||||
export const envVars = {
|
||||
// Hexclave rebrand: port-prefix var renamed outright (no dual-read).
|
||||
get NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_PROJECT_ID() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_PROJECT_ID ?? process.env.NEXT_PUBLIC_STACK_PROJECT_ID : undefined) ?? undefined;
|
||||
},
|
||||
get STACK_PROJECT_ID() {
|
||||
return (typeof process !== "undefined" ? process.env.HEXCLAVE_PROJECT_ID ?? process.env.STACK_PROJECT_ID : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY ?? process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY : undefined) ?? undefined;
|
||||
},
|
||||
get STACK_PUBLISHABLE_CLIENT_KEY() {
|
||||
return (typeof process !== "undefined" ? process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY ?? process.env.STACK_PUBLISHABLE_CLIENT_KEY : undefined) ?? undefined;
|
||||
},
|
||||
get STACK_SECRET_SERVER_KEY() {
|
||||
return (typeof process !== "undefined" ? process.env.HEXCLAVE_SECRET_SERVER_KEY ?? process.env.STACK_SECRET_SERVER_KEY : undefined) ?? undefined;
|
||||
},
|
||||
get STACK_SUPER_SECRET_ADMIN_KEY() {
|
||||
return (typeof process !== "undefined" ? process.env.HEXCLAVE_SUPER_SECRET_ADMIN_KEY ?? process.env.STACK_SUPER_SECRET_ADMIN_KEY : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_EXTRA_REQUEST_HEADERS() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_EXTRA_REQUEST_HEADERS ?? process.env.NEXT_PUBLIC_STACK_EXTRA_REQUEST_HEADERS : undefined) ?? undefined;
|
||||
},
|
||||
get STACK_EXTRA_REQUEST_HEADERS() {
|
||||
return (typeof process !== "undefined" ? process.env.HEXCLAVE_EXTRA_REQUEST_HEADERS ?? process.env.STACK_EXTRA_REQUEST_HEADERS : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_BROWSER_STACK_API_URL() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_BROWSER_HEXCLAVE_API_URL ?? process.env.NEXT_PUBLIC_BROWSER_STACK_API_URL : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_API_URL_BROWSER() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_API_URL_BROWSER ?? process.env.NEXT_PUBLIC_STACK_API_URL_BROWSER : undefined) ?? undefined;
|
||||
},
|
||||
get STACK_API_URL_BROWSER() {
|
||||
return (typeof process !== "undefined" ? process.env.HEXCLAVE_API_URL_BROWSER ?? process.env.STACK_API_URL_BROWSER : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_SERVER_STACK_API_URL() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_SERVER_HEXCLAVE_API_URL ?? process.env.NEXT_PUBLIC_SERVER_STACK_API_URL : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_API_URL_SERVER() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_API_URL_SERVER ?? process.env.NEXT_PUBLIC_STACK_API_URL_SERVER : undefined) ?? undefined;
|
||||
},
|
||||
get STACK_API_URL_SERVER() {
|
||||
return (typeof process !== "undefined" ? process.env.HEXCLAVE_API_URL_SERVER ?? process.env.STACK_API_URL_SERVER : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_API_URL() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_API_URL ?? process.env.NEXT_PUBLIC_STACK_API_URL : undefined) ?? undefined;
|
||||
},
|
||||
get STACK_API_URL() {
|
||||
return (typeof process !== "undefined" ? process.env.HEXCLAVE_API_URL ?? process.env.STACK_API_URL : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_URL() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_URL ?? process.env.NEXT_PUBLIC_STACK_URL : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_HOSTED_HANDLER_DOMAIN_SUFFIX ?? process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_HOSTED_HANDLER_URL_TEMPLATE() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_HOSTED_HANDLER_URL_TEMPLATE ?? process.env.NEXT_PUBLIC_STACK_HOSTED_HANDLER_URL_TEMPLATE : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_STRIPE_PUBLISHABLE_KEY ?? process.env.NEXT_PUBLIC_STACK_STRIPE_PUBLISHABLE_KEY : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_BOT_CHALLENGE_SITE_KEY() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_BOT_CHALLENGE_SITE_KEY ?? process.env.NEXT_PUBLIC_STACK_BOT_CHALLENGE_SITE_KEY : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_BOT_CHALLENGE_INVISIBLE_SITE_KEY() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_BOT_CHALLENGE_INVISIBLE_SITE_KEY ?? process.env.NEXT_PUBLIC_STACK_BOT_CHALLENGE_INVISIBLE_SITE_KEY : undefined) ?? undefined;
|
||||
},
|
||||
get NODE_ENV() {
|
||||
return (typeof process !== "undefined" ? process.env.NODE_ENV : undefined) ?? undefined;
|
||||
},
|
||||
get NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR() {
|
||||
return (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR ?? process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR : undefined) ?? undefined;
|
||||
},
|
||||
};
|
||||
@ -46,7 +46,7 @@ import type * as yup from "yup";
|
||||
import { constructRedirectUrl } from "../../../../utils/url";
|
||||
import { callOAuthCallback, getNewOAuthProviderOrScopeUrl } from "../../../auth";
|
||||
import { CookieHelper, createBrowserCookieHelper, createCookieHelper, createPlaceholderCookieHelper, deleteCookie, deleteCookieClient, getCookieClient, isSecure as isSecureCookieContext, saveVerifierAndState, setOrDeleteCookie, setOrDeleteCookieClient } from "../../../cookie";
|
||||
import { envVars } from "../../../env";
|
||||
import { envVars } from "../../../../generated/env";
|
||||
import { ApiKey, ApiKeyCreationOptions, ApiKeyUpdateOptions, apiKeyCreationOptionsToCrud } from "../../api-keys";
|
||||
import { ConvexCtx, GetCurrentPartialUserOptions, GetCurrentUserOptions, HandlerUrlOptions, HandlerUrls, OAuthScopesOnSignIn, RedirectMethod, RedirectToOptions, RequestLike, ResolvedHandlerUrls, TokenStoreInit, hexclaveAppInternalsSymbol } from "../../common";
|
||||
import { DeprecatedOAuthConnection, OAuthConnection } from "../../connected-accounts";
|
||||
@ -1547,10 +1547,14 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
|
||||
const tokenStore = this._getOrCreateTokenStore(await this._createCookieHelper());
|
||||
tokenStore.set(tokens);
|
||||
|
||||
// Pre-fetch the current user for the new session so the cache is already
|
||||
// populated when useUser() re-renders, avoiding a stale-cache render cycle.
|
||||
const newSession = this._getSessionFromTokenStore(tokenStore);
|
||||
this._currentUserCache.getOrWait([newSession], "write-only").catch(() => {});
|
||||
// If these tokens resolve to a session we already have (eg. the RDE dashboard re-installing a freshly minted
|
||||
// access token for the same access-only session), push the new token into it in place; constructing a new
|
||||
// session here would cold-invalidate every session-scoped cache and suspend the UI on each refresh.
|
||||
const session = this._getSessionFromTokenStore(tokenStore);
|
||||
session.updateAccessToken(tokens);
|
||||
|
||||
// Pre-fetch the current user so the cache is warm when useUser() re-renders (write-only, so it never suspends).
|
||||
runAsynchronously(this._currentUserCache.getOrWait([session], "write-only"));
|
||||
}
|
||||
|
||||
protected _getTokenStoreInitForFreshTokens(tokens: { accessToken: string | null, refreshToken: string }): TokenStoreInit | undefined {
|
||||
@ -2669,16 +2673,16 @@ export class _HexclaveClientAppImplIncomplete<HasTokenStore extends boolean, Pro
|
||||
private _getBotChallengeSiteKeys(): { visibleSiteKey: string, invisibleSiteKey: string } | null {
|
||||
if (!isBrowserLike()) return null;
|
||||
|
||||
const visibleSiteKey = envVars.NEXT_PUBLIC_STACK_BOT_CHALLENGE_SITE_KEY;
|
||||
const visibleSiteKey = envVars.HEXCLAVE_BOT_CHALLENGE_SITE_KEY;
|
||||
if (!visibleSiteKey) {
|
||||
if (!this._botChallengeSiteKeysWarned) {
|
||||
this._botChallengeSiteKeysWarned = true;
|
||||
console.warn("[stack-auth] NEXT_PUBLIC_STACK_BOT_CHALLENGE_SITE_KEY is not set — bot challenge fraud protection is disabled. Set the env variable to enable it.");
|
||||
console.warn("[stack-auth] HEXCLAVE_BOT_CHALLENGE_SITE_KEY is not set — bot challenge fraud protection is disabled. Set the env variable to enable it.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const invisibleSiteKey = envVars.NEXT_PUBLIC_STACK_BOT_CHALLENGE_INVISIBLE_SITE_KEY ?? visibleSiteKey;
|
||||
const invisibleSiteKey = envVars.HEXCLAVE_BOT_CHALLENGE_INVISIBLE_SITE_KEY ?? visibleSiteKey;
|
||||
|
||||
return { visibleSiteKey, invisibleSiteKey };
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import { Result } from "@hexclave/shared/dist/utils/results";
|
||||
import { Store } from "@hexclave/shared/dist/utils/stores";
|
||||
import { getDefaultApiUrls } from "@hexclave/shared/dist/utils/urls";
|
||||
import React, { useCallback } from "react"; // THIS_LINE_PLATFORM react-like
|
||||
import { envVars } from "../../../env";
|
||||
import { envVars } from "../../../../generated/env";
|
||||
import { HandlerUrlOptions, ResolvedHandlerUrls, hexclaveAppInternalsSymbol } from "../../common";
|
||||
import { resolveHandlerUrls } from "../../url-targets";
|
||||
|
||||
@ -21,7 +21,7 @@ if (clientVersion.startsWith("STACK_COMPILE_TIME")) {
|
||||
|
||||
const replaceHexclavePortPrefix = <T extends string | undefined>(input: T): T => {
|
||||
if (!input) return input;
|
||||
const prefix = envVars.NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX;
|
||||
const prefix = envVars.HEXCLAVE_PORT_PREFIX;
|
||||
return prefix ? input.replace(/\$\{NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81\}/g, prefix) as T : input;
|
||||
};
|
||||
|
||||
@ -40,7 +40,7 @@ const showMissingConfigAlertInBrowser = (message: string) => {
|
||||
};
|
||||
|
||||
const throwMissingProjectIdError = (): never => {
|
||||
const message = "Welcome to Hexclave! It seems that you haven't provided a project ID. Please create a project on the Hexclave dashboard at https://app.hexclave.com and put it in the NEXT_PUBLIC_STACK_PROJECT_ID environment variable.";
|
||||
const message = "Welcome to Hexclave! It seems that you haven't provided a project ID. Please create a project on the Hexclave dashboard at https://app.hexclave.com and put it in the HEXCLAVE_PROJECT_ID environment variable.";
|
||||
showMissingConfigAlertInBrowser(message);
|
||||
return throwErr(new Error(message));
|
||||
};
|
||||
@ -82,23 +82,23 @@ export function getUrls(partial: HandlerUrlOptions, options: { projectId: string
|
||||
}
|
||||
|
||||
export function getDefaultProjectId() {
|
||||
return envVars.NEXT_PUBLIC_STACK_PROJECT_ID || envVars.STACK_PROJECT_ID || throwMissingProjectIdError();
|
||||
return envVars.HEXCLAVE_PROJECT_ID || throwMissingProjectIdError();
|
||||
}
|
||||
|
||||
export function getDefaultPublishableClientKey() {
|
||||
return envVars.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY || envVars.STACK_PUBLISHABLE_CLIENT_KEY;
|
||||
return envVars.HEXCLAVE_PUBLISHABLE_CLIENT_KEY;
|
||||
}
|
||||
|
||||
export function getDefaultSecretServerKey() {
|
||||
return envVars.STACK_SECRET_SERVER_KEY || throwErr(new Error("No secret server key provided. Please copy your key from the Hexclave dashboard and put it in the STACK_SECRET_SERVER_KEY environment variable."));
|
||||
return envVars.HEXCLAVE_SECRET_SERVER_KEY || throwErr(new Error("No secret server key provided. Please copy your key from the Hexclave dashboard and put it in the HEXCLAVE_SECRET_SERVER_KEY environment variable."));
|
||||
}
|
||||
|
||||
export function getDefaultSuperSecretAdminKey() {
|
||||
return envVars.STACK_SUPER_SECRET_ADMIN_KEY || throwErr(new Error("No super secret admin key provided. Please copy your key from the Hexclave dashboard and put it in the STACK_SUPER_SECRET_ADMIN_KEY environment variable."));
|
||||
return envVars.HEXCLAVE_SUPER_SECRET_ADMIN_KEY || throwErr(new Error("No super secret admin key provided. Please copy your key from the Hexclave dashboard and put it in the HEXCLAVE_SUPER_SECRET_ADMIN_KEY environment variable."));
|
||||
}
|
||||
|
||||
export function getDefaultExtraRequestHeaders() {
|
||||
return JSON.parse(envVars.NEXT_PUBLIC_STACK_EXTRA_REQUEST_HEADERS || envVars.STACK_EXTRA_REQUEST_HEADERS || '{}');
|
||||
return JSON.parse(envVars.HEXCLAVE_EXTRA_REQUEST_HEADERS || '{}');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,9 +107,9 @@ export function getDefaultExtraRequestHeaders() {
|
||||
* The URL can be specified in several ways, in order of precedence:
|
||||
* 1. Directly through userSpecifiedBaseUrl parameter as string or browser/server object
|
||||
* 2. Through environment variables:
|
||||
* - Browser: NEXT_PUBLIC_BROWSER_STACK_API_URL
|
||||
* - Server: NEXT_PUBLIC_SERVER_STACK_API_URL
|
||||
* - Fallback: NEXT_PUBLIC_STACK_API_URL or NEXT_PUBLIC_STACK_URL
|
||||
* - Browser: NEXT_PUBLIC_HEXCLAVE_API_URL_BROWSER/VITE_HEXCLAVE_API_URL_BROWSER
|
||||
* - Server: HEXCLAVE_API_URL_SERVER
|
||||
* - Default: HEXCLAVE_API_URL
|
||||
* 3. Default base URL if none of the above are specified
|
||||
*
|
||||
* The function also ensures the URL doesn't end with a trailing slash
|
||||
@ -132,13 +132,12 @@ export function getBaseUrl(userSpecifiedBaseUrl: string | { browser: string, ser
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// note: NEXT_PUBLIC_BROWSER_STACK_API_URL was renamed to NEXT_PUBLIC_STACK_API_URL_BROWSER, and NEXT_PUBLIC_STACK_URL to NEXT_PUBLIC_STACK_API_URL
|
||||
if (isBrowserLike()) {
|
||||
url = envVars.NEXT_PUBLIC_BROWSER_STACK_API_URL || envVars.NEXT_PUBLIC_STACK_API_URL_BROWSER || envVars.STACK_API_URL_BROWSER;
|
||||
url = envVars.HEXCLAVE_API_URL_BROWSER;
|
||||
} else {
|
||||
url = envVars.NEXT_PUBLIC_SERVER_STACK_API_URL || envVars.NEXT_PUBLIC_STACK_API_URL_SERVER || envVars.STACK_API_URL_SERVER;
|
||||
url = envVars.HEXCLAVE_API_URL_SERVER;
|
||||
}
|
||||
url = url || envVars.NEXT_PUBLIC_STACK_API_URL || envVars.STACK_API_URL || envVars.NEXT_PUBLIC_STACK_URL || defaultBaseUrl;
|
||||
url = url || envVars.HEXCLAVE_API_URL || defaultBaseUrl;
|
||||
}
|
||||
|
||||
return replaceHexclavePortPrefix(url.endsWith('/') ? url.slice(0, -1) : url);
|
||||
@ -270,4 +269,4 @@ export function useAsyncCache<D extends any[], T>(cache: AsyncCache<D, Result<T>
|
||||
}
|
||||
return result.data;
|
||||
}
|
||||
// END_PLATFORM
|
||||
// END_PLATFORM
|
||||
|
||||
@ -108,6 +108,7 @@ describe("handler URL targets", () => {
|
||||
|
||||
expect(urls.signIn).toBe("https://project-id.example-stack-hosted.test/handler/sign-in");
|
||||
expect(urls.signOut).toBe("https://project-id.example-stack-hosted.test/handler/sign-out");
|
||||
expect(urls.home).toBe("/");
|
||||
expect(urls.afterSignIn).toBe("/");
|
||||
expect(urls.afterSignUp).toBe("/");
|
||||
expect(urls.afterSignOut).toBe("/");
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { getCustomPagePrompts, type CustomPagePrompt } from "@hexclave/shared/dist/interface/handler-urls";
|
||||
import { HexclaveAssertionError } from "@hexclave/shared/dist/utils/errors";
|
||||
import { getHostedHandlerUrlFromConfig } from "@hexclave/shared/dist/utils/redirect-urls";
|
||||
import { envVars } from "../env";
|
||||
import { envVars } from "../../generated/env";
|
||||
import { DefaultHandlerUrlTarget, HandlerPageUrls, HandlerUrlOptions, HandlerUrlTarget, HandlerUrls, ResolvedHandlerUrls } from "./common";
|
||||
|
||||
const localUrlPlaceholderOrigin = "http://example.com";
|
||||
@ -107,9 +107,9 @@ export const getHostedHandlerUrl = (options: { projectId: string, pagePath: stri
|
||||
return getHostedHandlerUrlFromConfig({
|
||||
projectId: options.projectId,
|
||||
hostedPath,
|
||||
hostedHandlerDomainSuffix: envVars.NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX,
|
||||
hostedHandlerUrlTemplate: envVars.NEXT_PUBLIC_STACK_HOSTED_HANDLER_URL_TEMPLATE,
|
||||
hexclavePortPrefix: envVars.NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX,
|
||||
hostedHandlerDomainSuffix: envVars.HEXCLAVE_HOSTED_HANDLER_DOMAIN_SUFFIX,
|
||||
hostedHandlerUrlTemplate: envVars.HEXCLAVE_HOSTED_HANDLER_URL_TEMPLATE,
|
||||
hexclavePortPrefix: envVars.HEXCLAVE_PORT_PREFIX,
|
||||
});
|
||||
};
|
||||
|
||||
@ -121,6 +121,7 @@ const isRelativeUrlString = (url: string): boolean => {
|
||||
};
|
||||
|
||||
const nonHostedHandlerNames = new Set<keyof HandlerUrls>([
|
||||
"home",
|
||||
"afterSignIn",
|
||||
"afterSignUp",
|
||||
"afterSignOut",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/ui",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"repository": "https://github.com/hexclave/hexclave",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
||||
199
pnpm-lock.yaml
199
pnpm-lock.yaml
@ -765,7 +765,7 @@ importers:
|
||||
version: 1.166.6(crossws@0.4.4(srvx@0.8.16))
|
||||
nitro:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.2)(mysql2@3.15.3)(rolldown@1.0.0-rc.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(xml2js@0.6.2)
|
||||
version: 3.0.0(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.2)(mysql2@3.15.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(xml2js@0.6.2)
|
||||
react:
|
||||
specifier: 19.2.1
|
||||
version: 19.2.1
|
||||
@ -1551,13 +1551,13 @@ importers:
|
||||
version: 10.4.21(postcss@8.5.6)
|
||||
eslint:
|
||||
specifier: ^9.32.0
|
||||
version: 9.39.1(jiti@2.6.1)
|
||||
version: 9.39.1(jiti@1.21.7)
|
||||
eslint-plugin-react-hooks:
|
||||
specifier: ^5.2.0
|
||||
version: 5.2.0(eslint@9.39.1(jiti@2.6.1))
|
||||
version: 5.2.0(eslint@9.39.1(jiti@1.21.7))
|
||||
eslint-plugin-react-refresh:
|
||||
specifier: ^0.4.20
|
||||
version: 0.4.24(eslint@9.39.1(jiti@2.6.1))
|
||||
version: 0.4.24(eslint@9.39.1(jiti@1.21.7))
|
||||
globals:
|
||||
specifier: ^15.15.0
|
||||
version: 15.15.0
|
||||
@ -1575,7 +1575,7 @@ importers:
|
||||
version: 5.9.3
|
||||
typescript-eslint:
|
||||
specifier: ^8.38.0
|
||||
version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
|
||||
version: 8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3)
|
||||
vite:
|
||||
specifier: ^5.4.19
|
||||
version: 5.4.21(@types/node@22.19.0)(lightningcss@1.32.0)(terser@5.44.0)
|
||||
@ -1698,19 +1698,19 @@ importers:
|
||||
version: link:../../packages/ui
|
||||
'@tanstack/react-router':
|
||||
specifier: ^1.168.23
|
||||
version: 1.169.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1)
|
||||
version: 1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
'@tanstack/react-start':
|
||||
specifier: ^1.167.42
|
||||
version: 1.167.58(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))
|
||||
version: 1.167.58(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))
|
||||
nitro:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.2)(mysql2@3.15.3)(rolldown@1.0.0-rc.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(xml2js@0.6.2)
|
||||
version: 3.0.0(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.2)(mysql2@3.15.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(xml2js@0.6.2)
|
||||
react:
|
||||
specifier: 19.2.1
|
||||
version: 19.2.1
|
||||
specifier: 19.2.3
|
||||
version: 19.2.3
|
||||
react-dom:
|
||||
specifier: 19.2.1
|
||||
version: 19.2.1(react@19.2.1)
|
||||
specifier: 19.2.3
|
||||
version: 19.2.3(react@19.2.3)
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^22.13.0
|
||||
@ -21544,9 +21544,9 @@ snapshots:
|
||||
eslint: 8.57.1
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/eslint-utils@4.9.0(eslint@9.39.1(jiti@2.6.1))':
|
||||
'@eslint-community/eslint-utils@4.9.0(eslint@9.39.1(jiti@1.21.7))':
|
||||
dependencies:
|
||||
eslint: 9.39.1(jiti@2.6.1)
|
||||
eslint: 9.39.1(jiti@1.21.7)
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)':
|
||||
@ -28037,28 +28037,6 @@ snapshots:
|
||||
- vite-plugin-solid
|
||||
- webpack
|
||||
|
||||
'@tanstack/react-start-rsc@0.0.37(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.169.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1)
|
||||
'@tanstack/react-start-server': 1.166.48(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)
|
||||
'@tanstack/router-core': 1.169.1
|
||||
'@tanstack/router-utils': 1.161.7
|
||||
'@tanstack/start-client-core': 1.168.1
|
||||
'@tanstack/start-fn-stubs': 1.161.6
|
||||
'@tanstack/start-plugin-core': 1.169.13(@tanstack/react-router@1.169.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(crossws@0.4.4(srvx@0.11.15))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))
|
||||
'@tanstack/start-server-core': 1.167.26(crossws@0.4.4(srvx@0.11.15))
|
||||
'@tanstack/start-storage-context': 1.166.34
|
||||
pathe: 2.0.3
|
||||
react: 19.2.1
|
||||
react-dom: 19.2.1(react@19.2.1)
|
||||
transitivePeerDependencies:
|
||||
- '@rsbuild/core'
|
||||
- crossws
|
||||
- supports-color
|
||||
- vite
|
||||
- vite-plugin-solid
|
||||
- webpack
|
||||
|
||||
'@tanstack/react-start-rsc@0.0.37(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.20.2))':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
@ -28081,6 +28059,28 @@ snapshots:
|
||||
- vite-plugin-solid
|
||||
- webpack
|
||||
|
||||
'@tanstack/react-start-rsc@0.0.37(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
'@tanstack/react-start-server': 1.166.48(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
'@tanstack/router-core': 1.169.1
|
||||
'@tanstack/router-utils': 1.161.7
|
||||
'@tanstack/start-client-core': 1.168.1
|
||||
'@tanstack/start-fn-stubs': 1.161.6
|
||||
'@tanstack/start-plugin-core': 1.169.13(@tanstack/react-router@1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.4(srvx@0.11.15))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))
|
||||
'@tanstack/start-server-core': 1.167.26(crossws@0.4.4(srvx@0.11.15))
|
||||
'@tanstack/start-storage-context': 1.166.34
|
||||
pathe: 2.0.3
|
||||
react: 19.2.3
|
||||
react-dom: 19.2.3(react@19.2.3)
|
||||
transitivePeerDependencies:
|
||||
- '@rsbuild/core'
|
||||
- crossws
|
||||
- supports-color
|
||||
- vite
|
||||
- vite-plugin-solid
|
||||
- webpack
|
||||
|
||||
'@tanstack/react-start-server@1.166.48(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)':
|
||||
dependencies:
|
||||
'@tanstack/history': 1.161.6
|
||||
@ -28160,19 +28160,19 @@ snapshots:
|
||||
- vite-plugin-solid
|
||||
- webpack
|
||||
|
||||
'@tanstack/react-start@1.167.58(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))':
|
||||
'@tanstack/react-start@1.167.58(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.20.2))':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.169.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1)
|
||||
'@tanstack/react-start-client': 1.166.47(react-dom@19.2.1(react@19.2.1))(react@19.2.1)
|
||||
'@tanstack/react-start-rsc': 0.0.37(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))
|
||||
'@tanstack/react-start-server': 1.166.48(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)
|
||||
'@tanstack/react-router': 1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
'@tanstack/react-start-client': 1.166.47(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
'@tanstack/react-start-rsc': 0.0.37(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.20.2))
|
||||
'@tanstack/react-start-server': 1.166.48(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
'@tanstack/router-utils': 1.161.7
|
||||
'@tanstack/start-client-core': 1.168.1
|
||||
'@tanstack/start-plugin-core': 1.169.13(@tanstack/react-router@1.169.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(crossws@0.4.4(srvx@0.11.15))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))
|
||||
'@tanstack/start-plugin-core': 1.169.13(@tanstack/react-router@1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.4(srvx@0.11.15))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.20.2))
|
||||
'@tanstack/start-server-core': 1.167.26(crossws@0.4.4(srvx@0.11.15))
|
||||
pathe: 2.0.3
|
||||
react: 19.2.1
|
||||
react-dom: 19.2.1(react@19.2.1)
|
||||
react: 19.2.3
|
||||
react-dom: 19.2.3(react@19.2.3)
|
||||
optionalDependencies:
|
||||
vite: 7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)
|
||||
transitivePeerDependencies:
|
||||
@ -28183,15 +28183,15 @@ snapshots:
|
||||
- vite-plugin-solid
|
||||
- webpack
|
||||
|
||||
'@tanstack/react-start@1.167.58(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.20.2))':
|
||||
'@tanstack/react-start@1.167.58(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
'@tanstack/react-start-client': 1.166.47(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
'@tanstack/react-start-rsc': 0.0.37(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.20.2))
|
||||
'@tanstack/react-start-rsc': 0.0.37(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))
|
||||
'@tanstack/react-start-server': 1.166.48(crossws@0.4.4(srvx@0.11.15))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
'@tanstack/router-utils': 1.161.7
|
||||
'@tanstack/start-client-core': 1.168.1
|
||||
'@tanstack/start-plugin-core': 1.169.13(@tanstack/react-router@1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.4(srvx@0.11.15))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.20.2))
|
||||
'@tanstack/start-plugin-core': 1.169.13(@tanstack/react-router@1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.4(srvx@0.11.15))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))
|
||||
'@tanstack/start-server-core': 1.167.26(crossws@0.4.4(srvx@0.11.15))
|
||||
pathe: 2.0.3
|
||||
react: 19.2.3
|
||||
@ -28338,28 +28338,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@tanstack/router-plugin@1.167.31(@tanstack/react-router@1.169.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))':
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
'@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0)
|
||||
'@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0)
|
||||
'@babel/template': 7.28.6
|
||||
'@babel/traverse': 7.29.0
|
||||
'@babel/types': 7.29.0
|
||||
'@tanstack/router-core': 1.169.1
|
||||
'@tanstack/router-generator': 1.166.39
|
||||
'@tanstack/router-utils': 1.161.7
|
||||
'@tanstack/virtual-file-routes': 1.161.7
|
||||
chokidar: 3.6.0
|
||||
unplugin: 3.0.0
|
||||
zod: 3.25.76
|
||||
optionalDependencies:
|
||||
'@tanstack/react-router': 1.169.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1)
|
||||
vite: 7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)
|
||||
webpack: 5.92.0(esbuild@0.24.2)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@tanstack/router-plugin@1.167.31(@tanstack/react-router@1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.20.2))':
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
@ -28382,6 +28360,28 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@tanstack/router-plugin@1.167.31(@tanstack/react-router@1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))':
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
'@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0)
|
||||
'@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0)
|
||||
'@babel/template': 7.28.6
|
||||
'@babel/traverse': 7.29.0
|
||||
'@babel/types': 7.29.0
|
||||
'@tanstack/router-core': 1.169.1
|
||||
'@tanstack/router-generator': 1.166.39
|
||||
'@tanstack/router-utils': 1.161.7
|
||||
'@tanstack/virtual-file-routes': 1.161.7
|
||||
chokidar: 3.6.0
|
||||
unplugin: 3.0.0
|
||||
zod: 3.25.76
|
||||
optionalDependencies:
|
||||
'@tanstack/react-router': 1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
||||
vite: 7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)
|
||||
webpack: 5.92.0(esbuild@0.24.2)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@tanstack/router-utils@1.161.4':
|
||||
dependencies:
|
||||
'@babel/core': 7.29.0
|
||||
@ -28496,7 +28496,7 @@ snapshots:
|
||||
- vite-plugin-solid
|
||||
- webpack
|
||||
|
||||
'@tanstack/start-plugin-core@1.169.13(@tanstack/react-router@1.169.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(crossws@0.4.4(srvx@0.11.15))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))':
|
||||
'@tanstack/start-plugin-core@1.169.13(@tanstack/react-router@1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.4(srvx@0.11.15))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.20.2))':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.27.1
|
||||
'@babel/core': 7.29.0
|
||||
@ -28504,7 +28504,7 @@ snapshots:
|
||||
'@rolldown/pluginutils': 1.0.0-beta.40
|
||||
'@tanstack/router-core': 1.169.1
|
||||
'@tanstack/router-generator': 1.166.39
|
||||
'@tanstack/router-plugin': 1.167.31(@tanstack/react-router@1.169.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))
|
||||
'@tanstack/router-plugin': 1.167.31(@tanstack/react-router@1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.20.2))
|
||||
'@tanstack/router-utils': 1.161.7
|
||||
'@tanstack/start-client-core': 1.168.1
|
||||
'@tanstack/start-server-core': 1.167.26(crossws@0.4.4(srvx@0.11.15))
|
||||
@ -28530,7 +28530,7 @@ snapshots:
|
||||
- vite-plugin-solid
|
||||
- webpack
|
||||
|
||||
'@tanstack/start-plugin-core@1.169.13(@tanstack/react-router@1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.4(srvx@0.11.15))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.20.2))':
|
||||
'@tanstack/start-plugin-core@1.169.13(@tanstack/react-router@1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(crossws@0.4.4(srvx@0.11.15))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.27.1
|
||||
'@babel/core': 7.29.0
|
||||
@ -28538,7 +28538,7 @@ snapshots:
|
||||
'@rolldown/pluginutils': 1.0.0-beta.40
|
||||
'@tanstack/router-core': 1.169.1
|
||||
'@tanstack/router-generator': 1.166.39
|
||||
'@tanstack/router-plugin': 1.167.31(@tanstack/react-router@1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.20.2))
|
||||
'@tanstack/router-plugin': 1.167.31(@tanstack/react-router@1.169.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(webpack@5.92.0(esbuild@0.24.2))
|
||||
'@tanstack/router-utils': 1.161.7
|
||||
'@tanstack/start-client-core': 1.168.1
|
||||
'@tanstack/start-server-core': 1.167.26(crossws@0.4.4(srvx@0.11.15))
|
||||
@ -29128,15 +29128,15 @@ snapshots:
|
||||
'@types/node': 22.19.0
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.46.3(@typescript-eslint/parser@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)':
|
||||
'@typescript-eslint/eslint-plugin@8.46.3(@typescript-eslint/parser@8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@typescript-eslint/parser': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
|
||||
'@typescript-eslint/parser': 8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3)
|
||||
'@typescript-eslint/scope-manager': 8.46.3
|
||||
'@typescript-eslint/type-utils': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
|
||||
'@typescript-eslint/type-utils': 8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3)
|
||||
'@typescript-eslint/visitor-keys': 8.46.3
|
||||
eslint: 9.39.1(jiti@2.6.1)
|
||||
eslint: 9.39.1(jiti@1.21.7)
|
||||
graphemer: 1.4.0
|
||||
ignore: 7.0.5
|
||||
natural-compare: 1.4.0
|
||||
@ -29174,14 +29174,14 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/parser@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)':
|
||||
'@typescript-eslint/parser@8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 8.46.3
|
||||
'@typescript-eslint/types': 8.46.3
|
||||
'@typescript-eslint/typescript-estree': 8.46.3(typescript@5.9.3)
|
||||
'@typescript-eslint/visitor-keys': 8.46.3
|
||||
debug: 4.4.3
|
||||
eslint: 9.39.1(jiti@2.6.1)
|
||||
eslint: 9.39.1(jiti@1.21.7)
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@ -29239,13 +29239,13 @@ snapshots:
|
||||
dependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
'@typescript-eslint/type-utils@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)':
|
||||
'@typescript-eslint/type-utils@8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.46.3
|
||||
'@typescript-eslint/typescript-estree': 8.46.3(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3)
|
||||
debug: 4.4.3
|
||||
eslint: 9.39.1(jiti@2.6.1)
|
||||
eslint: 9.39.1(jiti@1.21.7)
|
||||
ts-api-utils: 2.1.0(typescript@5.9.3)
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
@ -29315,13 +29315,13 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)':
|
||||
'@typescript-eslint/utils@8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1))
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@1.21.7))
|
||||
'@typescript-eslint/scope-manager': 8.46.3
|
||||
'@typescript-eslint/types': 8.46.3
|
||||
'@typescript-eslint/typescript-estree': 8.46.3(typescript@5.9.3)
|
||||
eslint: 9.39.1(jiti@2.6.1)
|
||||
eslint: 9.39.1(jiti@1.21.7)
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@ -32294,13 +32294,13 @@ snapshots:
|
||||
dependencies:
|
||||
eslint: 8.57.1
|
||||
|
||||
eslint-plugin-react-hooks@5.2.0(eslint@9.39.1(jiti@2.6.1)):
|
||||
eslint-plugin-react-hooks@5.2.0(eslint@9.39.1(jiti@1.21.7)):
|
||||
dependencies:
|
||||
eslint: 9.39.1(jiti@2.6.1)
|
||||
eslint: 9.39.1(jiti@1.21.7)
|
||||
|
||||
eslint-plugin-react-refresh@0.4.24(eslint@9.39.1(jiti@2.6.1)):
|
||||
eslint-plugin-react-refresh@0.4.24(eslint@9.39.1(jiti@1.21.7)):
|
||||
dependencies:
|
||||
eslint: 9.39.1(jiti@2.6.1)
|
||||
eslint: 9.39.1(jiti@1.21.7)
|
||||
|
||||
eslint-plugin-react@7.37.2(eslint@8.57.1):
|
||||
dependencies:
|
||||
@ -32394,9 +32394,9 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint@9.39.1(jiti@2.6.1):
|
||||
eslint@9.39.1(jiti@1.21.7):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1))
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@1.21.7))
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@eslint/config-array': 0.21.1
|
||||
'@eslint/config-helpers': 0.4.2
|
||||
@ -32431,7 +32431,7 @@ snapshots:
|
||||
natural-compare: 1.4.0
|
||||
optionator: 0.9.4
|
||||
optionalDependencies:
|
||||
jiti: 2.6.1
|
||||
jiti: 1.21.7
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@ -36080,7 +36080,7 @@ snapshots:
|
||||
jsonpath-plus: 10.4.0
|
||||
lodash.topath: 4.5.2
|
||||
|
||||
nitro@3.0.0(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.2)(mysql2@3.15.3)(rolldown@1.0.0-rc.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(xml2js@0.6.2):
|
||||
nitro@3.0.0(@electric-sql/pglite@0.3.2)(chokidar@4.0.3)(lru-cache@11.2.2)(mysql2@3.15.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0))(xml2js@0.6.2):
|
||||
dependencies:
|
||||
consola: 3.4.2
|
||||
cookie-es: 2.0.0
|
||||
@ -36100,7 +36100,6 @@ snapshots:
|
||||
unenv: 2.0.0-rc.21
|
||||
unstorage: 2.0.0-alpha.3(chokidar@4.0.3)(db0@0.3.4(@electric-sql/pglite@0.3.2)(mysql2@3.15.3))(lru-cache@11.2.2)(ofetch@1.5.1)
|
||||
optionalDependencies:
|
||||
rolldown: 1.0.0-rc.3
|
||||
vite: 7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.44.0)(tsx@4.21.0)(yaml@2.8.0)
|
||||
xml2js: 0.6.2
|
||||
transitivePeerDependencies:
|
||||
@ -39589,13 +39588,13 @@ snapshots:
|
||||
possible-typed-array-names: 1.0.0
|
||||
reflect.getprototypeof: 1.0.10
|
||||
|
||||
typescript-eslint@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3):
|
||||
typescript-eslint@8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@typescript-eslint/eslint-plugin': 8.46.3(@typescript-eslint/parser@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
|
||||
'@typescript-eslint/parser': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
|
||||
'@typescript-eslint/eslint-plugin': 8.46.3(@typescript-eslint/parser@8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3)
|
||||
'@typescript-eslint/parser': 8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3)
|
||||
'@typescript-eslint/typescript-estree': 8.46.3(typescript@5.9.3)
|
||||
'@typescript-eslint/utils': 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)
|
||||
eslint: 9.39.1(jiti@2.6.1)
|
||||
'@typescript-eslint/utils': 8.46.3(eslint@9.39.1(jiti@1.21.7))(typescript@5.9.3)
|
||||
eslint: 9.39.1(jiti@1.21.7)
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@ -159,6 +159,15 @@ withGeneratorLock(async () => {
|
||||
return baseEditFn({ relativePath, content, platforms: PLATFORMS["js"] });
|
||||
},
|
||||
filterFn: (relativePath) => {
|
||||
const jsGeneratedFiles = new Set([
|
||||
"scripts/generate-env.ts",
|
||||
"src/generated/.gitignore",
|
||||
"src/generated/env.ts",
|
||||
]);
|
||||
if (jsGeneratedFiles.has(relativePath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const ignores = [
|
||||
"postcss.config.js",
|
||||
"tailwind.config.js",
|
||||
@ -172,8 +181,6 @@ withGeneratorLock(async () => {
|
||||
"src/components-page/",
|
||||
"src/generated/",
|
||||
"src/providers/",
|
||||
"src/global.css",
|
||||
"src/global.d.ts",
|
||||
];
|
||||
|
||||
if (tanstackStartOnlyTemplateFiles.has(relativePath) || templateOnlyFiles.has(relativePath)) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/swift-sdk",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"private": true,
|
||||
"description": "Hexclave Swift SDK",
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hexclave/sdk-spec",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.11",
|
||||
"private": true,
|
||||
"description": "Hexclave SDK specification files",
|
||||
"scripts": {}
|
||||
|
||||
24
turbo.json
24
turbo.json
@ -100,6 +100,30 @@
|
||||
"dist/**"
|
||||
]
|
||||
},
|
||||
"@hexclave/next#build": {
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"@hexclave/template#build"
|
||||
]
|
||||
},
|
||||
"@hexclave/react#build": {
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"@hexclave/template#build"
|
||||
]
|
||||
},
|
||||
"@hexclave/tanstack-start#build": {
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"@hexclave/template#build"
|
||||
]
|
||||
},
|
||||
"@hexclave/js#build": {
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"@hexclave/template#build"
|
||||
]
|
||||
},
|
||||
"clean": {
|
||||
"cache": false
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user