@calljmp/service
Version:
Calljmp cloud service
131 lines (130 loc) • 4.08 kB
JavaScript
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);
}
}