arvo-core
Version:
This core package contains all the core classes and components of the Arvo Event Driven System
216 lines (215 loc) • 7.87 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createArvoError = exports.EventDataschemaUtil = exports.createTimestamp = exports.validateURI = void 0;
exports.cleanString = cleanString;
exports.parseSemanticVersion = parseSemanticVersion;
exports.compareSemanticVersions = compareSemanticVersions;
var WildCardArvoSemanticVersion_1 = require("./ArvoContract/WildCardArvoSemanticVersion");
var OpenTelemetry_1 = require("./OpenTelemetry");
var schema_1 = require("./schema");
/**
* Cleans a string by removing leading/trailing whitespace from each line,
* removing empty lines, and joining the remaining lines with newline characters.
*
* @param s - The input string to be cleaned.
* @returns A new string with cleaned content.
*
* @example
* const input = " Hello \n World \n\n ";
* const cleaned = cleanString(input);
* console.log(cleaned); // Output: "Hello\nWorld"
*/
function cleanString(s) {
return s
.split('\n')
.map(function (item) { return item.trim(); })
.filter(function (item) { return Boolean(item); })
.join('\n');
}
/**
* Validates if a given string is a properly encoded URI.
*
* This function checks if the input string remains unchanged after being
* decoded and then re-encoded, which indicates that it's a valid URI.
*
* @param value - The string to be validated as a URI.
* @returns A boolean indicating whether the input is a valid URI (true) or not (false).
*
* @example
* validateURI("https://example.com"); // Returns true
* validateURI("https://example.com/path with spaces"); // Returns false
* validateURI("https://example.com/path%20with%20spaces"); // Returns true
*/
var validateURI = function (value) {
try {
return value === encodeURI(decodeURI(value));
}
catch (_a) {
return false;
}
};
exports.validateURI = validateURI;
/**
* Creates an RFC 3339 compliant timestamp string with an optional UTC offset.
*
* @param offsetHours - The number of hours to offset from UTC. Positive values
* represent hours ahead of UTC, negative values represent
* hours behind UTC. Defaults to 0 (UTC).
* @returns A string representing the current date and time in RFC 3339 format
* with the specified UTC offset.
*
* @example
* // Returns current time in UTC
* createTimestamp();
*
* @example
* // Returns current time with +2 hours offset
* createTimestamp(2);
*
* @example
* // Returns current time with -5 hours offset
* createTimestamp(-5);
*/
var createTimestamp = function (offsetHours) {
if (offsetHours === void 0) { offsetHours = 0; }
var now = new Date();
var offsetMinutes = offsetHours * 60;
now.setMinutes(now.getMinutes() - now.getTimezoneOffset() + offsetMinutes);
return now
.toISOString()
.replace('Z', offsetHours >= 0
? "+".concat(String(offsetHours).padStart(2, '0'), ":00")
: "-".concat(String(Math.abs(offsetHours)).padStart(2, '0'), ":00"));
};
exports.createTimestamp = createTimestamp;
function parseSemanticVersion(version) {
var _a = version.split('.').map(function (part) {
var num = Number.parseInt(part, 10);
if (Number.isNaN(num)) {
throw new Error("Invalid version number in ".concat(version));
}
return num;
}), major = _a[0], minor = _a[1], patch = _a[2];
if (major === undefined || minor === undefined || patch === undefined) {
throw new Error("Invalid semantic version format: ".concat(version));
}
return { major: major, minor: minor, patch: patch };
}
/**
* Compares two semantic versions according to semver rules
* Returns:
* - Positive number if version1 > version2
* - Negative number if version1 < version2
* - 0 if version1 === version2
*/
function compareSemanticVersions(version1, version2) {
var v1 = parseSemanticVersion(version1);
var v2 = parseSemanticVersion(version2);
if (v1.major !== v2.major) {
return v1.major - v2.major;
}
if (v1.minor !== v2.minor) {
return v1.minor - v2.minor;
}
return v1.patch - v2.patch;
}
/**
* Manages event dataschema strings for versioned contracts.
* Handles creation and parsing of dataschema identifiers.
*/
// biome-ignore lint/complexity/noStaticOnlyClass: This needs to be a static class to group methods together
var EventDataschemaUtil = /** @class */ (function () {
function EventDataschemaUtil() {
}
EventDataschemaUtil.build = function (uri, version) {
return "".concat(uri, "/").concat(version);
};
/**
* Creates a dataschema string from a versioned contract.
* Format: `{contract.uri}/{contract.version}`
*
* @param contract - Versioned contract instance
* @returns Formatted dataschema string
*
* @example
* ```typescript
* const schema = EventDataschema.create(versionedContract);
* // Returns: "my-contract/1.0.0"
* ```
*/
EventDataschemaUtil.create = function (contract) {
return EventDataschemaUtil.build(contract.uri, contract.version);
};
/**
* Creates dataschema string with wildcard version.
* @param contract Versioned contract
* @returns `{contract.uri}/{WildCardArvoSemanticVersion}`
*/
EventDataschemaUtil.createWithWildCardVersion = function (contract) {
return EventDataschemaUtil.build(contract.uri, WildCardArvoSemanticVersion_1.WildCardArvoSemanticVersion);
};
/**
* Extracts URI and version from dataschema string.
*
* @param data - Event object or dataschema string
* @returns Parsed URI and version, or null if invalid
*
* @example
* ```typescript
* const result = EventDataschema.parse("my-contract/1.0.0");
* // Returns: { uri: "my-contract", version: "1.0.0" }
*
* const invalid = EventDataschema.parse("invalid-schema");
* // Returns: null
* ```
*/
EventDataschemaUtil.parse = function (data) {
var _a;
try {
var dataschema = typeof data === 'string' ? data : ((_a = data.dataschema) !== null && _a !== void 0 ? _a : '');
var items = dataschema.split('/');
var version = schema_1.ArvoSemanticVersionSchema.parse(items.pop());
var uri = items.join('/');
return { uri: uri, version: version };
}
catch (e) {
(0, OpenTelemetry_1.logToSpan)({
level: 'ERROR',
message: "Unable to parse the event dataschema: ".concat(e.message),
});
return null;
}
};
/**
* Validates if a given ArvoEvent or dataschema string represents a valid dataschema.
* A valid dataschema must:
* - Follow the format {uri}/{version}
* - Have a valid semantic version component
* - Contain a non-empty URI
*
* @param data - ArvoEvent object or dataschema string to validate
* @returns boolean - True if dataschema is valid, false otherwise
*/
EventDataschemaUtil.isValid = function (data) {
return Boolean(EventDataschemaUtil.parse(data));
};
return EventDataschemaUtil;
}());
exports.EventDataschemaUtil = EventDataschemaUtil;
/**
* Creates a standardized ArvoError payload from an Error object. This utility
* ensures consistent error reporting across the event system by extracting and
* structuring key error information.
*
* @param error - The source Error object to convert
* @returns ArvoErrorType - The standardized error payload
*/
var createArvoError = function (error) {
var _a;
return ({
errorName: error.name,
errorMessage: error.message,
errorStack: (_a = error.stack) !== null && _a !== void 0 ? _a : null,
});
};
exports.createArvoError = createArvoError;