UNPKG

@calljmp/service

Version:
131 lines (130 loc) 4.08 kB
import { Platform, } from './types'; const CLOUD_SERVICE_ARGS_HEADER = 'X-Calljmp-Args'; class CloudServiceArgs { constructor(data) { this.platform = data.platform || Platform.Unknown; this.serviceId = data.serviceId; this.userId = data.userId; } static from(args) { let value = null; if ('req' in args && 'header' in args.req && typeof args.req.header === 'function') { // Hono Context value = args.req.header(CLOUD_SERVICE_ARGS_HEADER); } else if ('header' in args && typeof args.header === 'function') { // Hono Request value = args.header(CLOUD_SERVICE_ARGS_HEADER); } else if (args instanceof Request) { value = args.headers.get(CLOUD_SERVICE_ARGS_HEADER); } else if (args && typeof args === 'object') { value = args[CLOUD_SERVICE_ARGS_HEADER]; } else if (typeof args === 'string') { value = args; } if (!value) { throw new Error(`Unable to resolve arguments from ${args}`); } const json = JSON.parse(value); return new CloudServiceArgs(json); } static tryFrom(args) { try { const data = CloudServiceArgs.from(args); return { args: data, error: null, }; } catch (error) { return { args: null, error: error, }; } } } export class CloudService { _sanitizeName(name) { // Handle UPPER_CASE: convert to camelCase if (name.includes('_')) { return name .toLowerCase() .split('_') .map((word, index) => index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1)) .join(''); } // Handle camelCase or PascalCase: ensure first letter is lowercase return name.charAt(0).toLowerCase() + name.slice(1); } _extractEnvByPrefix(prefix) { if (!this._env) { throw new Error('Environment not set'); } const result = {}; for (const [key, value] of Object.entries(this._env)) { if (key.startsWith(prefix)) { const sanitizedKey = this._sanitizeName(key.replace(prefix, '')); result[sanitizedKey] = value; } } return result; } get context() { if (!this._context) { throw new Error('Context is only available after fetch'); } return this._context; } get database() { if (!this._env) { throw new Error('Environment not set'); } return this._env.DATABASE; } get buckets() { if (this._buckets) { return this._buckets; } this._buckets = this._extractEnvByPrefix('BUCKET_'); return this._buckets; } get secrets() { if (this._secrets) { return this._secrets; } this._secrets = this._extractEnvByPrefix('SECRET_'); return this._secrets; } get variables() { if (this._variables) { return this._variables; } this._variables = this._extractEnvByPrefix('VARIABLE_'); return this._variables; } async fetch(request, env, executionCtx) { this._env = env; this._buckets = undefined; this._secrets = undefined; this._variables = undefined; this._context = { platform: Platform.Unknown, serviceId: null, userId: undefined, development: env?.DEVELOPMENT === true, }; const { args } = CloudServiceArgs.tryFrom(request); if (args) { this._context.platform = args.platform; this._context.serviceId = args.serviceId; this._context.userId = args.userId; } return this.onRequest(request, env, executionCtx); } }