@omen.foundation/node-microservice-runtime 0.1.68 → 0.1.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/services.js CHANGED
@@ -1,3 +1,4 @@
1
+ import pino from 'pino';
1
2
  import { BeamServer, BeamEnvironment, defaultTokenStorage, AccountService, AnnouncementsService, AuthService, ContentService, LeaderboardsService, StatsService, } from 'beamable-sdk';
2
3
  import { hostToHttpUrl, hostToPortalUrl, hostToStorageUrl, hostToMicroserviceRegistryUrl } from './utils/urls.js';
3
4
  import { createInventoryService } from './inventory.js';
@@ -102,6 +103,11 @@ class UnavailableBeamableServices {
102
103
  assumeUser() {
103
104
  return this;
104
105
  }
106
+ getLogger() {
107
+ // For unavailable services, return a basic logger that logs to stdout
108
+ // This allows logging even when services are unavailable
109
+ return pino({ name: 'beamable-unavailable', level: 'info' }, process.stdout);
110
+ }
105
111
  }
106
112
  class BeamableServicesFacade {
107
113
  manager;
@@ -187,6 +193,9 @@ class BeamableServicesFacade {
187
193
  assumeUser(userId) {
188
194
  return this.manager.createFacade(String(userId), new Set(this.scopes), this.serviceName);
189
195
  }
196
+ getLogger() {
197
+ return this.logger;
198
+ }
190
199
  scopeSetHas(scope) {
191
200
  const normalized = scope.trim().toLowerCase();
192
201
  if (!normalized) {
@@ -1 +1 @@
1
- {"version":3,"file":"services.js","sourceRoot":"","sources":["../src/services.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Logger } from 'pino';\r\nimport {\r\n BeamServer,\r\n BeamEnvironment,\r\n defaultTokenStorage,\r\n type HttpRequester,\r\n AccountService,\r\n AnnouncementsService,\r\n AuthService,\r\n ContentService,\r\n LeaderboardsService,\r\n StatsService,\r\n} from 'beamable-sdk';\r\nimport type { EnvironmentConfig } from './types.js';\r\nimport { hostToHttpUrl, hostToPortalUrl, hostToStorageUrl, hostToMicroserviceRegistryUrl } from './utils/urls.js';\r\nimport { createInventoryService, type InventoryService } from './inventory.js';\r\nimport { StorageService } from './storage.js';\r\nimport type { FederationRegistry } from './federation.js';\r\nimport { MissingScopesError } from './errors.js';\r\n\r\nconst RUNTIME_ENVIRONMENT_NAME = 'node-runtime';\r\n\r\nexport type BoundBeamApi = Record<string, (...args: unknown[]) => unknown>;\r\n\r\nlet cachedBeamApiModule: Record<string, unknown> | null = null;\r\n\r\nasync function resolveBeamApiModule(): Promise<Record<string, unknown>> {\r\n if (!cachedBeamApiModule) {\r\n const imported = await import('beamable-sdk/api');\r\n cachedBeamApiModule =\r\n imported && typeof imported === 'object' && 'default' in imported\r\n ? (imported.default as Record<string, unknown>)\r\n : (imported as Record<string, unknown>);\r\n }\r\n return cachedBeamApiModule;\r\n}\r\n\r\nasync function bindBeamApi(requester: HttpRequester): Promise<BoundBeamApi> {\r\n const module = await resolveBeamApiModule();\r\n const bound: Record<string, (...args: unknown[]) => unknown> = {};\r\n for (const key of Object.keys(module)) {\r\n const value = module[key];\r\n if (typeof value === 'function') {\r\n bound[key] = (...args: unknown[]) => (value as (r: HttpRequester, ...params: unknown[]) => unknown)(requester, ...args);\r\n }\r\n }\r\n return bound;\r\n}\r\n\r\nfunction createFailingApi(error: Error): BoundBeamApi {\r\n return new Proxy(\r\n {},\r\n {\r\n get() {\r\n throw error;\r\n },\r\n },\r\n ) as BoundBeamApi;\r\n}\r\n\r\ntype ServiceMap = {\r\n account: AccountService;\r\n announcements: AnnouncementsService;\r\n auth: AuthService;\r\n content: ContentService;\r\n leaderboards: LeaderboardsService;\r\n stats: StatsService;\r\n};\r\n\r\ntype ServiceKey = keyof ServiceMap;\r\n\r\nclass UnavailableRequester implements HttpRequester {\r\n constructor(private readonly error: Error) {}\r\n\r\n async request(): Promise<never> {\r\n throw this.error;\r\n }\r\n\r\n set baseUrl(_: string) {\r\n // no-op\r\n }\r\n\r\n set defaultHeaders(_: Record<string, string>) {\r\n // no-op\r\n }\r\n}\r\n\r\nclass UnavailableBeamableServices implements BeamableMicroserviceServices {\r\n private readonly requesterImpl: HttpRequester;\r\n private readonly apiBindings: BoundBeamApi;\r\n\r\n constructor(private readonly error: Error) {\r\n this.requesterImpl = new UnavailableRequester(this.error);\r\n this.apiBindings = createFailingApi(this.error);\r\n }\r\n\r\n private fail(): never {\r\n throw this.error;\r\n }\r\n\r\n get account(): AccountService {\r\n return this.fail();\r\n }\r\n\r\n get announcements(): AnnouncementsService {\r\n return this.fail();\r\n }\r\n\r\n get auth(): AuthService {\r\n return this.fail();\r\n }\r\n\r\n get content(): ContentService {\r\n return this.fail();\r\n }\r\n\r\n get leaderboards(): LeaderboardsService {\r\n return this.fail();\r\n }\r\n\r\n get stats(): StatsService {\r\n return this.fail();\r\n }\r\n\r\n get inventory(): InventoryService {\r\n return this.fail();\r\n }\r\n\r\n get storage(): StorageService {\r\n return this.fail();\r\n }\r\n\r\n get federation(): FederationRegistry {\r\n return this.fail();\r\n }\r\n\r\n get api(): BoundBeamApi {\r\n return this.apiBindings;\r\n }\r\n\r\n get requester(): HttpRequester {\r\n return this.requesterImpl;\r\n }\r\n\r\n hasScopes(..._scopes: string[]): boolean {\r\n return false;\r\n }\r\n\r\n requireScopes(...scopes: string[]): void {\r\n throw new MissingScopesError(scopes);\r\n }\r\n\r\n assumeUser(): BeamableMicroserviceServices {\r\n return this;\r\n }\r\n}\r\n\r\nclass BeamableServicesFacade implements BeamableMicroserviceServices {\r\n private readonly cache: Partial<Record<ServiceKey, ServiceMap[ServiceKey]>> = {};\r\n private readonly apiBindings: BoundBeamApi;\r\n private readonly storageService: StorageService;\r\n private readonly scopes: Set<string>;\r\n private readonly logger: Logger;\r\n private readonly serviceName?: string;\r\n private readonly federationRegistry?: FederationRegistry;\r\n private inventoryClient?: InventoryService;\r\n\r\n constructor(\r\n private readonly manager: BeamableServiceManager,\r\n private readonly beamServer: BeamServer,\r\n private readonly userId: string,\r\n scopes: Set<string>,\r\n serviceName?: string,\r\n ) {\r\n this.apiBindings = this.manager.getBoundApi();\r\n this.storageService = this.manager.getStorageService();\r\n this.scopes = scopes;\r\n this.serviceName = serviceName;\r\n this.federationRegistry = serviceName ? this.manager.getFederationRegistry(serviceName) : undefined;\r\n this.logger = this.manager.getLogger().child({ component: 'BeamableServicesFacade', service: serviceName });\r\n }\r\n\r\n private getOrCreate<K extends ServiceKey>(key: K, factory: () => ServiceMap[K]): ServiceMap[K] {\r\n if (!this.cache[key]) {\r\n this.cache[key] = factory();\r\n }\r\n return this.cache[key] as ServiceMap[K];\r\n }\r\n\r\n get account(): AccountService {\r\n return this.getOrCreate('account', () => this.beamServer.account(this.userId));\r\n }\r\n\r\n get announcements(): AnnouncementsService {\r\n return this.getOrCreate('announcements', () => this.beamServer.announcements(this.userId));\r\n }\r\n\r\n get auth(): AuthService {\r\n return this.getOrCreate('auth', () => this.beamServer.auth(this.userId));\r\n }\r\n\r\n get content(): ContentService {\r\n return this.getOrCreate('content', () => this.beamServer.content(this.userId));\r\n }\r\n\r\n get leaderboards(): LeaderboardsService {\r\n return this.getOrCreate('leaderboards', () => this.beamServer.leaderboards(this.userId));\r\n }\r\n\r\n get stats(): StatsService {\r\n return this.getOrCreate('stats', () => this.beamServer.stats(this.userId));\r\n }\r\n\r\n get inventory(): InventoryService {\r\n if (!this.inventoryClient) {\r\n this.inventoryClient = createInventoryService(\r\n this.apiBindings,\r\n this.logger.child({ component: 'InventoryClient' }),\r\n this.userId,\r\n (requiredScopes) => this.hasScopes(...requiredScopes),\r\n );\r\n }\r\n return this.inventoryClient;\r\n }\r\n\r\n get storage(): StorageService {\r\n return this.storageService;\r\n }\r\n\r\n get federation(): FederationRegistry {\r\n if (!this.federationRegistry) {\r\n throw new Error(\r\n this.serviceName\r\n ? `Federation registry is not configured for service \"${this.serviceName}\".`\r\n : 'Federation registry is not configured.',\r\n );\r\n }\r\n return this.federationRegistry;\r\n }\r\n\r\n get api(): BoundBeamApi {\r\n return this.apiBindings;\r\n }\r\n\r\n get requester(): HttpRequester {\r\n return this.manager.getRequester();\r\n }\r\n\r\n hasScopes(...requiredScopes: string[]): boolean {\r\n if (requiredScopes.length === 0) {\r\n return true;\r\n }\r\n return requiredScopes.every((scope) => this.scopeSetHas(scope));\r\n }\r\n\r\n requireScopes(...requiredScopes: string[]): void {\r\n if (!this.hasScopes(...requiredScopes)) {\r\n throw new MissingScopesError(requiredScopes);\r\n }\r\n }\r\n\r\n assumeUser(userId: string | number): BeamableMicroserviceServices {\r\n return this.manager.createFacade(String(userId), new Set(this.scopes), this.serviceName);\r\n }\r\n\r\n private scopeSetHas(scope: string): boolean {\r\n const normalized = scope.trim().toLowerCase();\r\n if (!normalized) {\r\n return false;\r\n }\r\n return this.scopes.has('*') || this.scopes.has(normalized);\r\n }\r\n}\r\n\r\nexport interface BeamableMicroserviceServices {\r\n readonly account: AccountService;\r\n readonly announcements: AnnouncementsService;\r\n readonly auth: AuthService;\r\n readonly content: ContentService;\r\n readonly leaderboards: LeaderboardsService;\r\n readonly stats: StatsService;\r\n readonly inventory: InventoryService;\r\n readonly storage: StorageService;\r\n readonly federation: FederationRegistry;\r\n readonly api: BoundBeamApi;\r\n readonly requester: HttpRequester;\r\n hasScopes(...scopes: string[]): boolean;\r\n requireScopes(...scopes: string[]): void;\r\n assumeUser(userId: string | number): BeamableMicroserviceServices;\r\n}\r\n\r\nexport class BeamableServiceManager {\r\n private readonly logger: Logger;\r\n private readonly tokenStorage: ReturnType<typeof defaultTokenStorage>;\r\n private readonly env: EnvironmentConfig;\r\n private beamServer?: BeamServer;\r\n private boundApi?: BoundBeamApi;\r\n private storageService?: StorageService;\r\n private initialized = false;\r\n private readonly federationRegistries = new Map<string, FederationRegistry>();\r\n\r\n constructor(env: EnvironmentConfig, logger: Logger) {\r\n this.env = env;\r\n this.logger = logger.child({ component: 'BeamableServiceManager' });\r\n this.tokenStorage = defaultTokenStorage({ pid: env.pid, tag: env.routingKey ?? RUNTIME_ENVIRONMENT_NAME });\r\n }\r\n\r\n async initialize(): Promise<void> {\r\n if (this.initialized) {\r\n return;\r\n }\r\n\r\n this.registerEnvironment();\r\n this.configureSharedEnvironment();\r\n\r\n if (this.env.refreshToken) {\r\n await this.tokenStorage.setTokenData({ refreshToken: this.env.refreshToken });\r\n }\r\n\r\n const useSignedRequest = Boolean(this.env.secret);\r\n if (!useSignedRequest && !this.env.refreshToken) {\r\n this.logger.warn(\r\n 'Beamable realm secret and refresh token are both missing; Beamable SDK requests may fail due to missing credentials.',\r\n );\r\n }\r\n\r\n try {\r\n this.beamServer = await BeamServer.init({\r\n cid: this.env.cid,\r\n pid: this.env.pid,\r\n environment: RUNTIME_ENVIRONMENT_NAME,\r\n useSignedRequest,\r\n tokenStorage: this.tokenStorage,\r\n serverEvents: { enabled: false },\r\n });\r\n } catch (error) {\r\n this.logger.error({ err: error }, 'Failed to initialize Beamable SDK. Services layer will be unavailable.');\r\n this.beamServer = undefined;\r\n this.initialized = false;\r\n return;\r\n }\r\n\r\n this.boundApi = await bindBeamApi(this.beamServer.requester);\r\n \r\n // Configure the requester's default headers to include the routing key in the correct format\r\n // The routing key format is: serviceName:routingKey\r\n // We'll set this per-request in createFacade since we need the service name\r\n this.storageService = new StorageService({\r\n requester: this.beamServer.requester,\r\n api: this.boundApi,\r\n env: this.env,\r\n logger: this.logger.child({ component: 'StorageService' }),\r\n });\r\n\r\n this.registerDefaultServices();\r\n this.initialized = true;\r\n this.logger.debug('Beamable SDK services initialized.');\r\n }\r\n\r\n createFacade(userId: string | number, scopes: Set<string>, serviceName?: string): BeamableMicroserviceServices {\r\n if (!this.initialized || !this.beamServer || !this.boundApi || !this.storageService) {\r\n return new UnavailableBeamableServices(new Error('Beamable services are not initialized.'));\r\n }\r\n \r\n // Set the routing key in the format serviceName:routingKey for the SDK\r\n // The SDK uses BEAM_ROUTING_KEY environment variable to construct the X-BEAM-SERVICE-ROUTING-KEY header\r\n // We need to set it to the full format: serviceName:routingKey\r\n if (serviceName && this.beamServer.requester) {\r\n const fullRoutingKey = `micro_${serviceName}:${this.env.routingKey}`;\r\n BeamServer.env.BEAM_ROUTING_KEY = fullRoutingKey;\r\n \r\n // Set default headers on the requester for all SDK requests\r\n // These headers are required for signature validation and routing\r\n const scopeHeader = `${this.env.cid}.${this.env.pid}`;\r\n this.beamServer.requester.defaultHeaders = {\r\n ...this.beamServer.requester.defaultHeaders,\r\n 'X-BEAM-SCOPE': scopeHeader,\r\n 'X-BEAM-SERVICE-ROUTING-KEY': fullRoutingKey,\r\n };\r\n }\r\n \r\n return new BeamableServicesFacade(this, this.beamServer, String(userId), new Set(scopes), serviceName);\r\n }\r\n\r\n getRequester(): HttpRequester {\r\n if (!this.initialized || !this.beamServer) {\r\n return new UnavailableRequester(new Error('Beamable services are not initialized.'));\r\n }\r\n return this.beamServer.requester;\r\n }\r\n\r\n getBoundApi(): BoundBeamApi {\r\n if (!this.boundApi) {\r\n throw new Error('Beamable bound API is not available.');\r\n }\r\n return this.boundApi;\r\n }\r\n\r\n getStorageService(): StorageService {\r\n if (!this.storageService) {\r\n throw new Error('Storage service is not initialized.');\r\n }\r\n return this.storageService;\r\n }\r\n\r\n getLogger(): Logger {\r\n return this.logger;\r\n }\r\n\r\n registerFederationRegistry(serviceName: string, registry: FederationRegistry): void {\r\n this.federationRegistries.set(serviceName, registry);\r\n }\r\n\r\n getFederationRegistry(serviceName: string): FederationRegistry | undefined {\r\n return this.federationRegistries.get(serviceName);\r\n }\r\n\r\n private registerEnvironment(): void {\r\n const apiUrl = hostToHttpUrl(this.env.host);\r\n const portalUrl = hostToPortalUrl(apiUrl);\r\n const storageUrl = hostToStorageUrl(apiUrl);\r\n const registryUrl = hostToMicroserviceRegistryUrl(apiUrl);\r\n\r\n try {\r\n BeamEnvironment.register(RUNTIME_ENVIRONMENT_NAME, {\r\n apiUrl,\r\n portalUrl,\r\n beamMongoExpressUrl: storageUrl,\r\n dockerRegistryUrl: `${registryUrl}/v2/`,\r\n });\r\n } catch (error) {\r\n this.logger.debug({ err: error }, 'Beamable environment was already registered. Reusing existing configuration.');\r\n }\r\n }\r\n\r\n private configureSharedEnvironment(): void {\r\n if (this.env.secret) {\r\n BeamServer.env.BEAM_REALM_SECRET = this.env.secret;\r\n }\r\n // BEAM_ROUTING_KEY is used by the SDK to construct the X-BEAM-SERVICE-ROUTING-KEY header\r\n // We set it to just the routing key value here, and will set the full format in createFacade\r\n // BEAM_ROUTING_KEY is used by the SDK to construct the X-BEAM-SERVICE-ROUTING-KEY header\r\n // For deployed services, routingKey is undefined, so we set it to empty string\r\n // The SDK will handle this appropriately\r\n BeamServer.env.BEAM_ROUTING_KEY = this.env.routingKey ?? '';\r\n }\r\n\r\n private registerDefaultServices(): void {\r\n if (!this.beamServer) {\r\n return;\r\n }\r\n this.beamServer.use(AccountService);\r\n this.beamServer.use(AnnouncementsService);\r\n this.beamServer.use(AuthService);\r\n this.beamServer.use(ContentService);\r\n this.beamServer.use(LeaderboardsService);\r\n this.beamServer.use(StatsService);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"services.js","sourceRoot":"","sources":["../src/services.ts"],"names":[],"mappings":"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","sourcesContent":["import pino, { type Logger } from 'pino';\r\nimport {\r\n BeamServer,\r\n BeamEnvironment,\r\n defaultTokenStorage,\r\n type HttpRequester,\r\n AccountService,\r\n AnnouncementsService,\r\n AuthService,\r\n ContentService,\r\n LeaderboardsService,\r\n StatsService,\r\n} from 'beamable-sdk';\r\nimport type { EnvironmentConfig } from './types.js';\r\nimport { hostToHttpUrl, hostToPortalUrl, hostToStorageUrl, hostToMicroserviceRegistryUrl } from './utils/urls.js';\r\nimport { createInventoryService, type InventoryService } from './inventory.js';\r\nimport { StorageService } from './storage.js';\r\nimport type { FederationRegistry } from './federation.js';\r\nimport { MissingScopesError } from './errors.js';\r\n\r\nconst RUNTIME_ENVIRONMENT_NAME = 'node-runtime';\r\n\r\nexport type BoundBeamApi = Record<string, (...args: unknown[]) => unknown>;\r\n\r\nlet cachedBeamApiModule: Record<string, unknown> | null = null;\r\n\r\nasync function resolveBeamApiModule(): Promise<Record<string, unknown>> {\r\n if (!cachedBeamApiModule) {\r\n const imported = await import('beamable-sdk/api');\r\n cachedBeamApiModule =\r\n imported && typeof imported === 'object' && 'default' in imported\r\n ? (imported.default as Record<string, unknown>)\r\n : (imported as Record<string, unknown>);\r\n }\r\n return cachedBeamApiModule;\r\n}\r\n\r\nasync function bindBeamApi(requester: HttpRequester): Promise<BoundBeamApi> {\r\n const module = await resolveBeamApiModule();\r\n const bound: Record<string, (...args: unknown[]) => unknown> = {};\r\n for (const key of Object.keys(module)) {\r\n const value = module[key];\r\n if (typeof value === 'function') {\r\n bound[key] = (...args: unknown[]) => (value as (r: HttpRequester, ...params: unknown[]) => unknown)(requester, ...args);\r\n }\r\n }\r\n return bound;\r\n}\r\n\r\nfunction createFailingApi(error: Error): BoundBeamApi {\r\n return new Proxy(\r\n {},\r\n {\r\n get() {\r\n throw error;\r\n },\r\n },\r\n ) as BoundBeamApi;\r\n}\r\n\r\ntype ServiceMap = {\r\n account: AccountService;\r\n announcements: AnnouncementsService;\r\n auth: AuthService;\r\n content: ContentService;\r\n leaderboards: LeaderboardsService;\r\n stats: StatsService;\r\n};\r\n\r\ntype ServiceKey = keyof ServiceMap;\r\n\r\nclass UnavailableRequester implements HttpRequester {\r\n constructor(private readonly error: Error) {}\r\n\r\n async request(): Promise<never> {\r\n throw this.error;\r\n }\r\n\r\n set baseUrl(_: string) {\r\n // no-op\r\n }\r\n\r\n set defaultHeaders(_: Record<string, string>) {\r\n // no-op\r\n }\r\n}\r\n\r\nclass UnavailableBeamableServices implements BeamableMicroserviceServices {\r\n private readonly requesterImpl: HttpRequester;\r\n private readonly apiBindings: BoundBeamApi;\r\n\r\n constructor(private readonly error: Error) {\r\n this.requesterImpl = new UnavailableRequester(this.error);\r\n this.apiBindings = createFailingApi(this.error);\r\n }\r\n\r\n private fail(): never {\r\n throw this.error;\r\n }\r\n\r\n get account(): AccountService {\r\n return this.fail();\r\n }\r\n\r\n get announcements(): AnnouncementsService {\r\n return this.fail();\r\n }\r\n\r\n get auth(): AuthService {\r\n return this.fail();\r\n }\r\n\r\n get content(): ContentService {\r\n return this.fail();\r\n }\r\n\r\n get leaderboards(): LeaderboardsService {\r\n return this.fail();\r\n }\r\n\r\n get stats(): StatsService {\r\n return this.fail();\r\n }\r\n\r\n get inventory(): InventoryService {\r\n return this.fail();\r\n }\r\n\r\n get storage(): StorageService {\r\n return this.fail();\r\n }\r\n\r\n get federation(): FederationRegistry {\r\n return this.fail();\r\n }\r\n\r\n get api(): BoundBeamApi {\r\n return this.apiBindings;\r\n }\r\n\r\n get requester(): HttpRequester {\r\n return this.requesterImpl;\r\n }\r\n\r\n hasScopes(..._scopes: string[]): boolean {\r\n return false;\r\n }\r\n\r\n requireScopes(...scopes: string[]): void {\r\n throw new MissingScopesError(scopes);\r\n }\r\n\r\n assumeUser(): BeamableMicroserviceServices {\r\n return this;\r\n }\r\n\r\n getLogger(): Logger {\r\n // For unavailable services, return a basic logger that logs to stdout\r\n // This allows logging even when services are unavailable\r\n return pino({ name: 'beamable-unavailable', level: 'info' }, process.stdout);\r\n }\r\n}\r\n\r\nclass BeamableServicesFacade implements BeamableMicroserviceServices {\r\n private readonly cache: Partial<Record<ServiceKey, ServiceMap[ServiceKey]>> = {};\r\n private readonly apiBindings: BoundBeamApi;\r\n private readonly storageService: StorageService;\r\n private readonly scopes: Set<string>;\r\n private readonly logger: Logger;\r\n private readonly serviceName?: string;\r\n private readonly federationRegistry?: FederationRegistry;\r\n private inventoryClient?: InventoryService;\r\n\r\n constructor(\r\n private readonly manager: BeamableServiceManager,\r\n private readonly beamServer: BeamServer,\r\n private readonly userId: string,\r\n scopes: Set<string>,\r\n serviceName?: string,\r\n ) {\r\n this.apiBindings = this.manager.getBoundApi();\r\n this.storageService = this.manager.getStorageService();\r\n this.scopes = scopes;\r\n this.serviceName = serviceName;\r\n this.federationRegistry = serviceName ? this.manager.getFederationRegistry(serviceName) : undefined;\r\n this.logger = this.manager.getLogger().child({ component: 'BeamableServicesFacade', service: serviceName });\r\n }\r\n\r\n private getOrCreate<K extends ServiceKey>(key: K, factory: () => ServiceMap[K]): ServiceMap[K] {\r\n if (!this.cache[key]) {\r\n this.cache[key] = factory();\r\n }\r\n return this.cache[key] as ServiceMap[K];\r\n }\r\n\r\n get account(): AccountService {\r\n return this.getOrCreate('account', () => this.beamServer.account(this.userId));\r\n }\r\n\r\n get announcements(): AnnouncementsService {\r\n return this.getOrCreate('announcements', () => this.beamServer.announcements(this.userId));\r\n }\r\n\r\n get auth(): AuthService {\r\n return this.getOrCreate('auth', () => this.beamServer.auth(this.userId));\r\n }\r\n\r\n get content(): ContentService {\r\n return this.getOrCreate('content', () => this.beamServer.content(this.userId));\r\n }\r\n\r\n get leaderboards(): LeaderboardsService {\r\n return this.getOrCreate('leaderboards', () => this.beamServer.leaderboards(this.userId));\r\n }\r\n\r\n get stats(): StatsService {\r\n return this.getOrCreate('stats', () => this.beamServer.stats(this.userId));\r\n }\r\n\r\n get inventory(): InventoryService {\r\n if (!this.inventoryClient) {\r\n this.inventoryClient = createInventoryService(\r\n this.apiBindings,\r\n this.logger.child({ component: 'InventoryClient' }),\r\n this.userId,\r\n (requiredScopes) => this.hasScopes(...requiredScopes),\r\n );\r\n }\r\n return this.inventoryClient;\r\n }\r\n\r\n get storage(): StorageService {\r\n return this.storageService;\r\n }\r\n\r\n get federation(): FederationRegistry {\r\n if (!this.federationRegistry) {\r\n throw new Error(\r\n this.serviceName\r\n ? `Federation registry is not configured for service \"${this.serviceName}\".`\r\n : 'Federation registry is not configured.',\r\n );\r\n }\r\n return this.federationRegistry;\r\n }\r\n\r\n get api(): BoundBeamApi {\r\n return this.apiBindings;\r\n }\r\n\r\n get requester(): HttpRequester {\r\n return this.manager.getRequester();\r\n }\r\n\r\n hasScopes(...requiredScopes: string[]): boolean {\r\n if (requiredScopes.length === 0) {\r\n return true;\r\n }\r\n return requiredScopes.every((scope) => this.scopeSetHas(scope));\r\n }\r\n\r\n requireScopes(...requiredScopes: string[]): void {\r\n if (!this.hasScopes(...requiredScopes)) {\r\n throw new MissingScopesError(requiredScopes);\r\n }\r\n }\r\n\r\n assumeUser(userId: string | number): BeamableMicroserviceServices {\r\n return this.manager.createFacade(String(userId), new Set(this.scopes), this.serviceName);\r\n }\r\n\r\n getLogger(): Logger {\r\n return this.logger;\r\n }\r\n\r\n private scopeSetHas(scope: string): boolean {\r\n const normalized = scope.trim().toLowerCase();\r\n if (!normalized) {\r\n return false;\r\n }\r\n return this.scopes.has('*') || this.scopes.has(normalized);\r\n }\r\n}\r\n\r\nexport interface BeamableMicroserviceServices {\r\n readonly account: AccountService;\r\n readonly announcements: AnnouncementsService;\r\n readonly auth: AuthService;\r\n readonly content: ContentService;\r\n readonly leaderboards: LeaderboardsService;\r\n readonly stats: StatsService;\r\n readonly inventory: InventoryService;\r\n readonly storage: StorageService;\r\n readonly federation: FederationRegistry;\r\n readonly api: BoundBeamApi;\r\n readonly requester: HttpRequester;\r\n hasScopes(...scopes: string[]): boolean;\r\n requireScopes(...scopes: string[]): void;\r\n assumeUser(userId: string | number): BeamableMicroserviceServices;\r\n getLogger(): Logger;\r\n}\r\n\r\nexport class BeamableServiceManager {\r\n private readonly logger: Logger;\r\n private readonly tokenStorage: ReturnType<typeof defaultTokenStorage>;\r\n private readonly env: EnvironmentConfig;\r\n private beamServer?: BeamServer;\r\n private boundApi?: BoundBeamApi;\r\n private storageService?: StorageService;\r\n private initialized = false;\r\n private readonly federationRegistries = new Map<string, FederationRegistry>();\r\n\r\n constructor(env: EnvironmentConfig, logger: Logger) {\r\n this.env = env;\r\n this.logger = logger.child({ component: 'BeamableServiceManager' });\r\n this.tokenStorage = defaultTokenStorage({ pid: env.pid, tag: env.routingKey ?? RUNTIME_ENVIRONMENT_NAME });\r\n }\r\n\r\n async initialize(): Promise<void> {\r\n if (this.initialized) {\r\n return;\r\n }\r\n\r\n this.registerEnvironment();\r\n this.configureSharedEnvironment();\r\n\r\n if (this.env.refreshToken) {\r\n await this.tokenStorage.setTokenData({ refreshToken: this.env.refreshToken });\r\n }\r\n\r\n const useSignedRequest = Boolean(this.env.secret);\r\n if (!useSignedRequest && !this.env.refreshToken) {\r\n this.logger.warn(\r\n 'Beamable realm secret and refresh token are both missing; Beamable SDK requests may fail due to missing credentials.',\r\n );\r\n }\r\n\r\n try {\r\n this.beamServer = await BeamServer.init({\r\n cid: this.env.cid,\r\n pid: this.env.pid,\r\n environment: RUNTIME_ENVIRONMENT_NAME,\r\n useSignedRequest,\r\n tokenStorage: this.tokenStorage,\r\n serverEvents: { enabled: false },\r\n });\r\n } catch (error) {\r\n this.logger.error({ err: error }, 'Failed to initialize Beamable SDK. Services layer will be unavailable.');\r\n this.beamServer = undefined;\r\n this.initialized = false;\r\n return;\r\n }\r\n\r\n this.boundApi = await bindBeamApi(this.beamServer.requester);\r\n \r\n // Configure the requester's default headers to include the routing key in the correct format\r\n // The routing key format is: serviceName:routingKey\r\n // We'll set this per-request in createFacade since we need the service name\r\n this.storageService = new StorageService({\r\n requester: this.beamServer.requester,\r\n api: this.boundApi,\r\n env: this.env,\r\n logger: this.logger.child({ component: 'StorageService' }),\r\n });\r\n\r\n this.registerDefaultServices();\r\n this.initialized = true;\r\n this.logger.debug('Beamable SDK services initialized.');\r\n }\r\n\r\n createFacade(userId: string | number, scopes: Set<string>, serviceName?: string): BeamableMicroserviceServices {\r\n if (!this.initialized || !this.beamServer || !this.boundApi || !this.storageService) {\r\n return new UnavailableBeamableServices(new Error('Beamable services are not initialized.'));\r\n }\r\n \r\n // Set the routing key in the format serviceName:routingKey for the SDK\r\n // The SDK uses BEAM_ROUTING_KEY environment variable to construct the X-BEAM-SERVICE-ROUTING-KEY header\r\n // We need to set it to the full format: serviceName:routingKey\r\n if (serviceName && this.beamServer.requester) {\r\n const fullRoutingKey = `micro_${serviceName}:${this.env.routingKey}`;\r\n BeamServer.env.BEAM_ROUTING_KEY = fullRoutingKey;\r\n \r\n // Set default headers on the requester for all SDK requests\r\n // These headers are required for signature validation and routing\r\n const scopeHeader = `${this.env.cid}.${this.env.pid}`;\r\n this.beamServer.requester.defaultHeaders = {\r\n ...this.beamServer.requester.defaultHeaders,\r\n 'X-BEAM-SCOPE': scopeHeader,\r\n 'X-BEAM-SERVICE-ROUTING-KEY': fullRoutingKey,\r\n };\r\n }\r\n \r\n return new BeamableServicesFacade(this, this.beamServer, String(userId), new Set(scopes), serviceName);\r\n }\r\n\r\n getRequester(): HttpRequester {\r\n if (!this.initialized || !this.beamServer) {\r\n return new UnavailableRequester(new Error('Beamable services are not initialized.'));\r\n }\r\n return this.beamServer.requester;\r\n }\r\n\r\n getBoundApi(): BoundBeamApi {\r\n if (!this.boundApi) {\r\n throw new Error('Beamable bound API is not available.');\r\n }\r\n return this.boundApi;\r\n }\r\n\r\n getStorageService(): StorageService {\r\n if (!this.storageService) {\r\n throw new Error('Storage service is not initialized.');\r\n }\r\n return this.storageService;\r\n }\r\n\r\n getLogger(): Logger {\r\n return this.logger;\r\n }\r\n\r\n registerFederationRegistry(serviceName: string, registry: FederationRegistry): void {\r\n this.federationRegistries.set(serviceName, registry);\r\n }\r\n\r\n getFederationRegistry(serviceName: string): FederationRegistry | undefined {\r\n return this.federationRegistries.get(serviceName);\r\n }\r\n\r\n private registerEnvironment(): void {\r\n const apiUrl = hostToHttpUrl(this.env.host);\r\n const portalUrl = hostToPortalUrl(apiUrl);\r\n const storageUrl = hostToStorageUrl(apiUrl);\r\n const registryUrl = hostToMicroserviceRegistryUrl(apiUrl);\r\n\r\n try {\r\n BeamEnvironment.register(RUNTIME_ENVIRONMENT_NAME, {\r\n apiUrl,\r\n portalUrl,\r\n beamMongoExpressUrl: storageUrl,\r\n dockerRegistryUrl: `${registryUrl}/v2/`,\r\n });\r\n } catch (error) {\r\n this.logger.debug({ err: error }, 'Beamable environment was already registered. Reusing existing configuration.');\r\n }\r\n }\r\n\r\n private configureSharedEnvironment(): void {\r\n if (this.env.secret) {\r\n BeamServer.env.BEAM_REALM_SECRET = this.env.secret;\r\n }\r\n // BEAM_ROUTING_KEY is used by the SDK to construct the X-BEAM-SERVICE-ROUTING-KEY header\r\n // We set it to just the routing key value here, and will set the full format in createFacade\r\n // BEAM_ROUTING_KEY is used by the SDK to construct the X-BEAM-SERVICE-ROUTING-KEY header\r\n // For deployed services, routingKey is undefined, so we set it to empty string\r\n // The SDK will handle this appropriately\r\n BeamServer.env.BEAM_ROUTING_KEY = this.env.routingKey ?? '';\r\n }\r\n\r\n private registerDefaultServices(): void {\r\n if (!this.beamServer) {\r\n return;\r\n }\r\n this.beamServer.use(AccountService);\r\n this.beamServer.use(AnnouncementsService);\r\n this.beamServer.use(AuthService);\r\n this.beamServer.use(ContentService);\r\n this.beamServer.use(LeaderboardsService);\r\n this.beamServer.use(StatsService);\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omen.foundation/node-microservice-runtime",
3
- "version": "0.1.68",
3
+ "version": "0.1.70",
4
4
  "description": "Beamable microservice runtime for Node.js/TypeScript services.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -888,6 +888,20 @@ COPY app/package*.json ./
888
888
  # Install dependencies (runtime is now on npm, so no special handling needed)
889
889
  RUN npm install --omit=dev && npm cache clean --force
890
890
 
891
+ # Pre-install OpenTelemetry collector binary and config to avoid runtime download delay (~12 seconds)
892
+ # This is stored in /opt/beam/collectors/ which persists and is checked first by the runtime
893
+ RUN mkdir -p /opt/beam/collectors/1.0.1 && \\
894
+ apk add --no-cache wget gzip && \\
895
+ wget https://collectors.beamable.com/version/1.0.1/collector-linux-amd64.gz -O /tmp/collector.gz && \\
896
+ gunzip /tmp/collector.gz && \\
897
+ mv /tmp/collector /opt/beam/collectors/1.0.1/collector-linux-amd64 && \\
898
+ chmod +x /opt/beam/collectors/1.0.1/collector-linux-amd64 && \\
899
+ wget https://collectors.beamable.com/version/1.0.1/clickhouse-config.yaml.gz -O /tmp/config.gz && \\
900
+ gunzip /tmp/config.gz && \\
901
+ mv /tmp/config /opt/beam/collectors/1.0.1/clickhouse-config.yaml && \\
902
+ rm -f /tmp/collector.gz /tmp/config.gz && \\
903
+ apk del wget gzip
904
+
891
905
  COPY app/dist ./dist
892
906
  COPY app/beam_openApi.json ./beam_openApi.json
893
907
 
package/dist/auth.cjs DELETED
@@ -1,97 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AuthManager = void 0;
4
- const node_crypto_1 = require("node:crypto");
5
- const node_url_1 = require("node:url");
6
- const errors_js_1 = require("./errors.js");
7
- class AuthManager {
8
- constructor(env, requester) {
9
- this.env = env;
10
- this.requester = requester;
11
- }
12
- async authenticate() {
13
- if (this.env.secret) {
14
- await this.authenticateWithRealmSecret();
15
- return;
16
- }
17
- if (this.env.refreshToken) {
18
- await this.authenticateWithRefreshToken();
19
- return;
20
- }
21
- throw new errors_js_1.AuthenticationError('Neither SECRET nor REFRESH_TOKEN is configured.');
22
- }
23
- async authenticateWithRealmSecret() {
24
- var _a, _b;
25
- const nonce = await this.requester.request('get', 'gateway/nonce');
26
- if (!(nonce === null || nonce === void 0 ? void 0 : nonce.nonce)) {
27
- throw new errors_js_1.AuthenticationError('Gateway did not provide a nonce for authentication.');
28
- }
29
- const signature = this.calculateRealmSignature((_a = this.env.secret) !== null && _a !== void 0 ? _a : '', nonce.nonce);
30
- const body = {
31
- cid: this.env.cid,
32
- pid: this.env.pid,
33
- signature,
34
- };
35
- const response = await this.requester.request('post', 'gateway/auth', body);
36
- if (!response || response.result !== 'ok') {
37
- throw new errors_js_1.AuthenticationError(`Realm secret authentication failed with result=${(_b = response === null || response === void 0 ? void 0 : response.result) !== null && _b !== void 0 ? _b : 'unknown'}.`);
38
- }
39
- }
40
- async authenticateWithRefreshToken() {
41
- var _a;
42
- const accessToken = await this.exchangeRefreshToken();
43
- const body = {
44
- cid: this.env.cid,
45
- pid: this.env.pid,
46
- token: accessToken,
47
- };
48
- const response = await this.requester.request('post', 'gateway/auth', body);
49
- if (!response || response.result !== 'ok') {
50
- throw new errors_js_1.AuthenticationError(`Refresh-token authentication failed with result=${(_a = response === null || response === void 0 ? void 0 : response.result) !== null && _a !== void 0 ? _a : 'unknown'}.`);
51
- }
52
- }
53
- calculateRealmSignature(secret, nonce) {
54
- const hash = (0, node_crypto_1.createHash)('md5');
55
- hash.update(secret + nonce, 'utf8');
56
- return hash.digest('base64');
57
- }
58
- async exchangeRefreshToken() {
59
- var _a;
60
- if (!this.env.refreshToken) {
61
- throw new errors_js_1.AuthenticationError('REFRESH_TOKEN missing.');
62
- }
63
- const baseUrl = this.hostToHttpUrl();
64
- const tokenUrl = new node_url_1.URL('/basic/auth/token', baseUrl).toString();
65
- const response = await fetch(tokenUrl, {
66
- method: 'POST',
67
- headers: {
68
- 'Content-Type': 'application/json',
69
- Accept: 'application/json',
70
- 'beam-scope': `${this.env.cid}.${this.env.pid}`,
71
- },
72
- body: JSON.stringify({
73
- grant_type: 'refresh_token',
74
- refresh_token: this.env.refreshToken,
75
- }),
76
- });
77
- if (!response.ok) {
78
- throw new errors_js_1.AuthenticationError(`Failed to retrieve access token. status=${response.status}`);
79
- }
80
- const payload = (await response.json());
81
- if (!payload.access_token) {
82
- throw new errors_js_1.AuthenticationError(`Refresh-token exchange failed: ${(_a = payload.error) !== null && _a !== void 0 ? _a : 'unknown error'}`);
83
- }
84
- return payload.access_token;
85
- }
86
- hostToHttpUrl() {
87
- const host = this.env.host.replace(/\/socket$/, '');
88
- if (host.startsWith('wss://')) {
89
- return `https://${host.substring('wss://'.length)}`;
90
- }
91
- if (host.startsWith('ws://')) {
92
- return `http://${host.substring('ws://'.length)}`;
93
- }
94
- return host;
95
- }
96
- }
97
- exports.AuthManager = AuthManager;