@collabland/common
Advanced tools
Comparing version 0.28.0 to 0.29.0
export { default as jsonata } from 'jsonata'; | ||
export { default as lodash } from 'lodash'; | ||
export { default as pMap } from 'p-map'; | ||
export * from './types'; | ||
export * from './utils'; |
@@ -7,12 +7,10 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.pMap = exports.lodash = exports.jsonata = void 0; | ||
exports.lodash = exports.jsonata = void 0; | ||
const tslib_1 = require("tslib"); | ||
var jsonata_1 = require("jsonata"); | ||
Object.defineProperty(exports, "jsonata", { enumerable: true, get: function () { return (0, tslib_1.__importDefault)(jsonata_1).default; } }); | ||
Object.defineProperty(exports, "jsonata", { enumerable: true, get: function () { return tslib_1.__importDefault(jsonata_1).default; } }); | ||
var lodash_1 = require("lodash"); | ||
Object.defineProperty(exports, "lodash", { enumerable: true, get: function () { return (0, tslib_1.__importDefault)(lodash_1).default; } }); | ||
var p_map_1 = require("p-map"); | ||
Object.defineProperty(exports, "pMap", { enumerable: true, get: function () { return (0, tslib_1.__importDefault)(p_map_1).default; } }); | ||
(0, tslib_1.__exportStar)(require("./types"), exports); | ||
(0, tslib_1.__exportStar)(require("./utils"), exports); | ||
Object.defineProperty(exports, "lodash", { enumerable: true, get: function () { return tslib_1.__importDefault(lodash_1).default; } }); | ||
tslib_1.__exportStar(require("./types"), exports); | ||
tslib_1.__exportStar(require("./utils"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -10,3 +10,3 @@ "use strict"; | ||
const bignumber_1 = require("@ethersproject/bignumber"); | ||
(0, tslib_1.__exportStar)(require("@ethersproject/bignumber"), exports); | ||
tslib_1.__exportStar(require("@ethersproject/bignumber"), exports); | ||
var bignumber_2 = require("@ethersproject/bignumber"); | ||
@@ -13,0 +13,0 @@ Object.defineProperty(exports, "BN", { enumerable: true, get: function () { return bignumber_2.BigNumber; } }); |
@@ -13,3 +13,3 @@ /// <reference types="node" /> | ||
*/ | ||
export declare function bs58Decode(data: string): Buffer; | ||
export declare function bs58Decode(data: string): Uint8Array; | ||
/** | ||
@@ -16,0 +16,0 @@ * Check if a string is BS58 encoded |
@@ -11,3 +11,5 @@ import { Debugger } from 'debug'; | ||
*/ | ||
export declare function getPinoLogger(): P.Logger | undefined; | ||
export declare function getPinoLogger(): import("pino").Logger<{ | ||
level: string; | ||
}> | undefined; | ||
export declare function getPinoDebugger(logger: P.Logger, debugFactory: (ns: string) => Debugger, namespace: string): Debugger; |
@@ -9,4 +9,4 @@ "use strict"; | ||
const tslib_1 = require("tslib"); | ||
const debug_1 = (0, tslib_1.__importDefault)(require("debug")); | ||
const util_1 = (0, tslib_1.__importDefault)(require("util")); | ||
const debug_1 = tslib_1.__importDefault(require("debug")); | ||
const util_1 = tslib_1.__importDefault(require("util")); | ||
const debug_pino_1 = require("./debug-pino"); | ||
@@ -13,0 +13,0 @@ const env_1 = require("./env"); |
@@ -35,6 +35,12 @@ /** | ||
* @param name - Name of the variable | ||
* @returns | ||
*/ | ||
export declare function getEnvVarAsNumber(name: string): number | undefined; | ||
/** | ||
* Get the number value of an environment variable | ||
* @param name - Name of the variable | ||
* @param defaultValue - Default value | ||
* @returns | ||
*/ | ||
export declare function getEnvVarAsNumber(name: string, defaultValue?: number): number | undefined; | ||
export declare function getEnvVarAsNumber(name: string, defaultValue: number): number; | ||
/** | ||
@@ -50,6 +56,12 @@ * Get the environment variable as boolean | ||
* @param name - Name of the variable | ||
* @returns | ||
*/ | ||
export declare function getEnvVarAsObject<T>(name: string): T | undefined; | ||
/** | ||
* Get the object value of an environment variable | ||
* @param name - Name of the variable | ||
* @param defaultValue - Default value | ||
* @returns | ||
*/ | ||
export declare function getEnvVarAsObject<T>(name: string, defaultValue?: T): T | undefined; | ||
export declare function getEnvVarAsObject<T>(name: string, defaultValue: T): T; | ||
/** | ||
@@ -56,0 +68,0 @@ * Set an environment variable to the given value. It does not override existing |
@@ -51,8 +51,2 @@ "use strict"; | ||
exports.getEnvVar = getEnvVar; | ||
/** | ||
* Get the number value of an environment variable | ||
* @param name - Name of the variable | ||
* @param defaultValue - Default value | ||
* @returns | ||
*/ | ||
function getEnvVarAsNumber(name, defaultValue) { | ||
@@ -82,8 +76,2 @@ const val = getEnvVar(name); | ||
exports.getEnvVarAsBoolean = getEnvVarAsBoolean; | ||
/** | ||
* Get the object value of an environment variable | ||
* @param name - Name of the variable | ||
* @param defaultValue - Default value | ||
* @returns | ||
*/ | ||
function getEnvVarAsObject(name, defaultValue) { | ||
@@ -90,0 +78,0 @@ const val = getEnvVar(name); |
@@ -9,8 +9,8 @@ "use strict"; | ||
const tslib_1 = require("tslib"); | ||
const cross_fetch_1 = (0, tslib_1.__importDefault)(require("cross-fetch")); | ||
const http_errors_1 = (0, tslib_1.__importDefault)(require("http-errors")); | ||
const cross_fetch_1 = tslib_1.__importDefault(require("cross-fetch")); | ||
const http_errors_1 = tslib_1.__importDefault(require("http-errors")); | ||
const debug_1 = require("./debug"); | ||
(0, tslib_1.__exportStar)(require("cross-fetch"), exports); | ||
tslib_1.__exportStar(require("cross-fetch"), exports); | ||
var http_errors_2 = require("http-errors"); | ||
Object.defineProperty(exports, "HttpErrors", { enumerable: true, get: function () { return (0, tslib_1.__importDefault)(http_errors_2).default; } }); | ||
Object.defineProperty(exports, "HttpErrors", { enumerable: true, get: function () { return tslib_1.__importDefault(http_errors_2).default; } }); | ||
/** | ||
@@ -35,3 +35,3 @@ * Http client using `cross-fetch` for browser and Node.js | ||
}); | ||
debugHttp('Fetch response: %d %O %O', res.status, headers, body); | ||
debugHttp('Fetch response: %s %d %O %O', res.url, res.status, headers, body); | ||
} | ||
@@ -38,0 +38,0 @@ try { |
@@ -12,1 +12,2 @@ export * from './bignumber'; | ||
export * from './promise-timeout'; | ||
export * from './totp'; |
@@ -8,13 +8,14 @@ "use strict"; | ||
const tslib_1 = require("tslib"); | ||
(0, tslib_1.__exportStar)(require("./bignumber"), exports); | ||
(0, tslib_1.__exportStar)(require("./bs58"), exports); | ||
(0, tslib_1.__exportStar)(require("./debug"), exports); | ||
(0, tslib_1.__exportStar)(require("./debug-pino"), exports); | ||
(0, tslib_1.__exportStar)(require("./env"), exports); | ||
(0, tslib_1.__exportStar)(require("./http-client-fetch"), exports); | ||
(0, tslib_1.__exportStar)(require("./id-generator"), exports); | ||
(0, tslib_1.__exportStar)(require("./jsonata"), exports); | ||
(0, tslib_1.__exportStar)(require("./jwt"), exports); | ||
(0, tslib_1.__exportStar)(require("./pmap"), exports); | ||
(0, tslib_1.__exportStar)(require("./promise-timeout"), exports); | ||
tslib_1.__exportStar(require("./bignumber"), exports); | ||
tslib_1.__exportStar(require("./bs58"), exports); | ||
tslib_1.__exportStar(require("./debug"), exports); | ||
tslib_1.__exportStar(require("./debug-pino"), exports); | ||
tslib_1.__exportStar(require("./env"), exports); | ||
tslib_1.__exportStar(require("./http-client-fetch"), exports); | ||
tslib_1.__exportStar(require("./id-generator"), exports); | ||
tslib_1.__exportStar(require("./jsonata"), exports); | ||
tslib_1.__exportStar(require("./jwt"), exports); | ||
tslib_1.__exportStar(require("./pmap"), exports); | ||
tslib_1.__exportStar(require("./promise-timeout"), exports); | ||
tslib_1.__exportStar(require("./totp"), exports); | ||
//# sourceMappingURL=index.js.map |
import { Expression, Focus } from 'jsonata'; | ||
import { BNLike } from './bignumber'; | ||
export declare type JsonEvaluator = Expression['evaluate'] & { | ||
@@ -11,2 +12,64 @@ query: string; | ||
/** | ||
* Trait type/value pair | ||
*/ | ||
export declare type Trait = { | ||
trait_type: string; | ||
value: string; | ||
}; | ||
/** | ||
* Filter for each token to match a list of traits using `and` or `or` condition | ||
*/ | ||
export declare type TraitFilterPerToken = { | ||
/** | ||
* Use `and` or `or` logic | ||
*/ | ||
condition?: 'and' | 'or'; | ||
/** | ||
* A list of trait to match the token | ||
*/ | ||
traits: Trait[]; | ||
}; | ||
/** | ||
* Trait based filter for all tokens owned by an account | ||
*/ | ||
export declare type TraitFilterForAllTokens = { | ||
/** | ||
* Asset uri | ||
*/ | ||
asset?: string; | ||
/** | ||
* Token ids | ||
*/ | ||
tokenId?: string; | ||
/** | ||
* Use `and` or `or` logic | ||
*/ | ||
condition?: 'and' | 'or'; | ||
/** | ||
* A list of filters at per token level | ||
*/ | ||
filters: TraitFilterPerToken[]; | ||
}; | ||
/** | ||
* Quantity based balance filter | ||
*/ | ||
export declare type BalanceFilter = { | ||
/** | ||
* Asset uri | ||
*/ | ||
asset?: string; | ||
/** | ||
* Minimal count | ||
*/ | ||
minCount?: BNLike; | ||
/** | ||
* Maximal count | ||
*/ | ||
maxCount?: BNLike; | ||
/** | ||
* Token id patterns | ||
*/ | ||
tokenId?: string; | ||
}; | ||
/** | ||
* Global jsonata functions | ||
@@ -13,0 +76,0 @@ */ |
@@ -9,4 +9,4 @@ "use strict"; | ||
const tslib_1 = require("tslib"); | ||
const jsonata_1 = (0, tslib_1.__importDefault)(require("jsonata")); | ||
const lodash_1 = (0, tslib_1.__importDefault)(require("lodash")); | ||
const jsonata_1 = tslib_1.__importDefault(require("jsonata")); | ||
const lodash_1 = tslib_1.__importDefault(require("lodash")); | ||
const bignumber_1 = require("./bignumber"); | ||
@@ -175,11 +175,14 @@ const debug_1 = require("./debug"); | ||
}; | ||
function _between(value, min, max) { | ||
// The value is default to 0 if it does not exist | ||
value = value !== null && value !== void 0 ? value : 0; | ||
debug('$between(%s, %s, %s)', value, min, max); | ||
const result = (min == null || greaterThanOrEqual(value, min)) && | ||
(max == null || lessThanOrEqual(value, max)); | ||
debug('Result: %s', result); | ||
return result; | ||
} | ||
const between = { | ||
implementation: (value, min, max) => { | ||
// The value is default to 0 if it does not exist | ||
value = value !== null && value !== void 0 ? value : 0; | ||
debug('$between(%s, %s, %s)', value, min, max); | ||
const result = (min == null || greaterThanOrEqual(value, min)) && | ||
(max == null || lessThanOrEqual(value, max)); | ||
debug('Result: %s', result); | ||
return result; | ||
return _between(value, min, max); | ||
}, | ||
@@ -204,2 +207,87 @@ signature: '<(snblo)(snblo)(snblo):b>', | ||
}; | ||
function matchesTraitsPerToken(value, filter) { | ||
var _a, _b; | ||
const attrs = (_b = (_a = value === null || value === void 0 ? void 0 : value.metadata) === null || _a === void 0 ? void 0 : _a.attributes) !== null && _b !== void 0 ? _b : []; | ||
const fn = (t) => { | ||
const result = attrs.some(a => { | ||
var _a, _b, _c, _d; | ||
return ((_a = a.trait_type) === null || _a === void 0 ? void 0 : _a.toLowerCase().trim()) === | ||
((_b = t.trait_type) === null || _b === void 0 ? void 0 : _b.toLowerCase().trim()) && | ||
((_c = a.value) === null || _c === void 0 ? void 0 : _c.toLowerCase().trim()) === ((_d = t.value) === null || _d === void 0 ? void 0 : _d.toLowerCase().trim()); | ||
}); | ||
debug('Matching trait %O against %O: %s', t, attrs, result); | ||
return result; | ||
}; | ||
if (filter.condition === 'or') { | ||
return filter.traits.some(fn); | ||
} | ||
else { | ||
return filter.traits.every(fn); | ||
} | ||
} | ||
const ownsTraitsPerToken = { | ||
implementation: (value, filter) => { | ||
return matchesTraitsPerToken(value, filter); | ||
}, | ||
signature: '<(j)(o):b>', | ||
}; | ||
const ownsTraits = { | ||
implementation: (balances, filter) => { | ||
debug('ownsTraits(%O, %O)', balances, filter); | ||
if (balances == null) | ||
return false; | ||
if (!Array.isArray(balances)) { | ||
balances = [balances]; | ||
} | ||
const result = balances | ||
.filter(b => { | ||
var _a; | ||
return filter.asset == null || | ||
filter.asset.toLowerCase() === ((_a = b === null || b === void 0 ? void 0 : b.asset) === null || _a === void 0 ? void 0 : _a.toLowerCase()); | ||
}) | ||
.some(b => { | ||
var _a, _b; | ||
const tokens = (_b = (_a = b === null || b === void 0 ? void 0 : b.tokens) === null || _a === void 0 ? void 0 : _a.filter(t => { | ||
return filter.tokenId == null || isInRanges(t.id, filter.tokenId); | ||
})) !== null && _b !== void 0 ? _b : []; | ||
const fn = (traits) => tokens.some(t => matchesTraitsPerToken(t, traits)); | ||
if (filter.condition === 'or') { | ||
return filter.filters.some(fn); | ||
} | ||
else { | ||
return filter.filters.every(fn); | ||
} | ||
}); | ||
return result; | ||
}, | ||
signature: '<(lao)(o):b>', | ||
}; | ||
const ownsBalance = { | ||
implementation: (balances, filter) => { | ||
debug('ownsBalance(%O, %O)', balances, filter); | ||
const { asset, minCount, maxCount, tokenId } = filter; | ||
if (balances == null) | ||
return bignumber_1.BN.from(0); | ||
if (!Array.isArray(balances)) { | ||
balances = [balances]; | ||
} | ||
const assets = balances.filter(b => { var _a; return asset == null || asset.toLowerCase() === ((_a = b === null || b === void 0 ? void 0 : b.asset) === null || _a === void 0 ? void 0 : _a.toLowerCase()); }); | ||
debug('Assets: %O', assets); | ||
const result = assets | ||
.map(a => { | ||
var _a; | ||
if (a.tokens == null) { | ||
return (_a = a.balance) !== null && _a !== void 0 ? _a : '0'; | ||
} | ||
return a.tokens | ||
.filter(t => tokenId == null || isInRanges(t.id, tokenId)) | ||
.map(t => { var _a; return (_a = t.balance) !== null && _a !== void 0 ? _a : '1'; }); | ||
}) | ||
.flat(); | ||
const total = _addAll(result); | ||
debug('Total balance: %s', total); | ||
return _between(total, minCount, maxCount); | ||
}, | ||
signature: '<(lao)(lo):o>', | ||
}; | ||
/** | ||
@@ -223,2 +311,5 @@ * Global jsonata functions | ||
inRanges, | ||
ownsTraits, | ||
ownsTraitsPerToken, | ||
ownsBalance, | ||
}; | ||
@@ -332,11 +423,3 @@ /** | ||
// CollabLand extensions | ||
'between', | ||
'includes', | ||
'compare', | ||
'eq', | ||
'ne', | ||
'gt', | ||
'gte', | ||
'lt', | ||
'lte', | ||
...Object.keys(exports.globalJsonQueryFunctions), | ||
]); | ||
@@ -378,3 +461,10 @@ /** | ||
const idStr = String(value); | ||
if (String(value) === ranges) { | ||
let hexIdString = idStr; | ||
try { | ||
hexIdString = bignumber_1.BN.from(idStr).toHexString(); | ||
} | ||
catch (err) { | ||
// Ignore error | ||
} | ||
if (idStr === ranges || hexIdString === ranges) { | ||
debug('Result: %s', true); | ||
@@ -386,2 +476,3 @@ return true; | ||
const result = ids.some(range => { | ||
var _a; | ||
if (typeof range === 'string') { | ||
@@ -393,3 +484,5 @@ if (idStr === range) | ||
const regex = wildcardToRegExp(range); | ||
return idStr.match(regex); | ||
const matched = (_a = idStr.match(regex)) !== null && _a !== void 0 ? _a : hexIdString.match(regex); | ||
if (matched != null) | ||
return true; | ||
} | ||
@@ -396,0 +489,0 @@ return false; |
@@ -10,3 +10,3 @@ "use strict"; | ||
const crypto_1 = require("crypto"); | ||
const jsonwebtoken_1 = (0, tslib_1.__importDefault)(require("jsonwebtoken")); | ||
const jsonwebtoken_1 = tslib_1.__importDefault(require("jsonwebtoken")); | ||
const env_1 = require("./env"); | ||
@@ -59,3 +59,3 @@ /** | ||
exports.getJwtAudience = getJwtAudience; | ||
(0, tslib_1.__exportStar)(require("jsonwebtoken"), exports); | ||
tslib_1.__exportStar(require("jsonwebtoken"), exports); | ||
//# sourceMappingURL=jwt.js.map |
@@ -1,6 +0,6 @@ | ||
import pMap from 'p-map'; | ||
import pMapFn from 'p-map'; | ||
/** | ||
* Options for paginated p-map | ||
*/ | ||
export declare type PMapByPageOptions = pMap.Options & { | ||
export declare type PMapByPageOptions = pMapFn.Options & { | ||
pageSize?: number; | ||
@@ -15,3 +15,3 @@ }; | ||
*/ | ||
export declare function pMapByPage<T = unknown, N = unknown>(input: Iterable<T>, mapper: pMap.Mapper<T[], N>, options?: PMapByPageOptions): Promise<N[]>; | ||
export declare function pMapByPage<T = unknown, N = unknown>(input: Iterable<T>, mapper: pMapFn.Mapper<T[], N>, options?: PMapByPageOptions): Promise<N[]>; | ||
/** | ||
@@ -24,3 +24,3 @@ * Map a large collection asynchronously with pagination (start, end) | ||
*/ | ||
export declare function pMapByRange<N = unknown>(range: number | [number, number], mapper: pMap.Mapper<{ | ||
export declare function pMapByRange<N = unknown>(range: number | [number, number], mapper: pMapFn.Mapper<{ | ||
start: number; | ||
@@ -36,3 +36,3 @@ end: number; | ||
*/ | ||
export declare function pMapByPageOffsetAndLimit<N = unknown>(size: number, mapper: pMap.Mapper<{ | ||
export declare function pMapByPageOffsetAndLimit<N = unknown>(size: number, mapper: pMapFn.Mapper<{ | ||
offset: number; | ||
@@ -45,1 +45,36 @@ limit: number; | ||
}): Record<string, V[]>; | ||
export declare function pMap<Element, NewElement>(input: Iterable<Element>, mapper: pMapFn.Mapper<Element, NewElement>, options?: pMapFn.Options): Promise<NewElement[]>; | ||
export declare namespace pMap { | ||
type Options = pMapFn.Options; | ||
type Mapper = pMapFn.Mapper; | ||
} | ||
export interface AsyncFetchOptions<VALUE, STATE, SUMMARY = undefined> { | ||
next: (state?: STATE) => Promise<{ | ||
state?: STATE; | ||
value?: VALUE; | ||
done?: boolean; | ||
}>; | ||
initialState?: STATE; | ||
reduce?: (prev: SUMMARY | undefined, current: VALUE) => SUMMARY; | ||
initialSummary?: SUMMARY; | ||
} | ||
/** | ||
* Async iterator to fetch items from a collection asynchronously | ||
* @param options - Options to fetch next item | ||
* @returns | ||
*/ | ||
export declare function fetchIterator<VALUE, STATE, SUMMARY = undefined>(options: AsyncFetchOptions<VALUE, STATE, SUMMARY>): AsyncGenerator<Awaited<VALUE>, Awaited<SUMMARY> | undefined, unknown>; | ||
export interface AsyncFetchByPageOptions<VALUE, STATE> { | ||
next: (state?: STATE) => Promise<{ | ||
state?: STATE; | ||
value?: VALUE[]; | ||
done?: boolean; | ||
}>; | ||
initialState?: STATE; | ||
} | ||
/** | ||
* Fetch items by page asynchronously and return items one by one | ||
* @param options - Options to fetch next page | ||
* @returns | ||
*/ | ||
export declare function fetchIteratorByPage<VALUE, STATE>(options: AsyncFetchByPageOptions<VALUE, STATE>): AsyncGenerator<Awaited<VALUE>, void, unknown>; |
@@ -7,5 +7,7 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.mapByKeyValue = exports.pMapByPageOffsetAndLimit = exports.pMapByRange = exports.pMapByPage = void 0; | ||
exports.fetchIteratorByPage = exports.fetchIterator = exports.pMap = exports.mapByKeyValue = exports.pMapByPageOffsetAndLimit = exports.pMapByRange = exports.pMapByPage = void 0; | ||
const tslib_1 = require("tslib"); | ||
const p_map_1 = (0, tslib_1.__importDefault)(require("p-map")); | ||
const p_map_1 = tslib_1.__importDefault(require("p-map")); | ||
const debug_1 = require("./debug"); | ||
const debug = (0, debug_1.debugFactory)('collabland:common'); | ||
/** | ||
@@ -72,3 +74,3 @@ * Get range for a given page number (starting with 0) | ||
const itemsByPage = paginateList(input, options === null || options === void 0 ? void 0 : options.pageSize); | ||
const pages = await (0, p_map_1.default)(itemsByPage, mapper, options); | ||
const pages = await pMap(itemsByPage, mapper, options); | ||
return pages; | ||
@@ -86,3 +88,3 @@ } | ||
const rangesByPage = paginateRanges(range, options === null || options === void 0 ? void 0 : options.pageSize); | ||
const pages = await (0, p_map_1.default)(rangesByPage, mapper, options); | ||
const pages = await pMap(rangesByPage, mapper, options); | ||
return pages; | ||
@@ -100,3 +102,3 @@ } | ||
const itemsByPage = paginatePages(size, options === null || options === void 0 ? void 0 : options.pageSize); | ||
const pages = await (0, p_map_1.default)(itemsByPage, mapper, options); | ||
const pages = await pMap(itemsByPage, mapper, options); | ||
return pages; | ||
@@ -122,2 +124,52 @@ } | ||
exports.mapByKeyValue = mapByKeyValue; | ||
function pMap(input, mapper, options) { | ||
return (0, p_map_1.default)(input, mapper, { concurrency: 5, ...options }); | ||
} | ||
exports.pMap = pMap; | ||
/** | ||
* Async iterator to fetch items from a collection asynchronously | ||
* @param options - Options to fetch next item | ||
* @returns | ||
*/ | ||
async function* fetchIterator(options) { | ||
let state = options.initialState; | ||
let summary = options.initialSummary; | ||
let i = 0; | ||
for (;;) { | ||
debug('[%s] state=%O, summary=%O', i++, state, summary); | ||
const result = await options.next(state); | ||
state = result.state; | ||
if (result.value != null) { | ||
if (options.reduce != null) { | ||
summary = options.reduce(summary, result.value); | ||
} | ||
yield result.value; | ||
} | ||
if (result.value == null || result.done) | ||
return summary; | ||
} | ||
} | ||
exports.fetchIterator = fetchIterator; | ||
/** | ||
* Fetch items by page asynchronously and return items one by one | ||
* @param options - Options to fetch next page | ||
* @returns | ||
*/ | ||
async function* fetchIteratorByPage(options) { | ||
let state = options.initialState; | ||
let i = 0; | ||
for (;;) { | ||
debug('[%s] state=%O', i++, state); | ||
const result = await options.next(state); | ||
state = result.state; | ||
if (result.value != null) { | ||
for (const v of result.value) { | ||
yield v; | ||
} | ||
} | ||
if (result.done) | ||
return; | ||
} | ||
} | ||
exports.fetchIteratorByPage = fetchIteratorByPage; | ||
//# sourceMappingURL=pmap.js.map |
{ | ||
"name": "@collabland/common", | ||
"version": "0.28.0", | ||
"version": "0.29.0", | ||
"description": "CollabLand common utilities", | ||
@@ -32,3 +32,3 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"@ethersproject/bignumber": "^5.5.0", | ||
"@ethersproject/bignumber": "^5.6.0", | ||
"@types/bs58": "^4.0.1", | ||
@@ -42,5 +42,5 @@ "@types/debug": "^4.1.5", | ||
"borsh": "^0.7.0", | ||
"bs58": "^4.0.1", | ||
"bs58": "^5.0.0", | ||
"cross-fetch": "^3.1.3", | ||
"debug": "^4.3.2", | ||
"debug": "^4.3.3", | ||
"http-errors": "^1.8.0", | ||
@@ -51,2 +51,3 @@ "jsonata": "^1.8.4", | ||
"nanoid": "^3.1.20", | ||
"node-otp": "^1.2.3", | ||
"p-map": "^4.0.0", | ||
@@ -57,11 +58,11 @@ "pino": "^7.3.0", | ||
"devDependencies": { | ||
"@loopback/build": "^8.0.0", | ||
"@loopback/eslint-config": "^12.0.0", | ||
"@loopback/testlab": "^4.0.0", | ||
"@loopback/build": "^8.1.0", | ||
"@loopback/eslint-config": "^12.0.2", | ||
"@loopback/testlab": "^4.1.0", | ||
"@types/node": "^16.11.9", | ||
"typescript": "~4.5.2" | ||
"typescript": "~4.6.0" | ||
}, | ||
"copyright.owner": "Abridged, Inc.", | ||
"author": "Abridged, Inc.", | ||
"gitHead": "86d1583aa3e44990cd3c13b5562a0100df3d7599" | ||
"gitHead": "44c8eea8d516870eda5427bd2ec3e2a1c19d29d2" | ||
} |
@@ -8,4 +8,3 @@ // Copyright Abridged, Inc. 2021. All Rights Reserved. | ||
export {default as lodash} from 'lodash'; | ||
export {default as pMap} from 'p-map'; | ||
export * from './types'; | ||
export * from './utils'; |
@@ -68,5 +68,14 @@ // Copyright Abridged, Inc. 2021. All Rights Reserved. | ||
* @param name - Name of the variable | ||
* @returns | ||
*/ | ||
export function getEnvVarAsNumber(name: string): number | undefined; | ||
/** | ||
* Get the number value of an environment variable | ||
* @param name - Name of the variable | ||
* @param defaultValue - Default value | ||
* @returns | ||
*/ | ||
export function getEnvVarAsNumber(name: string, defaultValue: number): number; | ||
export function getEnvVarAsNumber( | ||
@@ -103,5 +112,14 @@ name: string, | ||
* @param name - Name of the variable | ||
* @returns | ||
*/ | ||
export function getEnvVarAsObject<T>(name: string): T | undefined; | ||
/** | ||
* Get the object value of an environment variable | ||
* @param name - Name of the variable | ||
* @param defaultValue - Default value | ||
* @returns | ||
*/ | ||
export function getEnvVarAsObject<T>(name: string, defaultValue: T): T; | ||
export function getEnvVarAsObject<T>( | ||
@@ -108,0 +126,0 @@ name: string, |
@@ -38,3 +38,9 @@ // Copyright Abridged, Inc. 2021. All Rights Reserved. | ||
}); | ||
debugHttp('Fetch response: %d %O %O', res.status, headers, body); | ||
debugHttp( | ||
'Fetch response: %s %d %O %O', | ||
res.url, | ||
res.status, | ||
headers, | ||
body, | ||
); | ||
} | ||
@@ -41,0 +47,0 @@ try { |
@@ -17,1 +17,2 @@ // Copyright Abridged, Inc. 2021. All Rights Reserved. | ||
export * from './promise-timeout'; | ||
export * from './totp'; |
@@ -8,3 +8,3 @@ // Copyright Abridged, Inc. 2021. All Rights Reserved. | ||
import lodash from 'lodash'; | ||
import {AnyError} from '../types'; | ||
import {AnyError, AnyType} from '../types'; | ||
import {BN, BNLike, toBigNumber} from './bignumber'; | ||
@@ -207,12 +207,16 @@ import {debugFactory, stringify} from './debug'; | ||
function _between(value: BNLike, min: BNLike, max: BNLike) { | ||
// The value is default to 0 if it does not exist | ||
value = value ?? 0; | ||
debug('$between(%s, %s, %s)', value, min, max); | ||
const result = | ||
(min == null || greaterThanOrEqual(value, min)) && | ||
(max == null || lessThanOrEqual(value, max)); | ||
debug('Result: %s', result); | ||
return result; | ||
} | ||
const between: JsonQueryFunction = { | ||
implementation: (value: BNLike, min: BNLike, max: BNLike) => { | ||
// The value is default to 0 if it does not exist | ||
value = value ?? 0; | ||
debug('$between(%s, %s, %s)', value, min, max); | ||
const result = | ||
(min == null || greaterThanOrEqual(value, min)) && | ||
(max == null || lessThanOrEqual(value, max)); | ||
debug('Result: %s', result); | ||
return result; | ||
return _between(value, min, max); | ||
}, | ||
@@ -241,2 +245,166 @@ signature: '<(snblo)(snblo)(snblo):b>', | ||
/** | ||
* Trait type/value pair | ||
*/ | ||
export type Trait = {trait_type: string; value: string}; | ||
/** | ||
* Filter for each token to match a list of traits using `and` or `or` condition | ||
*/ | ||
export type TraitFilterPerToken = { | ||
/** | ||
* Use `and` or `or` logic | ||
*/ | ||
condition?: 'and' | 'or'; | ||
/** | ||
* A list of trait to match the token | ||
*/ | ||
traits: Trait[]; | ||
}; | ||
/** | ||
* Trait based filter for all tokens owned by an account | ||
*/ | ||
export type TraitFilterForAllTokens = { | ||
/** | ||
* Asset uri | ||
*/ | ||
asset?: string; | ||
/** | ||
* Token ids | ||
*/ | ||
tokenId?: string; | ||
/** | ||
* Use `and` or `or` logic | ||
*/ | ||
condition?: 'and' | 'or'; | ||
/** | ||
* A list of filters at per token level | ||
*/ | ||
filters: TraitFilterPerToken[]; | ||
}; | ||
function matchesTraitsPerToken(value: AnyType, filter: TraitFilterPerToken) { | ||
const attrs: Trait[] = value?.metadata?.attributes ?? []; | ||
const fn = (t: Trait) => { | ||
const result = attrs.some( | ||
a => | ||
a.trait_type?.toLowerCase().trim() === | ||
t.trait_type?.toLowerCase().trim() && | ||
a.value?.toLowerCase().trim() === t.value?.toLowerCase().trim(), | ||
); | ||
debug('Matching trait %O against %O: %s', t, attrs, result); | ||
return result; | ||
}; | ||
if (filter.condition === 'or') { | ||
return filter.traits.some(fn); | ||
} else { | ||
return filter.traits.every(fn); | ||
} | ||
} | ||
const ownsTraitsPerToken: JsonQueryFunction = { | ||
implementation: (value: AnyType, filter: TraitFilterPerToken) => { | ||
return matchesTraitsPerToken(value, filter); | ||
}, | ||
signature: '<(j)(o):b>', | ||
}; | ||
const ownsTraits: JsonQueryFunction = { | ||
implementation: ( | ||
balances: | ||
| {tokens: AnyType[]; asset: string} | ||
| {tokens: AnyType[]; asset: string}[] | ||
| undefined | ||
| null, | ||
filter: TraitFilterForAllTokens, | ||
) => { | ||
debug('ownsTraits(%O, %O)', balances, filter); | ||
if (balances == null) return false; | ||
if (!Array.isArray(balances)) { | ||
balances = [balances]; | ||
} | ||
const result = balances | ||
.filter( | ||
b => | ||
filter.asset == null || | ||
filter.asset.toLowerCase() === b?.asset?.toLowerCase(), | ||
) | ||
.some(b => { | ||
const tokens = | ||
b?.tokens?.filter(t => { | ||
return filter.tokenId == null || isInRanges(t.id, filter.tokenId); | ||
}) ?? []; | ||
const fn = (traits: TraitFilterPerToken) => | ||
tokens.some(t => matchesTraitsPerToken(t, traits)); | ||
if (filter.condition === 'or') { | ||
return filter.filters.some(fn); | ||
} else { | ||
return filter.filters.every(fn); | ||
} | ||
}); | ||
return result; | ||
}, | ||
signature: '<(lao)(o):b>', | ||
}; | ||
/** | ||
* Quantity based balance filter | ||
*/ | ||
export type BalanceFilter = { | ||
/** | ||
* Asset uri | ||
*/ | ||
asset?: string; | ||
/** | ||
* Minimal count | ||
*/ | ||
minCount?: BNLike; | ||
/** | ||
* Maximal count | ||
*/ | ||
maxCount?: BNLike; | ||
/** | ||
* Token id patterns | ||
*/ | ||
tokenId?: string; | ||
}; | ||
const ownsBalance: JsonQueryFunction = { | ||
implementation: ( | ||
balances: | ||
| {tokens?: AnyType[]; asset: string; balance: AnyType} | ||
| {tokens?: AnyType[]; asset: string; balance: AnyType}[] | ||
| undefined | ||
| null, | ||
filter: BalanceFilter, | ||
) => { | ||
debug('ownsBalance(%O, %O)', balances, filter); | ||
const {asset, minCount, maxCount, tokenId} = filter; | ||
if (balances == null) return BN.from(0); | ||
if (!Array.isArray(balances)) { | ||
balances = [balances]; | ||
} | ||
const assets = balances.filter( | ||
b => asset == null || asset.toLowerCase() === b?.asset?.toLowerCase(), | ||
); | ||
debug('Assets: %O', assets); | ||
const result = assets | ||
.map(a => { | ||
if (a.tokens == null) { | ||
return a.balance ?? '0'; | ||
} | ||
return a.tokens | ||
.filter(t => tokenId == null || isInRanges(t.id, tokenId)) | ||
.map(t => t.balance ?? '1'); | ||
}) | ||
.flat(); | ||
const total = _addAll(result); | ||
debug('Total balance: %s', total); | ||
return _between(total, minCount, maxCount); | ||
}, | ||
signature: '<(lao)(lo):o>', | ||
}; | ||
/** | ||
* Global jsonata functions | ||
@@ -259,2 +427,5 @@ */ | ||
inRanges, | ||
ownsTraits, | ||
ownsTraitsPerToken, | ||
ownsBalance, | ||
}; | ||
@@ -392,11 +563,3 @@ | ||
// CollabLand extensions | ||
'between', | ||
'includes', | ||
'compare', | ||
'eq', | ||
'ne', | ||
'gt', | ||
'gte', | ||
'lt', | ||
'lte', | ||
...Object.keys(globalJsonQueryFunctions), | ||
]); | ||
@@ -437,3 +600,9 @@ | ||
const idStr = String(value); | ||
if (String(value) === ranges) { | ||
let hexIdString = idStr; | ||
try { | ||
hexIdString = BN.from(idStr).toHexString(); | ||
} catch (err: AnyError) { | ||
// Ignore error | ||
} | ||
if (idStr === ranges || hexIdString === ranges) { | ||
debug('Result: %s', true); | ||
@@ -450,3 +619,4 @@ return true; | ||
const regex = wildcardToRegExp(range); | ||
return idStr.match(regex); | ||
const matched = idStr.match(regex) ?? hexIdString.match(regex); | ||
if (matched != null) return true; | ||
} | ||
@@ -453,0 +623,0 @@ return false; |
@@ -6,4 +6,7 @@ // Copyright Abridged, Inc. 2021. All Rights Reserved. | ||
import pMap from 'p-map'; | ||
import pMapFn from 'p-map'; | ||
import {debugFactory} from './debug'; | ||
const debug = debugFactory('collabland:common'); | ||
/** | ||
@@ -67,3 +70,3 @@ * Get range for a given page number (starting with 0) | ||
*/ | ||
export type PMapByPageOptions = pMap.Options & { | ||
export type PMapByPageOptions = pMapFn.Options & { | ||
pageSize?: number; | ||
@@ -81,3 +84,3 @@ }; | ||
input: Iterable<T>, | ||
mapper: pMap.Mapper<T[], N>, | ||
mapper: pMapFn.Mapper<T[], N>, | ||
options?: PMapByPageOptions, | ||
@@ -99,3 +102,3 @@ ): Promise<N[]> { | ||
range: number | [number, number], | ||
mapper: pMap.Mapper<{start: number; end: number}, N>, | ||
mapper: pMapFn.Mapper<{start: number; end: number}, N>, | ||
options?: PMapByPageOptions, | ||
@@ -117,3 +120,3 @@ ): Promise<N[]> { | ||
size: number, | ||
mapper: pMap.Mapper<{offset: number; limit: number}, N>, | ||
mapper: pMapFn.Mapper<{offset: number; limit: number}, N>, | ||
options?: PMapByPageOptions, | ||
@@ -144,1 +147,78 @@ ): Promise<N[]> { | ||
} | ||
export function pMap<Element, NewElement>( | ||
input: Iterable<Element>, | ||
mapper: pMapFn.Mapper<Element, NewElement>, | ||
options?: pMapFn.Options, | ||
): Promise<NewElement[]> { | ||
return pMapFn(input, mapper, {concurrency: 5, ...options}); | ||
} | ||
export namespace pMap { | ||
export type Options = pMapFn.Options; | ||
export type Mapper = pMapFn.Mapper; | ||
} | ||
export interface AsyncFetchOptions<VALUE, STATE, SUMMARY = undefined> { | ||
next: ( | ||
state?: STATE, | ||
) => Promise<{state?: STATE; value?: VALUE; done?: boolean}>; | ||
initialState?: STATE; | ||
reduce?: (prev: SUMMARY | undefined, current: VALUE) => SUMMARY; | ||
initialSummary?: SUMMARY; | ||
} | ||
/** | ||
* Async iterator to fetch items from a collection asynchronously | ||
* @param options - Options to fetch next item | ||
* @returns | ||
*/ | ||
export async function* fetchIterator<VALUE, STATE, SUMMARY = undefined>( | ||
options: AsyncFetchOptions<VALUE, STATE, SUMMARY>, | ||
) { | ||
let state = options.initialState; | ||
let summary = options.initialSummary; | ||
let i = 0; | ||
for (;;) { | ||
debug('[%s] state=%O, summary=%O', i++, state, summary); | ||
const result = await options.next(state); | ||
state = result.state; | ||
if (result.value != null) { | ||
if (options.reduce != null) { | ||
summary = options.reduce(summary, result.value); | ||
} | ||
yield result.value; | ||
} | ||
if (result.value == null || result.done) return summary; | ||
} | ||
} | ||
export interface AsyncFetchByPageOptions<VALUE, STATE> { | ||
next: ( | ||
state?: STATE, | ||
) => Promise<{state?: STATE; value?: VALUE[]; done?: boolean}>; | ||
initialState?: STATE; | ||
} | ||
/** | ||
* Fetch items by page asynchronously and return items one by one | ||
* @param options - Options to fetch next page | ||
* @returns | ||
*/ | ||
export async function* fetchIteratorByPage<VALUE, STATE>( | ||
options: AsyncFetchByPageOptions<VALUE, STATE>, | ||
) { | ||
let state = options.initialState; | ||
let i = 0; | ||
for (;;) { | ||
debug('[%s] state=%O', i++, state); | ||
const result = await options.next(state); | ||
state = result.state; | ||
if (result.value != null) { | ||
for (const v of result.value) { | ||
yield v; | ||
} | ||
} | ||
if (result.done) return; | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
156904
63
3815
21
+ Addednode-otp@^1.2.3
+ Addedbase-x@4.0.0(transitive)
+ Addedbs58@5.0.0(transitive)
+ Addednode-otp@1.2.3(transitive)
Updatedbs58@^5.0.0
Updateddebug@^4.3.3