Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions @nself/sdk-core/src/__tests__/sdk-core.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ describe('resolveApiUrl', () => {
expect(PROD_API_URL).toBe('https://api.nself.org');
});

it('STAGING_API_URL is the canonical staging IP', () => {
expect(STAGING_API_URL).toBe('http://167.235.233.65');
it('STAGING_API_URL has no hardcoded fallback (staging server decommissioned)', () => {
expect(STAGING_API_URL).toBeUndefined();
});
});

Expand Down
26 changes: 20 additions & 6 deletions @nself/sdk-core/src/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@
* Purpose: Provide a single canonical source of truth for nSelf API endpoint
* base URLs, reading from environment variables with a safe fallback.
* Inputs: VITE_NSELF_API_URL (Vite client) or NSELF_API_URL (Node/server) env vars.
* Outputs: Resolved base URL string; staging URL constant.
* Outputs: Resolved base URL string; staging URL constant (undefined unless
* explicitly configured -- no default staging host).
* Constraints: No fetch calls here; pure URL resolution; no framework deps.
* SPORT: F11-SUBDOMAIN-MAP.md (api.nself.org)
*/

/** Production API base URL. */
export const PROD_API_URL = 'https://api.nself.org' as const;

/** Staging API base URL (Hetzner staging server). */
export const STAGING_API_URL = 'http://167.235.233.65' as const;
/**
* Staging API base URL. No default: the Hetzner staging server
* (167.235.233.65) was permanently destroyed 2026-09-12. Must be supplied
* via VITE_NSELF_STAGING_URL / NSELF_STAGING_URL when a staging env exists.
*/
export const STAGING_API_URL: string | undefined = undefined;

/** Read a Vite env var safely across bundler/non-bundler envs. */
const readViteEnv = (key: string): string | undefined => {
Expand Down Expand Up @@ -57,12 +62,21 @@ export const resolveApiUrl = (): string => {
};

/**
* Resolve the staging API URL from environment variables, falling back
* to the canonical staging server IP.
* Resolve the staging API URL from environment variables.
*
* Returns undefined when no staging env var is set -- there is no hardcoded
* fallback (the prior Hetzner staging IP was decommissioned 2026-09-12).
*/
export const resolveStagingUrl = (): string => {
export const resolveStagingUrl = (): string | undefined => {
const viteUrl = readViteEnv('VITE_NSELF_STAGING_URL');
if (viteUrl && viteUrl.length > 0) return viteUrl.replace(/\/$/, '');

const nodeUrl =
typeof process !== 'undefined' && process.env != null
? process.env['NSELF_STAGING_URL']
: undefined;

if (nodeUrl && nodeUrl.length > 0) return nodeUrl.replace(/\/$/, '');

return STAGING_API_URL;
};
Loading