@outofscope/sdk-config
v0.1.4
Published
Thin TypeScript client for platform-config-api
Readme
@outofscope/sdk-config
TypeScript client for platform-config-api, published on npm as @outofscope/sdk-config. The package exposes a minimal HTTP client for public and administrative configuration and provides types for the platform's serialized data.
Installation
npm install @outofscope/sdk-config
# or
pnpm add @outofscope/sdk-config
yarn add @outofscope/sdk-configQuick setup
The library automatically detects the base URL from the PLATFORM_CONFIG_BASE_URL environment variable or from PLATFORM_STAGE (dev, uat, prod). You can override it manually with the baseUrl option:
import { createConfigClient } from '@outofscope/sdk-config';
const client = createConfigClient({
baseUrl: 'https://custom-gateway.example.com/config',
});If you do not provide
baseUrl, the client useshttps://dev-api.outofscope.app/config,https://uat-api.outofscope.app/config, orhttps://api.outofscope.app/configbased onPLATFORM_STAGE.In browser/edge environments where
processis not available, the client automatically relies onPLATFORM_STAGEand no longer throws aReferenceErrorif you do not expose environment variables.
IAM security headers
All requests to platform-config-api must include the IAM headers:
x-session-id– session identifier (returned by/iam/auth/login)x-app-key– identifier for the authorized applicationx-tenant-id– current tenant, validated together with the session and application key
The client can send either static values (sessionId, appKey, tenantId) or values computed for each call (getSessionId, getAppKey, getTenantId). Values returned from callbacks take precedence.
import { createConfigClient } from '@outofscope/sdk-config';
const client = createConfigClient({
baseUrl: 'https://dev-api.outofscope.app/config',
sessionId: 'sess_123',
appKey: 'app_456',
tenantId: 'demo',
});
// or dynamically, for example when refreshing a token before every request
const dynamicClient = createConfigClient({
baseUrl: 'https://dev-api.outofscope.app/config',
getSessionId: async () => refreshSession(),
getAppKey: () => process.env.APP_KEY,
getTenantId: () => currentTenant(),
});Usage
Public config (front-end or edge)
const client = createConfigClient();
const tenant = await client.public.getTenantByHost(window.location.hostname);
console.log(tenant.displayName, tenant.shopify.domain);Admin operations (backend)
const client = createConfigClient({
baseUrl: 'https://dev-api.outofscope.app/config',
sessionId: 'sess_123',
appKey: 'app_456',
tenantId: 'demo',
});
// List all tenants
const tenants = await client.admin.listTenants();
// Create or update a tenant
const tenant = await client.admin.updateTenant('demo', {
tenantId: 'demo',
displayName: 'Demo Storefront',
shopify: { domain: 'demo.myshopify.com' },
});
// Update a tenant secret
await client.admin.updateTenantSecret('demo', 'storefrontToken', { value: '***' });Client surface
createConfigClient returns:
public.getTenantByHost(host?: string)→TenantPublicConfigadmin.listTenants()→AdminTenantSummary[]admin.getTenant(tenantId)→AdminTenantConfigadmin.updateTenant(tenantId, input)→AdminTenantConfigadmin.patchTenant(tenantId, partialInput)→AdminTenantConfigadmin.addTenantHost(tenantId, { host })→AdminHostsResponseadmin.listTenantHosts(tenantId)→AdminHostsResponseadmin.deleteTenantHost(tenantId, host)→AdminHostDeleteResponseadmin.updateTenantSecret(tenantId, key, { value })→AdminSecretUpsertResponse
Error handling
Requests that fail (non-2xx status) throw ConfigApiError, exposing status, statusText, and body for debugging.
try {
await client.admin.getTenant('missing');
} catch (err) {
if (err instanceof ConfigApiError) {
console.error(err.status, err.statusText, err.body);
}
}Exported types
The package exports the types described in src/types.ts to avoid duplicating schemas (TenantConfig, TenantPublicConfig, AdminHostsResponse, etc.).
Local development
npm install
npm test # runs the Vitest suite
npm run lint # type-checks the project
npm run build # generates the artifacts in the dist folderNode.js 18+ is required.
