@dbx-tools/shared-core 0.3.43 → 0.4.0

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.
@@ -0,0 +1,126 @@
1
+ /**
2
+ * JWT access-token helpers for Databricks Apps.
3
+ *
4
+ * Parses bearer tokens and `x-forwarded-access-token` payloads to read
5
+ * OAuth scopes and other claims from incoming HTTP requests.
6
+ *
7
+ * @module
8
+ */
9
+ import { forEachHeaderValue } from "./http.js";
10
+ import * as json from "./json.js";
11
+ import { isLevelEnabled, logger } from "./log.js";
12
+ const BEARER_PREFIX_REGEX = /^bearer\s+/i;
13
+ const SPLIT_REGEX = /\s+|\s*,\s*/;
14
+ const log = logger("shared/token");
15
+ /**
16
+ * Decode a JWT segment (base64url with standard base64 padding), or
17
+ * `undefined` when the segment is not valid base64.
18
+ */
19
+ function decodeJwtSegment(segment) {
20
+ const normalized = segment.replace(/-/g, "+").replace(/_/g, "/");
21
+ const padded = normalized + "=".repeat((4 - (normalized.length % 4)) % 4);
22
+ try {
23
+ const binary = atob(padded);
24
+ const bytes = Uint8Array.from(binary, (ch) => ch.charCodeAt(0));
25
+ return new TextDecoder().decode(bytes);
26
+ }
27
+ catch {
28
+ return undefined;
29
+ }
30
+ }
31
+ /**
32
+ * Decode the JWT payload from a bearer token string or request headers.
33
+ *
34
+ * When `input` is header-like, walks every value for `headerName` (default
35
+ * `x-forwarded-access-token`) and merges claim keys left-to-right.
36
+ */
37
+ export function getAccessTokenPayload(input, headerName = "x-forwarded-access-token") {
38
+ let accessTokenPayload;
39
+ if (!(typeof input === "string")) {
40
+ if (headerName) {
41
+ forEachHeaderValue(input, headerName, (value) => {
42
+ for (const [payloadKey, payloadValue] of Object.entries(getAccessTokenPayload(value))) {
43
+ if (!accessTokenPayload || !(payloadKey in accessTokenPayload)) {
44
+ if (!accessTokenPayload)
45
+ accessTokenPayload = {};
46
+ accessTokenPayload[payloadKey] = payloadValue;
47
+ }
48
+ }
49
+ });
50
+ }
51
+ }
52
+ else {
53
+ input = input.trim();
54
+ if (input) {
55
+ const match = BEARER_PREFIX_REGEX.exec(input);
56
+ if (match) {
57
+ const endIndex = match.index + match[0].length;
58
+ input = input.slice(endIndex);
59
+ }
60
+ const parts = input.split(".", 4);
61
+ if (parts.length === 2 || parts.length === 3) {
62
+ // A malformed segment yields undefined; fall through to empty object.
63
+ accessTokenPayload = json.parseRecord(decodeJwtSegment(parts[1]));
64
+ }
65
+ }
66
+ }
67
+ if (!accessTokenPayload)
68
+ accessTokenPayload = {};
69
+ log.debug("getAccessTokenPayload", { accessTokenPayload });
70
+ return accessTokenPayload;
71
+ }
72
+ /**
73
+ * OAuth scopes from the access-token JWT on `input`.
74
+ *
75
+ * Defaults to the `x-forwarded-access-token` header, which Databricks Apps
76
+ * forward from the browser session.
77
+ */
78
+ export function getAccessTokenScopes(input, headerName) {
79
+ const payload = getAccessTokenPayload(input, headerName);
80
+ let accessTokenScopes = iterateClaims(payload.scope);
81
+ if (isLevelEnabled("debug")) {
82
+ accessTokenScopes = Array.from(accessTokenScopes);
83
+ log.debug("getAccessTokenScopes", { accessTokenScopes });
84
+ }
85
+ return accessTokenScopes;
86
+ }
87
+ /**
88
+ * Return true when `scopes` contains any value from `allowed`.
89
+ *
90
+ * Accepts the raw {@link MASTRA_SCOPES_KEY} array stamped on
91
+ * `RequestContext` as well as iterables from {@link getAccessTokenScopes}.
92
+ */
93
+ export function includesAccessTokenScope(scopes, allowed) {
94
+ if (allowed.length) {
95
+ for (const scope of iterateClaims(scopes)) {
96
+ if (allowed.includes(scope)) {
97
+ log.debug("includesAccessTokenScope", { scope, allowed });
98
+ return true;
99
+ }
100
+ }
101
+ }
102
+ return false;
103
+ }
104
+ /** Split a JWT `scope` claim string or array into individual scope tokens. */
105
+ function* iterateClaims(input, distinct = true) {
106
+ const seen = distinct ? new Set() : undefined;
107
+ function* visit(value) {
108
+ if (typeof value === "string") {
109
+ for (const claim of value.split(SPLIT_REGEX)) {
110
+ const token = claim.trim();
111
+ if (!token || seen?.has(token)) {
112
+ continue;
113
+ }
114
+ seen?.add(token);
115
+ yield token;
116
+ }
117
+ }
118
+ else if (Array.isArray(value)) {
119
+ for (const item of value) {
120
+ yield* visit(item);
121
+ }
122
+ }
123
+ }
124
+ yield* visit(input);
125
+ }
126
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdG9rZW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7R0FPRztBQUVILE9BQU8sRUFBRSxrQkFBa0IsRUFBbUIsTUFBTSxRQUFRLENBQUM7QUFDN0QsT0FBTyxLQUFLLElBQUksTUFBTSxRQUFRLENBQUM7QUFDL0IsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFFL0MsTUFBTSxtQkFBbUIsR0FBRyxhQUFhLENBQUM7QUFDMUMsTUFBTSxXQUFXLEdBQUcsYUFBYSxDQUFDO0FBQ2xDLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUVuQzs7O0dBR0c7QUFDSCxTQUFTLGdCQUFnQixDQUFDLE9BQWU7SUFDdkMsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNqRSxNQUFNLE1BQU0sR0FBRyxVQUFVLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUMxRSxJQUFJLENBQUM7UUFDSCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDNUIsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoRSxPQUFPLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLHFCQUFxQixDQUNuQyxLQUEwQixFQUMxQixhQUFpQywwQkFBMEI7SUFFM0QsSUFBSSxrQkFBdUQsQ0FBQztJQUM1RCxJQUFJLENBQUMsQ0FBQyxPQUFPLEtBQUssS0FBSyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQ2pDLElBQUksVUFBVSxFQUFFLENBQUM7WUFDZixrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFLENBQUMsS0FBYSxFQUFFLEVBQUU7Z0JBQ3RELEtBQUssTUFBTSxDQUFDLFVBQVUsRUFBRSxZQUFZLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDdEYsSUFBSSxDQUFDLGtCQUFrQixJQUFJLENBQUMsQ0FBQyxVQUFVLElBQUksa0JBQWtCLENBQUMsRUFBRSxDQUFDO3dCQUMvRCxJQUFJLENBQUMsa0JBQWtCOzRCQUFFLGtCQUFrQixHQUFHLEVBQUUsQ0FBQzt3QkFDakQsa0JBQWtCLENBQUMsVUFBVSxDQUFDLEdBQUcsWUFBWSxDQUFDO29CQUNoRCxDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO1NBQU0sQ0FBQztRQUNOLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDckIsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLE1BQU0sS0FBSyxHQUFHLG1CQUFtQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QyxJQUFJLEtBQUssRUFBRSxDQUFDO2dCQUNWLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztnQkFDL0MsS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDaEMsQ0FBQztZQUNELE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2xDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDN0Msc0VBQXNFO2dCQUN0RSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUUsQ0FBQyxDQUFDLENBQUM7WUFDckUsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBQ0QsSUFBSSxDQUFDLGtCQUFrQjtRQUFFLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztJQUNqRCxHQUFHLENBQUMsS0FBSyxDQUFDLHVCQUF1QixFQUFFLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDO0lBQzNELE9BQU8sa0JBQWtCLENBQUM7QUFDNUIsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxLQUEwQixFQUMxQixVQUFtQjtJQUVuQixNQUFNLE9BQU8sR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDekQsSUFBSSxpQkFBaUIsR0FBcUIsYUFBYSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2RSxJQUFJLGNBQWMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQzVCLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUNsRCxHQUFHLENBQUMsS0FBSyxDQUFDLHNCQUFzQixFQUFFLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFDRCxPQUFPLGlCQUFpQixDQUFDO0FBQzNCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSx3QkFBd0IsQ0FBQyxNQUFlLEVBQUUsT0FBMEI7SUFDbEYsSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbkIsS0FBSyxNQUFNLEtBQUssSUFBSSxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUMxQyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDNUIsR0FBRyxDQUFDLEtBQUssQ0FBQywwQkFBMEIsRUFBRSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUMxRCxPQUFPLElBQUksQ0FBQztZQUNkLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVELDhFQUE4RTtBQUM5RSxRQUFRLENBQUMsQ0FBQyxhQUFhLENBQUMsS0FBYyxFQUFFLFFBQVEsR0FBRyxJQUFJO0lBQ3JELE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLEVBQVUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBRXRELFFBQVEsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFjO1FBQzVCLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDOUIsS0FBSyxNQUFNLEtBQUssSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7Z0JBQzdDLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDM0IsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQy9CLFNBQVM7Z0JBQ1gsQ0FBQztnQkFDRCxJQUFJLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNqQixNQUFNLEtBQUssQ0FBQztZQUNkLENBQUM7UUFDSCxDQUFDO2FBQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDaEMsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDekIsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3JCLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN0QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBKV1QgYWNjZXNzLXRva2VuIGhlbHBlcnMgZm9yIERhdGFicmlja3MgQXBwcy5cbiAqXG4gKiBQYXJzZXMgYmVhcmVyIHRva2VucyBhbmQgYHgtZm9yd2FyZGVkLWFjY2Vzcy10b2tlbmAgcGF5bG9hZHMgdG8gcmVhZFxuICogT0F1dGggc2NvcGVzIGFuZCBvdGhlciBjbGFpbXMgZnJvbSBpbmNvbWluZyBIVFRQIHJlcXVlc3RzLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBmb3JFYWNoSGVhZGVyVmFsdWUsIHR5cGUgSGVhZGVyTGlrZSB9IGZyb20gXCIuL2h0dHBcIjtcbmltcG9ydCAqIGFzIGpzb24gZnJvbSBcIi4vanNvblwiO1xuaW1wb3J0IHsgaXNMZXZlbEVuYWJsZWQsIGxvZ2dlciB9IGZyb20gXCIuL2xvZ1wiO1xuXG5jb25zdCBCRUFSRVJfUFJFRklYX1JFR0VYID0gL15iZWFyZXJcXHMrL2k7XG5jb25zdCBTUExJVF9SRUdFWCA9IC9cXHMrfFxccyosXFxzKi87XG5jb25zdCBsb2cgPSBsb2dnZXIoXCJzaGFyZWQvdG9rZW5cIik7XG5cbi8qKlxuICogRGVjb2RlIGEgSldUIHNlZ21lbnQgKGJhc2U2NHVybCB3aXRoIHN0YW5kYXJkIGJhc2U2NCBwYWRkaW5nKSwgb3JcbiAqIGB1bmRlZmluZWRgIHdoZW4gdGhlIHNlZ21lbnQgaXMgbm90IHZhbGlkIGJhc2U2NC5cbiAqL1xuZnVuY3Rpb24gZGVjb2RlSnd0U2VnbWVudChzZWdtZW50OiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBub3JtYWxpemVkID0gc2VnbWVudC5yZXBsYWNlKC8tL2csIFwiK1wiKS5yZXBsYWNlKC9fL2csIFwiL1wiKTtcbiAgY29uc3QgcGFkZGVkID0gbm9ybWFsaXplZCArIFwiPVwiLnJlcGVhdCgoNCAtIChub3JtYWxpemVkLmxlbmd0aCAlIDQpKSAlIDQpO1xuICB0cnkge1xuICAgIGNvbnN0IGJpbmFyeSA9IGF0b2IocGFkZGVkKTtcbiAgICBjb25zdCBieXRlcyA9IFVpbnQ4QXJyYXkuZnJvbShiaW5hcnksIChjaCkgPT4gY2guY2hhckNvZGVBdCgwKSk7XG4gICAgcmV0dXJuIG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShieXRlcyk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBEZWNvZGUgdGhlIEpXVCBwYXlsb2FkIGZyb20gYSBiZWFyZXIgdG9rZW4gc3RyaW5nIG9yIHJlcXVlc3QgaGVhZGVycy5cbiAqXG4gKiBXaGVuIGBpbnB1dGAgaXMgaGVhZGVyLWxpa2UsIHdhbGtzIGV2ZXJ5IHZhbHVlIGZvciBgaGVhZGVyTmFtZWAgKGRlZmF1bHRcbiAqIGB4LWZvcndhcmRlZC1hY2Nlc3MtdG9rZW5gKSBhbmQgbWVyZ2VzIGNsYWltIGtleXMgbGVmdC10by1yaWdodC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFjY2Vzc1Rva2VuUGF5bG9hZChcbiAgaW5wdXQ6IEhlYWRlckxpa2UgfCBzdHJpbmcsXG4gIGhlYWRlck5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZCA9IFwieC1mb3J3YXJkZWQtYWNjZXNzLXRva2VuXCIsXG4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGxldCBhY2Nlc3NUb2tlblBheWxvYWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkO1xuICBpZiAoISh0eXBlb2YgaW5wdXQgPT09IFwic3RyaW5nXCIpKSB7XG4gICAgaWYgKGhlYWRlck5hbWUpIHtcbiAgICAgIGZvckVhY2hIZWFkZXJWYWx1ZShpbnB1dCwgaGVhZGVyTmFtZSwgKHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBbcGF5bG9hZEtleSwgcGF5bG9hZFZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhnZXRBY2Nlc3NUb2tlblBheWxvYWQodmFsdWUpKSkge1xuICAgICAgICAgIGlmICghYWNjZXNzVG9rZW5QYXlsb2FkIHx8ICEocGF5bG9hZEtleSBpbiBhY2Nlc3NUb2tlblBheWxvYWQpKSB7XG4gICAgICAgICAgICBpZiAoIWFjY2Vzc1Rva2VuUGF5bG9hZCkgYWNjZXNzVG9rZW5QYXlsb2FkID0ge307XG4gICAgICAgICAgICBhY2Nlc3NUb2tlblBheWxvYWRbcGF5bG9hZEtleV0gPSBwYXlsb2FkVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaW5wdXQgPSBpbnB1dC50cmltKCk7XG4gICAgaWYgKGlucHV0KSB7XG4gICAgICBjb25zdCBtYXRjaCA9IEJFQVJFUl9QUkVGSVhfUkVHRVguZXhlYyhpbnB1dCk7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgY29uc3QgZW5kSW5kZXggPSBtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aDtcbiAgICAgICAgaW5wdXQgPSBpbnB1dC5zbGljZShlbmRJbmRleCk7XG4gICAgICB9XG4gICAgICBjb25zdCBwYXJ0cyA9IGlucHV0LnNwbGl0KFwiLlwiLCA0KTtcbiAgICAgIGlmIChwYXJ0cy5sZW5ndGggPT09IDIgfHwgcGFydHMubGVuZ3RoID09PSAzKSB7XG4gICAgICAgIC8vIEEgbWFsZm9ybWVkIHNlZ21lbnQgeWllbGRzIHVuZGVmaW5lZDsgZmFsbCB0aHJvdWdoIHRvIGVtcHR5IG9iamVjdC5cbiAgICAgICAgYWNjZXNzVG9rZW5QYXlsb2FkID0ganNvbi5wYXJzZVJlY29yZChkZWNvZGVKd3RTZWdtZW50KHBhcnRzWzFdISkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoIWFjY2Vzc1Rva2VuUGF5bG9hZCkgYWNjZXNzVG9rZW5QYXlsb2FkID0ge307XG4gIGxvZy5kZWJ1ZyhcImdldEFjY2Vzc1Rva2VuUGF5bG9hZFwiLCB7IGFjY2Vzc1Rva2VuUGF5bG9hZCB9KTtcbiAgcmV0dXJuIGFjY2Vzc1Rva2VuUGF5bG9hZDtcbn1cblxuLyoqXG4gKiBPQXV0aCBzY29wZXMgZnJvbSB0aGUgYWNjZXNzLXRva2VuIEpXVCBvbiBgaW5wdXRgLlxuICpcbiAqIERlZmF1bHRzIHRvIHRoZSBgeC1mb3J3YXJkZWQtYWNjZXNzLXRva2VuYCBoZWFkZXIsIHdoaWNoIERhdGFicmlja3MgQXBwc1xuICogZm9yd2FyZCBmcm9tIHRoZSBicm93c2VyIHNlc3Npb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBY2Nlc3NUb2tlblNjb3BlcyhcbiAgaW5wdXQ6IEhlYWRlckxpa2UgfCBzdHJpbmcsXG4gIGhlYWRlck5hbWU/OiBzdHJpbmcsXG4pOiBJdGVyYWJsZTxzdHJpbmc+IHtcbiAgY29uc3QgcGF5bG9hZCA9IGdldEFjY2Vzc1Rva2VuUGF5bG9hZChpbnB1dCwgaGVhZGVyTmFtZSk7XG4gIGxldCBhY2Nlc3NUb2tlblNjb3BlczogSXRlcmFibGU8c3RyaW5nPiA9IGl0ZXJhdGVDbGFpbXMocGF5bG9hZC5zY29wZSk7XG4gIGlmIChpc0xldmVsRW5hYmxlZChcImRlYnVnXCIpKSB7XG4gICAgYWNjZXNzVG9rZW5TY29wZXMgPSBBcnJheS5mcm9tKGFjY2Vzc1Rva2VuU2NvcGVzKTtcbiAgICBsb2cuZGVidWcoXCJnZXRBY2Nlc3NUb2tlblNjb3Blc1wiLCB7IGFjY2Vzc1Rva2VuU2NvcGVzIH0pO1xuICB9XG4gIHJldHVybiBhY2Nlc3NUb2tlblNjb3Blcztcbn1cblxuLyoqXG4gKiBSZXR1cm4gdHJ1ZSB3aGVuIGBzY29wZXNgIGNvbnRhaW5zIGFueSB2YWx1ZSBmcm9tIGBhbGxvd2VkYC5cbiAqXG4gKiBBY2NlcHRzIHRoZSByYXcge0BsaW5rIE1BU1RSQV9TQ09QRVNfS0VZfSBhcnJheSBzdGFtcGVkIG9uXG4gKiBgUmVxdWVzdENvbnRleHRgIGFzIHdlbGwgYXMgaXRlcmFibGVzIGZyb20ge0BsaW5rIGdldEFjY2Vzc1Rva2VuU2NvcGVzfS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluY2x1ZGVzQWNjZXNzVG9rZW5TY29wZShzY29wZXM6IHVua25vd24sIGFsbG93ZWQ6IHJlYWRvbmx5IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gIGlmIChhbGxvd2VkLmxlbmd0aCkge1xuICAgIGZvciAoY29uc3Qgc2NvcGUgb2YgaXRlcmF0ZUNsYWltcyhzY29wZXMpKSB7XG4gICAgICBpZiAoYWxsb3dlZC5pbmNsdWRlcyhzY29wZSkpIHtcbiAgICAgICAgbG9nLmRlYnVnKFwiaW5jbHVkZXNBY2Nlc3NUb2tlblNjb3BlXCIsIHsgc2NvcGUsIGFsbG93ZWQgfSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKiBTcGxpdCBhIEpXVCBgc2NvcGVgIGNsYWltIHN0cmluZyBvciBhcnJheSBpbnRvIGluZGl2aWR1YWwgc2NvcGUgdG9rZW5zLiAqL1xuZnVuY3Rpb24qIGl0ZXJhdGVDbGFpbXMoaW5wdXQ6IHVua25vd24sIGRpc3RpbmN0ID0gdHJ1ZSk6IEl0ZXJhYmxlPHN0cmluZz4ge1xuICBjb25zdCBzZWVuID0gZGlzdGluY3QgPyBuZXcgU2V0PHN0cmluZz4oKSA6IHVuZGVmaW5lZDtcblxuICBmdW5jdGlvbiogdmlzaXQodmFsdWU6IHVua25vd24pOiBJdGVyYWJsZTxzdHJpbmc+IHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBmb3IgKGNvbnN0IGNsYWltIG9mIHZhbHVlLnNwbGl0KFNQTElUX1JFR0VYKSkge1xuICAgICAgICBjb25zdCB0b2tlbiA9IGNsYWltLnRyaW0oKTtcbiAgICAgICAgaWYgKCF0b2tlbiB8fCBzZWVuPy5oYXModG9rZW4pKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgc2Vlbj8uYWRkKHRva2VuKTtcbiAgICAgICAgeWllbGQgdG9rZW47XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHZhbHVlKSB7XG4gICAgICAgIHlpZWxkKiB2aXNpdChpdGVtKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB5aWVsZCogdmlzaXQoaW5wdXQpO1xufVxuIl19
@@ -0,0 +1 @@
1
+ {"root":["../src/async.ts","../src/brand.ts","../src/error.ts","../src/function.ts","../src/hash.ts","../src/http.ts","../src/json.ts","../src/log.ts","../src/net.ts","../src/object.ts","../src/predicate.ts","../src/string.ts","../src/token.ts","../index.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -17,21 +17,25 @@
17
17
  "dependencies": {
18
18
  "zod": "4.3.6"
19
19
  },
20
- "main": "index.ts",
20
+ "main": "./lib/index.js",
21
21
  "license": "UNLICENSED",
22
22
  "publishConfig": {
23
23
  "access": "public"
24
24
  },
25
- "version": "0.3.43",
26
- "types": "index.ts",
25
+ "version": "0.4.0",
26
+ "types": "./lib/index.d.ts",
27
27
  "type": "module",
28
28
  "exports": {
29
- ".": "./index.ts",
29
+ ".": {
30
+ "types": "./lib/index.d.ts",
31
+ "default": "./lib/index.js"
32
+ },
30
33
  "./package.json": "./package.json"
31
34
  },
32
35
  "files": [
33
36
  "index.ts",
34
- "src"
37
+ "src",
38
+ "lib"
35
39
  ],
36
40
  "peerDependenciesMeta": {
37
41
  "consola": {