@lightbend/akkaserverless-javascript-sdk
Version:
Akka Serverless JavaScript SDK
279 lines • 8.77 kB
JavaScript
"use strict";
/*
* Copyright 2021 Lightbend Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Metadata = void 0;
const cloudevent_1 = require("./cloudevent");
const jwt_claims_1 = require("./jwt-claims");
class MetadataMapProxyHandler {
constructor(metadata) {
this.metadata = metadata;
}
ownKeys(target) {
const keys = new Array();
for (const entry of this.metadata.entries) {
keys.push(entry.key);
}
return keys;
}
deleteProperty(target, key) {
if (typeof key === 'string') {
const hasKey = this.metadata.has(key);
if (hasKey) {
this.metadata.delete(key);
}
return hasKey;
}
return false;
}
get(target, key, receiver) {
if (typeof key === 'string') {
const lowercaseKey = key.toLowerCase();
for (const entry of this.metadata.entries) {
if (lowercaseKey === entry.key.toLowerCase()) {
if (entry.stringValue) {
return entry.stringValue;
}
if (entry.bytesValue) {
return entry.bytesValue;
}
}
}
}
return undefined;
}
has(target, key) {
if (typeof key === 'string') {
const lowercaseKey = key.toLowerCase();
for (const entry of this.metadata.entries) {
if (lowercaseKey === entry.key.toLowerCase()) {
return true;
}
}
}
return false;
}
set(target, key, value, receiver) {
if (typeof key === 'string') {
this.metadata.delete(key);
this.metadata.set(key, value);
return true;
}
return false;
}
getOwnPropertyDescriptor(target, key) {
const superThis = this;
if (typeof key === 'string') {
const v = this.get(target, key, null);
if (v !== undefined) {
return new (class {
constructor() {
this.value = v;
this.writable = true;
this.enumerable = true;
this.configurable = false;
}
get() {
return v;
}
set(v) {
superThis.set(target, key, v, null);
}
})();
}
}
return undefined;
}
}
/**
* Akka Serverless metadata.
*
* Metadata is treated as case insensitive on lookup, and case sensitive on set. Multiple values per key are supported,
* setting a value will add it to the current values for that key. You should delete first if you wish to replace a
* value.
*
* Values can either be strings or byte buffers. If a non string or byte buffer value is set, it will be converted to
* a string using toString.
*
* @param entries - the list of entries
*/
class Metadata {
constructor(entries = []) {
/**
* The metadata expressed as an object/map.
*
* The map is backed by the this Metadata object - changes to this map will be reflected in this metadata object and
* changes to this object will be reflected in the map.
*
* The map will return the first metadata entry that matches the key, case insensitive, when properties are looked up.
* When setting properties, it will replace all entries that match the key, case insensitive.
*/
this.asMap = new Proxy(new (class {
})(), new MetadataMapProxyHandler(this));
/**
* The Cloudevent data from this Metadata.
*
* This object is backed by this Metadata, changes to the Cloudevent will be reflected in the Metadata.
*/
this.cloudevent = new cloudevent_1.Cloudevent(this);
/**
* The JWT claims, if there was a validated bearer token with this request.
*/
this.jwtClaims = new jwt_claims_1.JwtClaims(this);
this.entries = entries;
}
/**
* If this metadata object is being returned as the metadata for an HTTP transcoded response, this will set the
* HTTP status code for the response.
*
* This will have no impact on gRPC responses.
*
* @param code The status code to set.
*/
setHttpStatusCode(code) {
if (code < 100 || code >= 600) {
throw new Error('Invalid HTTP status code: ' + code);
}
this.set('_akkasls-http-code', code.toString());
}
/**
* @returns CloudEvent subject value
* @deprecated Use cloudevent.subject instead.
*/
getSubject() {
const subject = this.get('ce-subject');
if (subject.length > 0) {
return subject[0];
}
else {
return undefined;
}
}
/**
* Create a new MetadataEntry.
*
* @param key - the key for the entry
* @param value - the value for the entry
* @returns a new MetadataEntry
*/
createMetadataEntry(key, value) {
if (typeof value === 'string') {
return { key: key, stringValue: value, bytesValue: undefined };
}
else if (Buffer.isBuffer(value)) {
return { key: key, bytesValue: value, stringValue: undefined };
}
else {
return { key: key, stringValue: value.toString(), bytesValue: undefined };
}
}
/**
* Get the value from a metadata entry.
*
* @param entry - the metadata entry
* @returns the value for the given entry
*/
getValue(entry) {
if (entry.bytesValue !== undefined) {
return entry.bytesValue;
}
else {
return entry.stringValue;
}
}
/**
* Get all the values for the given key.
*
* The key is case insensitive.
*
* @param key - the key to get
* @returns all the values, or an empty array if no values exist for the key
*/
get(key) {
const values = [];
this.entries.forEach((entry) => {
if (key.toLowerCase() === entry.key.toLowerCase()) {
const value = this.getValue(entry);
if (value) {
values.push(value);
}
}
});
return values;
}
/**
* Set a given key value.
*
* This will append the key value to the metadata, it won't replace any existing values for existing keys.
*
* @param key - the key to set
* @param value - the value to set
* @returns this updated metadata
*/
set(key, value) {
this.entries.push(this.createMetadataEntry(key, value));
return this;
}
/**
* Delete all values with the given key.
*
* The key is case insensitive.
*
* @param key - the key to delete
* @returns this updated metadata
*/
delete(key) {
let idx = 0;
while (idx < this.entries.length) {
const entry = this.entries[idx];
if (key.toLowerCase() !== entry.key.toLowerCase()) {
idx++;
}
else {
this.entries.splice(idx, 1);
}
}
return this;
}
/**
* Whether there exists a metadata value for the given key.
*
* The key is case insensitive.
*
* @param key - the key to check
* @returns whether values exist for the given key
*/
has(key) {
for (const idx in this.entries) {
const entry = this.entries[idx];
if (key.toLowerCase() === entry.key.toLowerCase()) {
return true;
}
}
return false;
}
/**
* Clear the metadata.
*
* @returns this updated metadata
*/
clear() {
this.entries.splice(0, this.entries.length);
return this;
}
}
exports.Metadata = Metadata;
//# sourceMappingURL=metadata.js.map