diff options
Diffstat (limited to '')
49 files changed, 1966 insertions, 0 deletions
diff --git a/node_modules/side-channel-list/.editorconfig b/node_modules/side-channel-list/.editorconfig new file mode 100644 index 0000000..72e0eba --- /dev/null +++ b/node_modules/side-channel-list/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = tab +indent_size = 2 +trim_trailing_whitespace = true diff --git a/node_modules/side-channel-list/.eslintrc b/node_modules/side-channel-list/.eslintrc new file mode 100644 index 0000000..93978e7 --- /dev/null +++ b/node_modules/side-channel-list/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "max-lines-per-function": 0, + "multiline-comment-style": 1, + "new-cap": [2, { "capIsNewExceptions": ["GetIntrinsic"] }], + }, +} diff --git a/node_modules/side-channel-list/.github/FUNDING.yml b/node_modules/side-channel-list/.github/FUNDING.yml new file mode 100644 index 0000000..eaff735 --- /dev/null +++ b/node_modules/side-channel-list/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/side-channel-list +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/side-channel-list/.nycrc b/node_modules/side-channel-list/.nycrc new file mode 100644 index 0000000..1826526 --- /dev/null +++ b/node_modules/side-channel-list/.nycrc @@ -0,0 +1,13 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "lines": 86, + "statements": 85.93, + "functions": 82.43, + "branches": 76.06, + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/side-channel-list/CHANGELOG.md b/node_modules/side-channel-list/CHANGELOG.md new file mode 100644 index 0000000..e68bcb9 --- /dev/null +++ b/node_modules/side-channel-list/CHANGELOG.md @@ -0,0 +1,36 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.0.1](https://github.com/ljharb/side-channel-list.git +/compare/v1.0.0...v1.0.1) - 2026-04-08 + +### Fixed + +- [Fix] `delete`: do not reset the list when deleting the head node of a multi-node list [`#3`](https://github.com/ljharb/side-channel-list.git +/issues/3) + +### Commits + +- [actions] update workflows [`9e79e6b`](https://github.com/ljharb/side-channel-list.git +/commit/9e79e6bf845532fafbf03b547429fe4f737214a3) +- [Deps] update `@arethetypeswrong/cli`, `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/tape`, `eslint`, `npmignore` [`babf3ca`](https://github.com/ljharb/side-channel-list.git +/commit/babf3ca4849d2fd893a470a6b82c62a80ccc9307) +- [Deps] update `object-inspect` [`9f0f4b8`](https://github.com/ljharb/side-channel-list.git +/commit/9f0f4b88ff2aa8b7b7c9e589ac1513f133d64b9f) + +## v1.0.0 - 2024-12-10 + +### Commits + +- Initial implementation, tests, readme, types [`5d6baee`](https://github.com/ljharb/side-channel-list.git +/commit/5d6baee5c9054a1238007f5a1dfc109a7a816251) +- Initial commit [`3ae784c`](https://github.com/ljharb/side-channel-list.git +/commit/3ae784c63a47895fbaeed2a91ab54a8029a7a100) +- npm init [`07055a4`](https://github.com/ljharb/side-channel-list.git +/commit/07055a4d139895565b199dba5fe2479c1a1b9e28) +- Only apps should have lockfiles [`9573058`](https://github.com/ljharb/side-channel-list.git +/commit/9573058a47494e2d68f8c6c77b5d7fbe441949c1) diff --git a/node_modules/side-channel-list/LICENSE b/node_modules/side-channel-list/LICENSE new file mode 100644 index 0000000..f82f389 --- /dev/null +++ b/node_modules/side-channel-list/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Jordan Harband + +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. diff --git a/node_modules/side-channel-list/README.md b/node_modules/side-channel-list/README.md new file mode 100644 index 0000000..d9c7a13 --- /dev/null +++ b/node_modules/side-channel-list/README.md @@ -0,0 +1,62 @@ +# side-channel-list <sup>[![Version Badge][npm-version-svg]][package-url]</sup> + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +Store information about any JS value in a side channel, using a linked list. + +Warning: this implementation will leak memory until you `delete` the `key`. +Use [`side-channel`](https://npmjs.com/side-channel) for the best available strategy. + +## Getting started + +```sh +npm install --save side-channel-list +``` + +## Usage/Examples + +```js +const assert = require('assert'); +const getSideChannelList = require('side-channel-list'); + +const channel = getSideChannelList(); + +const key = {}; +assert.equal(channel.has(key), false); +assert.throws(() => channel.assert(key), TypeError); + +channel.set(key, 42); + +channel.assert(key); // does not throw +assert.equal(channel.has(key), true); +assert.equal(channel.get(key), 42); + +channel.delete(key); +assert.equal(channel.has(key), false); +assert.throws(() => channel.assert(key), TypeError); +``` + +## Tests + +Clone the repo, `npm install`, and run `npm test` + +[package-url]: https://npmjs.org/package/side-channel-list +[npm-version-svg]: https://versionbadg.es/ljharb/side-channel-list.svg +[deps-svg]: https://david-dm.org/ljharb/side-channel-list.svg +[deps-url]: https://david-dm.org/ljharb/side-channel-list +[dev-deps-svg]: https://david-dm.org/ljharb/side-channel-list/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/side-channel-list#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/side-channel-list.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/side-channel-list.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/side-channel-list.svg +[downloads-url]: https://npm-stat.com/charts.html?package=side-channel-list +[codecov-image]: https://codecov.io/gh/ljharb/side-channel-list/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/side-channel-list/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/side-channel-list +[actions-url]: https://github.com/ljharb/side-channel-list/actions diff --git a/node_modules/side-channel-list/index.d.ts b/node_modules/side-channel-list/index.d.ts new file mode 100644 index 0000000..c9cabc8 --- /dev/null +++ b/node_modules/side-channel-list/index.d.ts @@ -0,0 +1,13 @@ +declare namespace getSideChannelList { + type Channel<K, V> = { + assert: (key: K) => void; + has: (key: K) => boolean; + get: (key: K) => V | undefined; + set: (key: K, value: V) => void; + delete: (key: K) => boolean; + }; +} + +declare function getSideChannelList<V, K>(): getSideChannelList.Channel<K, V>; + +export = getSideChannelList; diff --git a/node_modules/side-channel-list/index.js b/node_modules/side-channel-list/index.js new file mode 100644 index 0000000..4460229 --- /dev/null +++ b/node_modules/side-channel-list/index.js @@ -0,0 +1,111 @@ +'use strict'; + +var inspect = require('object-inspect'); + +var $TypeError = require('es-errors/type'); + +/* +* This function traverses the list returning the node corresponding to the given key. +* +* That node is also moved to the head of the list, so that if it's accessed again we don't need to traverse the whole list. +* By doing so, all the recently used nodes can be accessed relatively quickly. +*/ +/** @type {import('./list.d.ts').listGetNode} */ +// eslint-disable-next-line consistent-return +var listGetNode = function (list, key, isDelete) { + /** @type {typeof list | NonNullable<(typeof list)['next']>} */ + var prev = list; + /** @type {(typeof list)['next']} */ + var curr; + // eslint-disable-next-line eqeqeq + for (; (curr = prev.next) != null; prev = curr) { + if (curr.key === key) { + prev.next = curr.next; + if (!isDelete) { + // eslint-disable-next-line no-extra-parens + curr.next = /** @type {NonNullable<typeof list.next>} */ (list.next); + list.next = curr; // eslint-disable-line no-param-reassign + } + return curr; + } + } +}; + +/** @type {import('./list.d.ts').listGet} */ +var listGet = function (objects, key) { + if (!objects) { + return void undefined; + } + var node = listGetNode(objects, key); + return node && node.value; +}; +/** @type {import('./list.d.ts').listSet} */ +var listSet = function (objects, key, value) { + var node = listGetNode(objects, key); + if (node) { + node.value = value; + } else { + // Prepend the new node to the beginning of the list + objects.next = /** @type {import('./list.d.ts').ListNode<typeof value, typeof key>} */ ({ // eslint-disable-line no-param-reassign, no-extra-parens + key: key, + next: objects.next, + value: value + }); + } +}; +/** @type {import('./list.d.ts').listHas} */ +var listHas = function (objects, key) { + if (!objects) { + return false; + } + return !!listGetNode(objects, key); +}; +/** @type {import('./list.d.ts').listDelete} */ +// eslint-disable-next-line consistent-return +var listDelete = function (objects, key) { + if (objects) { + return listGetNode(objects, key, true); + } +}; + +/** @type {import('.')} */ +module.exports = function getSideChannelList() { + /** @typedef {ReturnType<typeof getSideChannelList>} Channel */ + /** @typedef {Parameters<Channel['get']>[0]} K */ + /** @typedef {Parameters<Channel['set']>[1]} V */ + + /** @type {import('./list.d.ts').RootNode<V, K> | undefined} */ var $o; + + /** @type {Channel} */ + var channel = { + assert: function (key) { + if (!channel.has(key)) { + throw new $TypeError('Side channel does not contain ' + inspect(key)); + } + }, + 'delete': function (key) { + var deletedNode = listDelete($o, key); + if (deletedNode && $o && !$o.next) { + $o = void undefined; + } + return !!deletedNode; + }, + get: function (key) { + return listGet($o, key); + }, + has: function (key) { + return listHas($o, key); + }, + set: function (key, value) { + if (!$o) { + // Initialize the linked list as an empty node, so that we don't have to special-case handling of the first node: we can always refer to it as (previous node).next, instead of something like (list).head + $o = { + next: void undefined + }; + } + // eslint-disable-next-line no-extra-parens + listSet(/** @type {NonNullable<typeof $o>} */ ($o), key, value); + } + }; + return channel; +}; diff --git a/node_modules/side-channel-list/list.d.ts b/node_modules/side-channel-list/list.d.ts new file mode 100644 index 0000000..2c759e2 --- /dev/null +++ b/node_modules/side-channel-list/list.d.ts @@ -0,0 +1,14 @@ +type ListNode<T, K> = { + key: K; + next: undefined | ListNode<T, K>; + value: T; +}; +type RootNode<T, K> = { + next: undefined | ListNode<T, K>; +}; + +export function listGetNode<T, K>(list: RootNode<T, K>, key: ListNode<T, K>['key'], isDelete?: boolean): ListNode<T, K> | undefined; +export function listGet<T, K>(objects: undefined | RootNode<T, K>, key: ListNode<T, K>['key']): T | undefined; +export function listSet<T, K>(objects: RootNode<T, K>, key: ListNode<T, K>['key'], value: T): void; +export function listHas<T, K>(objects: undefined | RootNode<T, K>, key: ListNode<T, K>['key']): boolean; +export function listDelete<T, K>(objects: undefined | RootNode<T, K>, key: ListNode<T, K>['key']): ListNode<T, K> | undefined; diff --git a/node_modules/side-channel-list/package.json b/node_modules/side-channel-list/package.json new file mode 100644 index 0000000..bc4c08c --- /dev/null +++ b/node_modules/side-channel-list/package.json @@ -0,0 +1,77 @@ +{ + "name": "side-channel-list", + "version": "1.0.1", + "description": "Store information about any JS value in a side channel, using a linked list", + "main": "index.js", + "exports": { + ".": "./index.js", + "./package.json": "./package.json" + }, + "types": "./index.d.ts", + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prelint": "evalmd README.md && eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git')", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -p . && attw -P", + "pretest": "npm run lint", + "tests-only": "nyc tape 'test/**/*.js'", + "test": "npm run tests-only", + "posttest": "npx npm@'>= 10.2' audit --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ljharb/side-channel-list.git" + }, + "keywords": [], + "author": "Jordan Harband <ljharb@gmail.com>", + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/side-channel-list/issues" + }, + "homepage": "https://github.com/ljharb/side-channel-list#readme", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.18.2", + "@ljharb/eslint-config": "^22.2.2", + "@ljharb/tsconfig": "^0.3.2", + "@types/object-inspect": "^1.13.0", + "@types/tape": "^5.8.1", + "auto-changelog": "^2.5.0", + "eclint": "^2.8.1", + "encoding": "^0.1.13", + "eslint": "^8.57.1", + "evalmd": "^0.0.19", + "in-publish": "^2.0.1", + "npmignore": "^0.3.5", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "engines": { + "node": ">= 0.4" + } +} diff --git a/node_modules/side-channel-list/test/index.js b/node_modules/side-channel-list/test/index.js new file mode 100644 index 0000000..d1b915d --- /dev/null +++ b/node_modules/side-channel-list/test/index.js @@ -0,0 +1,154 @@ +'use strict'; + +var test = require('tape'); + +var getSideChannelList = require('../'); + +test('getSideChannelList', function (t) { + t.test('export', function (st) { + st.equal(typeof getSideChannelList, 'function', 'is a function'); + + st.equal(getSideChannelList.length, 0, 'takes no arguments'); + + var channel = getSideChannelList(); + st.ok(channel, 'is truthy'); + st.equal(typeof channel, 'object', 'is an object'); + st.end(); + }); + + t.test('assert', function (st) { + var channel = getSideChannelList(); + st['throws']( + function () { channel.assert({}); }, + TypeError, + 'nonexistent value throws' + ); + + var o = {}; + channel.set(o, 'data'); + st.doesNotThrow(function () { channel.assert(o); }, 'existent value noops'); + + st.end(); + }); + + t.test('has', function (st) { + var channel = getSideChannelList(); + /** @type {unknown[]} */ var o = []; + + st.equal(channel.has(o), false, 'nonexistent value yields false'); + + channel.set(o, 'foo'); + st.equal(channel.has(o), true, 'existent value yields true'); + + st.equal(channel.has('abc'), false, 'non object value non existent yields false'); + + channel.set('abc', 'foo'); + st.equal(channel.has('abc'), true, 'non object value that exists yields true'); + + st.end(); + }); + + t.test('get', function (st) { + var channel = getSideChannelList(); + var o = {}; + st.equal(channel.get(o), undefined, 'nonexistent value yields undefined'); + + var data = {}; + channel.set(o, data); + st.equal(channel.get(o), data, '"get" yields data set by "set"'); + + st.end(); + }); + + t.test('set', function (st) { + var channel = getSideChannelList(); + var o = function () {}; + st.equal(channel.get(o), undefined, 'value not set'); + + channel.set(o, 42); + st.equal(channel.get(o), 42, 'value was set'); + + channel.set(o, Infinity); + st.equal(channel.get(o), Infinity, 'value was set again'); + + var o2 = {}; + channel.set(o2, 17); + st.equal(channel.get(o), Infinity, 'o is not modified'); + st.equal(channel.get(o2), 17, 'o2 is set'); + + channel.set(o, 14); + st.equal(channel.get(o), 14, 'o is modified'); + st.equal(channel.get(o2), 17, 'o2 is not modified'); + + st.end(); + }); + + t.test('delete', function (st) { + var channel = getSideChannelList(); + var o = {}; + st.equal(channel['delete']({}), false, 'nonexistent value yields false'); + + channel.set(o, 42); + st.equal(channel.has(o), true, 'value is set'); + + st.equal(channel['delete']({}), false, 'nonexistent value still yields false'); + + st.equal(channel['delete'](o), true, 'deleted value yields true'); + + st.equal(channel.has(o), false, 'value is no longer set'); + + st.end(); + }); + + t.test('delete: first node in a multi-node list', function (st) { + var channel = getSideChannelList(); + + channel.set('a', 1); + channel.set('b', 2); + + st.equal(channel['delete']('b'), true, 'deleting first data node yields true'); + + st.equal(channel.has('a'), true, 'second node is still present after deleting first'); + st.equal(channel.get('a'), 1, 'second node value is intact after deleting first'); + st.equal(channel.has('b'), false, 'deleted node is gone'); + + st.end(); + }); + + t.test('delete: last remaining node empties the list', function (st) { + var channel = getSideChannelList(); + + channel.set('a', 1); + channel.set('b', 2); + + st.equal(channel['delete']('b'), true, 'delete first node'); + st.equal(channel['delete']('a'), true, 'delete second (last) node'); + + st.equal(channel.has('a'), false, 'a is gone'); + st.equal(channel.has('b'), false, 'b is gone'); + st.equal(channel.get('a'), undefined, 'get a yields undefined'); + + channel.set('c', 3); + st.equal(channel.get('c'), 3, 'can set new values after emptying'); + + st.end(); + }); + + t.test('delete: middle node in a multi-node list', function (st) { + var channel = getSideChannelList(); + + channel.set('a', 1); + channel.set('b', 2); + channel.set('c', 3); + + st.equal(channel['delete']('b'), true, 'deleting middle node yields true'); + + st.equal(channel.get('a'), 1, 'first node still intact'); + st.equal(channel.has('b'), false, 'middle node is gone'); + st.equal(channel.get('c'), 3, 'last node still intact'); + + st.end(); + }); + + t.end(); +}); diff --git a/node_modules/side-channel-list/tsconfig.json b/node_modules/side-channel-list/tsconfig.json new file mode 100644 index 0000000..d9a6668 --- /dev/null +++ b/node_modules/side-channel-list/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es2021", + }, + "exclude": [ + "coverage", + ], +} diff --git a/node_modules/side-channel-map/.editorconfig b/node_modules/side-channel-map/.editorconfig new file mode 100644 index 0000000..72e0eba --- /dev/null +++ b/node_modules/side-channel-map/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = tab +indent_size = 2 +trim_trailing_whitespace = true diff --git a/node_modules/side-channel-map/.eslintrc b/node_modules/side-channel-map/.eslintrc new file mode 100644 index 0000000..93978e7 --- /dev/null +++ b/node_modules/side-channel-map/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "max-lines-per-function": 0, + "multiline-comment-style": 1, + "new-cap": [2, { "capIsNewExceptions": ["GetIntrinsic"] }], + }, +} diff --git a/node_modules/side-channel-map/.github/FUNDING.yml b/node_modules/side-channel-map/.github/FUNDING.yml new file mode 100644 index 0000000..f2891bd --- /dev/null +++ b/node_modules/side-channel-map/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/side-channel-map +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/side-channel-map/.nycrc b/node_modules/side-channel-map/.nycrc new file mode 100644 index 0000000..1826526 --- /dev/null +++ b/node_modules/side-channel-map/.nycrc @@ -0,0 +1,13 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "lines": 86, + "statements": 85.93, + "functions": 82.43, + "branches": 76.06, + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/side-channel-map/CHANGELOG.md b/node_modules/side-channel-map/CHANGELOG.md new file mode 100644 index 0000000..b6ccea9 --- /dev/null +++ b/node_modules/side-channel-map/CHANGELOG.md @@ -0,0 +1,22 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.0.1](https://github.com/ljharb/side-channel-map/compare/v1.0.0...v1.0.1) - 2024-12-10 + +### Commits + +- [Deps] update `call-bound` [`6d05aaa`](https://github.com/ljharb/side-channel-map/commit/6d05aaa4ce5f2be4e7825df433d650696f0ba40f) +- [types] fix generics ordering [`11c0184`](https://github.com/ljharb/side-channel-map/commit/11c0184132ac11fdc16857e12682e148e5e9ee74) + +## v1.0.0 - 2024-12-10 + +### Commits + +- Initial implementation, tests, readme, types [`ad877b4`](https://github.com/ljharb/side-channel-map/commit/ad877b42926d46d63fff76a2bd01d2b4a01959a9) +- Initial commit [`28f8879`](https://github.com/ljharb/side-channel-map/commit/28f8879c512abe8fcf9b6a4dc7754a0287e5eba4) +- npm init [`2c9604e`](https://github.com/ljharb/side-channel-map/commit/2c9604e5aa40223e425ea7cea78f8a07697504bd) +- Only apps should have lockfiles [`5e7ba9c`](https://github.com/ljharb/side-channel-map/commit/5e7ba9cffe3ef42095815adc8ac1255b49bbadf5) diff --git a/node_modules/side-channel-map/LICENSE b/node_modules/side-channel-map/LICENSE new file mode 100644 index 0000000..f82f389 --- /dev/null +++ b/node_modules/side-channel-map/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Jordan Harband + +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. diff --git a/node_modules/side-channel-map/README.md b/node_modules/side-channel-map/README.md new file mode 100644 index 0000000..8fa6f77 --- /dev/null +++ b/node_modules/side-channel-map/README.md @@ -0,0 +1,62 @@ +# side-channel-map <sup>[![Version Badge][npm-version-svg]][package-url]</sup> + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +Store information about any JS value in a side channel, using a Map. + +Warning: if the `key` is an object, this implementation will leak memory until you `delete` it. +Use [`side-channel`](https://npmjs.com/side-channel) for the best available strategy. + +## Getting started + +```sh +npm install --save side-channel-map +``` + +## Usage/Examples + +```js +const assert = require('assert'); +const getSideChannelMap = require('side-channel-map'); + +const channel = getSideChannelMap(); + +const key = {}; +assert.equal(channel.has(key), false); +assert.throws(() => channel.assert(key), TypeError); + +channel.set(key, 42); + +channel.assert(key); // does not throw +assert.equal(channel.has(key), true); +assert.equal(channel.get(key), 42); + +channel.delete(key); +assert.equal(channel.has(key), false); +assert.throws(() => channel.assert(key), TypeError); +``` + +## Tests + +Clone the repo, `npm install`, and run `npm test` + +[package-url]: https://npmjs.org/package/side-channel-map +[npm-version-svg]: https://versionbadg.es/ljharb/side-channel-map.svg +[deps-svg]: https://david-dm.org/ljharb/side-channel-map.svg +[deps-url]: https://david-dm.org/ljharb/side-channel-map +[dev-deps-svg]: https://david-dm.org/ljharb/side-channel-map/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/side-channel-map#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/side-channel-map.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/side-channel-map.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/side-channel-map.svg +[downloads-url]: https://npm-stat.com/charts.html?package=side-channel-map +[codecov-image]: https://codecov.io/gh/ljharb/side-channel-map/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/side-channel-map/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/side-channel-map +[actions-url]: https://github.com/ljharb/side-channel-map/actions diff --git a/node_modules/side-channel-map/index.d.ts b/node_modules/side-channel-map/index.d.ts new file mode 100644 index 0000000..de33e89 --- /dev/null +++ b/node_modules/side-channel-map/index.d.ts @@ -0,0 +1,15 @@ +declare namespace getSideChannelMap { + type Channel<K, V> = { + assert: (key: K) => void; + has: (key: K) => boolean; + get: (key: K) => V | undefined; + set: (key: K, value: V) => void; + delete: (key: K) => boolean; + }; +} + +declare function getSideChannelMap<K, V>(): getSideChannelMap.Channel<K, V>; + +declare const x: false | typeof getSideChannelMap; + +export = x; diff --git a/node_modules/side-channel-map/index.js b/node_modules/side-channel-map/index.js new file mode 100644 index 0000000..e111100 --- /dev/null +++ b/node_modules/side-channel-map/index.js @@ -0,0 +1,68 @@ +'use strict'; + +var GetIntrinsic = require('get-intrinsic'); +var callBound = require('call-bound'); +var inspect = require('object-inspect'); + +var $TypeError = require('es-errors/type'); +var $Map = GetIntrinsic('%Map%', true); + +/** @type {<K, V>(thisArg: Map<K, V>, key: K) => V} */ +var $mapGet = callBound('Map.prototype.get', true); +/** @type {<K, V>(thisArg: Map<K, V>, key: K, value: V) => void} */ +var $mapSet = callBound('Map.prototype.set', true); +/** @type {<K, V>(thisArg: Map<K, V>, key: K) => boolean} */ +var $mapHas = callBound('Map.prototype.has', true); +/** @type {<K, V>(thisArg: Map<K, V>, key: K) => boolean} */ +var $mapDelete = callBound('Map.prototype.delete', true); +/** @type {<K, V>(thisArg: Map<K, V>) => number} */ +var $mapSize = callBound('Map.prototype.size', true); + +/** @type {import('.')} */ +module.exports = !!$Map && /** @type {Exclude<import('.'), false>} */ function getSideChannelMap() { + /** @typedef {ReturnType<typeof getSideChannelMap>} Channel */ + /** @typedef {Parameters<Channel['get']>[0]} K */ + /** @typedef {Parameters<Channel['set']>[1]} V */ + + /** @type {Map<K, V> | undefined} */ var $m; + + /** @type {Channel} */ + var channel = { + assert: function (key) { + if (!channel.has(key)) { + throw new $TypeError('Side channel does not contain ' + inspect(key)); + } + }, + 'delete': function (key) { + if ($m) { + var result = $mapDelete($m, key); + if ($mapSize($m) === 0) { + $m = void undefined; + } + return result; + } + return false; + }, + get: function (key) { // eslint-disable-line consistent-return + if ($m) { + return $mapGet($m, key); + } + }, + has: function (key) { + if ($m) { + return $mapHas($m, key); + } + return false; + }, + set: function (key, value) { + if (!$m) { + // @ts-expect-error TS can't handle narrowing a variable inside a closure + $m = new $Map(); + } + $mapSet($m, key, value); + } + }; + + // @ts-expect-error TODO: figure out why TS is erroring here + return channel; +}; diff --git a/node_modules/side-channel-map/package.json b/node_modules/side-channel-map/package.json new file mode 100644 index 0000000..18e8080 --- /dev/null +++ b/node_modules/side-channel-map/package.json @@ -0,0 +1,80 @@ +{ + "name": "side-channel-map", + "version": "1.0.1", + "description": "Store information about any JS value in a side channel, using a Map", + "main": "index.js", + "exports": { + ".": "./index.js", + "./package.json": "./package.json" + }, + "types": "./index.d.ts", + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prelint": "evalmd README.md && eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git')", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -p . && attw -P", + "pretest": "npm run lint", + "tests-only": "nyc tape 'test/**/*.js'", + "test": "npm run tests-only", + "posttest": "npx npm@'>= 10.2' audit --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ljharb/side-channel-map.git" + }, + "keywords": [], + "author": "Jordan Harband <ljharb@gmail.com>", + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/side-channel-map/issues" + }, + "homepage": "https://github.com/ljharb/side-channel-map#readme", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.1", + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.2", + "@types/get-intrinsic": "^1.2.3", + "@types/object-inspect": "^1.13.0", + "@types/tape": "^5.6.5", + "auto-changelog": "^2.5.0", + "eclint": "^2.8.1", + "encoding": "^0.1.13", + "eslint": "=8.8.0", + "evalmd": "^0.0.19", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "engines": { + "node": ">= 0.4" + } +} diff --git a/node_modules/side-channel-map/test/index.js b/node_modules/side-channel-map/test/index.js new file mode 100644 index 0000000..1743323 --- /dev/null +++ b/node_modules/side-channel-map/test/index.js @@ -0,0 +1,114 @@ +'use strict'; + +var test = require('tape'); + +var getSideChannelMap = require('../'); + +test('getSideChannelMap', { skip: typeof Map !== 'function' }, function (t) { + var getSideChannel = getSideChannelMap || function () { + throw new EvalError('should never happen'); + }; + + t.test('export', function (st) { + st.equal(typeof getSideChannel, 'function', 'is a function'); + + st.equal(getSideChannel.length, 0, 'takes no arguments'); + + var channel = getSideChannel(); + st.ok(channel, 'is truthy'); + st.equal(typeof channel, 'object', 'is an object'); + st.end(); + }); + + t.test('assert', function (st) { + var channel = getSideChannel(); + st['throws']( + function () { channel.assert({}); }, + TypeError, + 'nonexistent value throws' + ); + + var o = {}; + channel.set(o, 'data'); + st.doesNotThrow(function () { channel.assert(o); }, 'existent value noops'); + + st.end(); + }); + + t.test('has', function (st) { + var channel = getSideChannel(); + /** @type {unknown[]} */ var o = []; + + st.equal(channel.has(o), false, 'nonexistent value yields false'); + + channel.set(o, 'foo'); + st.equal(channel.has(o), true, 'existent value yields true'); + + st.equal(channel.has('abc'), false, 'non object value non existent yields false'); + + channel.set('abc', 'foo'); + st.equal(channel.has('abc'), true, 'non object value that exists yields true'); + + st.end(); + }); + + t.test('get', function (st) { + var channel = getSideChannel(); + var o = {}; + st.equal(channel.get(o), undefined, 'nonexistent value yields undefined'); + + var data = {}; + channel.set(o, data); + st.equal(channel.get(o), data, '"get" yields data set by "set"'); + + st.end(); + }); + + t.test('set', function (st) { + var channel = getSideChannel(); + var o = function () {}; + st.equal(channel.get(o), undefined, 'value not set'); + + channel.set(o, 42); + st.equal(channel.get(o), 42, 'value was set'); + + channel.set(o, Infinity); + st.equal(channel.get(o), Infinity, 'value was set again'); + + var o2 = {}; + channel.set(o2, 17); + st.equal(channel.get(o), Infinity, 'o is not modified'); + st.equal(channel.get(o2), 17, 'o2 is set'); + + channel.set(o, 14); + st.equal(channel.get(o), 14, 'o is modified'); + st.equal(channel.get(o2), 17, 'o2 is not modified'); + + st.end(); + }); + + t.test('delete', function (st) { + var channel = getSideChannel(); + var o = {}; + st.equal(channel['delete']({}), false, 'nonexistent value yields false'); + + channel.set(o, 42); + st.equal(channel.has(o), true, 'value is set'); + + st.equal(channel['delete']({}), false, 'nonexistent value still yields false'); + + st.equal(channel['delete'](o), true, 'deleted value yields true'); + + st.equal(channel.has(o), false, 'value is no longer set'); + + st.end(); + }); + + t.end(); +}); + +test('getSideChannelMap, no Maps', { skip: typeof Map === 'function' }, function (t) { + t.equal(getSideChannelMap, false, 'is false'); + + t.end(); +}); diff --git a/node_modules/side-channel-map/tsconfig.json b/node_modules/side-channel-map/tsconfig.json new file mode 100644 index 0000000..d9a6668 --- /dev/null +++ b/node_modules/side-channel-map/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es2021", + }, + "exclude": [ + "coverage", + ], +} diff --git a/node_modules/side-channel-weakmap/.editorconfig b/node_modules/side-channel-weakmap/.editorconfig new file mode 100644 index 0000000..72e0eba --- /dev/null +++ b/node_modules/side-channel-weakmap/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = tab +indent_size = 2 +trim_trailing_whitespace = true diff --git a/node_modules/side-channel-weakmap/.eslintrc b/node_modules/side-channel-weakmap/.eslintrc new file mode 100644 index 0000000..9b13ad8 --- /dev/null +++ b/node_modules/side-channel-weakmap/.eslintrc @@ -0,0 +1,12 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "id-length": 0, + "max-lines-per-function": 0, + "multiline-comment-style": 1, + "new-cap": [2, { "capIsNewExceptions": ["GetIntrinsic"] }], + }, +} diff --git a/node_modules/side-channel-weakmap/.github/FUNDING.yml b/node_modules/side-channel-weakmap/.github/FUNDING.yml new file mode 100644 index 0000000..2ae71cd --- /dev/null +++ b/node_modules/side-channel-weakmap/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/side-channel-weakmap +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/side-channel-weakmap/.nycrc b/node_modules/side-channel-weakmap/.nycrc new file mode 100644 index 0000000..1826526 --- /dev/null +++ b/node_modules/side-channel-weakmap/.nycrc @@ -0,0 +1,13 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "lines": 86, + "statements": 85.93, + "functions": 82.43, + "branches": 76.06, + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/side-channel-weakmap/CHANGELOG.md b/node_modules/side-channel-weakmap/CHANGELOG.md new file mode 100644 index 0000000..aba7ab0 --- /dev/null +++ b/node_modules/side-channel-weakmap/CHANGELOG.md @@ -0,0 +1,28 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.0.2](https://github.com/ljharb/side-channel-weakmap/compare/v1.0.1...v1.0.2) - 2024-12-10 + +### Commits + +- [types] fix generics ordering [`1b62e94`](https://github.com/ljharb/side-channel-weakmap/commit/1b62e94a2ad6ed30b640ba73c4a2535836c67289) + +## [v1.0.1](https://github.com/ljharb/side-channel-weakmap/compare/v1.0.0...v1.0.1) - 2024-12-10 + +### Commits + +- [types] fix generics ordering [`08a4a5d`](https://github.com/ljharb/side-channel-weakmap/commit/08a4a5dbffedc3ebc79f1aaaf5a3dd6d2196dc1b) +- [Deps] update `side-channel-map` [`b53fe44`](https://github.com/ljharb/side-channel-weakmap/commit/b53fe447dfdd3a9aebedfd015b384eac17fce916) + +## v1.0.0 - 2024-12-10 + +### Commits + +- Initial implementation, tests, readme, types [`53c0fa4`](https://github.com/ljharb/side-channel-weakmap/commit/53c0fa4788435a006f58b9d7b43cb65989ecee49) +- Initial commit [`a157947`](https://github.com/ljharb/side-channel-weakmap/commit/a157947f26fcaf2c4a941d3a044e76bf67343532) +- npm init [`54dfc55`](https://github.com/ljharb/side-channel-weakmap/commit/54dfc55bafb16265910d5aad4e743c43aee5bbbb) +- Only apps should have lockfiles [`0ddd6c7`](https://github.com/ljharb/side-channel-weakmap/commit/0ddd6c7b07fe8ee04d67b2e9f7255af7ce62c07d) diff --git a/node_modules/side-channel-weakmap/LICENSE b/node_modules/side-channel-weakmap/LICENSE new file mode 100644 index 0000000..3900dd7 --- /dev/null +++ b/node_modules/side-channel-weakmap/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Jordan Harband + +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. diff --git a/node_modules/side-channel-weakmap/README.md b/node_modules/side-channel-weakmap/README.md new file mode 100644 index 0000000..856ee36 --- /dev/null +++ b/node_modules/side-channel-weakmap/README.md @@ -0,0 +1,62 @@ +# side-channel-weakmap <sup>[![Version Badge][npm-version-svg]][package-url]</sup> + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +Store information about any JS value in a side channel. Uses WeakMap if available. + +Warning: this implementation will leak memory until you `delete` the `key`. +Use [`side-channel`](https://npmjs.com/side-channel) for the best available strategy. + +## Getting started + +```sh +npm install --save side-channel-weakmap +``` + +## Usage/Examples + +```js +const assert = require('assert'); +const getSideChannelList = require('side-channel-weakmap'); + +const channel = getSideChannelList(); + +const key = {}; +assert.equal(channel.has(key), false); +assert.throws(() => channel.assert(key), TypeError); + +channel.set(key, 42); + +channel.assert(key); // does not throw +assert.equal(channel.has(key), true); +assert.equal(channel.get(key), 42); + +channel.delete(key); +assert.equal(channel.has(key), false); +assert.throws(() => channel.assert(key), TypeError); +``` + +## Tests + +Clone the repo, `npm install`, and run `npm test` + +[package-url]: https://npmjs.org/package/side-channel-weakmap +[npm-version-svg]: https://versionbadg.es/ljharb/side-channel-weakmap.svg +[deps-svg]: https://david-dm.org/ljharb/side-channel-weakmap.svg +[deps-url]: https://david-dm.org/ljharb/side-channel-weakmap +[dev-deps-svg]: https://david-dm.org/ljharb/side-channel-weakmap/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/side-channel-weakmap#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/side-channel-weakmap.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/side-channel-weakmap.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/side-channel-weakmap.svg +[downloads-url]: https://npm-stat.com/charts.html?package=side-channel-weakmap +[codecov-image]: https://codecov.io/gh/ljharb/side-channel-weakmap/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/side-channel-weakmap/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/side-channel-weakmap +[actions-url]: https://github.com/ljharb/side-channel-weakmap/actions diff --git a/node_modules/side-channel-weakmap/index.d.ts b/node_modules/side-channel-weakmap/index.d.ts new file mode 100644 index 0000000..ce1bc2a --- /dev/null +++ b/node_modules/side-channel-weakmap/index.d.ts @@ -0,0 +1,15 @@ +declare namespace getSideChannelWeakMap { + type Channel<K, V> = { + assert: (key: K) => void; + has: (key: K) => boolean; + get: (key: K) => V | undefined; + set: (key: K, value: V) => void; + delete: (key: K) => boolean; + } +} + +declare function getSideChannelWeakMap<K, V>(): getSideChannelWeakMap.Channel<K, V>; + +declare const x: false | typeof getSideChannelWeakMap; + +export = x; diff --git a/node_modules/side-channel-weakmap/index.js b/node_modules/side-channel-weakmap/index.js new file mode 100644 index 0000000..e5b8183 --- /dev/null +++ b/node_modules/side-channel-weakmap/index.js @@ -0,0 +1,84 @@ +'use strict'; + +var GetIntrinsic = require('get-intrinsic'); +var callBound = require('call-bound'); +var inspect = require('object-inspect'); +var getSideChannelMap = require('side-channel-map'); + +var $TypeError = require('es-errors/type'); +var $WeakMap = GetIntrinsic('%WeakMap%', true); + +/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K) => V} */ +var $weakMapGet = callBound('WeakMap.prototype.get', true); +/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K, value: V) => void} */ +var $weakMapSet = callBound('WeakMap.prototype.set', true); +/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K) => boolean} */ +var $weakMapHas = callBound('WeakMap.prototype.has', true); +/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K) => boolean} */ +var $weakMapDelete = callBound('WeakMap.prototype.delete', true); + +/** @type {import('.')} */ +module.exports = $WeakMap + ? /** @type {Exclude<import('.'), false>} */ function getSideChannelWeakMap() { + /** @typedef {ReturnType<typeof getSideChannelWeakMap>} Channel */ + /** @typedef {Parameters<Channel['get']>[0]} K */ + /** @typedef {Parameters<Channel['set']>[1]} V */ + + /** @type {WeakMap<K & object, V> | undefined} */ var $wm; + /** @type {Channel | undefined} */ var $m; + + /** @type {Channel} */ + var channel = { + assert: function (key) { + if (!channel.has(key)) { + throw new $TypeError('Side channel does not contain ' + inspect(key)); + } + }, + 'delete': function (key) { + if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { + if ($wm) { + return $weakMapDelete($wm, key); + } + } else if (getSideChannelMap) { + if ($m) { + return $m['delete'](key); + } + } + return false; + }, + get: function (key) { + if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { + if ($wm) { + return $weakMapGet($wm, key); + } + } + return $m && $m.get(key); + }, + has: function (key) { + if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { + if ($wm) { + return $weakMapHas($wm, key); + } + } + return !!$m && $m.has(key); + }, + set: function (key, value) { + if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) { + if (!$wm) { + $wm = new $WeakMap(); + } + $weakMapSet($wm, key, value); + } else if (getSideChannelMap) { + if (!$m) { + $m = getSideChannelMap(); + } + // eslint-disable-next-line no-extra-parens + /** @type {NonNullable<typeof $m>} */ ($m).set(key, value); + } + } + }; + + // @ts-expect-error TODO: figure out why this is erroring + return channel; + } + : getSideChannelMap; diff --git a/node_modules/side-channel-weakmap/package.json b/node_modules/side-channel-weakmap/package.json new file mode 100644 index 0000000..9ef6583 --- /dev/null +++ b/node_modules/side-channel-weakmap/package.json @@ -0,0 +1,87 @@ +{ + "name": "side-channel-weakmap", + "version": "1.0.2", + "description": "Store information about any JS value in a side channel. Uses WeakMap if available.", + "main": "index.js", + "exports": { + ".": "./index.js", + "./package.json": "./package.json" + }, + "types": "./index.d.ts", + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prelint": "eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git')", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -p . && attw -P", + "pretest": "npm run lint", + "tests-only": "nyc tape 'test/**/*.js'", + "test": "npm run tests-only", + "posttest": "npx npm@'>=10.2' audit --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ljharb/side-channel-weakmap.git" + }, + "keywords": [ + "weakmap", + "map", + "side", + "channel", + "metadata" + ], + "author": "Jordan Harband <ljharb@gmail.com>", + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/side-channel-weakmap/issues" + }, + "homepage": "https://github.com/ljharb/side-channel-weakmap#readme", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.1", + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.2", + "@types/call-bind": "^1.0.5", + "@types/get-intrinsic": "^1.2.3", + "@types/object-inspect": "^1.13.0", + "@types/tape": "^5.6.5", + "auto-changelog": "^2.5.0", + "eclint": "^2.8.1", + "encoding": "^0.1.13", + "eslint": "=8.8.0", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "engines": { + "node": ">= 0.4" + } +} diff --git a/node_modules/side-channel-weakmap/test/index.js b/node_modules/side-channel-weakmap/test/index.js new file mode 100644 index 0000000..a01248b --- /dev/null +++ b/node_modules/side-channel-weakmap/test/index.js @@ -0,0 +1,114 @@ +'use strict'; + +var test = require('tape'); + +var getSideChannelWeakMap = require('../'); + +test('getSideChannelMap', { skip: typeof WeakMap !== 'function' && typeof Map !== 'function' }, function (t) { + var getSideChannel = getSideChannelWeakMap || function () { + throw new EvalError('should never happen'); + }; + + t.test('export', function (st) { + st.equal(typeof getSideChannel, 'function', 'is a function'); + + st.equal(getSideChannel.length, 0, 'takes no arguments'); + + var channel = getSideChannel(); + st.ok(channel, 'is truthy'); + st.equal(typeof channel, 'object', 'is an object'); + st.end(); + }); + + t.test('assert', function (st) { + var channel = getSideChannel(); + st['throws']( + function () { channel.assert({}); }, + TypeError, + 'nonexistent value throws' + ); + + var o = {}; + channel.set(o, 'data'); + st.doesNotThrow(function () { channel.assert(o); }, 'existent value noops'); + + st.end(); + }); + + t.test('has', function (st) { + var channel = getSideChannel(); + /** @type {unknown[]} */ var o = []; + + st.equal(channel.has(o), false, 'nonexistent value yields false'); + + channel.set(o, 'foo'); + st.equal(channel.has(o), true, 'existent value yields true'); + + st.equal(channel.has('abc'), false, 'non object value non existent yields false'); + + channel.set('abc', 'foo'); + st.equal(channel.has('abc'), true, 'non object value that exists yields true'); + + st.end(); + }); + + t.test('get', function (st) { + var channel = getSideChannel(); + var o = {}; + st.equal(channel.get(o), undefined, 'nonexistent value yields undefined'); + + var data = {}; + channel.set(o, data); + st.equal(channel.get(o), data, '"get" yields data set by "set"'); + + st.end(); + }); + + t.test('set', function (st) { + var channel = getSideChannel(); + var o = function () {}; + st.equal(channel.get(o), undefined, 'value not set'); + + channel.set(o, 42); + st.equal(channel.get(o), 42, 'value was set'); + + channel.set(o, Infinity); + st.equal(channel.get(o), Infinity, 'value was set again'); + + var o2 = {}; + channel.set(o2, 17); + st.equal(channel.get(o), Infinity, 'o is not modified'); + st.equal(channel.get(o2), 17, 'o2 is set'); + + channel.set(o, 14); + st.equal(channel.get(o), 14, 'o is modified'); + st.equal(channel.get(o2), 17, 'o2 is not modified'); + + st.end(); + }); + + t.test('delete', function (st) { + var channel = getSideChannel(); + var o = {}; + st.equal(channel['delete']({}), false, 'nonexistent value yields false'); + + channel.set(o, 42); + st.equal(channel.has(o), true, 'value is set'); + + st.equal(channel['delete']({}), false, 'nonexistent value still yields false'); + + st.equal(channel['delete'](o), true, 'deleted value yields true'); + + st.equal(channel.has(o), false, 'value is no longer set'); + + st.end(); + }); + + t.end(); +}); + +test('getSideChannelMap, no WeakMaps and/or Maps', { skip: typeof WeakMap === 'function' || typeof Map === 'function' }, function (t) { + t.equal(getSideChannelWeakMap, false, 'is false'); + + t.end(); +}); diff --git a/node_modules/side-channel-weakmap/tsconfig.json b/node_modules/side-channel-weakmap/tsconfig.json new file mode 100644 index 0000000..d9a6668 --- /dev/null +++ b/node_modules/side-channel-weakmap/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es2021", + }, + "exclude": [ + "coverage", + ], +} diff --git a/node_modules/side-channel/.editorconfig b/node_modules/side-channel/.editorconfig new file mode 100644 index 0000000..72e0eba --- /dev/null +++ b/node_modules/side-channel/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = tab +indent_size = 2 +trim_trailing_whitespace = true diff --git a/node_modules/side-channel/.eslintrc b/node_modules/side-channel/.eslintrc new file mode 100644 index 0000000..9b13ad8 --- /dev/null +++ b/node_modules/side-channel/.eslintrc @@ -0,0 +1,12 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "id-length": 0, + "max-lines-per-function": 0, + "multiline-comment-style": 1, + "new-cap": [2, { "capIsNewExceptions": ["GetIntrinsic"] }], + }, +} diff --git a/node_modules/side-channel/.github/FUNDING.yml b/node_modules/side-channel/.github/FUNDING.yml new file mode 100644 index 0000000..2a94840 --- /dev/null +++ b/node_modules/side-channel/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/side-channel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/side-channel/.nycrc b/node_modules/side-channel/.nycrc new file mode 100644 index 0000000..1826526 --- /dev/null +++ b/node_modules/side-channel/.nycrc @@ -0,0 +1,13 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "lines": 86, + "statements": 85.93, + "functions": 82.43, + "branches": 76.06, + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/side-channel/CHANGELOG.md b/node_modules/side-channel/CHANGELOG.md new file mode 100644 index 0000000..decafe5 --- /dev/null +++ b/node_modules/side-channel/CHANGELOG.md @@ -0,0 +1,120 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.1.1](https://github.com/ljharb/side-channel/compare/v1.1.0...v1.1.1) - 2026-06-08 + +### Commits + +- [Fix] `assert`: do not observably access object keys when throwing [`fc17361`](https://github.com/ljharb/side-channel/commit/fc173615136e6a6c3194656e6088afbc0bd6f9b8) +- [actions] update workflows [`35b18c0`](https://github.com/ljharb/side-channel/commit/35b18c0bced5769d59226cd44a7e4003ad0aee81) +- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/tape`, `auto-changelog`, `eslint`, `npmignore` [`b456a01`](https://github.com/ljharb/side-channel/commit/b456a01396cfdd028e5d39ea84885fe9178a72cf) +- [Deps] update `object-inspect`, `side-channel-list` [`accf1a1`](https://github.com/ljharb/side-channel/commit/accf1a1a2767a22b1f5eeb5769a1db4c35a78090) +- [readme] replace runkit CI badge with shields.io check-runs badge [`7e0c956`](https://github.com/ljharb/side-channel/commit/7e0c956411cc29267197a49a155a3d9bd01bacac) + +## [v1.1.0](https://github.com/ljharb/side-channel/compare/v1.0.6...v1.1.0) - 2024-12-11 + +### Commits + +- [Refactor] extract implementations to `side-channel-weakmap`, `side-channel-map`, `side-channel-list` [`ada5955`](https://github.com/ljharb/side-channel/commit/ada595549a5c4c6c853756d598846b180941c6da) +- [New] add `channel.delete` [`c01d2d3`](https://github.com/ljharb/side-channel/commit/c01d2d3fd51dbb1ce6da72ad7916e61bd6172aad) +- [types] improve types [`0c54356`](https://github.com/ljharb/side-channel/commit/0c5435651417df41b8cc1a5f7cdce8bffae68cde) +- [readme] add content [`be24868`](https://github.com/ljharb/side-channel/commit/be248682ac294b0e22c883092c45985aa91c490a) +- [actions] split out node 10-20, and 20+ [`c4488e2`](https://github.com/ljharb/side-channel/commit/c4488e241ef3d49a19fe266ac830a2e644305911) +- [types] use shared tsconfig [`0e0d57c`](https://github.com/ljharb/side-channel/commit/0e0d57c2ff17c7b45c6cbd43ebcf553edc9e3adc) +- [Dev Deps] update `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/get-intrinsic`, `@types/object-inspect`, `@types/tape`, `auto-changelog`, `tape` [`fb4f622`](https://github.com/ljharb/side-channel/commit/fb4f622e64a99a1e40b6e5cd7691674a9dc429e4) +- [Deps] update `call-bind`, `get-intrinsic`, `object-inspect` [`b78336b`](https://github.com/ljharb/side-channel/commit/b78336b886172d1b457d414ac9e28de8c5fecc78) +- [Tests] replace `aud` with `npm audit` [`ee3ab46`](https://github.com/ljharb/side-channel/commit/ee3ab4690d954311c35115651bcfd45edd205aa1) +- [Dev Deps] add missing peer dep [`c03e21a`](https://github.com/ljharb/side-channel/commit/c03e21a7def3b67cdc15ae22316884fefcb2f6a8) + +## [v1.0.6](https://github.com/ljharb/side-channel/compare/v1.0.5...v1.0.6) - 2024-02-29 + +### Commits + +- add types [`9beef66`](https://github.com/ljharb/side-channel/commit/9beef6643e6d717ea57bedabf86448123a7dd9e9) +- [meta] simplify `exports` [`4334cf9`](https://github.com/ljharb/side-channel/commit/4334cf9df654151504c383b62a2f9ebdc8d9d5ac) +- [Deps] update `call-bind` [`d6043c4`](https://github.com/ljharb/side-channel/commit/d6043c4d8f4d7be9037dd0f0419c7a2e0e39ec6a) +- [Dev Deps] update `tape` [`6aca376`](https://github.com/ljharb/side-channel/commit/6aca3761868dc8cd5ff7fd9799bf6b95e09a6eb0) + +## [v1.0.5](https://github.com/ljharb/side-channel/compare/v1.0.4...v1.0.5) - 2024-02-06 + +### Commits + +- [actions] reuse common workflows [`3d2e1ff`](https://github.com/ljharb/side-channel/commit/3d2e1ffd16dd6eaaf3e40ff57951f840d2d63c04) +- [meta] use `npmignore` to autogenerate an npmignore file [`04296ea`](https://github.com/ljharb/side-channel/commit/04296ea17d1544b0a5d20fd5bfb31aa4f6513eb9) +- [meta] add `.editorconfig`; add `eclint` [`130f0a6`](https://github.com/ljharb/side-channel/commit/130f0a6adbc04d385c7456a601d38344dce3d6a9) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `safe-publish-latest`, `tape` [`d480c2f`](https://github.com/ljharb/side-channel/commit/d480c2fbe757489ae9b4275491ffbcc3ac4725e9) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `tape` [`ecbe70e`](https://github.com/ljharb/side-channel/commit/ecbe70e53a418234081a77971fec1fdfae20c841) +- [actions] update rebase action [`75240b9`](https://github.com/ljharb/side-channel/commit/75240b9963b816e8846400d2287cb68f88c7fba7) +- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `npmignore`, `tape` [`ae8d281`](https://github.com/ljharb/side-channel/commit/ae8d281572430099109870fd9430d2ca3f320b8d) +- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `tape` [`7125b88`](https://github.com/ljharb/side-channel/commit/7125b885fd0eacad4fee9b073b72d14065ece278) +- [Deps] update `call-bind`, `get-intrinsic`, `object-inspect` [`82577c9`](https://github.com/ljharb/side-channel/commit/82577c9796304519139a570f82a317211b5f3b86) +- [Deps] update `call-bind`, `get-intrinsic`, `object-inspect` [`550aadf`](https://github.com/ljharb/side-channel/commit/550aadf20475a6081fd70304cc54f77259a5c8a8) +- [Tests] increase coverage [`5130877`](https://github.com/ljharb/side-channel/commit/5130877a7b27c862e64e6d1c12a178b28808859d) +- [Deps] update `get-intrinsic`, `object-inspect` [`ba0194c`](https://github.com/ljharb/side-channel/commit/ba0194c505b1a8a0427be14cadd5b8a46d4d01b8) +- [meta] add missing `engines.node` [`985fd24`](https://github.com/ljharb/side-channel/commit/985fd249663cb06617a693a94fe08cad12f5cb70) +- [Refactor] use `es-errors`, so things that only need those do not need `get-intrinsic` [`40227a8`](https://github.com/ljharb/side-channel/commit/40227a87b01709ad2c0eebf87eb4223a800099b9) +- [Deps] update `get-intrinsic` [`a989b40`](https://github.com/ljharb/side-channel/commit/a989b4024958737ae7be9fbffdeff2078f33a0fd) +- [Deps] update `object-inspect` [`aec42d2`](https://github.com/ljharb/side-channel/commit/aec42d2ec541a31aaa02475692c87d489237d9a3) + +## [v1.0.4](https://github.com/ljharb/side-channel/compare/v1.0.3...v1.0.4) - 2020-12-29 + +### Commits + +- [Tests] migrate tests to Github Actions [`10909cb`](https://github.com/ljharb/side-channel/commit/10909cbf8ce9c0bf96f604cf13d7ffd5a22c2d40) +- [Refactor] Use a linked list rather than an array, and move accessed nodes to the beginning [`195613f`](https://github.com/ljharb/side-channel/commit/195613f28b5c1e6072ef0b61b5beebaf2b6a304e) +- [meta] do not publish github action workflow files [`290ec29`](https://github.com/ljharb/side-channel/commit/290ec29cd21a60585145b4a7237ec55228c52c27) +- [Tests] run `nyc` on all tests; use `tape` runner [`ea6d030`](https://github.com/ljharb/side-channel/commit/ea6d030ff3fe6be2eca39e859d644c51ecd88869) +- [actions] add "Allow Edits" workflow [`d464d8f`](https://github.com/ljharb/side-channel/commit/d464d8fe52b5eddf1504a0ed97f0941a90f32c15) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog` [`02daca8`](https://github.com/ljharb/side-channel/commit/02daca87c6809821c97be468d1afa2f5ef447383) +- [Refactor] use `call-bind` and `get-intrinsic` instead of `es-abstract` [`e09d481`](https://github.com/ljharb/side-channel/commit/e09d481528452ebafa5cdeae1af665c35aa2deee) +- [Deps] update `object.assign` [`ee83aa8`](https://github.com/ljharb/side-channel/commit/ee83aa81df313b5e46319a63adb05cf0c179079a) +- [actions] update rebase action to use checkout v2 [`7726b0b`](https://github.com/ljharb/side-channel/commit/7726b0b058b632fccea709f58960871defaaa9d7) + +## [v1.0.3](https://github.com/ljharb/side-channel/compare/v1.0.2...v1.0.3) - 2020-08-23 + +### Commits + +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `tape` [`1f10561`](https://github.com/ljharb/side-channel/commit/1f105611ef3acf32dec8032ae5c0baa5e56bb868) +- [Deps] update `es-abstract`, `object-inspect` [`bc20159`](https://github.com/ljharb/side-channel/commit/bc201597949a505e37cef9eaf24c7010831e6f03) +- [Dev Deps] update `@ljharb/eslint-config`, `tape` [`b9b2b22`](https://github.com/ljharb/side-channel/commit/b9b2b225f9e0ea72a6ec2b89348f0bd690bc9ed1) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape` [`7055ab4`](https://github.com/ljharb/side-channel/commit/7055ab4de0860606efd2003674a74f1fe6ebc07e) +- [Dev Deps] update `auto-changelog`; add `aud` [`d278c37`](https://github.com/ljharb/side-channel/commit/d278c37d08227be4f84aa769fcd919e73feeba40) +- [actions] switch Automatic Rebase workflow to `pull_request_target` event [`3bcf982`](https://github.com/ljharb/side-channel/commit/3bcf982faa122745b39c33ce83d32fdf003741c6) +- [Tests] only audit prod deps [`18d01c4`](https://github.com/ljharb/side-channel/commit/18d01c4015b82a3d75044c4d5ba7917b2eac01ec) +- [Deps] update `es-abstract` [`6ab096d`](https://github.com/ljharb/side-channel/commit/6ab096d9de2b482cf5e0717e34e212f5b2b9bc9a) +- [Dev Deps] update `tape` [`9dc174c`](https://github.com/ljharb/side-channel/commit/9dc174cc651dfd300b4b72da936a0a7eda5f9452) +- [Deps] update `es-abstract` [`431d0f0`](https://github.com/ljharb/side-channel/commit/431d0f0ff11fbd2ae6f3115582a356d3a1cfce82) +- [Deps] update `es-abstract` [`49869fd`](https://github.com/ljharb/side-channel/commit/49869fd323bf4453f0ba515c0fb265cf5ab7b932) +- [meta] Add package.json to package's exports [`77d9cdc`](https://github.com/ljharb/side-channel/commit/77d9cdceb2a9e47700074f2ae0c0a202e7dac0d4) + +## [v1.0.2](https://github.com/ljharb/side-channel/compare/v1.0.1...v1.0.2) - 2019-12-20 + +### Commits + +- [Dev Deps] update `@ljharb/eslint-config`, `tape` [`4a526df`](https://github.com/ljharb/side-channel/commit/4a526df44e4701566ed001ec78546193f818b082) +- [Deps] update `es-abstract` [`d4f6e62`](https://github.com/ljharb/side-channel/commit/d4f6e629b6fb93a07415db7f30d3c90fd7f264fe) + +## [v1.0.1](https://github.com/ljharb/side-channel/compare/v1.0.0...v1.0.1) - 2019-12-01 + +### Commits + +- [Fix] add missing "exports" [`d212907`](https://github.com/ljharb/side-channel/commit/d2129073abf0701a5343bf28aa2145617604dc2e) + +## v1.0.0 - 2019-12-01 + +### Commits + +- Initial implementation [`dbebd3a`](https://github.com/ljharb/side-channel/commit/dbebd3a4b5ed64242f9a6810efe7c4214cd8cde4) +- Initial tests [`73bdefe`](https://github.com/ljharb/side-channel/commit/73bdefe568c9076cf8c0b8719bc2141aec0e19b8) +- Initial commit [`43c03e1`](https://github.com/ljharb/side-channel/commit/43c03e1c2849ec50a87b7a5cd76238a62b0b8770) +- npm init [`5c090a7`](https://github.com/ljharb/side-channel/commit/5c090a765d66a5527d9889b89aeff78dee91348c) +- [meta] add `auto-changelog` [`a5c4e56`](https://github.com/ljharb/side-channel/commit/a5c4e5675ec02d5eb4d84b4243aeea2a1d38fbec) +- [actions] add automatic rebasing / merge commit blocking [`bab1683`](https://github.com/ljharb/side-channel/commit/bab1683d8f9754b086e94397699fdc645e0d7077) +- [meta] add `funding` field; create FUNDING.yml [`63d7aea`](https://github.com/ljharb/side-channel/commit/63d7aeaf34f5650650ae97ca4b9fae685bd0937c) +- [Tests] add `npm run lint` [`46a5a81`](https://github.com/ljharb/side-channel/commit/46a5a81705cd2664f83df232c01dbbf2ee952885) +- Only apps should have lockfiles [`8b16b03`](https://github.com/ljharb/side-channel/commit/8b16b0305f00895d90c4e2e5773c854cfea0e448) +- [meta] add `safe-publish-latest` [`2f098ef`](https://github.com/ljharb/side-channel/commit/2f098ef092a39399cfe548b19a1fc03c2fd2f490) diff --git a/node_modules/side-channel/LICENSE b/node_modules/side-channel/LICENSE new file mode 100644 index 0000000..3900dd7 --- /dev/null +++ b/node_modules/side-channel/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Jordan Harband + +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. diff --git a/node_modules/side-channel/README.md b/node_modules/side-channel/README.md new file mode 100644 index 0000000..73ba466 --- /dev/null +++ b/node_modules/side-channel/README.md @@ -0,0 +1,61 @@ +# side-channel <sup>[![Version Badge][npm-version-svg]][package-url]</sup> + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +Store information about any JS value in a side channel. Uses WeakMap if available. + +Warning: in an environment that lacks `WeakMap`, this implementation will leak memory until you `delete` the `key`. + +## Getting started + +```sh +npm install --save side-channel +``` + +## Usage/Examples + +```js +const assert = require('assert'); +const getSideChannel = require('side-channel'); + +const channel = getSideChannel(); + +const key = {}; +assert.equal(channel.has(key), false); +assert.throws(() => channel.assert(key), TypeError); + +channel.set(key, 42); + +channel.assert(key); // does not throw +assert.equal(channel.has(key), true); +assert.equal(channel.get(key), 42); + +channel.delete(key); +assert.equal(channel.has(key), false); +assert.throws(() => channel.assert(key), TypeError); +``` + +## Tests + +Clone the repo, `npm install`, and run `npm test` + +[package-url]: https://npmjs.org/package/side-channel +[npm-version-svg]: https://versionbadg.es/ljharb/side-channel.svg +[deps-svg]: https://david-dm.org/ljharb/side-channel.svg +[deps-url]: https://david-dm.org/ljharb/side-channel +[dev-deps-svg]: https://david-dm.org/ljharb/side-channel/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/side-channel#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/side-channel.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/side-channel.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/side-channel.svg +[downloads-url]: https://npm-stat.com/charts.html?package=side-channel +[codecov-image]: https://codecov.io/gh/ljharb/side-channel/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/side-channel/ +[actions-image]: https://img.shields.io/github/check-runs/ljharb/side-channel/main +[actions-url]: https://github.com/ljharb/side-channel/actions diff --git a/node_modules/side-channel/index.d.ts b/node_modules/side-channel/index.d.ts new file mode 100644 index 0000000..18c6317 --- /dev/null +++ b/node_modules/side-channel/index.d.ts @@ -0,0 +1,14 @@ +import getSideChannelList from 'side-channel-list'; +import getSideChannelMap from 'side-channel-map'; +import getSideChannelWeakMap from 'side-channel-weakmap'; + +declare namespace getSideChannel { + type Channel<K, V> = + | getSideChannelList.Channel<K, V> + | ReturnType<Exclude<typeof getSideChannelMap<K, V>, false>> + | ReturnType<Exclude<typeof getSideChannelWeakMap<K, V>, false>>; +} + +declare function getSideChannel<K, V>(): getSideChannel.Channel<K, V>; + +export = getSideChannel; diff --git a/node_modules/side-channel/index.js b/node_modules/side-channel/index.js new file mode 100644 index 0000000..c5fe1fa --- /dev/null +++ b/node_modules/side-channel/index.js @@ -0,0 +1,46 @@ +'use strict'; + +var $TypeError = require('es-errors/type'); +var inspect = require('object-inspect'); +var getSideChannelList = require('side-channel-list'); +var getSideChannelMap = require('side-channel-map'); +var getSideChannelWeakMap = require('side-channel-weakmap'); + +var makeChannel = getSideChannelWeakMap || getSideChannelMap || getSideChannelList; + +/** @type {import('.')} */ +module.exports = function getSideChannel() { + /** @typedef {ReturnType<typeof getSideChannel>} Channel */ + + /** @type {Channel | undefined} */ var $channelData; + + /** @type {Channel} */ + var channel = { + assert: function (key) { + if (!channel.has(key)) { + var keyDesc = key && Object(key) === key + ? 'the given object key' + : inspect(key); + throw new $TypeError('Side channel does not contain ' + keyDesc); + } + }, + 'delete': function (key) { + return !!$channelData && $channelData['delete'](key); + }, + get: function (key) { + return $channelData && $channelData.get(key); + }, + has: function (key) { + return !!$channelData && $channelData.has(key); + }, + set: function (key, value) { + if (!$channelData) { + $channelData = makeChannel(); + } + + $channelData.set(key, value); + } + }; + + return channel; +}; diff --git a/node_modules/side-channel/package.json b/node_modules/side-channel/package.json new file mode 100644 index 0000000..e39158e --- /dev/null +++ b/node_modules/side-channel/package.json @@ -0,0 +1,85 @@ +{ + "name": "side-channel", + "version": "1.1.1", + "description": "Store information about any JS value in a side channel. Uses WeakMap if available.", + "main": "index.js", + "exports": { + ".": "./index.js", + "./package.json": "./package.json" + }, + "types": "./index.d.ts", + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prelint": "eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git')", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -p . && attw -P", + "pretest": "npm run lint", + "tests-only": "nyc tape 'test/**/*.js'", + "test": "npm run tests-only", + "posttest": "npx npm@'>=10.2' audit --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ljharb/side-channel.git" + }, + "keywords": [ + "weakmap", + "map", + "side", + "channel", + "metadata" + ], + "author": "Jordan Harband <ljharb@gmail.com>", + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/side-channel/issues" + }, + "homepage": "https://github.com/ljharb/side-channel#readme", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.18.3", + "@ljharb/eslint-config": "^22.2.3", + "@ljharb/tsconfig": "^0.3.2", + "@types/object-inspect": "^1.13.0", + "@types/tape": "^5.8.1", + "auto-changelog": "^2.6.0", + "eclint": "^2.8.1", + "encoding": "^0.1.13", + "eslint": "^8.57.1", + "in-publish": "^2.0.1", + "npmignore": "^0.3.5", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "engines": { + "node": ">= 0.4" + } +} diff --git a/node_modules/side-channel/test/index.js b/node_modules/side-channel/test/index.js new file mode 100644 index 0000000..5d28efd --- /dev/null +++ b/node_modules/side-channel/test/index.js @@ -0,0 +1,120 @@ +'use strict'; + +var test = require('tape'); + +var getSideChannel = require('../'); + +test('getSideChannel', function (t) { + t.test('export', function (st) { + st.equal(typeof getSideChannel, 'function', 'is a function'); + + st.equal(getSideChannel.length, 0, 'takes no arguments'); + + var channel = getSideChannel(); + st.ok(channel, 'is truthy'); + st.equal(typeof channel, 'object', 'is an object'); + st.end(); + }); + + t.test('assert', function (st) { + var channel = getSideChannel(); + st['throws']( + function () { channel.assert({}); }, + TypeError, + 'nonexistent value throws' + ); + + var o = {}; + channel.set(o, 'data'); + st.doesNotThrow(function () { channel.assert(o); }, 'existent value noops'); + + var accessed = false; + var trap = {}; + Object.defineProperty(trap, 'foo', { + enumerable: true, + get: function () { + accessed = true; + return 1; + } + }); + st['throws']( + function () { channel.assert(trap); }, + TypeError, + 'missing object key throws' + ); + st.equal(accessed, false, 'a missing object key is not observably accessed'); + + st.end(); + }); + + t.test('has', function (st) { + var channel = getSideChannel(); + /** @type {unknown[]} */ var o = []; + + st.equal(channel.has(o), false, 'nonexistent value yields false'); + + channel.set(o, 'foo'); + st.equal(channel.has(o), true, 'existent value yields true'); + + st.equal(channel.has('abc'), false, 'non object value non existent yields false'); + + channel.set('abc', 'foo'); + st.equal(channel.has('abc'), true, 'non object value that exists yields true'); + + st.end(); + }); + + t.test('get', function (st) { + var channel = getSideChannel(); + var o = {}; + st.equal(channel.get(o), undefined, 'nonexistent value yields undefined'); + + var data = {}; + channel.set(o, data); + st.equal(channel.get(o), data, '"get" yields data set by "set"'); + + st.end(); + }); + + t.test('set', function (st) { + var channel = getSideChannel(); + var o = function () {}; + st.equal(channel.get(o), undefined, 'value not set'); + + channel.set(o, 42); + st.equal(channel.get(o), 42, 'value was set'); + + channel.set(o, Infinity); + st.equal(channel.get(o), Infinity, 'value was set again'); + + var o2 = {}; + channel.set(o2, 17); + st.equal(channel.get(o), Infinity, 'o is not modified'); + st.equal(channel.get(o2), 17, 'o2 is set'); + + channel.set(o, 14); + st.equal(channel.get(o), 14, 'o is modified'); + st.equal(channel.get(o2), 17, 'o2 is not modified'); + + st.end(); + }); + + t.test('delete', function (st) { + var channel = getSideChannel(); + var o = {}; + st.equal(channel['delete']({}), false, 'nonexistent value yields false'); + + channel.set(o, 42); + st.equal(channel.has(o), true, 'value is set'); + + st.equal(channel['delete']({}), false, 'nonexistent value still yields false'); + + st.equal(channel['delete'](o), true, 'deleted value yields true'); + + st.equal(channel.has(o), false, 'value is no longer set'); + + st.end(); + }); + + t.end(); +}); diff --git a/node_modules/side-channel/tsconfig.json b/node_modules/side-channel/tsconfig.json new file mode 100644 index 0000000..d9a6668 --- /dev/null +++ b/node_modules/side-channel/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es2021", + }, + "exclude": [ + "coverage", + ], +} |