Files
spacesops-startos/startos/actions/configurePlatform.ts
T
spacesopsandClaude Opus 4.7 147f51d710 Rename SUBSD_* env vars to SUBS_* to match upstream refactor
The upstream SpacesOps app refactored its SUBSD_* environment variables to
SUBS_* (verified against server.js in spacesops/spacesops:v1.0.0). Update the
package to match so the configured values reach the app:

- main.ts: inject SUBS_URI_VALUE / SUBS_RPC_USER / SUBS_RPC_PASSWORD.
- configurePlatform action + storeJson: rename store keys subsd*→subs* and the
  field labels/descriptions (SUBS URL / SUBS RPC User / SUBS RPC Password).
- README, instructions, release notes: SUBSD→SUBS.

Note: the image's /app/setup-spacesops-env.sh still exports SUBSD_* defaults
(partial upstream refactor) — see report; vars the package does not set (e.g.
SUBS_RPC_URL) currently have no in-image default.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 12:19:51 -04:00

164 lines
4.3 KiB
TypeScript

import { storeJson } from '../fileModels/storeJson'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import {
DEFAULT_COINGECKO_TOKEN_COINS,
DEFAULT_OPERATOR_RELAY,
DEFAULT_PLATFORM_MODE,
} from '../utils'
const { InputSpec, Value } = sdk
const inputSpec = InputSpec.of({
operatorRelay: Value.text({
name: i18n('Operator Nostr Relay'),
description: i18n(
'The Nostr relay SpacesOps publishes operator events to (OPERATOR_RELAY).',
),
warning: null,
footnote: null,
default: DEFAULT_OPERATOR_RELAY,
required: true,
masked: false,
placeholder: 'wss://relay.example.com',
minLength: 1,
maxLength: null,
}),
platformMode: Value.select({
name: i18n('Platform Mode'),
description: i18n(
'Sets PLATFORM_MODE. Only changes the UI theme color; "test" does not change behavior.',
),
warning: null,
footnote: null,
default: DEFAULT_PLATFORM_MODE,
values: {
prod: 'Production',
test: 'Test',
},
}),
coingeckoApiKey: Value.text({
name: i18n('CoinGecko API Key'),
description: i18n(
'Optional CoinGecko API key (COINGECKO_API_KEY) used for pricing features. Leave blank to disable pricing.',
),
warning: null,
footnote: null,
default: null,
required: false,
masked: true,
placeholder: null,
minLength: null,
maxLength: null,
}),
coingeckoTokenCoins: Value.text({
name: i18n('CoinGecko Token Coins'),
description: i18n(
'The CoinGecko coin id(s) to price against (COINGECKO_TOKEN_COINS).',
),
warning: null,
footnote: null,
default: DEFAULT_COINGECKO_TOKEN_COINS,
required: false,
masked: false,
placeholder: 'bitcoin',
minLength: null,
maxLength: null,
}),
subsUrl: Value.text({
name: i18n('SUBS URL'),
description: i18n(
'Optional SUBS service URL (SUBS_URI_VALUE) for the subname-purchase flow. Leave blank to disable.',
),
warning: null,
footnote: null,
default: null,
required: false,
masked: false,
placeholder: 'http://host:7244',
minLength: null,
maxLength: null,
}),
subsUser: Value.text({
name: i18n('SUBS RPC User'),
description: i18n('Optional SUBS RPC username (SUBS_RPC_USER).'),
warning: null,
footnote: null,
default: null,
required: false,
masked: false,
placeholder: null,
minLength: null,
maxLength: null,
}),
subsPassword: Value.text({
name: i18n('SUBS RPC Password'),
description: i18n('Optional SUBS RPC password (SUBS_RPC_PASSWORD).'),
warning: null,
footnote: null,
default: null,
required: false,
masked: true,
placeholder: null,
minLength: null,
maxLength: null,
}),
})
export const configurePlatform = sdk.Action.withInput(
// id
'configure-platform',
// metadata
async ({ effects }) => ({
name: i18n('Configure Platform'),
description: i18n(
'Set optional SpacesOps settings: Nostr relay, theme mode, CoinGecko pricing, and SUBS backend. Saving restarts the service so the new settings take effect.',
),
warning: null,
allowedStatuses: 'any',
group: null,
visibility: 'enabled',
}),
// input
inputSpec,
// prefill — load current values from store
async ({ effects }) => {
const store = await storeJson.read().once()
return {
operatorRelay: store?.operatorRelay ?? DEFAULT_OPERATOR_RELAY,
platformMode: store?.platformMode ?? DEFAULT_PLATFORM_MODE,
coingeckoApiKey: store?.coingeckoApiKey ?? null,
coingeckoTokenCoins:
store?.coingeckoTokenCoins ?? DEFAULT_COINGECKO_TOKEN_COINS,
subsUrl: store?.subsUrl ?? null,
subsUser: store?.subsUser ?? null,
subsPassword: store?.subsPassword ?? null,
}
},
// run
async ({ effects, input }) => {
await storeJson.merge(effects, {
operatorRelay: input.operatorRelay,
platformMode: input.platformMode,
coingeckoApiKey: input.coingeckoApiKey || null,
coingeckoTokenCoins: input.coingeckoTokenCoins || null,
subsUrl: input.subsUrl || null,
subsUser: input.subsUser || null,
subsPassword: input.subsPassword || null,
})
return {
version: '1',
title: i18n('Success'),
message: i18n(
'Platform configuration saved. The service is restarting to apply the new settings.',
),
result: null,
}
},
)