├── .all-contributorsrc ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── docs.yml ├── .gitignore ├── .npmignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── docs ├── .nojekyll ├── CNAME ├── assets │ ├── custom.css │ ├── highlight.css │ ├── icons.js │ ├── icons.svg │ ├── main.js │ ├── material-style.css │ ├── navigation.js │ ├── search.js │ └── style.css ├── classes │ └── Jsoning.html ├── enums │ ├── Events.html │ └── MathOps.html ├── index.html ├── interfaces │ ├── JSONValueArray.html │ └── JSONValueRecord.html ├── modules.html ├── sitemap.xml └── types │ ├── JSONValue.html │ └── JsoningOptions.html ├── media ├── jsoning-square.png ├── jsoning-square.svg ├── jsoning.png ├── jsoning.svg └── typedoc_css.css ├── package-lock.json ├── package.json ├── src └── index.ts ├── tests └── test.js ├── tsconfig.json └── typedoc.json /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "jsoning", 3 | "projectOwner": "khalby786", 4 | "repoType": "github", 5 | "repoHost": "https://github.com", 6 | "files": [ 7 | "README.md" 8 | ], 9 | "imageSize": 100, 10 | "commit": true, 11 | "commitConvention": "angular", 12 | "contributors": [ 13 | { 14 | "login": "khalby786", 15 | "name": "Khaleel Gibran", 16 | "avatar_url": "https://avatars.githubusercontent.com/u/38468163?v=4", 17 | "profile": "https://github.com/khalby786", 18 | "contributions": [ 19 | "code", 20 | "doc", 21 | "design", 22 | "infra", 23 | "test", 24 | "tutorial" 25 | ] 26 | }, 27 | { 28 | "login": "aboutDavid", 29 | "name": "David", 30 | "avatar_url": "https://avatars.githubusercontent.com/u/62346025?v=4", 31 | "profile": "https://aboutdavid.me/", 32 | "contributions": [ 33 | "doc" 34 | ] 35 | }, 36 | { 37 | "login": "Jonyk56", 38 | "name": "Jonyk56", 39 | "avatar_url": "https://avatars.githubusercontent.com/u/44901605?v=4", 40 | "profile": "https://github.com/Jonyk56", 41 | "contributions": [ 42 | "code" 43 | ] 44 | }, 45 | { 46 | "login": "ayntee", 47 | "name": "ayntee", 48 | "avatar_url": "https://avatars.githubusercontent.com/u/34645569?v=4", 49 | "profile": "https://github.com/ayntee", 50 | "contributions": [ 51 | "code" 52 | ] 53 | }, 54 | { 55 | "login": "oadpoaw", 56 | "name": "undefine", 57 | "avatar_url": "https://avatars.githubusercontent.com/u/46276781?v=4", 58 | "profile": "https://xetha-bot.me/", 59 | "contributions": [ 60 | "code", 61 | "bug", 62 | "security" 63 | ] 64 | }, 65 | { 66 | "login": "adi-g15", 67 | "name": "Aditya Gupta", 68 | "avatar_url": "https://avatars.githubusercontent.com/u/37269665?v=4", 69 | "profile": "https://github.com/adi-g15", 70 | "contributions": [ 71 | "code" 72 | ] 73 | }, 74 | { 75 | "login": "manmal", 76 | "name": "Manuel Maly", 77 | "avatar_url": "https://avatars.githubusercontent.com/u/142797?v=4", 78 | "profile": "http://www.creativepragmatics.com", 79 | "contributions": [ 80 | "code", 81 | "bug" 82 | ] 83 | }, 84 | { 85 | "login": "wh0", 86 | "name": "wh0", 87 | "avatar_url": "https://avatars.githubusercontent.com/u/382796?v=4", 88 | "profile": "https://wh0.github.io/", 89 | "contributions": [ 90 | "code" 91 | ] 92 | }, 93 | { 94 | "login": "akpi816218", 95 | "name": "akpi816218", 96 | "avatar_url": "https://avatars.githubusercontent.com/u/111009970?v=4", 97 | "profile": "https://akpi.is-a.dev/", 98 | "contributions": [ 99 | "code", 100 | "doc", 101 | "example", 102 | "maintenance", 103 | "test", 104 | "tool" 105 | ] 106 | } 107 | ], 108 | "contributorsPerLine": 7, 109 | "skipCi": true 110 | } -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": "latest", 6 | "sourceType": "module" 7 | }, 8 | "plugins": ["@typescript-eslint"], 9 | "root": true, 10 | "env": { 11 | "es6": true, 12 | "node": true 13 | }, 14 | "rules": { 15 | "@typescript-eslint/no-unused-vars": "error", 16 | "camelcase": "error", 17 | "capitalized-comments": "off", 18 | "comma-dangle": "error", 19 | "eol-last": "error", 20 | "func-call-spacing": "error", 21 | "getter-return": "error", 22 | "indent": "off", 23 | "new-parens": "error", 24 | "no-alert": "error", 25 | "no-console": "error", 26 | "no-const-assign": "error", 27 | "no-debugger": "error", 28 | "no-delete-var": "error", 29 | "no-dupe-args": "error", 30 | "no-dupe-keys": "error", 31 | "no-duplicate-case": "error", 32 | "no-duplicate-imports": "error", 33 | "no-eq-null": "error", 34 | "no-eval": "error", 35 | "no-fallthrough": "error", 36 | "no-implied-eval": "error", 37 | "no-invalid-regexp": "error", 38 | "no-invalid-this": "error", 39 | "no-irregular-whitespace": "error", 40 | "no-lonely-if": "error", 41 | "no-multi-str": "error", 42 | "no-param-reassign": "error", 43 | "no-redeclare": "error", 44 | "no-self-assign": "error", 45 | "no-self-compare": "error", 46 | "no-trailing-spaces": "error", 47 | "no-unneeded-ternary": "error", 48 | "no-unreachable": "error", 49 | "no-unused-expressions": "error", 50 | "no-unused-vars": "off", 51 | "no-var": "error", 52 | "no-with": "error", 53 | "object-curly-newline": "error", 54 | "prefer-arrow-callback": "error", 55 | "prefer-const": "error", 56 | "prefer-promise-reject-errors": "error", 57 | "prefer-template": "error", 58 | "semi-spacing": "error", 59 | "strict": "error", 60 | "use-isnan": "error" 61 | } 62 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: khalby786 7 | 8 | --- 9 | 10 | ## Describe the bug 11 | A clear and concise description of what the bug is. 12 | 13 | ## Reproducible code sample (if applicable) 14 | 15 | ```javascript 16 | // place the code here 17 | ``` 18 | 19 | ## Expected behavior 20 | A clear and concise description of what you expected to happen. 21 | 22 | ## Further details 23 | - Jsoning version: 24 | - Node.js version: 25 | - Operating system: 26 | 27 | ## Additional context 28 | If applicable, add any other context about the problem here. 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Generate documentation 2 | 3 | on: 4 | push: 5 | branches: [ $default-branch ] 6 | pull_request: 7 | branches: [ $default-branch ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | matrix: 16 | node-version: [12.x] 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Generate documentation using TypeDoc 21 | uses: actions/setup-node@v1 22 | with: 23 | node-version: '12.x' 24 | - run: npm install 25 | - run: npm run gendocs 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .nyc_output 3 | coverage 4 | dist 5 | *.test.json -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | docs 2 | src 3 | tests 4 | docma.js 5 | tsconfig.json 6 | scripts 7 | .github 8 | .all-contributorsrc 9 | .eslintrc 10 | .gitignore 11 | .prettierrc -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": false, 6 | "useTabs": false, 7 | "arrowParens": "avoid" 8 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at khalby786@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ## Pull Request Process 9 | 10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a 11 | build. 12 | 2. Update the README.md with details of changes to the interface, this includes new environment 13 | variables, exposed ports, useful file locations and container parameters. 14 | 3. Increase the version numbers in `package.json`, any examples files and the README.md to the new version that this 15 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). 16 | 17 | ## Code of Conduct 18 | 19 | ### Our Pledge 20 | 21 | In the interest of fostering an open and welcoming environment, we as 22 | contributors and maintainers pledge to making participation in our project and 23 | our community a harassment-free experience for everyone, regardless of age, body 24 | size, disability, ethnicity, gender identity and expression, level of experience, 25 | nationality, personal appearance, race, religion, or sexual identity and 26 | orientation. 27 | 28 | ### Our Standards 29 | 30 | Examples of behavior that contributes to creating a positive environment 31 | include: 32 | 33 | * Using welcoming and inclusive language 34 | * Being respectful of differing viewpoints and experiences 35 | * Gracefully accepting constructive criticism 36 | * Focusing on what is best for the community 37 | * Showing empathy towards other community members 38 | 39 | Examples of unacceptable behavior by participants include: 40 | 41 | * The use of sexualized language or imagery and unwelcome sexual attention or 42 | advances 43 | * Trolling, insulting/derogatory comments, and personal or political attacks 44 | * Public or private harassment 45 | * Publishing others' private information, such as a physical or electronic 46 | address, without explicit permission 47 | * Other conduct which could reasonably be considered inappropriate in a 48 | professional setting 49 | 50 | ### Our Responsibilities 51 | 52 | Project maintainers are responsible for clarifying the standards of acceptable 53 | behavior and are expected to take appropriate and fair corrective action in 54 | response to any instances of unacceptable behavior. 55 | 56 | Project maintainers have the right and responsibility to remove, edit, or 57 | reject comments, commits, code, wiki edits, issues, and other contributions 58 | that are not aligned to this Code of Conduct, or to ban temporarily or 59 | permanently any contributor for other behaviors that they deem inappropriate, 60 | threatening, offensive, or harmful. 61 | 62 | ### Scope 63 | 64 | This Code of Conduct applies both within project spaces and in public spaces 65 | when an individual is representing the project or its community. Examples of 66 | representing a project or community include using an official project e-mail 67 | address, posting via an official social media account, or acting as an appointed 68 | representative at an online or offline event. Representation of a project may be 69 | further defined and clarified by project maintainers. 70 | 71 | ### Enforcement 72 | 73 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 74 | reported by contacting the project owner at [khalby786@gmail.com](mailto:khalby786@gmail.com). All 75 | complaints will be reviewed and investigated and will result in a response that 76 | is deemed necessary and appropriate to the circumstances. The project owner is 77 | obligated to maintain confidentiality with regard to the reporter of an incident. 78 | Further details of specific enforcement policies may be posted separately. 79 | 80 | Project maintainers who do not follow or enforce the Code of Conduct in good 81 | faith may face temporary or permanent repercussions as determined by other 82 | members of the project's leadership. 83 | 84 | ### Attribution 85 | 86 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 87 | available at [http://contributor-covenant.org/version/1/4][version] 88 | 89 | [homepage]: http://contributor-covenant.org 90 | [version]: http://contributor-covenant.org/version/1/4/ 91 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Khaleel Gibran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | jsoning 4 | 5 | ✨ A simple key-value JSON-based lightweight database. ✨ 6 | 7 |
8 | 9 | ![CodeCov](https://codecov.io/gh/khalby786/jsoning/branch/master/graph/badge.svg) 10 | [![Build Status](https://travis-ci.org/khalby786/jsoning.svg?branch=master)](https://travis-ci.org/khalby786/jsoning) 11 | [![Latest Stable Version](https://img.shields.io/npm/v/jsoning.svg)](https://www.npmjs.com/package/jsoning) 12 | [![NPM Downloads](https://img.shields.io/npm/dm/jsoning.svg)](https://www.npmjs.com/package/jsoning) 13 | ![node-current](https://img.shields.io/node/v/jsoning) 14 | [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fkhalby786%2Fjsoning.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fkhalby786%2Fjsoning?ref=badge_shield) 15 | 16 |
17 | 18 | [View Demo](https://glitch.com/edit/#!/jsoning) · [Report Bug](https://github.com/khalby786/jsoning/issues) · [Request Feature](https://github.com/khalby786/jsoning/issues) 19 | 20 |
21 | 22 | --- 23 | 24 | Jsoning is a simplified wrapper for Node.js that lets you write and read data to and from JSON files. It's designed to be beginner-friendly and easy to use, with a simple API that makes it easy to get started with. It's perfect for small projects, prototyping, and learning how to work with databases. 25 | 26 | 27 | ## Features 28 | 29 | - Use existing JSON files to read and write key-value pairs 30 | - EventEmitters to listen to changes in the database 31 | - Atomic file writing to prevent data corruption 32 | - Easier to use than a toaster 33 | - TypeScript support for all the fixed-type addicts out there 34 | 35 | ## Install 36 | 37 | **Node.js v16.x or greater is required for this package to work.** 38 | 39 | ```bash 40 | npm i jsoning 41 | 42 | # pnpm if you're feeling fast 43 | pnpm i jsoning 44 | 45 | # yarn if you're feeling fancy 46 | yarn add jsoning 47 | ``` 48 | 49 | View the full documentation [here](https://jsoning.js.org/). 50 | 51 | ## Basic Usage 52 | 53 | ```ts 54 | import { Jsoning, MathOps } from 'jsoning'; 55 | const db = new Jsoning('database.json'); 56 | 57 | // Set some values with a key 58 | await db.set('birthday', '07-aug'); 59 | await db.set('age', '13'); 60 | 61 | // Push stuff to an array for a particular key 62 | await db.push('transformers', 'optimus prime'); 63 | await db.push('transformers', 'bumblebee'); 64 | await db.push('transformers', 'iron hide'); 65 | 66 | // Get the value of a key 67 | console.log(await db.get('transformers')); // [ 'optimus prime', 'bumblebee', 'iron hide' ] 68 | 69 | // Get all the values 70 | console.log(await db.all()); // { Record of the whole database contents } 71 | 72 | // does such a value exist? 73 | console.log(await db.has('value2')); // false 74 | 75 | // My age keeps changing, so I'm deleting it 76 | console.log(await db.delete('age')); // true 77 | 78 | // I got $100 for my birthday 79 | await db.set('money', 100); 80 | 81 | // and someone gave me $200 more 82 | await db.math('money', MathOps.Add, 200); 83 | 84 | // Just wanna make sure how much money I got 85 | console.log(await db.get('money')); // 300 86 | 87 | // RIP iron hide, he died 88 | await db.remove('transformers', 'iron hide'); 89 | 90 | // I'm getting bored, so I'm clearing the whole database 91 | await db.clear(); 92 | ``` 93 | 94 | ## Contributing 95 | 96 | Please see `CONTRIBUTING.md` for more details on contributing! 97 | 98 | ### Contributors 99 | 100 | 101 | [![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors-) 102 | 103 | 104 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 |
Khaleel Gibran
Khaleel Gibran

💻 📖 🎨 🚇 ⚠️
David
David

📖
Jonyk56
Jonyk56

💻
ayntee
ayntee

💻
undefine
undefine

💻 🐛 🛡️
Aditya Gupta
Aditya Gupta

💻
Manuel Maly
Manuel Maly

💻 🐛
wh0
wh0

💻
akpi816218
akpi816218

💻 📖 💡 🚧 ⚠️ 🔧
126 | 127 | 128 | 129 | 130 | 131 | 132 | This project follows the [all-contributors](https://allcontributors.org) specification. 133 | Contributions of any kind are welcome! 134 | 135 | ## License 136 | 137 | This package is open sourced under the [MIT License](https://github.com/khalby786/jsoning/blob/master/LICENSE.md). 138 | 139 | [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fkhalby786%2Fjsoning.svg?type=small)](https://app.fossa.com/projects/git%2Bgithub.com%2Fkhalby786%2Fjsoning?ref=badge_large) 140 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | jsoning.js.org -------------------------------------------------------------------------------- /docs/assets/custom.css: -------------------------------------------------------------------------------- 1 | @import url("https://cdn.jsdelivr.net/npm/hack-font@3.3.0/build/web/hack-subset.css"); 2 | @import url("https://rsms.me/inter/inter.css"); 3 | 4 | :root { 5 | --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important; 6 | --font-mono: "Hack", "Fira Code", "Fira Mono", "Roboto Mono", monospace !important; 7 | } -------------------------------------------------------------------------------- /docs/assets/highlight.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --light-hl-0: #795E26; 3 | --dark-hl-0: #DCDCAA; 4 | --light-hl-1: #000000; 5 | --dark-hl-1: #D4D4D4; 6 | --light-hl-2: #A31515; 7 | --dark-hl-2: #CE9178; 8 | --light-hl-3: #008000; 9 | --dark-hl-3: #6A9955; 10 | --light-hl-4: #AF00DB; 11 | --dark-hl-4: #C586C0; 12 | --light-hl-5: #001080; 13 | --dark-hl-5: #9CDCFE; 14 | --light-hl-6: #0000FF; 15 | --dark-hl-6: #569CD6; 16 | --light-hl-7: #0070C1; 17 | --dark-hl-7: #4FC1FF; 18 | --light-hl-8: #098658; 19 | --dark-hl-8: #B5CEA8; 20 | --light-hl-9: #267F99; 21 | --dark-hl-9: #4EC9B0; 22 | --light-code-background: #FFFFFF; 23 | --dark-code-background: #1E1E1E; 24 | } 25 | 26 | @media (prefers-color-scheme: light) { :root { 27 | --hl-0: var(--light-hl-0); 28 | --hl-1: var(--light-hl-1); 29 | --hl-2: var(--light-hl-2); 30 | --hl-3: var(--light-hl-3); 31 | --hl-4: var(--light-hl-4); 32 | --hl-5: var(--light-hl-5); 33 | --hl-6: var(--light-hl-6); 34 | --hl-7: var(--light-hl-7); 35 | --hl-8: var(--light-hl-8); 36 | --hl-9: var(--light-hl-9); 37 | --code-background: var(--light-code-background); 38 | } } 39 | 40 | @media (prefers-color-scheme: dark) { :root { 41 | --hl-0: var(--dark-hl-0); 42 | --hl-1: var(--dark-hl-1); 43 | --hl-2: var(--dark-hl-2); 44 | --hl-3: var(--dark-hl-3); 45 | --hl-4: var(--dark-hl-4); 46 | --hl-5: var(--dark-hl-5); 47 | --hl-6: var(--dark-hl-6); 48 | --hl-7: var(--dark-hl-7); 49 | --hl-8: var(--dark-hl-8); 50 | --hl-9: var(--dark-hl-9); 51 | --code-background: var(--dark-code-background); 52 | } } 53 | 54 | :root[data-theme='light'] { 55 | --hl-0: var(--light-hl-0); 56 | --hl-1: var(--light-hl-1); 57 | --hl-2: var(--light-hl-2); 58 | --hl-3: var(--light-hl-3); 59 | --hl-4: var(--light-hl-4); 60 | --hl-5: var(--light-hl-5); 61 | --hl-6: var(--light-hl-6); 62 | --hl-7: var(--light-hl-7); 63 | --hl-8: var(--light-hl-8); 64 | --hl-9: var(--light-hl-9); 65 | --code-background: var(--light-code-background); 66 | } 67 | 68 | :root[data-theme='dark'] { 69 | --hl-0: var(--dark-hl-0); 70 | --hl-1: var(--dark-hl-1); 71 | --hl-2: var(--dark-hl-2); 72 | --hl-3: var(--dark-hl-3); 73 | --hl-4: var(--dark-hl-4); 74 | --hl-5: var(--dark-hl-5); 75 | --hl-6: var(--dark-hl-6); 76 | --hl-7: var(--dark-hl-7); 77 | --hl-8: var(--dark-hl-8); 78 | --hl-9: var(--dark-hl-9); 79 | --code-background: var(--dark-code-background); 80 | } 81 | 82 | .hl-0 { color: var(--hl-0); } 83 | .hl-1 { color: var(--hl-1); } 84 | .hl-2 { color: var(--hl-2); } 85 | .hl-3 { color: var(--hl-3); } 86 | .hl-4 { color: var(--hl-4); } 87 | .hl-5 { color: var(--hl-5); } 88 | .hl-6 { color: var(--hl-6); } 89 | .hl-7 { color: var(--hl-7); } 90 | .hl-8 { color: var(--hl-8); } 91 | .hl-9 { color: var(--hl-9); } 92 | pre, code { background: var(--code-background); } 93 | -------------------------------------------------------------------------------- /docs/assets/icons.js: -------------------------------------------------------------------------------- 1 | (function(svg) { 2 | svg.innerHTML = ``; 3 | svg.style.display = 'none'; 4 | if (location.protocol === 'file:') { 5 | if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', updateUseElements); 6 | else updateUseElements() 7 | function updateUseElements() { 8 | document.querySelectorAll('use').forEach(el => { 9 | if (el.getAttribute('href').includes('#icon-')) { 10 | el.setAttribute('href', el.getAttribute('href').replace(/.*#/, '#')); 11 | } 12 | }); 13 | } 14 | } 15 | })(document.body.appendChild(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))) -------------------------------------------------------------------------------- /docs/assets/icons.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/assets/material-style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=Space+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap"); 2 | 3 | :root, 4 | :root[data-theme="light"], 5 | :root[data-theme="dark"] { 6 | --font-sans: "Space Grotesk", sans-serif; 7 | --font-mono: "Space Mono", monospace; 8 | 9 | --color-background: var(--md-sys-color-surface-container); 10 | --color-background-secondary: var(--md-sys-color-surface-container-high); 11 | --color-background-warning: var(--md-sys-color-error-container); 12 | --color-warning-text: var(--md-sys-color-on-error-container); 13 | --color-icon-background: var(--md-sys-color-on-primary); 14 | --color-accent: var(--md-sys-color-secondary-container); 15 | --color-active-menu-item: var(--md-sys-color-surface-container-highest); 16 | --color-text: var(--md-sys-color-on-surface); 17 | --color-text-aside: var(--md-sys-color-on-surface-variant); 18 | --color-link: var(--md-sys-color-primary); 19 | 20 | --color-ts-project: var(--md-sys-color-secondary); 21 | --color-ts-module: var(--color-ts-project); 22 | --color-ts-namespace: var(--color-ts-project); 23 | 24 | --color-ts-enum: var(--md-sys-color-tertiary); 25 | --color-ts-enum-member: var(--color-ts-enum); 26 | 27 | --color-ts-variable: var(--md-sys-color-primary); 28 | --color-ts-function: var(--md-sys-color-secondary); 29 | --color-ts-class: var(--md-sys-color-tertiary); 30 | --color-ts-interface: var(--md-sys-color-tertiary); 31 | 32 | --color-ts-constructor: var(--md-sys-color-inverse-primary); 33 | 34 | --color-ts-property: var(--md-sys-color-on-background); 35 | --color-ts-method: var(--color-ts-function); 36 | 37 | --color-ts-call-signature: var(--color-ts-method); 38 | --color-ts-index-signature: var(--color-ts-property); /* ? */ 39 | --color-ts-constructor-signature: var(--color-ts-function); 40 | --color-ts-parameter: var(--md-sys-color-primary); 41 | 42 | --color-ts-type-parameter: var(--md-sys-color-tertiary); 43 | --color-ts-accessor: var(--color-ts-property); 44 | --color-ts-get-signature: var(--color-ts-accessor); 45 | --color-ts-set-signature: var(--color-ts-accessor); 46 | --color-ts-type-alias: var(--md-sys-color-tertiary); 47 | 48 | /* --external-icon: var(--md-sys-external-icon); 49 | --color-scheme: var(--md-sys-color-scheme); */ 50 | 51 | --top-app-bar-height: 4.5rem; 52 | --footer-height: 3.5rem; 53 | } 54 | 55 | body { 56 | font-family: var(--font-sans); 57 | } 58 | code, 59 | pre { 60 | font-family: var(--font-mono); 61 | } 62 | 63 | img { 64 | max-width: 100%; 65 | } 66 | 67 | *::-webkit-scrollbar { 68 | width: 8px; 69 | height: 8px; 70 | } 71 | *::-webkit-scrollbar-track { 72 | background: none; 73 | } 74 | *::-webkit-scrollbar-thumb { 75 | border: none; 76 | } 77 | 78 | .container-main { 79 | min-height: calc(100vh - var(--top-app-bar-height) - var(--footer-height)); 80 | } 81 | .col-content { 82 | overflow: hidden; 83 | box-sizing: border-box; 84 | padding: 1.75rem; 85 | border-radius: 28px; 86 | background-color: var(--md-sys-color-surface); 87 | } 88 | .page-menu { 89 | height: fit-content; 90 | padding: 0.75rem 1.75rem; 91 | border-radius: 28px; 92 | background-color: var(--md-sys-color-surface); 93 | } 94 | .site-menu > *, 95 | .page-menu > * { 96 | position: relative; 97 | } 98 | .title { 99 | display: block; 100 | max-width: calc(100% - 5rem); 101 | white-space: nowrap; 102 | overflow: hidden; 103 | text-overflow: ellipsis; 104 | font-size: 22px; 105 | } 106 | 107 | .tsd-page-toolbar { 108 | padding: 8px 0; 109 | height: calc(var(--top-app-bar-height) - 16px); 110 | background-color: var(--color-background); 111 | border-bottom: none; 112 | } 113 | .tsd-page-toolbar .tsd-toolbar-contents { 114 | height: 56px; 115 | } 116 | .tsd-page-toolbar .table-cell { 117 | height: 56px; 118 | margin-left: 1.5rem; 119 | } 120 | .tsd-page-toolbar .tsd-toolbar-icon { 121 | padding: 20px 0; 122 | } 123 | #tsd-search { 124 | line-height: 56px; 125 | border-radius: 22px; 126 | } 127 | #tsd-search .results { 128 | z-index: -1; 129 | top: calc(56px - 22px); 130 | padding-top: 22px; 131 | box-shadow: 0px 4px 2px rgba(0, 0, 0, 0.125); 132 | background-color: var(--color-background-secondary); 133 | border-bottom-left-radius: 22px; 134 | border-bottom-right-radius: 22px; 135 | overflow: hidden; 136 | } 137 | #tsd-search .results li { 138 | background: none; 139 | } 140 | #tsd-search .results a { 141 | padding: 1rem 0.25rem; 142 | } 143 | .col-sidebar { 144 | padding-top: 0; 145 | margin-right: 1rem; 146 | } 147 | 148 | .tsd-signature { 149 | padding: 1rem 1.5rem; 150 | border-radius: 24px; 151 | background-color: var(--md-sys-color-surface-container); 152 | } 153 | 154 | .tsd-page-navigation ul { 155 | padding-left: 0.44rem; 156 | } 157 | .tsd-navigation a, 158 | .tsd-navigation summary > span, 159 | .tsd-page-navigation a { 160 | padding: 0.88rem; 161 | border-radius: 24px; 162 | } 163 | .tsd-navigation a:hover, 164 | .tsd-page-navigation a:hover { 165 | text-decoration: none; 166 | background-color: var(--md-sys-color-surface-container-high); 167 | } 168 | .page-menu .tsd-accordion-summary svg { 169 | position: absolute; 170 | right: 0; 171 | } 172 | .site-menu .tsd-navigation .tsd-accordion-summary { 173 | display: flex; 174 | flex-direction: row-reverse; 175 | width: 100%; 176 | } 177 | 178 | .tsd-small-nested-navigation { 179 | margin-left: 1rem; 180 | } 181 | .tsd-nested-navigation { 182 | margin-left: 2.5rem; 183 | } 184 | .tsd-nested-navigation > li > a, 185 | .tsd-nested-navigation > li > span { 186 | width: 100%; 187 | } 188 | .tsd-navigation > a, 189 | .tsd-navigation .tsd-accordion-summary { 190 | width: 100%; 191 | } 192 | .tsd-index-accordion .tsd-accordion-summary > svg { 193 | position: absolute; 194 | right: 1.5rem; 195 | margin-top: 1rem; 196 | } 197 | .tsd-accordion-summary .tsd-kind-icon ~ span { 198 | margin-right: 2.5rem; 199 | } 200 | .tsd-accordion-summary .tsd-nested-navigation > li > a, 201 | .tsd-nested-navigation > li > span { 202 | width: calc(100% - 0.44rem); 203 | } 204 | .tsd-kind-icon ~ span { 205 | white-space: nowrap; 206 | overflow: hidden; 207 | text-overflow: ellipsis; 208 | } 209 | .tsd-generator { 210 | padding: 0; 211 | border-top: none; 212 | height: var(--footer-height); 213 | line-height: var(--footer-height); 214 | } 215 | .tsd-generator > p { 216 | padding: 0 2rem; 217 | } 218 | 219 | @media (max-width: 769px) { 220 | .container { 221 | padding: 1rem; 222 | } 223 | .col-sidebar { 224 | margin-right: 0; 225 | } 226 | } 227 | @media (min-width: 770px) { 228 | .container-main { 229 | margin: 0 auto; 230 | } 231 | .site-menu { 232 | margin-right: 0.5rem; 233 | } 234 | } 235 | @media (min-width: 1200px) { 236 | .page-menu, 237 | .site-menu { 238 | max-height: calc(100vh - var(--footer-height) - var(--top-app-bar-height)); 239 | top: var(--top-app-bar-height); 240 | } 241 | .page-menu { 242 | margin-left: 1rem; 243 | } 244 | .col-sidebar { 245 | margin-right: 0; 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /docs/assets/navigation.js: -------------------------------------------------------------------------------- 1 | window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAACn2STU/DMAyG/woy14qupQPW24R2YBJUGojL1EPUuDQiTaMkRVSo/x2JbvnY6K726+dxrOx/wOC3gRx2WKNCUaGGCKqGcapQQL63AYo16bmBCCQxDeTQdrTnqG8a0/Jr1/1kgkKeJavsdpGN5RhZwkb0LSpiWCfmJJsvFEY7B4q+1fFU/RNZwYMHfiamKeTZ2KF8Ouev9MiJ1rNP3upOMPHhuNUUjw+NkJykIftJGFQ1mb/o9rV4eSe8x7VSZHAWZgfjMBL60uWdZ7PJHVadopdpU+Yc56//Nki8WnNGLtznyHM2M0hfdKJYrO6TZepvPR2ykMdPEWKC7v+scix/AWPJ7BzFAgAA" -------------------------------------------------------------------------------- /docs/assets/search.js: -------------------------------------------------------------------------------- 1 | window.searchData = "data:application/octet-stream;base64,H4sIAAAAAAAACq1bWY/kthH+L9oHvxBa8RBFzpthJ0ECOA5swC+DxULu1uzI7guSenadxf73oHioq9SkumeQp+aIdbGOr0hK87UYjp/H4uHxa/Fnf9gWD6LWrDi0+654KP7168///q3dnbvvh6H9q2DFedgVD0V/mLrhqd1043tKUT5P+13Bis2uHcduLB6K4htbFfxLtzkO21XJnmRddGUbXotr8bPg6a8Tlvk6aePx0B8+/Xya+uNhXIokk6tydV3Liws+fgQBt6W9mwmRUFac2qE7TNfWXdTxSqhZW//pcBw6oP17v+t+eO42f96tukwz32NOGYy/WGVmk35qp+efTxd/dofzfnwfnq46kl+8+P12uyLgnZ9OWxr1J+X+ev59GtrNtCYc0bxBw0/n3dSfdn+taUA0b9DwY//Sb7s1+TPFvdIv0fvbS3eYlsHzD++N3T+6pXsR/zs/mzYsKE9HblXqr2+U+mO366alL7HgmeD1sn/Yde2wIjrOv17yf87j84rgMP16ub90++PLmjdmgjd443ha1gRxhp++V64wSxifZQcREfhWs7bml3awOR7GaThvpuOwKusdJVyFyxxsb9up/b0du3VFiOpNWo6LzpZUciG6V4eo1MX7IyrLpPxxpTJvyG53u3XZnuBNsre08NP+X6/9Gxo+3fLMp7d7ZkOgJZ2lq+hyQ/6+nZ7XxQeKN0l/bm/kpCd4k+wThsak8NMaOt6QPlCATMof1jHyVmQxTGbgZwUpr6UrbpWsEPR0T+15d0nN/XF73nVjzPg4ieHyAyv6w7b7Ujx8LV66YeyPh+KhEKUsbcGKp77bbeGk4TWwYnPc78GaD2Hutw6gEig8yfuqYI8Vk7xU1n74wB4jh5twDxwZL9gjT5FxQiYK9ihSZDAhmSht3TDFqtJyyerwt2a8bIRmDROlsJaZ8NwyUdbmIlyCDUlb5f9BugLpySUqssQa6JJrhBnQrmvLOJhTq4ZxxXgpNWe8jk/AoqpWjINJSmjGwSZuDONgFJeKiSpwCc54qWvDhIhTkvGSK8WE8gIvpmnwfs2ELqXlxLQwo0qu5YW+gac6tZSGLNkAXZOiM4TOAp1J0VmaTJBbwibTaZF2kF4yGXNOM4+7DOOpxbspROmyRSQpJaWEyEuZpKRJwSH2EJwEZU0pIRQyGSQ3hSghCFInKWl8OIRBNklKGiEOgZAmSWld+vJSVJZJy2RZS6aq8MvDr3BVw5R0f6PCh7gplSx9mLKMl0YLVA4x+a9TXcVKUTpwqSY+MXEQK6Wu4oAHObUINLVcFoiAnIHKUyUP1s9W8rB8Xoei5VDGBhzSKAZMpTI1q8E4ri2rdRw0TJaylqw28YkNA13FAWeibLRhWsQn0g+QcZCmOu1CmsEin8FuCkAI3Obc10hYTlWaRgXosdqvq4a1SFaVjazBfZ6mVuGJrsGhDdPAZOFBEwfArXjNtAUm1lSAuZqzxoVQataIOHBoZTVrog1N7Xm0/2k8IVocVFaTTFE35ULT1AwYVa0hkfzA5Q8MXKyqSnk7uXV2wrolWOGfgILSSMEaG5xkqjiAWAlZMwOxEhVnRvonyMg6iwwitgFYrA56OazWitqjN9jm0hUsWbPWlQYPZpuqAeeFqSjZqGh2HQfauVQxEz1jzJX9OouWbsq1Mal98wRdTh23AAC8bKwN5cZDMljFvdmiUt5spVzMRSmj2TBlXF5UkhkoEaU5MqnJQqibcpHjyBSHIBKy1AR9HkEqGXpkpb3jwMrZAuc4agpYWWnBbOVtYpZfGQcwatM7G4PafhMgbO7xc7f2Bqg6GACDCGHektr4gMHAxt2DVXEQMdHqOIiYaM0VzAGU22R/FXaRndYGWNCQJVVIwTlNlQjJRJPSGn1JQV5VoWJ4xeeRmEfSJybayFXZHuimFOPONsm5xy6tgpGcg43+gYOuWnFoE1VpDIdeAFaH5FRSejADGug4bsqhmhtELt3EgXELajys1cZ6YGsqAzDmaRx6uSkdBibKMSCngXqsfBuFtdfzSM8jtxOFjWBlgi28snGWV/Momsy5mEdyng06kFd5dr8geYy6bDwWuW5gHNILv+1suAi+1Tr4Vvs2KysZ4ErY4FHtvWZ58BrM+AyR0jsLppyzdBWcBQMHUpVS3mtA47xmYK0uTxqQUjXzyAT64A03EvPI15RmDhfCCLzraHzvds9sHLkE9yPuR8h/IruLclPuYKGV3xxo4YsFykca96CGRBRlIxqP6brRsDfwU66JKt54RKqk9v0GprgQTJaweiHjQLlOizYHEvq6SLZ86Tet7mD40g1Tt/2nPyA+PhYF+1p8DOfFy2XU12+Xg+HD16KGJ9++gcz4HuTCxfnMVShHiHk9V0vUVGtqWCGq8Gv9rwx/Sx5+xcWcFl4tINH6YkuTs2W7HTGPrjPmCIn1B2a4w7rwNuaiT1wvPj7zrAfMWfOc1rj6oF1Er+iUN6Jo4gWTc7A3Z+FB/1IRxbNqMuwp1XDjSZXrnPI6v4Df27HfYCk2l4rCIC6ShzbHEdTh5Ar8ZN1KZARwSyPg89KL2NComjtsCIz+/R12ezZqWB9c9BCrc1yccLnbxQuXvLi34DHBcgXjuGmQbTZ7G6QV37wji5HuEI2EzuNh8q+2kNKsg4jSU09trXPpLBJ44tiJVgDfTDlQPpJMskEONkRPYrFD104kl1UWk1D6wgsHAmQ5QwWnTP4tBfIQjghPoBhfQJKi0LQG0PMdJQLpi52FlNfqasLdH2g85N0lFl8IIF6JokIWkYiKZye6TRaVaA15/vBaFy3cIvW5zN8eaXPNQQqGz+1xkbM8C+ELrsN3EwWhbA4hOOl2nXuMc+8+8M30NNrpiRKyriaL8TGYBgugWd7c6vNXVjVYaLpxdft+mhZ4k9VD+E4T7bo8l9jEKS9Ll8gK5dR17Qa2L/3YT+61K7IzG2qs8Es/LjIkW4A24R5gpyHMgvhrcuPL6Tgs3K5yLQk3wqd2mRTZxF2as0iG9OY0aOl3dIecq8blhldhXUHWonlmm1mFec50Qwhnmdt48DQc9wTtsolcX6/ZvR5FaYkOBVzgiCbS81P/0pFtlM6uUua97l5Dot0CAtsAXtea+yfiplwyxDjdCRRrueG/4iJac26ul1x/jMcD5Nb13hF11Fw76w+0jLN9JWX0oZ/6dtf/l24bsqVc4fVHEePUHjZ05dkDJ95B9IeJtsQqy4X10YaYW22M5HKH0yScQHGQZ0sq5cDpO2pPlUs1sgYKnSZ7ukCZAjlC9hw5M+/Anj/itzqortGBl19XFQlcYH+33BvX2XXwa+aR4kqzjgyEd/5WBvsdbT0zhQLcL/6zVeRGBCa3+K5O1Ehpbtc3Mw/hU1xkM/J4hvvPjujT2W1SZgOf7rU0hXfHTQv+pAWc3bSgPNi3FHtkzjzcqf0XKwjOcQRMxg/A1O3bqd+05JrGZjuZoRqPJ5Iu4sJXXDev8Mgzu+8ySKfOuYascv60FClFJZbrW4fuM9GV3cVUi4CisBwWqJqLCkakw5GCYI4nsUE4HKfnBZjwLD9hPNM7N5PNbhSPI2nsJrvVjYWQ7ORBFL3hyQJQjVnTNXQ8dcNVEdmsRJPgpHucbNwJ6xWfxgf+HJ4tNp5ZryfWeWr7gbau7KFBYa5h6jfnHb2qgjdGt4+kpwVc1FlzsZnd8HQc9tSlWUuRS09Dv++n/mVxD57t6VjncIRrAYrwVQ6fcO35L+EQjCJw4uRyOBFMYF4o5fdso+LncUgtumLndJt0rdazL84iuW0jdpNnXFxqZL1EGKfzQLO9yd7a3GqHcXkINRf7EYnaEie3HAlvjN30/nzatouTa5NFJ7SnGafjsIBPld1HoQCO879HoA6DLidzrXQ8bzZdt0hUm9VosMbNphvHp/OO9rUmW1krh7rxvHmmSZDNHrTo6bmlt1NZ1Rwz0f59141WyJj5FcGNm9LXnRhp5k3PXU+Q0WSBEYHq4uy0+oYPnQYW60jtH6ZhsUXOOTl3en7Fqdn9cxTB97tvgVMFl3Uc5lu816qzOYQS7+rcoLMVcyNDUl5w0im03Xftmrgd/UxvS3TWJRzbE3if6XVNnd2GcMI0PXe0ta9mTGTrKQLo7K0DVtbTPSPn2Zc4CT9/7ulmQt+6JLwqjw+sOPWnbtcfuuLh8cO3b/8DWvJ2ZuE5AAA="; -------------------------------------------------------------------------------- /docs/enums/Events.html: -------------------------------------------------------------------------------- 1 | Events | Jsoning - v1.0.0

Enumeration Events

Enumeration Members

Clear 160 | Copy 161 | Delete 162 | Get 163 | Push 164 | Remove 165 | Set 166 |

Enumeration Members

Clear: "clear"
Copy: "copy"
Delete: "delete"
Get: "get"
Push: "push"
Remove: "remove"
Set: "set"
-------------------------------------------------------------------------------- /docs/enums/MathOps.html: -------------------------------------------------------------------------------- 1 | MathOps | Jsoning - v1.0.0

Enumeration MathOpsReadonly

MathOps

160 |

Enumeration Members

Add 161 | Divide 162 | Multiply 163 | Subtract 164 |

Enumeration Members

Add: "add"
Divide: "divide"
Multiply: "multiply"
Subtract: "subtract"
-------------------------------------------------------------------------------- /docs/interfaces/JSONValueRecord.html: -------------------------------------------------------------------------------- 1 | JSONValueRecord | Jsoning - v1.0.0

Interface JSONValueRecord

interface JSONValueRecord {}

Hierarchy

-------------------------------------------------------------------------------- /docs/modules.html: -------------------------------------------------------------------------------- 1 | Jsoning - v1.0.0

Jsoning - v1.0.0

References

default 160 |

Enumerations

Events 161 | MathOps 162 |

Classes

Jsoning 163 |

Interfaces

Type Aliases

References

Renames and re-exports Jsoning
-------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | https://jsoning.js.org/modules.html 5 | 2024-03-27T07:50:58.714Z 6 | 7 | 8 | https://jsoning.js.org/index.html 9 | 2024-03-27T07:50:58.714Z 10 | 11 | 12 | https://jsoning.js.org/enums/Events.html 13 | 2024-03-27T07:50:58.714Z 14 | 15 | 16 | https://jsoning.js.org/enums/MathOps.html 17 | 2024-03-27T07:50:58.714Z 18 | 19 | 20 | https://jsoning.js.org/classes/Jsoning.html 21 | 2024-03-27T07:50:58.714Z 22 | 23 | 24 | https://jsoning.js.org/interfaces/JSONValueArray.html 25 | 2024-03-27T07:50:58.714Z 26 | 27 | 28 | https://jsoning.js.org/interfaces/JSONValueRecord.html 29 | 2024-03-27T07:50:58.714Z 30 | 31 | 32 | https://jsoning.js.org/types/JSONValue.html 33 | 2024-03-27T07:50:58.714Z 34 | 35 | 36 | https://jsoning.js.org/types/JsoningOptions.html 37 | 2024-03-27T07:50:58.714Z 38 | 39 | 40 | -------------------------------------------------------------------------------- /docs/types/JSONValue.html: -------------------------------------------------------------------------------- 1 | JSONValue | Jsoning - v1.0.0

Type alias JSONValue

JSONValue: string | number | boolean | JSONValueRecord | JSONValueArray | undefined | null

Defines the types element values can be.

160 |
-------------------------------------------------------------------------------- /docs/types/JsoningOptions.html: -------------------------------------------------------------------------------- 1 | JsoningOptions | Jsoning - v1.0.0

Type alias JsoningOptions

JsoningOptions: {
    ignoreJsonFileCheck?: boolean;
}

Defines the types element values can be.

160 |

Type declaration

  • Optional ignoreJsonFileCheck?: boolean

    Whether to ignore if the file is not a JSON file. Default is true.

    161 |
-------------------------------------------------------------------------------- /media/jsoning-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khalby786/jsoning/58bdb2f4378a42a821462b4f206da4390377be6a/media/jsoning-square.png -------------------------------------------------------------------------------- /media/jsoning-square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /media/jsoning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/khalby786/jsoning/58bdb2f4378a42a821462b4f206da4390377be6a/media/jsoning.png -------------------------------------------------------------------------------- /media/typedoc_css.css: -------------------------------------------------------------------------------- 1 | @import url("https://cdn.jsdelivr.net/npm/hack-font@3.3.0/build/web/hack-subset.css"); 2 | @import url("https://rsms.me/inter/inter.css"); 3 | 4 | :root { 5 | --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important; 6 | --font-mono: "Hack", "Fira Code", "Fira Mono", "Roboto Mono", monospace !important; 7 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsoning", 3 | "version": "1.0.1", 4 | "description": "A simple key-value JSON-based persistent lightweight database.", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "scripts": { 8 | "build": "npm run fmt && tsc && npm run gendocs", 9 | "delete": "rm tests*/*.test.*", 10 | "gendocs": "typedoc", 11 | "fmt": "prettier -w src", 12 | "lint": "eslint src/index.ts", 13 | "prepack": "npm run build", 14 | "prepublishOnly": "npm run build", 15 | "pretest": "npm run build", 16 | "test": "npx ava tests/test.js", 17 | "upgrade": "ncu -u && npm i" 18 | }, 19 | "dependencies": { 20 | "write-file-atomic": "^5.0.1" 21 | }, 22 | "devDependencies": { 23 | "@types/node": "^20.11.30", 24 | "@types/write-file-atomic": "^4.0.3", 25 | "@typescript-eslint/eslint-plugin": "^7.3.1", 26 | "@typescript-eslint/parser": "^7.3.1", 27 | "all-contributors-cli": "^6.26.1", 28 | "ava": "^6.1.2", 29 | "docdash": "^2.0.2", 30 | "eslint": "^8.57.0", 31 | "jsdoc": "^4.0.2", 32 | "npm-check-updates": "^16.14.17", 33 | "prettier": "3.2.5", 34 | "typedoc": "^0.25.12", 35 | "typedoc-material-theme": "^1.0.2", 36 | "typedoc-plugin-missing-exports": "^2.2.0", 37 | "typescript": "^5.4.3" 38 | }, 39 | "repository": "khalby786/jsoning", 40 | "homepage": "https://jsoning.js.org", 41 | "license": "MIT", 42 | "keywords": [ 43 | "json", 44 | "database" 45 | ], 46 | "author": { 47 | "name": "Khaleel Gibran", 48 | "url": "https://github.com/khalby786" 49 | }, 50 | "contributors": [ 51 | { 52 | "name": "Akhil Pillai", 53 | "url": "https://akpi.is-a.dev/" 54 | } 55 | ], 56 | "engines": { 57 | "node": ">=16.0.0" 58 | }, 59 | "type": "module" 60 | } 61 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from "path"; 2 | import { existsSync, readFileSync, writeFileSync } from "fs"; 3 | import { readFile, writeFile } from "fs/promises"; 4 | import EventEmitter from "events"; 5 | import writeFileAtomic from "write-file-atomic"; 6 | 7 | export interface JSONValueArray extends Array {} 8 | export interface JSONValueRecord extends Record {} 9 | 10 | /** 11 | * Defines the types element values can be. 12 | * @typedef JSONValue 13 | * @type {(string|number|boolean|Record|JSONValueArray|undefined|null)} 14 | */ 15 | export type JSONValue = 16 | | string 17 | | number 18 | | boolean 19 | | JSONValueRecord 20 | | JSONValueArray 21 | | undefined 22 | | null; 23 | 24 | /** 25 | * Defines the types element values can be. 26 | * @typedef JsoningOptions 27 | * @type {{ignoreJsonFileCheck?: boolean}} 28 | */ 29 | export type JsoningOptions = { 30 | /** 31 | * Whether to ignore if the file is not a JSON file. Default is `true`. 32 | * @type {boolean} 33 | */ 34 | ignoreJsonFileCheck?: boolean; 35 | }; 36 | 37 | /** 38 | * @enum {string} MathOps 39 | * @readonly 40 | */ 41 | export enum MathOps { 42 | Add = "add", 43 | Subtract = "subtract", 44 | Multiply = "multiply", 45 | Divide = "divide" 46 | } 47 | 48 | export enum Events { 49 | Get = "get", 50 | Set = "set", 51 | Delete = "delete", 52 | Clear = "clear", 53 | Push = "push", 54 | Remove = "remove", 55 | Copy = "copy" 56 | } 57 | 58 | /** 59 | * The main class exported by the module. 60 | * @extends EventEmitter 61 | */ 62 | export class Jsoning extends EventEmitter { 63 | /** 64 | * Emitted when the database is read. 65 | * @event Jsoning#get 66 | * @param {string} key The key of the element that was read. 67 | * @param {JSONValue} value The value of the element that was read. 68 | */ 69 | /** 70 | * Emitted when an element is set. 71 | * @event Jsoning#set 72 | * @param {string} key The key of the element that was set. 73 | * @param {JSONValue} oldValue The old value of the element. 74 | * @param {JSONValue} newValue The new value of the element. 75 | */ 76 | /** 77 | * Emitted when an element is deleted. 78 | * @event Jsoning#delete 79 | * @param {string} key The key of the element that was deleted. 80 | * @param {JSONValue} value The value of the element that was deleted. 81 | */ 82 | /** 83 | * Emitted when the database is cleared. 84 | * @event Jsoning#clear 85 | * @param {Record} data The data that was cleared. 86 | */ 87 | /** 88 | * Emitted when a value is pushed to an array. 89 | * @event Jsoning#push 90 | * @param {string} key The key of the element that was pushed to. 91 | * @param {JSONValue} value The value that was pushed to the element. 92 | * @param {JSONValue[]} array The array that was pushed to (before modification). 93 | */ 94 | /** 95 | * Emitted when a value is removed from an array. 96 | * @event Jsoning#remove 97 | * @param {string} key The key of the element that was removed from. 98 | * @param {JSONValue} value The value that was removed from the element (before modification). 99 | */ 100 | /** 101 | * Emitted when the database is copied. 102 | * @event Jsoning#copy 103 | * @param {string} destination The path to which the database was copied. 104 | * @param {Record} data The data that was copied. 105 | */ 106 | 107 | database: string; 108 | options: JsoningOptions; 109 | 110 | /** 111 | * Create a new JSON file for storing or initialize an exisiting file to be used. 112 | * @param {string} database Path to the JSON file to be created or used. 113 | */ 114 | constructor( 115 | database: string, 116 | options: JsoningOptions = { 117 | ignoreJsonFileCheck: true 118 | } 119 | ) { 120 | super(); 121 | 122 | // use an existing database or create a new one 123 | if (!existsSync(resolve(process.cwd(), database))) 124 | writeFileSync(resolve(process.cwd(), database), "{}"); 125 | else 126 | try { 127 | JSON.parse(readFileSync(resolve(process.cwd(), database), "utf-8")); 128 | } catch (err) { 129 | throw new Error("Invalid JSON file"); 130 | } 131 | 132 | /** 133 | * @property {JsoningOptions} options Options for the Jsoning instance. 134 | */ 135 | this.options = options; 136 | 137 | if (!/\w+.json/.test(database) && !options.ignoreJsonFileCheck) { 138 | // database name MUST be of the pattern "words.json" unless the user forces it 139 | throw new TypeError( 140 | "Invalid database file name. Make sure to provide a valid JSON database filename." 141 | ); 142 | } 143 | 144 | /** 145 | * @property {string} database Path to the JSON file to be used. 146 | */ 147 | this.database = database; 148 | } 149 | 150 | /** 151 | * Adds an element to the database with the given value. If element with the given key exists, element value is updated. 152 | * @param {string} key Key of the element to be set. 153 | * @param {JSONValue} value Value of the element to be set. 154 | * @returns {Promise} If element is set/updated successfully, returns true; else false. 155 | * @fires Jsoning#set 156 | */ 157 | async set(key: string, value: JSONValue): Promise { 158 | if (typeof key !== "string" || key === "") { 159 | throw new TypeError("Invalid key"); 160 | } 161 | 162 | const db = JSON.parse( 163 | await readFile(resolve(process.cwd(), this.database), "utf-8") 164 | ); 165 | 166 | const oldValue = db[key]; 167 | db[key] = value; 168 | 169 | try { 170 | await writeFileAtomic( 171 | resolve(process.cwd(), this.database), 172 | JSON.stringify(db) 173 | ); 174 | 175 | this.emit(Events.Set, key, oldValue, value); 176 | return true; 177 | } catch (err) { 178 | throw new Error(`Failed to set element: ${err}`); 179 | } 180 | } 181 | 182 | /** 183 | * Returns all the elements and their values of the JSON file. 184 | * @returns {Promise>} All the key-value pairs of the database. 185 | */ 186 | async all(): Promise> { 187 | return JSON.parse( 188 | await readFile(resolve(process.cwd(), this.database), "utf-8") 189 | ); 190 | } 191 | 192 | /** 193 | * Deletes an element from the database based on its key. 194 | * @param {string} key The key of the element to be deleted. 195 | * @returns {Promise} Returns true if the value exists, else returns false. 196 | */ 197 | async delete(key: string): Promise { 198 | if (typeof key !== "string" || key === "") { 199 | throw new TypeError("Invalid key of element"); 200 | } 201 | 202 | const db = JSON.parse( 203 | await readFile(resolve(process.cwd(), this.database), "utf-8") 204 | ); 205 | 206 | if (key in db) { 207 | try { 208 | const removeProp = key; 209 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 210 | const { [removeProp]: remove, ...rest } = db; 211 | 212 | await writeFileAtomic( 213 | resolve(process.cwd(), this.database), 214 | JSON.stringify(rest) 215 | ); 216 | 217 | this.emit(Events.Delete, key, db[key]); 218 | return true; 219 | } catch (err) { 220 | throw new Error(`Failed to delete element: ${err}`); 221 | } 222 | } else { 223 | return false; 224 | } 225 | } 226 | 227 | /** 228 | * Returns the value of an element by key. 229 | * @typeParam T The type of the value to be fetched. 230 | * @param {string} key The key of the element to be fetched. 231 | * @returns {Promise} Returns value if element exists, else returns null. 232 | */ 233 | async get(key: string): Promise { 234 | if (typeof key !== "string" || key == "") { 235 | throw new TypeError("Invalid key of element"); 236 | } 237 | 238 | const db = JSON.parse( 239 | await readFile(resolve(process.cwd(), this.database), "utf-8") 240 | ); 241 | if (key in db) { 242 | this.emit(Events.Get, key, db[key]); 243 | return db[key]; 244 | } else { 245 | return null; 246 | } 247 | } 248 | 249 | /** 250 | * Deletes the contents of the JSON file. 251 | * @returns {Promise} Returns true if the file is cleared, else false. 252 | */ 253 | async clear(): Promise { 254 | try { 255 | await writeFileAtomic( 256 | resolve(process.cwd(), this.database), 257 | JSON.stringify({}) 258 | ); 259 | const data = JSON.parse( 260 | await readFile(resolve(process.cwd(), this.database), "utf-8") 261 | ); 262 | 263 | this.emit(Events.Clear, data); 264 | return true; 265 | } catch (err) { 266 | throw new Error(`Failed to clear database: ${err}`); 267 | } 268 | } 269 | 270 | /** 271 | * Performs basic mathematical operations on values of elements. 272 | * @param {string} key The key of the element on which the mathematical operation is to be performed. 273 | * @param {MathOps} operation The operation to perform, one of add, subtract, multiply and divide. 274 | * @param {number} operand The number for performing the mathematical operation (the operand). 275 | * @returns {Promise} True if the operation succeeded, else false. 276 | */ 277 | async math( 278 | key: string, 279 | operation: MathOps, 280 | operand: number 281 | ): Promise { 282 | // key types 283 | if (typeof key !== "string" || key == "") { 284 | throw new TypeError("Invalid key of element"); 285 | } 286 | 287 | // operand check 288 | if (typeof operand !== "number") { 289 | throw new TypeError("Operand must be a number type!"); 290 | } 291 | 292 | // see if value exists 293 | const db = JSON.parse( 294 | await readFile(resolve(process.cwd(), this.database), "utf-8") 295 | ); 296 | if (key in db) { 297 | // key exists 298 | const value = db[key]; 299 | if (typeof value !== "number") { 300 | throw new TypeError( 301 | "Key of existing element must be a number for Jsoning#math to happen." 302 | ); 303 | } 304 | let result: number; 305 | switch (operation) { 306 | case MathOps.Add: 307 | result = value + operand; 308 | break; 309 | case MathOps.Subtract: 310 | result = value - operand; 311 | break; 312 | case MathOps.Multiply: 313 | result = value * operand; 314 | break; 315 | case MathOps.Divide: 316 | result = value / operand; 317 | break; 318 | default: 319 | throw new Error("Operation not found!"); 320 | } 321 | db[key] = result; 322 | try { 323 | await writeFileAtomic( 324 | resolve(process.cwd(), this.database), 325 | JSON.stringify(db) 326 | ); 327 | this.emit(Events.Set, key, value, result); 328 | return true; 329 | } catch (err) { 330 | throw new Error(`Failed to perform math operation: ${err}`); 331 | } 332 | } else { 333 | // key doesn't exist 334 | return false; 335 | } 336 | } 337 | 338 | /** 339 | * Check if a particular element exists by key. 340 | * @param {string} key The key of the element to see if the element exists. 341 | * @returns {Promise} True if the element exists, false if the element doesn't exist. 342 | */ 343 | async has(key: string): Promise { 344 | // too many tricks 345 | if (typeof key !== "string" || key == "") { 346 | throw new TypeError("Invalid key of element"); 347 | } 348 | 349 | const db = JSON.parse( 350 | await readFile(resolve(process.cwd(), this.database), "utf-8") 351 | ); 352 | 353 | if (key in db) { 354 | return true; 355 | } else { 356 | return false; 357 | } 358 | } 359 | 360 | /** 361 | * Adds the given value into the provided element (if it's an array) in the database based on the key. If no such element exists, it will initialize a new element with an empty array. 362 | * @param {string} key The key of the element. 363 | * @param {JSONValue} value The value to be added to the element array. 364 | * @returns {Promise} True if the the value was pushed to an array successfully, else false. 365 | */ 366 | async push(key: string, value: JSONValue): Promise { 367 | // see if element exists 368 | const db = JSON.parse( 369 | await readFile(resolve(process.cwd(), this.database), "utf-8") 370 | ); 371 | 372 | if (key in db) { 373 | if (!Array.isArray(db[key])) { 374 | // it's not an array! 375 | if (db[key] !== undefined && db[key] !== null) { 376 | // its not undefined or null 377 | throw new TypeError( 378 | "Existing element must be of type Array for Jsoning#push to work." 379 | ); 380 | } else if (!db[key]) { 381 | // it may not be an array, but its either undefined or null 382 | // so we initialize a new array 383 | db[key] = []; 384 | db[key].push(value); 385 | try { 386 | await writeFileAtomic( 387 | resolve(process.cwd(), this.database), 388 | JSON.stringify(db) 389 | ); 390 | 391 | this.emit(Events.Push, key, value, db[key]); 392 | return true; 393 | } catch (err) { 394 | throw new Error(`Failed to push element: ${err}`); 395 | } 396 | } 397 | } else { 398 | // but what if...? it was an array 399 | db[key].push(value); 400 | try { 401 | await writeFileAtomic( 402 | resolve(process.cwd(), this.database), 403 | JSON.stringify(db) 404 | ); 405 | return true; 406 | } catch (err) { 407 | throw new Error(`Failed to push element: ${err}`); 408 | } 409 | } 410 | } else { 411 | // key doesn't exist, so let's make one and do the pushing 412 | db[key] = []; 413 | db[key].push(value); 414 | try { 415 | await writeFileAtomic( 416 | resolve(process.cwd(), this.database), 417 | JSON.stringify(db) 418 | ); 419 | 420 | this.emit(Events.Push, key, value, db[key]); 421 | return true; 422 | } catch (err) { 423 | throw new Error(`Failed to push element: ${err}`); 424 | } 425 | } 426 | } 427 | 428 | /** 429 | * Removes a given primitive value from an array in the database based on the key. If the value does not exist or is not an array, it will do nothing. 430 | * @param {string} key The key of the element. 431 | * @param {JSONValue} value The value to be removed from the element array. 432 | * @returns {Promise} True if successfully removed or not found or the key does not exist, else false. 433 | */ 434 | async remove(key: string, value: JSONValue): Promise { 435 | // see if element exists 436 | const db = JSON.parse( 437 | await readFile(resolve(process.cwd(), this.database), "utf-8") 438 | ); 439 | 440 | if (!(key in db)) { 441 | return true; 442 | } 443 | if (!Array.isArray(db[key])) { 444 | throw new Error( 445 | "Existing element must be of type Array for Jsoning#remove to work." 446 | ); 447 | } 448 | db[key] = db[key].filter((item: unknown) => item !== value); 449 | try { 450 | await writeFileAtomic( 451 | resolve(process.cwd(), this.database), 452 | JSON.stringify(db) 453 | ); 454 | this.emit(Events.Remove, key, value); 455 | return true; 456 | } catch (err) { 457 | throw new Error(`Failed to remove element: ${err}`); 458 | } 459 | } 460 | 461 | /** 462 | * Copies the database to a new location. 463 | * @param {string} destination The path to copy the database to. 464 | */ 465 | async copy(destination: string): Promise; 466 | /** 467 | * Copies the database to a new location and returns a new Jsoning instance with the copied database. 468 | * @param {string} destination The path to copy the database to. 469 | * @param {true} createInstance Returns a new Jsoning instance with the copied database. 470 | */ 471 | async copy(destination: string, createInstance: true): Promise; 472 | async copy( 473 | destination: string, 474 | createInstance?: true 475 | ): Promise { 476 | const data = await readFile(resolve(process.cwd(), this.database), "utf-8"); 477 | try { 478 | JSON.parse(data); 479 | } catch (err) { 480 | throw new Error( 481 | "Invalid JSON file, aborted copy to prevent malformed data" 482 | ); 483 | } 484 | 485 | await writeFile(resolve(process.cwd(), destination), data); 486 | this.emit(Events.Copy, destination, JSON.parse(data)); 487 | if (createInstance) return new Jsoning(destination); 488 | } 489 | } 490 | 491 | export default Jsoning; 492 | -------------------------------------------------------------------------------- /tests/test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | 3 | // Clean up test files from previous runs 4 | for (const file of (await readdir('./tests')).filter(name => 5 | /^test\d+\.test\.json$/.test(name) 6 | )) 7 | await rm(resolve(join(process.cwd(), 'tests', file))); 8 | 9 | import { Jsoning } from '../dist/index.js'; 10 | import { readdir, rm } from 'fs/promises'; 11 | import { join, resolve } from 'path'; 12 | 13 | test("New Jsoning with non-JSON file", async t => { 14 | t.throws( 15 | () => new Jsoning("./tests/test0.test.txt", { ignoreJsonFileCheck: false }) 16 | ); 17 | }); 18 | 19 | test('Jsoning#set', async t => { 20 | const db = new Jsoning('./tests/test1.test.json'); 21 | t.is(await db.set('foo', 'bar'), true); 22 | }); 23 | 24 | test('Jsoning#clear', async t => { 25 | const db = new Jsoning('./tests/test2.test.json'); 26 | await db.set('foo', 'bar'); 27 | t.truthy(await db.clear()); 28 | }); 29 | 30 | test('Jsoning#push - new element', async t => { 31 | const db = new Jsoning('./tests/test3.test.json'); 32 | t.is(await db.push('bar', 'bar'), true); 33 | }); 34 | 35 | test('Jsoning#all', async t => { 36 | const db = new Jsoning('./tests/test4.test.json'); 37 | await db.push('bar', 'bar'); 38 | t.truthy(await db.all()); 39 | }); 40 | 41 | test('Jsoning#push - already existing element', async t => { 42 | const db = new Jsoning('./tests/test5.test.json'); 43 | await db.push('bar', 'bar'); 44 | t.is(await db.push('bar', 'foo'), true); 45 | }); 46 | 47 | test('Jsoning#get', async t => { 48 | const db = new Jsoning('./tests/test6.test.json'); 49 | await db.push('bar', 'bar'); 50 | t.deepEqual(await db.get('bar'), ['bar']); 51 | }); 52 | 53 | test('Jsoning#math', async t => { 54 | const db = new Jsoning('./tests/test7.test.json'); 55 | await db.set('number', 300); 56 | t.is(await db.math('number', 'add', 300), true); 57 | }); 58 | 59 | test('Jsoning#has - deliberate false', async t => { 60 | const db = new Jsoning('./tests/test8.test.json'); 61 | t.is(await db.has('khaleel'), false); 62 | }); 63 | 64 | test('Jsoning#has - existing element', async t => { 65 | const db = new Jsoning('./tests/test9.test.json'); 66 | // await db.clear(); 67 | await db.push('bar', 'pog'); 68 | t.is(await db.has('bar'), true); 69 | }); 70 | 71 | test('Jsoning#remove - existing element', async t => { 72 | const db = new Jsoning('./tests/test10.test.json'); 73 | await db.set('removeArea', ['a', 'b', 'a']); 74 | t.is(await db.remove('removeArea', 'a'), true); 75 | t.deepEqual(await db.get('removeArea'), ['b']); 76 | }); 77 | 78 | test('Jsoning#remove - non-existent element', async t => { 79 | const db = new Jsoning('./tests/test11.test.json'); 80 | await db.set('removeArea', ['a', 'b', 'a']); 81 | t.is(await db.remove('removeArea', 'c'), true); 82 | t.deepEqual(await db.get('removeArea'), ['a', 'b', 'a']); 83 | }); 84 | 85 | test('Jsoning#remove - non-existent key', async t => { 86 | const db = new Jsoning('./tests/test12.test.json'); 87 | t.is(await db.remove('noRemoveArea', 'a'), true); 88 | t.is(await db.has('noRemoveArea'), false); 89 | }); 90 | 91 | test('Jsoning#remove - non-array key', async t => { 92 | const db = new Jsoning('./tests/test13.test.json'); 93 | await db.set('nonArray', 'no touching'); 94 | t.throwsAsync(db.remove('nonArray', 'a')); 95 | t.is(await db.get('nonArray'), 'no touching'); 96 | }); 97 | 98 | test('Jsoning#copy', async t => { 99 | const db = new Jsoning('./tests/test14.test.json'); 100 | await db.set('copyArea', ['a', 'b', 'c']); 101 | t.like( 102 | await (await db.copy('./tests/test15.test.json', true)).get('copyArea'), 103 | ['a', 'b', 'c'] 104 | ); 105 | }); 106 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/**/*"], 3 | "compilerOptions": { 4 | "allowSyntheticDefaultImports": true, 5 | "module": "Node16", 6 | "target": "ESNext", 7 | "allowJs": true, 8 | "checkJs": true, 9 | "declaration": true, 10 | "declarationDir": "dist", 11 | "outDir": "dist" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://typedoc.org/schema.json", 3 | "entryPoints": ["./src/index.ts"], 4 | "out": "./docs", 5 | "cname": "jsoning.js.org", 6 | "githubPages": true, 7 | "includeVersion": true, 8 | "name": "Jsoning", 9 | "navigation": true, 10 | "readme": "./README.md", 11 | "sidebarLinks": { 12 | "GitHub": "https://github.com/khalby786/jsoning" 13 | }, 14 | "sitemapBaseUrl": "https://jsoning.js.org", 15 | "plugin": ["typedoc-material-theme"], 16 | "themeColor": "#6750A4", 17 | "searchInComments": true, 18 | "customCss": "./media/typedoc_css.css", 19 | "hideGenerator": true 20 | } 21 | --------------------------------------------------------------------------------