diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f468993..0bc3b42 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,16 +1,11 @@ version: 2 updates: - - package-ecosystem: 'github-actions' - directory: '/' - schedule: - interval: 'daily' - commit-message: - prefix: 'chore' - include: 'scope' - - package-ecosystem: 'npm' - directory: '/' - schedule: - interval: 'daily' - commit-message: - prefix: 'chore' - include: 'scope' +- package-ecosystem: npm + directory: "/" + schedule: + interval: daily + time: "10:00" + open-pull-requests-limit: 10 + commit-message: + prefix: "deps" + prefix-development: "deps(dev)" diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml new file mode 100644 index 0000000..d57c2a0 --- /dev/null +++ b/.github/workflows/automerge.yml @@ -0,0 +1,8 @@ +name: Automerge +on: [ pull_request ] + +jobs: + automerge: + uses: protocol/.github/.github/workflows/automerge.yml@master + with: + job: 'automerge' diff --git a/.github/workflows/js-test-and-release.yml b/.github/workflows/js-test-and-release.yml new file mode 100644 index 0000000..d155996 --- /dev/null +++ b/.github/workflows/js-test-and-release.yml @@ -0,0 +1,145 @@ +name: test & maybe release +on: + push: + branches: + - master # with #262 - ${{{ github.default_branch }}} + pull_request: + branches: + - master # with #262 - ${{{ github.default_branch }}} + +jobs: + + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present lint + - run: npm run --if-present dep-check + + test-node: + needs: check + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest, ubuntu-latest, macos-latest] + node: [16] + fail-fast: true + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node }} + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present test:node + - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + with: + flags: node + + test-chrome: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present test:chrome + - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + with: + flags: chrome + + test-chrome-webworker: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present test:chrome-webworker + - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + with: + flags: chrome-webworker + + test-firefox: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present test:firefox + - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + with: + flags: firefox + + test-firefox-webworker: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npm run --if-present test:firefox-webworker + - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + with: + flags: firefox-webworker + + test-electron-main: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npx xvfb-maybe npm run --if-present test:electron-main + - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + with: + flags: electron-main + + test-electron-renderer: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - run: npx xvfb-maybe npm run --if-present test:electron-renderer + - uses: codecov/codecov-action@81cd2dc8148241f03f5839d295e000b8f761e378 # v3.1.0 + with: + flags: electron-renderer + + release: + needs: [test-node, test-chrome, test-chrome-webworker, test-firefox, test-firefox-webworker, test-electron-main, test-electron-renderer] + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/master' # with #262 - 'refs/heads/${{{ github.default_branch }}}' + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-node@v3 + with: + node-version: lts/* + - uses: ipfs/aegir/actions/cache-node-modules@master + - uses: ipfs/aegir/actions/docker-login@master + with: + docker-token: ${{ secrets.DOCKER_TOKEN }} + docker-username: ${{ secrets.DOCKER_USERNAME }} + - run: npm run --if-present release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 2d0c064..3745440 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ dist/ node_modules/ coverage/ +.coverage +package-lock.json diff --git a/LICENSE b/LICENSE index 6307fc5..20ce483 100644 --- a/LICENSE +++ b/LICENSE @@ -1,13 +1,4 @@ -Copyright 2020 Rod Vagg +This project is dual licensed under MIT and Apache-2.0. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +MIT: https://www.opensource.org/licenses/mit +Apache-2.0: https://www.apache.org/licenses/license-2.0 diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..14478a3 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,5 @@ +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..72dc60d --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,19 @@ +The MIT License (MIT) + +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/README.md b/README.md index 9e14638..12350db 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,23 @@ -# ipld-garbage +# ipld-garbage -Generate garbage objects conformant with the [IPLD Data Model](https://docs.ipld.io/#the-data-model). Useful for fuzzing. +[![codecov](https://img.shields.io/codecov/c/github/achingbrain/js-ipld-garbage.svg?style=flat-square)](https://codecov.io/gh/achingbrain/js-ipld-garbage) +[![CI](https://img.shields.io/github/workflow/status/achingbrain/js-ipld-garbage/test%20&%20maybe%20release/master?style=flat-square)](https://github.com/achingbrain/js-ipld-garbage/actions/workflows/js-test-and-release.yml) + +> Garbage data generator for the IPLD Data Model + +## Table of contents + +- [Install](#install) +- [API](#api) + - [`options`](#options) +- [License](#license) +- [Contribute](#contribute) + +## Install + +```console +$ npm i ipld-garbage +``` Based on [substack's "garbage"](https://github.com/substack/node-garbage). @@ -12,8 +29,8 @@ Where `count` determines the approximate target number of bytes a garbage object ### `options` - * `options.weights` an object with properties matching the IPLD data model types (see below) with numbers (>= `0`) that will weight randomness selection. Default: `{ list: 1, map: 1, string: 1, bytes: 1, boolean: 1, integer: 1, float: 1, null: 1, CID: 1 }`. - * `options.initialWeights` an object, similar to `options.weights`, that only applies to the initial object. Subsequent object creation will use `options.weights`. This allows for weighting of the container object to be more typical of IPLD data, which is typically some kind of map or list. Default `{ list: 10, map: 10, string: 1, bytes: 1, boolean: 1, integer: 1, float: 1, null: 1, CID: 1 }`. +- `options.weights` an object with properties matching the IPLD data model types (see below) with numbers (>= `0`) that will weight randomness selection. Default: `{ list: 1, map: 1, string: 1, bytes: 1, boolean: 1, integer: 1, float: 1, null: 1, CID: 1 }`. +- `options.initialWeights` an object, similar to `options.weights`, that only applies to the initial object. Subsequent object creation will use `options.weights`. This allows for weighting of the container object to be more typical of IPLD data, which is typically some kind of map or list. Default `{ list: 10, map: 10, string: 1, bytes: 1, boolean: 1, integer: 1, float: 1, null: 1, CID: 1 }`. Where you provide a custom `weights`, it will override `initialWeights`. e.g. `{ weights: { float: 0 } }` will result in no floats at all, even for the initial object. @@ -39,22 +56,25 @@ Might yield: All IPLD Data Model types are within range for random creation, including top-level returns (a single call to `garbage()` might just return a `null`): -* null -* boolean -* integer -* float -* string -* bytes -* list -* map -* CID +- null +- boolean +- integer +- float +- string +- bytes +- list +- map +- CID Use `import { toString } from 'ipld-garbage/to-string'` to import a function that can turn an object returned by `garbage()` to a JavaScript string. This may be useful for generating a fixed set of test fixtures rather than relying on randomness during each run. -## License and Copyright +## License + +Licensed under either of -Copyright 2020 Rod Vagg +- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / ) +- MIT ([LICENSE-MIT](LICENSE-MIT) / ) -Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +## Contribute -Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. diff --git a/package.json b/package.json index e0d05b1..e9b4c3e 100644 --- a/package.json +++ b/package.json @@ -2,58 +2,62 @@ "name": "ipld-garbage", "version": "3.0.5", "description": "Garbage data generator for the IPLD Data Model", - "main": "ipld-garbage.js", - "types": "./types/ipld-garbage.d.ts", - "type": "module", - "scripts": { - "lint": "standard *.js", - "build": "npm run build:js && npm run build:types", - "build:js": "ipjs build --tests --main && npm run build:copy", - "build:copy": "cp -a tsconfig.json *.js *.ts dist/", - "build:types": "npm run build:copy && cd dist && tsc --build", - "test:cjs": "npm run build", - "test:node": "hundreds node test.js", - "test:browser": "polendina --page --worker --serviceworker --runner=bare-sync --cleanup dist/cjs/browser-test.js", - "test": "npm run lint && npm run test:node && npm run test:cjs && npm run test:browser", - "coverage": "c8 --reporter=html node node test.js && npx st -d coverage -p 8080" - }, + "author": "Rod (http://r.va.gg/)", + "license": "Apache-2.0 OR MIT", + "homepage": "https://github.com/achingbrain/js-ipld-garbage#readme", "repository": { "type": "git", - "url": "https://github.com/rvagg/js-ipld-garbage" + "url": "git+https://github.com/achingbrain/js-ipld-garbage.git" + }, + "bugs": { + "url": "https://github.com/achingbrain/js-ipld-garbage/issues" }, "keywords": [ - "garbage", - "IPLD" + "IPLD", + "garbage" ], - "author": "Rod (http://r.va.gg/)", - "license": "Apache-2.0", - "devDependencies": { - "@sindresorhus/is": "^5.1.0", - "hundreds": "^0.0.9", - "ipjs": "^5.0.0", - "polendina": "^3.0.0", - "standard": "^17.0.0", - "typescript": "^4.2.3" + "engines": { + "node": ">=16.0.0", + "npm": ">=7.0.0" + }, + "type": "module", + "types": "./dist/src/index.d.ts", + "typesVersions": { + "*": { + "*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ], + "src/*": [ + "*", + "dist/*", + "dist/src/*", + "dist/src/*/index" + ] + } }, + "files": [ + "src", + "dist", + "!dist/test", + "!**/*.tsbuildinfo" + ], "exports": { ".": { - "import": "./ipld-garbage.js" + "types": "./dist/src/index.d.ts", + "import": "./src/index.js" }, "./to-string": { - "import": "./to-string.js" + "types": "./src/to-string.d.ts", + "import": "./src/to-string.js" } }, - "dependencies": { - "multiformats": "^9.0.0" - }, - "typesVersions": { - "*": { - "*": [ - "types/*" - ], - "types/*": [ - "types/*" - ] + "eslintConfig": { + "extends": "ipfs", + "parserOptions": { + "sourceType": "module" } }, "release": { @@ -61,37 +65,106 @@ "master" ], "plugins": [ - ["@semantic-release/commit-analyzer", { - "preset": "conventionalcommits", - "releaseRules": [ - {"breaking": true, "release": "major"}, - {"revert": true, "release": "patch"}, - {"type": "feat", "release": "minor"}, - {"type": "fix", "release": "patch"}, - {"type": "chore", "release": "patch"}, - {"type": "docs", "release": "patch"}, - {"type": "test", "release": "patch"}, - {"scope": "no-release", "release": false} - ] - }], - ["@semantic-release/release-notes-generator", { - "preset": "conventionalcommits", - "presetConfig": { - "types": [ - {"type": "feat", "section": "Features"}, - {"type": "fix", "section": "Bug Fixes"}, - {"type": "chore", "section": "Trivial Changes"}, - {"type": "docs", "section": "Trivial Changes"}, - {"type": "test", "section": "Tests"} + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + { + "breaking": true, + "release": "major" + }, + { + "revert": true, + "release": "patch" + }, + { + "type": "feat", + "release": "minor" + }, + { + "type": "fix", + "release": "patch" + }, + { + "type": "docs", + "release": "patch" + }, + { + "type": "test", + "release": "patch" + }, + { + "type": "deps", + "release": "patch" + }, + { + "scope": "no-release", + "release": false + } ] } - }], + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + { + "type": "feat", + "section": "Features" + }, + { + "type": "fix", + "section": "Bug Fixes" + }, + { + "type": "chore", + "section": "Trivial Changes" + }, + { + "type": "docs", + "section": "Documentation" + }, + { + "type": "deps", + "section": "Dependencies" + }, + { + "type": "test", + "section": "Tests" + } + ] + } + } + ], "@semantic-release/changelog", - ["@semantic-release/npm", { - "pkgRoot": "dist" - }], + "@semantic-release/npm", "@semantic-release/github", "@semantic-release/git" ] + }, + "scripts": { + "clean": "aegir clean", + "lint": "aegir lint", + "build": "aegir build", + "release": "aegir release", + "test": "npm run lint && aegir test", + "test:ts": "npm run test --prefix test/ts-use", + "test:node": "aegir test -t node --cov", + "test:chrome": "aegir test -t browser --cov", + "test:chrome-webworker": "aegir test -t webworker", + "test:firefox": "aegir test -t browser -- --browser firefox", + "test:firefox-webworker": "aegir test -t webworker -- --browser firefox", + "test:electron-main": "aegir test -t electron-main", + "dep-check": "aegir dep-check" + }, + "dependencies": { + "multiformats": "^10.0.1" + }, + "devDependencies": { + "@sindresorhus/is": "^5.3.0", + "aegir": "^37.5.6" } } diff --git a/ipld-garbage.js b/src/index.js similarity index 100% rename from ipld-garbage.js rename to src/index.js diff --git a/interface.ts b/src/interface.ts similarity index 99% rename from interface.ts rename to src/interface.ts index 6a2342a..3053720 100644 --- a/interface.ts +++ b/src/interface.ts @@ -12,4 +12,4 @@ export interface GarbageWeights { export interface GarbageOptions { initialWeights?: GarbageWeights weights?: GarbageWeights -} \ No newline at end of file +} diff --git a/to-string.js b/src/to-string.js similarity index 100% rename from to-string.js rename to src/to-string.js diff --git a/test.js b/test/index.spec.js similarity index 90% rename from test.js rename to test/index.spec.js index 5efb8a0..9751534 100644 --- a/test.js +++ b/test/index.spec.js @@ -1,4 +1,4 @@ -import { garbage } from 'ipld-garbage' +import { garbage } from '../src/index.js' import is from '@sindresorhus/is' const expectedTypes = ['null', 'boolean', 'int', 'float', 'string', 'Uint8Array', 'Array', 'Object', 'CID'] @@ -49,4 +49,4 @@ for (const type of Object.keys(types)) { } } -console.log('\u001b[32m✔\u001b[39m yep') +console.log('\u001b[32m✔\u001b[39m yep') // eslint-disable-line no-console diff --git a/tsconfig.json b/tsconfig.json index a96c2d6..8708ca6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,45 +1,11 @@ { + "extends": "aegir/src/config/tsconfig.aegir.json", "compilerOptions": { - "allowJs": true, - "checkJs": true, - "forceConsistentCasingInFileNames": true, - "noImplicitReturns": false, - "noImplicitAny": true, - "noImplicitThis": true, - "noFallthroughCasesInSwitch": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "strictFunctionTypes": false, - "strictNullChecks": true, - "strictPropertyInitialization": true, - "strictBindCallApply": true, - "strict": true, - "alwaysStrict": true, - "esModuleInterop": true, - "target": "ES2018", - "moduleResolution": "node", - "declaration": true, - "declarationMap": true, - "outDir": "types", - "skipLibCheck": true, - "stripInternal": true, - "resolveJsonModule": true, - "emitDeclarationOnly": true, - "baseUrl": ".", - "paths": { - "ipld-garbage": [ - "./ipld-garbage.js" - ] - } + "outDir": "dist", + "emitDeclarationOnly": true }, "include": [ - "ipld-garbage.js", - "to-string.js" - ], - "exclude": [ - "node_modules", - "esm", - "cjs" - ], - "compileOnSave": false + "src", + "test" + ] }