WIP: bootstrap and partial real Solana watcher implementation

This commit is contained in:
2026-08-16 09:17:45 +00:00
commit dc23412c3f
7232 changed files with 1687637 additions and 0 deletions

View File

@@ -0,0 +1,154 @@
// Generated by LiveScript 1.6.0
var values, keys, pairsToObj, objToPairs, listsToObj, objToLists, empty, each, map, compact, filter, reject, partition, find;
values = function(object){
var i$, x, results$ = [];
for (i$ in object) {
x = object[i$];
results$.push(x);
}
return results$;
};
keys = function(object){
var x, results$ = [];
for (x in object) {
results$.push(x);
}
return results$;
};
pairsToObj = function(object){
var i$, len$, x, resultObj$ = {};
for (i$ = 0, len$ = object.length; i$ < len$; ++i$) {
x = object[i$];
resultObj$[x[0]] = x[1];
}
return resultObj$;
};
objToPairs = function(object){
var key, value, results$ = [];
for (key in object) {
value = object[key];
results$.push([key, value]);
}
return results$;
};
listsToObj = curry$(function(keys, values){
var i$, len$, i, key, resultObj$ = {};
for (i$ = 0, len$ = keys.length; i$ < len$; ++i$) {
i = i$;
key = keys[i$];
resultObj$[key] = values[i];
}
return resultObj$;
});
objToLists = function(object){
var keys, values, key, value;
keys = [];
values = [];
for (key in object) {
value = object[key];
keys.push(key);
values.push(value);
}
return [keys, values];
};
empty = function(object){
var x;
for (x in object) {
return false;
}
return true;
};
each = curry$(function(f, object){
var i$, x;
for (i$ in object) {
x = object[i$];
f(x);
}
return object;
});
map = curry$(function(f, object){
var k, x, resultObj$ = {};
for (k in object) {
x = object[k];
resultObj$[k] = f(x);
}
return resultObj$;
});
compact = function(object){
var k, x, resultObj$ = {};
for (k in object) {
x = object[k];
if (x) {
resultObj$[k] = x;
}
}
return resultObj$;
};
filter = curry$(function(f, object){
var k, x, resultObj$ = {};
for (k in object) {
x = object[k];
if (f(x)) {
resultObj$[k] = x;
}
}
return resultObj$;
});
reject = curry$(function(f, object){
var k, x, resultObj$ = {};
for (k in object) {
x = object[k];
if (!f(x)) {
resultObj$[k] = x;
}
}
return resultObj$;
});
partition = curry$(function(f, object){
var passed, failed, k, x;
passed = {};
failed = {};
for (k in object) {
x = object[k];
(f(x) ? passed : failed)[k] = x;
}
return [passed, failed];
});
find = curry$(function(f, object){
var i$, x;
for (i$ in object) {
x = object[i$];
if (f(x)) {
return x;
}
}
});
module.exports = {
values: values,
keys: keys,
pairsToObj: pairsToObj,
objToPairs: objToPairs,
listsToObj: listsToObj,
objToLists: objToLists,
empty: empty,
each: each,
map: map,
filter: filter,
compact: compact,
reject: reject,
partition: partition,
find: find
};
function curry$(f, bound){
var context,
_curry = function(args) {
return f.length > 1 ? function(){
var params = args ? args.concat() : [];
context = bound ? context || this : this;
return params.push.apply(params, arguments) <
f.length && arguments.length ?
_curry.call(context, params) : f.apply(context, params);
} : f;
};
return _curry();
}

View File

@@ -0,0 +1,111 @@
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const url = require('url');
const util = require('util');
const pkg = require('../package.json');
const jayson = require('../');
const program = require('commander');
const eyes = require('eyes');
const net = require('net')
// initialize program and define arguments
program.version(pkg.version)
.option('-m, --method [name]', 'Method', String)
.option('-p, --params [json]', 'Array or Object to use as parameters', JSON.parse)
.option('-u, --url [url]', 'URL to server', url.parse)
.option('-q, --quiet', 'Only output the response value and any errors', Boolean)
.option('-s, --socket [path] or [ip:port]', 'Path to UNIX socket, or TCP socket address', parseSocket)
.option('-j, --json', 'Only output the response value as JSON (implies --quiet)')
.option('-c, --color', 'Color output', Boolean)
.parse(process.argv);
const inspect = eyes.inspector({
stream: null,
styles: program.color ? eyes.defaults.styles : {all: false}
});
// quiet is implied if json is specified
if(program.json) program.quiet = true;
// wrapper for printing different kinds of output
const std = {
out: getPrinter({ fn: console.log }),
err: getPrinter({ fn: console.error })
};
// do we have all arguments required to do something?
if(!(program.method && (program.url || program.socket))) {
std.err.result(program.helpInformation());
return process.exit(-1);
}
const client = (program.socket && program.socket.host)
? jayson.client.tcp(program.socket)
: (program.url && program.url.protocol == 'https:')
? jayson.client.https(program.url || program.socket)
: jayson.client.http(program.url || program.socket);
std.out.noise(
colorize('magenta', '-> %s(%s)'),
program.method,
Array.isArray(program.params) ? program.params.join(', ') : JSON.stringify(program.params)
);
client.request(program.method, program.params, function(err, response) {
if(err) {
std.err.noise(colorize('red', '<- %s'), err.stack);
return process.exit(-1);
}
if(!response) {
std.err.noise(colorize('red', '<- %s'), 'empty response');
return process.exit(-1);
}
if(program.json) {
std.out.result('%s', JSON.stringify(response).replace("\n", ""));
return process.exit(0);
}
std.out.noise('<- %s', inspect(response), true);
process.exit(response.error ? response.error.code : 0);
});
function parseSocket(value) {
const addr = value.split(":");
if (addr.length == 2 && (net.isIP(addr[0]) || addr[0].toLowerCase() == "localhost")) {
return {port: addr[1], host: addr[0]};
}
return {socketPath: path.normalize(value)};
}
function colorize(color, format) {
return program.color
? eyes.stylize(format, color, {})
: format;
}
function getPrinter(options) {
const fn = options.fn || console.log;
return {
// print noise (printed if program is not quiet)
noise: function() {
if(program.quiet) return;
return fn.apply(console, arguments);
},
// print results (always printed)
result: function() {
return fn.apply(console, arguments);
}
};
}

View File

@@ -0,0 +1,227 @@
'use strict'
const { test } = require('node:test')
const { strict: assert } = require('node:assert')
const slowRedact = require('../index.js')
// Tests for Issue #2319: @pinojs/redact fails to redact patterns with 3+ consecutive wildcards
test('three consecutive wildcards: *.*.*.password (4 levels deep)', () => {
const obj = {
simple: { password: 'secret-2-levels' },
user: { auth: { password: 'secret-3-levels' } },
nested: { deep: { auth: { password: 'secret-4-levels' } } }
}
const redact = slowRedact({
paths: ['*.*.*.password']
})
const result = redact(obj)
const parsed = JSON.parse(result)
// Only the 4-level deep password should be redacted
assert.strictEqual(parsed.simple.password, 'secret-2-levels', '2-level password should NOT be redacted')
assert.strictEqual(parsed.user.auth.password, 'secret-3-levels', '3-level password should NOT be redacted')
assert.strictEqual(parsed.nested.deep.auth.password, '[REDACTED]', '4-level password SHOULD be redacted')
})
test('four consecutive wildcards: *.*.*.*.password (5 levels deep)', () => {
const obj = {
simple: { password: 'secret-2-levels' },
user: { auth: { password: 'secret-3-levels' } },
nested: { deep: { auth: { password: 'secret-4-levels' } } },
config: { user: { auth: { settings: { password: 'secret-5-levels' } } } }
}
const redact = slowRedact({
paths: ['*.*.*.*.password']
})
const result = redact(obj)
const parsed = JSON.parse(result)
// Only the 5-level deep password should be redacted
assert.strictEqual(parsed.simple.password, 'secret-2-levels', '2-level password should NOT be redacted')
assert.strictEqual(parsed.user.auth.password, 'secret-3-levels', '3-level password should NOT be redacted')
assert.strictEqual(parsed.nested.deep.auth.password, 'secret-4-levels', '4-level password should NOT be redacted')
assert.strictEqual(parsed.config.user.auth.settings.password, '[REDACTED]', '5-level password SHOULD be redacted')
})
test('five consecutive wildcards: *.*.*.*.*.password (6 levels deep)', () => {
const obj = {
simple: { password: 'secret-2-levels' },
user: { auth: { password: 'secret-3-levels' } },
nested: { deep: { auth: { password: 'secret-4-levels' } } },
config: { user: { auth: { settings: { password: 'secret-5-levels' } } } },
data: {
reqConfig: {
data: {
credentials: {
settings: {
password: 'secret-6-levels'
}
}
}
}
}
}
const redact = slowRedact({
paths: ['*.*.*.*.*.password']
})
const result = redact(obj)
const parsed = JSON.parse(result)
// Only the 6-level deep password should be redacted
assert.strictEqual(parsed.simple.password, 'secret-2-levels', '2-level password should NOT be redacted')
assert.strictEqual(parsed.user.auth.password, 'secret-3-levels', '3-level password should NOT be redacted')
assert.strictEqual(parsed.nested.deep.auth.password, 'secret-4-levels', '4-level password should NOT be redacted')
assert.strictEqual(parsed.config.user.auth.settings.password, 'secret-5-levels', '5-level password should NOT be redacted')
assert.strictEqual(parsed.data.reqConfig.data.credentials.settings.password, '[REDACTED]', '6-level password SHOULD be redacted')
})
test('three wildcards with censor function receives correct values', () => {
const obj = {
nested: { deep: { auth: { password: 'secret-value' } } }
}
const censorCalls = []
const redact = slowRedact({
paths: ['*.*.*.password'],
censor: (value, path) => {
censorCalls.push({ value, path: [...path] })
return '[REDACTED]'
}
})
const result = redact(obj)
const parsed = JSON.parse(result)
// Should have been called exactly once with the correct value
assert.strictEqual(censorCalls.length, 1, 'censor should be called once')
assert.strictEqual(censorCalls[0].value, 'secret-value', 'censor should receive the actual value')
assert.deepStrictEqual(censorCalls[0].path, ['nested', 'deep', 'auth', 'password'], 'censor should receive correct path')
assert.strictEqual(parsed.nested.deep.auth.password, '[REDACTED]')
})
test('three wildcards with multiple matches', () => {
const obj = {
api1: { v1: { auth: { token: 'token1' } } },
api2: { v2: { auth: { token: 'token2' } } },
api3: { v1: { auth: { token: 'token3' } } }
}
const redact = slowRedact({
paths: ['*.*.*.token']
})
const result = redact(obj)
const parsed = JSON.parse(result)
// All three tokens should be redacted
assert.strictEqual(parsed.api1.v1.auth.token, '[REDACTED]')
assert.strictEqual(parsed.api2.v2.auth.token, '[REDACTED]')
assert.strictEqual(parsed.api3.v1.auth.token, '[REDACTED]')
})
test('three wildcards with remove option', () => {
const obj = {
nested: { deep: { auth: { password: 'secret', username: 'admin' } } }
}
const redact = slowRedact({
paths: ['*.*.*.password'],
remove: true
})
const result = redact(obj)
const parsed = JSON.parse(result)
// Password should be removed entirely
assert.strictEqual('password' in parsed.nested.deep.auth, false, 'password key should be removed')
assert.strictEqual(parsed.nested.deep.auth.username, 'admin', 'username should remain')
})
test('mixed: two and three wildcards in same redactor', () => {
const obj = {
user: { auth: { password: 'secret-3-levels' } },
config: { deep: { auth: { password: 'secret-4-levels' } } }
}
const redact = slowRedact({
paths: ['*.*.password', '*.*.*.password']
})
const result = redact(obj)
const parsed = JSON.parse(result)
// Both should be redacted
assert.strictEqual(parsed.user.auth.password, '[REDACTED]', '3-level should be redacted by *.*.password')
assert.strictEqual(parsed.config.deep.auth.password, '[REDACTED]', '4-level should be redacted by *.*.*.password')
})
test('three wildcards should not call censor for non-existent paths', () => {
const obj = {
shallow: { data: 'value' },
nested: { deep: { auth: { password: 'secret' } } }
}
let censorCallCount = 0
const redact = slowRedact({
paths: ['*.*.*.password'],
censor: (value, path) => {
censorCallCount++
return '[REDACTED]'
}
})
redact(obj)
// Should only be called once for the path that exists
assert.strictEqual(censorCallCount, 1, 'censor should only be called for existing paths')
})
test('three wildcards with arrays', () => {
const obj = {
users: [
{ auth: { password: 'secret1' } },
{ auth: { password: 'secret2' } }
]
}
const redact = slowRedact({
paths: ['*.*.*.password']
})
const result = redact(obj)
const parsed = JSON.parse(result)
// Both passwords should be redacted (users[0].auth.password is 4 levels)
assert.strictEqual(parsed.users[0].auth.password, '[REDACTED]')
assert.strictEqual(parsed.users[1].auth.password, '[REDACTED]')
})
test('four wildcards with authorization header (real-world case)', () => {
const obj = {
requests: {
api1: {
config: {
headers: {
authorization: 'Bearer secret-token'
}
}
},
api2: {
config: {
headers: {
authorization: 'Bearer another-token'
}
}
}
}
}
const redact = slowRedact({
paths: ['*.*.*.*.authorization']
})
const result = redact(obj)
const parsed = JSON.parse(result)
// Both authorization headers should be redacted
assert.strictEqual(parsed.requests.api1.config.headers.authorization, '[REDACTED]')
assert.strictEqual(parsed.requests.api2.config.headers.authorization, '[REDACTED]')
})

View File

@@ -0,0 +1,6 @@
var set = require("./set.js");
var getPrototypeOf = require("./getPrototypeOf.js");
function _superPropSet(t, e, o, r, p, f) {
return set(getPrototypeOf(f ? t.prototype : t), e, o, r, p);
}
module.exports = _superPropSet, module.exports.__esModule = true, module.exports["default"] = module.exports;

View File

@@ -0,0 +1,57 @@
{
"reg": {
"name": "reg",
"browser": "Firefox 54.0.0 (Windows 7 0.0.0)",
"suite": "escape-long",
"hz": 292285.14849283424,
"success": true,
"fastest": false,
"rme": 0.029313572210377326,
"rhz": 0.6340733965180414,
"sampleSize": 170
},
"fn if": {
"name": "fn if",
"browser": "Firefox 54.0.0 (Windows 7 0.0.0)",
"suite": "escape-long",
"hz": 163169.81969413554,
"success": true,
"fastest": false,
"rme": 0.024903199178875946,
"rhz": 0.35397502170806816,
"sampleSize": 163
},
"fn if reverse": {
"name": "fn if reverse",
"browser": "Firefox 54.0.0 (Windows 7 0.0.0)",
"suite": "escape-long",
"hz": 164334.08219979555,
"success": true,
"fastest": false,
"rme": 0.022262815350227484,
"rhz": 0.3565007329363297,
"sampleSize": 163
},
"escape31": {
"name": "escape31",
"browser": "Firefox 54.0.0 (Windows 7 0.0.0)",
"suite": "escape-long",
"hz": 163872.13126377563,
"success": true,
"fastest": false,
"rme": 0.025364753280213054,
"rhz": 0.3554985923878372,
"sampleSize": 163
},
"native": {
"name": "native",
"browser": "Firefox 54.0.0 (Windows 7 0.0.0)",
"suite": "escape-long",
"hz": 460964.2197541997,
"success": true,
"fastest": true,
"rme": 0.04515613595385393,
"rhz": 1,
"sampleSize": 168
}
}

View File

@@ -0,0 +1,92 @@
import { ReadonlyUint8Array } from './readonly-uint8array';
/**
* Concatenates an array of `Uint8Array`s into a single `Uint8Array`.
* Reuses the original byte array when applicable.
*
* @param byteArrays - The array of byte arrays to concatenate.
*
* @example
* ```ts
* const bytes1 = new Uint8Array([0x01, 0x02]);
* const bytes2 = new Uint8Array([]);
* const bytes3 = new Uint8Array([0x03, 0x04]);
* const bytes = mergeBytes([bytes1, bytes2, bytes3]);
* // ^ [0x01, 0x02, 0x03, 0x04]
* ```
*/
export declare const mergeBytes: (byteArrays: Uint8Array[]) => Uint8Array;
/**
* Pads a `Uint8Array` with zeroes to the specified length.
* If the array is longer than the specified length, it is returned as-is.
*
* @param bytes - The byte array to pad.
* @param length - The desired length of the byte array.
*
* @example
* Adds zeroes to the end of the byte array to reach the desired length.
* ```ts
* const bytes = new Uint8Array([0x01, 0x02]);
* const paddedBytes = padBytes(bytes, 4);
* // ^ [0x01, 0x02, 0x00, 0x00]
* ```
*
* @example
* Returns the original byte array if it is already at the desired length.
* ```ts
* const bytes = new Uint8Array([0x01, 0x02]);
* const paddedBytes = padBytes(bytes, 2);
* // bytes === paddedBytes
* ```
*/
export declare const padBytes: (bytes: ReadonlyUint8Array | Uint8Array, length: number) => ReadonlyUint8Array | Uint8Array;
/**
* Fixes a `Uint8Array` to the specified length.
* If the array is longer than the specified length, it is truncated.
* If the array is shorter than the specified length, it is padded with zeroes.
*
* @param bytes - The byte array to truncate or pad.
* @param length - The desired length of the byte array.
*
* @example
* Truncates the byte array to the desired length.
* ```ts
* const bytes = new Uint8Array([0x01, 0x02, 0x03, 0x04]);
* const fixedBytes = fixBytes(bytes, 2);
* // ^ [0x01, 0x02]
* ```
*
* @example
* Adds zeroes to the end of the byte array to reach the desired length.
* ```ts
* const bytes = new Uint8Array([0x01, 0x02]);
* const fixedBytes = fixBytes(bytes, 4);
* // ^ [0x01, 0x02, 0x00, 0x00]
* ```
*
* @example
* Returns the original byte array if it is already at the desired length.
* ```ts
* const bytes = new Uint8Array([0x01, 0x02]);
* const fixedBytes = fixBytes(bytes, 2);
* // bytes === fixedBytes
* ```
*/
export declare const fixBytes: (bytes: ReadonlyUint8Array | Uint8Array, length: number) => ReadonlyUint8Array | Uint8Array;
/**
* Returns true if and only if the provided `data` byte array contains
* the provided `bytes` byte array at the specified `offset`.
*
* @param data - The byte sequence to search for.
* @param bytes - The byte array in which to search for `data`.
* @param offset - The position in `bytes` where the search begins.
*
* @example
* ```ts
* const bytes = new Uint8Array([0x01, 0x02, 0x03, 0x04]);
* const data = new Uint8Array([0x02, 0x03]);
* containsBytes(bytes, data, 1); // true
* containsBytes(bytes, data, 2); // false
* ```
*/
export declare function containsBytes(data: ReadonlyUint8Array | Uint8Array, bytes: ReadonlyUint8Array | Uint8Array, offset: number): boolean;
//# sourceMappingURL=bytes.d.ts.map

View File

@@ -0,0 +1,33 @@
The MIT License (MIT)
Copyright (c) 2017 [these people](https://github.com/rollup/rollup/graphs/contributors)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
MIT License
Copyright (c) 2020 Evan Wallace
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,48 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReferenceTracker = void 0;
/* eslint-disable @typescript-eslint/no-namespace */
const eslintUtils = __importStar(require("@eslint-community/eslint-utils"));
const ReferenceTrackerREAD = eslintUtils.ReferenceTracker.READ;
const ReferenceTrackerCALL = eslintUtils.ReferenceTracker.CALL;
const ReferenceTrackerCONSTRUCT = eslintUtils.ReferenceTracker.CONSTRUCT;
const ReferenceTrackerESM = eslintUtils.ReferenceTracker.ESM;
/**
* The tracker for references. This provides reference tracking for global variables, CommonJS modules, and ES modules.
*
* @see {@link https://eslint-community.github.io/eslint-utils/api/scope-utils.html#referencetracker-class}
*/
exports.ReferenceTracker = eslintUtils.ReferenceTracker;

View File

@@ -0,0 +1,270 @@
'use strict';
module.exports = function generate_required(it, $keyword, $ruleType) {
var out = ' ';
var $lvl = it.level;
var $dataLvl = it.dataLevel;
var $schema = it.schema[$keyword];
var $schemaPath = it.schemaPath + it.util.getProperty($keyword);
var $errSchemaPath = it.errSchemaPath + '/' + $keyword;
var $breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || '');
var $valid = 'valid' + $lvl;
var $isData = it.opts.$data && $schema && $schema.$data,
$schemaValue;
if ($isData) {
out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; ';
$schemaValue = 'schema' + $lvl;
} else {
$schemaValue = $schema;
}
var $vSchema = 'schema' + $lvl;
if (!$isData) {
if ($schema.length < it.opts.loopRequired && it.schema.properties && Object.keys(it.schema.properties).length) {
var $required = [];
var arr1 = $schema;
if (arr1) {
var $property, i1 = -1,
l1 = arr1.length - 1;
while (i1 < l1) {
$property = arr1[i1 += 1];
var $propertySch = it.schema.properties[$property];
if (!($propertySch && (it.opts.strictKeywords ? (typeof $propertySch == 'object' && Object.keys($propertySch).length > 0) || $propertySch === false : it.util.schemaHasRules($propertySch, it.RULES.all)))) {
$required[$required.length] = $property;
}
}
}
} else {
var $required = $schema;
}
}
if ($isData || $required.length) {
var $currentErrorPath = it.errorPath,
$loopRequired = $isData || $required.length >= it.opts.loopRequired,
$ownProperties = it.opts.ownProperties;
if ($breakOnError) {
out += ' var missing' + ($lvl) + '; ';
if ($loopRequired) {
if (!$isData) {
out += ' var ' + ($vSchema) + ' = validate.schema' + ($schemaPath) + '; ';
}
var $i = 'i' + $lvl,
$propertyPath = 'schema' + $lvl + '[' + $i + ']',
$missingProperty = '\' + ' + $propertyPath + ' + \'';
if (it.opts._errorDataPathProperty) {
it.errorPath = it.util.getPathExpr($currentErrorPath, $propertyPath, it.opts.jsonPointers);
}
out += ' var ' + ($valid) + ' = true; ';
if ($isData) {
out += ' if (schema' + ($lvl) + ' === undefined) ' + ($valid) + ' = true; else if (!Array.isArray(schema' + ($lvl) + ')) ' + ($valid) + ' = false; else {';
}
out += ' for (var ' + ($i) + ' = 0; ' + ($i) + ' < ' + ($vSchema) + '.length; ' + ($i) + '++) { ' + ($valid) + ' = ' + ($data) + '[' + ($vSchema) + '[' + ($i) + ']] !== undefined ';
if ($ownProperties) {
out += ' && Object.prototype.hasOwnProperty.call(' + ($data) + ', ' + ($vSchema) + '[' + ($i) + ']) ';
}
out += '; if (!' + ($valid) + ') break; } ';
if ($isData) {
out += ' } ';
}
out += ' if (!' + ($valid) + ') { ';
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = ''; /* istanbul ignore else */
if (it.createErrors !== false) {
out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } ';
if (it.opts.messages !== false) {
out += ' , message: \'';
if (it.opts._errorDataPathProperty) {
out += 'is a required property';
} else {
out += 'should have required property \\\'' + ($missingProperty) + '\\\'';
}
out += '\' ';
}
if (it.opts.verbose) {
out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
}
out += ' } ';
} else {
out += ' {} ';
}
var __err = out;
out = $$outStack.pop();
if (!it.compositeRule && $breakOnError) {
/* istanbul ignore if */
if (it.async) {
out += ' throw new ValidationError([' + (__err) + ']); ';
} else {
out += ' validate.errors = [' + (__err) + ']; return false; ';
}
} else {
out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += ' } else { ';
} else {
out += ' if ( ';
var arr2 = $required;
if (arr2) {
var $propertyKey, $i = -1,
l2 = arr2.length - 1;
while ($i < l2) {
$propertyKey = arr2[$i += 1];
if ($i) {
out += ' || ';
}
var $prop = it.util.getProperty($propertyKey),
$useData = $data + $prop;
out += ' ( ( ' + ($useData) + ' === undefined ';
if ($ownProperties) {
out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($propertyKey)) + '\') ';
}
out += ') && (missing' + ($lvl) + ' = ' + (it.util.toQuotedString(it.opts.jsonPointers ? $propertyKey : $prop)) + ') ) ';
}
}
out += ') { ';
var $propertyPath = 'missing' + $lvl,
$missingProperty = '\' + ' + $propertyPath + ' + \'';
if (it.opts._errorDataPathProperty) {
it.errorPath = it.opts.jsonPointers ? it.util.getPathExpr($currentErrorPath, $propertyPath, true) : $currentErrorPath + ' + ' + $propertyPath;
}
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = ''; /* istanbul ignore else */
if (it.createErrors !== false) {
out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } ';
if (it.opts.messages !== false) {
out += ' , message: \'';
if (it.opts._errorDataPathProperty) {
out += 'is a required property';
} else {
out += 'should have required property \\\'' + ($missingProperty) + '\\\'';
}
out += '\' ';
}
if (it.opts.verbose) {
out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
}
out += ' } ';
} else {
out += ' {} ';
}
var __err = out;
out = $$outStack.pop();
if (!it.compositeRule && $breakOnError) {
/* istanbul ignore if */
if (it.async) {
out += ' throw new ValidationError([' + (__err) + ']); ';
} else {
out += ' validate.errors = [' + (__err) + ']; return false; ';
}
} else {
out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += ' } else { ';
}
} else {
if ($loopRequired) {
if (!$isData) {
out += ' var ' + ($vSchema) + ' = validate.schema' + ($schemaPath) + '; ';
}
var $i = 'i' + $lvl,
$propertyPath = 'schema' + $lvl + '[' + $i + ']',
$missingProperty = '\' + ' + $propertyPath + ' + \'';
if (it.opts._errorDataPathProperty) {
it.errorPath = it.util.getPathExpr($currentErrorPath, $propertyPath, it.opts.jsonPointers);
}
if ($isData) {
out += ' if (' + ($vSchema) + ' && !Array.isArray(' + ($vSchema) + ')) { var err = '; /* istanbul ignore else */
if (it.createErrors !== false) {
out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } ';
if (it.opts.messages !== false) {
out += ' , message: \'';
if (it.opts._errorDataPathProperty) {
out += 'is a required property';
} else {
out += 'should have required property \\\'' + ($missingProperty) + '\\\'';
}
out += '\' ';
}
if (it.opts.verbose) {
out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
}
out += ' } ';
} else {
out += ' {} ';
}
out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } else if (' + ($vSchema) + ' !== undefined) { ';
}
out += ' for (var ' + ($i) + ' = 0; ' + ($i) + ' < ' + ($vSchema) + '.length; ' + ($i) + '++) { if (' + ($data) + '[' + ($vSchema) + '[' + ($i) + ']] === undefined ';
if ($ownProperties) {
out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', ' + ($vSchema) + '[' + ($i) + ']) ';
}
out += ') { var err = '; /* istanbul ignore else */
if (it.createErrors !== false) {
out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } ';
if (it.opts.messages !== false) {
out += ' , message: \'';
if (it.opts._errorDataPathProperty) {
out += 'is a required property';
} else {
out += 'should have required property \\\'' + ($missingProperty) + '\\\'';
}
out += '\' ';
}
if (it.opts.verbose) {
out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
}
out += ' } ';
} else {
out += ' {} ';
}
out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } } ';
if ($isData) {
out += ' } ';
}
} else {
var arr3 = $required;
if (arr3) {
var $propertyKey, i3 = -1,
l3 = arr3.length - 1;
while (i3 < l3) {
$propertyKey = arr3[i3 += 1];
var $prop = it.util.getProperty($propertyKey),
$missingProperty = it.util.escapeQuotes($propertyKey),
$useData = $data + $prop;
if (it.opts._errorDataPathProperty) {
it.errorPath = it.util.getPath($currentErrorPath, $propertyKey, it.opts.jsonPointers);
}
out += ' if ( ' + ($useData) + ' === undefined ';
if ($ownProperties) {
out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($propertyKey)) + '\') ';
}
out += ') { var err = '; /* istanbul ignore else */
if (it.createErrors !== false) {
out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } ';
if (it.opts.messages !== false) {
out += ' , message: \'';
if (it.opts._errorDataPathProperty) {
out += 'is a required property';
} else {
out += 'should have required property \\\'' + ($missingProperty) + '\\\'';
}
out += '\' ';
}
if (it.opts.verbose) {
out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
}
out += ' } ';
} else {
out += ' {} ';
}
out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } ';
}
}
}
}
it.errorPath = $currentErrorPath;
} else if ($breakOnError) {
out += ' if (true) {';
}
return out;
}

View File

@@ -0,0 +1 @@
{"version":3,"file":"reverse-codec.d.ts","sourceRoot":"","sources":["../../src/reverse-codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EACnB,MAAM,SAAS,CAAC;AAsBjB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,SAAS,MAAM,EACtD,OAAO,EAAE,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,GACxC,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAehC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,KAAK,SAAS,MAAM,EACpD,OAAO,EAAE,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,GACtC,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAe9B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,GAAG,SAAS,KAAK,EAAE,KAAK,SAAS,MAAM,EACvE,KAAK,EAAE,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,GACzC,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAEnC"}

View File

@@ -0,0 +1,13 @@
import { Parser, Printer } from "../index.js";
export declare const parsers: {
angular: Parser;
html: Parser;
lwc: Parser;
mjml: Parser;
vue: Parser;
};
export declare const printers: {
html: Printer;
};

View File

@@ -0,0 +1,110 @@
//binary data writer tuned for encoding binary specific to the postgres binary protocol
export class Writer {
private buffer: Buffer
private offset: number = 5
private headerPosition: number = 0
constructor(private size = 256) {
this.buffer = Buffer.allocUnsafe(size)
}
private ensure(size: number): void {
const remaining = this.buffer.length - this.offset
if (remaining < size) {
const oldBuffer = this.buffer
// exponential growth factor of around ~ 1.5
// https://stackoverflow.com/questions/2269063/buffer-growth-strategy
const newSize = oldBuffer.length + (oldBuffer.length >> 1) + size
this.buffer = Buffer.allocUnsafe(newSize)
oldBuffer.copy(this.buffer)
}
}
public addInt32(num: number): Writer {
this.ensure(4)
this.buffer[this.offset++] = (num >>> 24) & 0xff
this.buffer[this.offset++] = (num >>> 16) & 0xff
this.buffer[this.offset++] = (num >>> 8) & 0xff
this.buffer[this.offset++] = (num >>> 0) & 0xff
return this
}
public addInt16(num: number): Writer {
this.ensure(2)
this.buffer[this.offset++] = (num >>> 8) & 0xff
this.buffer[this.offset++] = (num >>> 0) & 0xff
return this
}
public addCString(string: string): Writer {
if (!string) {
this.ensure(1)
} else {
const len = Buffer.byteLength(string)
this.ensure(len + 1) // +1 for null terminator
this.buffer.write(string, this.offset, 'utf-8')
this.offset += len
}
this.buffer[this.offset++] = 0 // null terminator
return this
}
public addString(string: string = ''): Writer {
const len = Buffer.byteLength(string)
this.ensure(len)
this.buffer.write(string, this.offset)
this.offset += len
return this
}
// Write an Int32 byte-length prefix immediately followed by the string's UTF-8
// bytes. Postgres' Bind wire format prefixes every parameter with its length,
// and doing it in one method computes Buffer.byteLength ONCE — the previous
// `addInt32(Buffer.byteLength(s)).addString(s)` pairing scanned the string
// three times (byteLength for the prefix, byteLength again inside addString,
// then the encode), which is costly for large text parameters.
public addInt32PrefixedString(string: string): Writer {
const len = Buffer.byteLength(string)
this.ensure(4 + len)
const buffer = this.buffer
let offset = this.offset
buffer[offset++] = (len >>> 24) & 0xff
buffer[offset++] = (len >>> 16) & 0xff
buffer[offset++] = (len >>> 8) & 0xff
buffer[offset++] = (len >>> 0) & 0xff
buffer.write(string, offset, 'utf-8')
this.offset = offset + len
return this
}
public add(otherBuffer: Buffer): Writer {
this.ensure(otherBuffer.length)
otherBuffer.copy(this.buffer, this.offset)
this.offset += otherBuffer.length
return this
}
private join(code?: number): Buffer {
if (code) {
this.buffer[this.headerPosition] = code
//length is everything in this packet minus the code
const length = this.offset - (this.headerPosition + 1)
this.buffer.writeInt32BE(length, this.headerPosition + 1)
}
return this.buffer.slice(code ? 0 : 5, this.offset)
}
public flush(code?: number): Buffer {
const result = this.join(code)
this.offset = 5
this.headerPosition = 0
this.buffer = Buffer.allocUnsafe(this.size)
return result
}
public clear(): void {
this.offset = 5
this.headerPosition = 0
}
}

View File

@@ -0,0 +1 @@
{"version":3,"file":"outerExpressionKinds.js","sourceRoot":"","sources":["../../src/enums/outerExpressionKinds.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,MAAM,CAAC,IAAI,oBAAyB,CAAC;AACrC,CAAC,UAAU,oBAAoB;IAC3B,oBAAoB,CAAC,oBAAoB,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC;IAC9E,oBAAoB,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,gBAAgB,CAAC;IACpF,oBAAoB,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,GAAG,mBAAmB,CAAC;IAC1F,oBAAoB,CAAC,oBAAoB,CAAC,6BAA6B,CAAC,GAAG,CAAC,CAAC,GAAG,6BAA6B,CAAC;IAC9G,oBAAoB,CAAC,oBAAoB,CAAC,8BAA8B,CAAC,GAAG,EAAE,CAAC,GAAG,8BAA8B,CAAC;IACjH,oBAAoB,CAAC,oBAAoB,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,GAAG,WAAW,CAAC;IAC3E,oBAAoB,CAAC,oBAAoB,CAAC,2BAA2B,CAAC,GAAG,EAAE,CAAC,GAAG,2BAA2B,CAAC;IAC3G,oBAAoB,CAAC,oBAAoB,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,GAAG,aAAa,CAAC;IAChF,oBAAoB,CAAC,oBAAoB,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,GAAG,OAAO,CAAC;IACpE,oBAAoB,CAAC,oBAAoB,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,GAAG,YAAY,CAAC;IAC7E,oBAAoB,CAAC,oBAAoB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;IAC/D,oBAAoB,CAAC,oBAAoB,CAAC,mDAAmD,CAAC,GAAG,CAAC,CAAC,GAAG,mDAAmD,CAAC;IAC1J,oBAAoB,CAAC,oBAAoB,CAAC,2BAA2B,CAAC,GAAG,GAAG,CAAC,GAAG,2BAA2B,CAAC;AAChH,CAAC,CAAC,CAAC,oBAAoB,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC,CAAC"}

View File

@@ -0,0 +1,113 @@
// disable automatic export
export {};
// Uses ArrayLike to admit Uint8 and co.
type OutputBuffer = ArrayLike<number>;
type InputBuffer = ArrayLike<number>;
interface RandomOptions {
/** `Array` of 16 random bytes (0-255) */
random?: InputBuffer | undefined;
}
interface RngOptions {
/** Alternative to `options.random`, a `Function` that returns an `Array` of 16 random bytes (0-255) */
rng?: (() => InputBuffer) | undefined;
}
interface V1BaseOptions {
/** RFC "node" field as an `Array[6]` of byte values (per 4.1.6) */
node?: InputBuffer | undefined;
/** RFC "clock sequence" as a `Number` between 0 - 0x3fff */
clockseq?: number | undefined;
/** RFC "timestamp" field (`Number` of milliseconds, unix epoch) */
msecs?: number | Date | undefined;
/** RFC "timestamp" field (`Number` of nanoseconds to add to msecs, should be 0-10,000) */
nsecs?: number | undefined;
}
interface V1RandomOptions extends V1BaseOptions, RandomOptions {}
interface V1RngOptions extends V1BaseOptions, RngOptions {}
export type V1Options = V1RandomOptions | V1RngOptions;
export type V4Options = RandomOptions | RngOptions;
export type V6Options = V1Options;
interface V7BaseOptions {
msecs?: number | Date | undefined;
seq?: number;
}
export type V7Options = (RandomOptions | RngOptions) & V7BaseOptions;
type VToV = ((uuid: string) => string) & ((uuid: OutputBuffer) => Uint8Array);
type v1String = (options?: V1Options) => string;
type v1Buffer = <T extends OutputBuffer>(options: V1Options | null | undefined, buffer: T, offset?: number) => T;
type v1 = v1Buffer & v1String;
type v1ToV6 = VToV;
type v4String = (options?: V4Options) => string;
type v4Buffer = <T extends OutputBuffer>(options: V4Options | null | undefined, buffer: T, offset?: number) => T;
type v4 = v4Buffer & v4String;
type v3String = (name: string | InputBuffer, namespace: string | InputBuffer) => string;
type v3Buffer = <T extends OutputBuffer>(
name: string | InputBuffer,
namespace: string | InputBuffer,
buffer: T,
offset?: number,
) => T;
interface v3Static {
// https://github.com/uuidjs/uuid/blob/master/src/v35.js#L16
DNS: string;
// https://github.com/uuidjs/uuid/blob/master/src/v35.js#L17
URL: string;
}
type v3 = v3Buffer & v3String & v3Static;
type v5String = (name: string | InputBuffer, namespace: string | InputBuffer) => string;
type v5Buffer = <T extends OutputBuffer>(
name: string | InputBuffer,
namespace: string | InputBuffer,
buffer: T,
offset?: number,
) => T;
interface v5Static {
// https://github.com/uuidjs/uuid/blob/master/src/v35.js#L16
DNS: string;
// https://github.com/uuidjs/uuid/blob/master/src/v35.js#L17
URL: string;
}
type v5 = v5Buffer & v5String & v5Static;
type v6String = (options?: V6Options) => string;
type v6Buffer = <T extends OutputBuffer>(options: V6Options | null | undefined, buffer: T, offset?: number) => T;
type v6 = v6Buffer & v6String;
type v6ToV1 = VToV;
type v7String = (options?: V7Options) => string;
type v7Buffer = <T extends OutputBuffer>(options: V7Options | null | undefined, buffer: T, offset?: number) => T;
type v7 = v7Buffer & v7String;
type NIL = string;
type MAX = string;
type parse = (uuid: string) => Uint8Array;
type stringify = (buffer: InputBuffer, offset?: number) => string;
type validate = (uuid: string) => boolean;
type version = (uuid: string) => number;
export const NIL: NIL;
export const MAX: MAX;
export const parse: parse;
export const stringify: stringify;
export const v1: v1;
export const v1ToV6: v1ToV6;
export const v3: v3;
export const v4: v4;
export const v5: v5;
export const v6: v6;
export const v6ToV1: v6ToV1;
export const v7: v7;
export const validate: validate;
export const version: version;

View File

@@ -0,0 +1,81 @@
name: CI
on:
push:
paths-ignore:
- 'docs/**'
- '*.md'
pull_request:
paths-ignore:
- 'docs/**'
- '*.md'
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: "${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}"
cancel-in-progress: true
jobs:
dependency-review:
name: Dependency Review
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Check out repo
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Dependency review
uses: actions/dependency-review-action@v4
test:
name: Test
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
node-version: [18, 20]
steps:
- name: Check out repo
uses: actions/checkout@v6
with:
persist-credentials: false
- name: Setup Node ${{ matrix.node-version }}
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm install --ignore-scripts
env:
NODE_ENV: development
- name: Lint-CI
run: npm run lint-ci
- name: Test-Types
run: npm run test-types
- name: Test-CI
run: npm run test-ci
automerge:
name: Automerge Dependabot PRs
if: >
github.event_name == 'pull_request' &&
github.event.pull_request.user.login == 'dependabot[bot]'
needs: test
permissions:
pull-requests: write
contents: write
runs-on: ubuntu-latest
steps:
- uses: fastify/github-action-merge-dependabot@v3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -0,0 +1,136 @@
(function() {
'use strict';
var collator;
try {
collator = (typeof Intl !== "undefined" && typeof Intl.Collator !== "undefined") ? Intl.Collator("generic", { sensitivity: "base" }) : null;
} catch (err){
console.log("Collator could not be initialized and wouldn't be used");
}
// arrays to re-use
var prevRow = [],
str2Char = [];
/**
* Based on the algorithm at http://en.wikipedia.org/wiki/Levenshtein_distance.
*/
var Levenshtein = {
/**
* Calculate levenshtein distance of the two strings.
*
* @param str1 String the first string.
* @param str2 String the second string.
* @param [options] Additional options.
* @param [options.useCollator] Use `Intl.Collator` for locale-sensitive string comparison.
* @return Integer the levenshtein distance (0 and above).
*/
get: function(str1, str2, options) {
var useCollator = (options && collator && options.useCollator);
var str1Len = str1.length,
str2Len = str2.length;
// base cases
if (str1Len === 0) return str2Len;
if (str2Len === 0) return str1Len;
// two rows
var curCol, nextCol, i, j, tmp;
// initialise previous row
for (i=0; i<str2Len; ++i) {
prevRow[i] = i;
str2Char[i] = str2.charCodeAt(i);
}
prevRow[str2Len] = str2Len;
var strCmp;
if (useCollator) {
// calculate current row distance from previous row using collator
for (i = 0; i < str1Len; ++i) {
nextCol = i + 1;
for (j = 0; j < str2Len; ++j) {
curCol = nextCol;
// substution
strCmp = 0 === collator.compare(str1.charAt(i), String.fromCharCode(str2Char[j]));
nextCol = prevRow[j] + (strCmp ? 0 : 1);
// insertion
tmp = curCol + 1;
if (nextCol > tmp) {
nextCol = tmp;
}
// deletion
tmp = prevRow[j + 1] + 1;
if (nextCol > tmp) {
nextCol = tmp;
}
// copy current col value into previous (in preparation for next iteration)
prevRow[j] = curCol;
}
// copy last col value into previous (in preparation for next iteration)
prevRow[j] = nextCol;
}
}
else {
// calculate current row distance from previous row without collator
for (i = 0; i < str1Len; ++i) {
nextCol = i + 1;
for (j = 0; j < str2Len; ++j) {
curCol = nextCol;
// substution
strCmp = str1.charCodeAt(i) === str2Char[j];
nextCol = prevRow[j] + (strCmp ? 0 : 1);
// insertion
tmp = curCol + 1;
if (nextCol > tmp) {
nextCol = tmp;
}
// deletion
tmp = prevRow[j + 1] + 1;
if (nextCol > tmp) {
nextCol = tmp;
}
// copy current col value into previous (in preparation for next iteration)
prevRow[j] = curCol;
}
// copy last col value into previous (in preparation for next iteration)
prevRow[j] = nextCol;
}
}
return nextCol;
}
};
// amd
if (typeof define !== "undefined" && define !== null && define.amd) {
define(function() {
return Levenshtein;
});
}
// commonjs
else if (typeof module !== "undefined" && module !== null && typeof exports !== "undefined" && module.exports === exports) {
module.exports = Levenshtein;
}
// web worker
else if (typeof self !== "undefined" && typeof self.postMessage === 'function' && typeof self.importScripts === 'function') {
self.Levenshtein = Levenshtein;
}
// browser main thread
else if (typeof window !== "undefined" && window !== null) {
window.Levenshtein = Levenshtein;
}
}());

View File

@@ -0,0 +1,35 @@
{
"keys-while": {
"name": "keys-while",
"browser": "Mobile Safari 10.0.0 (iOS 10.3.0)",
"suite": "iter",
"hz": 23603.301526308816,
"success": true,
"fastest": true,
"rme": 0.030880882113979637,
"rhz": 1,
"sampleSize": 167
},
"keys-for": {
"name": "keys-for",
"browser": "Mobile Safari 10.0.0 (iOS 10.3.0)",
"suite": "iter",
"hz": 23426.457275766345,
"success": true,
"fastest": true,
"rme": 0.02398797289803229,
"rhz": 0.9925076476972784,
"sampleSize": 171
},
"incr-for": {
"name": "incr-for",
"browser": "Mobile Safari 10.0.0 (iOS 10.3.0)",
"suite": "iter",
"hz": 11144.323028321938,
"success": true,
"fastest": false,
"rme": 0.024524181905002183,
"rhz": 0.47215102581730795,
"sampleSize": 164
}
}

View File

@@ -0,0 +1,49 @@
'use strict'
module.exports = splitPropertyKey
/**
* Splits the property key delimited by a dot character but not when it is preceded
* by a backslash.
*
* @param {string} key A string identifying the property.
*
* @returns {string[]} Returns a list of string containing each delimited property.
* e.g. `'prop2\.domain\.corp.prop2'` should return [ 'prop2.domain.com', 'prop2' ]
*/
function splitPropertyKey (key) {
const result = []
let backslash = false
let segment = ''
for (let i = 0; i < key.length; i++) {
const c = key.charAt(i)
if (c === '\\') {
backslash = true
continue
}
if (backslash) {
backslash = false
segment += c
continue
}
/* Non-escaped dot, push to result */
if (c === '.') {
result.push(segment)
segment = ''
continue
}
segment += c
}
/* Push last entry to result */
if (segment.length) {
result.push(segment)
}
return result
}