Comparing version 6.1.1 to 7.0.0
/// <reference types="node" resolution-mode="require"/> | ||
import { PathLike } from 'fs'; | ||
import { Adapter, SyncAdapter } from '../../core/Low.js'; | ||
export declare class JSONFile<T> implements Adapter<T> { | ||
#private; | ||
import { DataFile, DataFileSync } from './DataFile.js'; | ||
export declare class JSONFile<T> extends DataFile<T> { | ||
constructor(filename: PathLike); | ||
read(): Promise<T | null>; | ||
write(obj: T): Promise<void>; | ||
} | ||
export declare class JSONFileSync<T> implements SyncAdapter<T> { | ||
#private; | ||
export declare class JSONFileSync<T> extends DataFileSync<T> { | ||
constructor(filename: PathLike); | ||
read(): T | null; | ||
write(obj: T): void; | ||
} |
@@ -1,37 +0,17 @@ | ||
import { TextFile, TextFileSync } from './TextFile.js'; | ||
export class JSONFile { | ||
#adapter; | ||
import { DataFile, DataFileSync } from './DataFile.js'; | ||
export class JSONFile extends DataFile { | ||
constructor(filename) { | ||
this.#adapter = new TextFile(filename); | ||
super(filename, { | ||
parse: JSON.parse, | ||
stringify: (data) => JSON.stringify(data, null, 2), | ||
}); | ||
} | ||
async read() { | ||
const data = await this.#adapter.read(); | ||
if (data === null) { | ||
return null; | ||
} | ||
else { | ||
return JSON.parse(data); | ||
} | ||
} | ||
write(obj) { | ||
return this.#adapter.write(JSON.stringify(obj, null, 2)); | ||
} | ||
} | ||
export class JSONFileSync { | ||
#adapter; | ||
export class JSONFileSync extends DataFileSync { | ||
constructor(filename) { | ||
this.#adapter = new TextFileSync(filename); | ||
super(filename, { | ||
parse: JSON.parse, | ||
stringify: (data) => JSON.stringify(data, null, 2), | ||
}); | ||
} | ||
read() { | ||
const data = this.#adapter.read(); | ||
if (data === null) { | ||
return null; | ||
} | ||
else { | ||
return JSON.parse(data); | ||
} | ||
} | ||
write(obj) { | ||
this.#adapter.write(JSON.stringify(obj, null, 2)); | ||
} | ||
} |
/// <reference types="node" resolution-mode="require"/> | ||
import fs from 'node:fs'; | ||
import { PathLike } from 'node:fs'; | ||
import { Adapter, SyncAdapter } from '../../core/Low.js'; | ||
export declare class TextFile implements Adapter<string> { | ||
#private; | ||
constructor(filename: fs.PathLike); | ||
constructor(filename: PathLike); | ||
read(): Promise<string | null>; | ||
@@ -12,5 +12,5 @@ write(str: string): Promise<void>; | ||
#private; | ||
constructor(filename: fs.PathLike); | ||
constructor(filename: PathLike); | ||
read(): string | null; | ||
write(str: string): void; | ||
} |
@@ -1,3 +0,3 @@ | ||
import fs from 'node:fs'; | ||
import * as fsPromises from 'node:fs/promises'; | ||
import { readFileSync, renameSync, writeFileSync } from 'node:fs'; | ||
import { readFile } from 'node:fs/promises'; | ||
import path from 'node:path'; | ||
@@ -15,3 +15,3 @@ import { Writer } from 'steno'; | ||
try { | ||
data = await fsPromises.readFile(this.#filename, 'utf-8'); | ||
data = await readFile(this.#filename, 'utf-8'); | ||
} | ||
@@ -41,3 +41,3 @@ catch (e) { | ||
try { | ||
data = fs.readFileSync(this.#filename, 'utf-8'); | ||
data = readFileSync(this.#filename, 'utf-8'); | ||
} | ||
@@ -53,5 +53,5 @@ catch (e) { | ||
write(str) { | ||
fs.writeFileSync(this.#tempFilename, str); | ||
fs.renameSync(this.#tempFilename, this.#filename); | ||
writeFileSync(this.#tempFilename, str); | ||
renameSync(this.#tempFilename, this.#filename); | ||
} | ||
} |
@@ -15,2 +15,3 @@ export interface Adapter<T> { | ||
write(): Promise<void>; | ||
update(fn: (data: T) => unknown): Promise<void>; | ||
} | ||
@@ -23,2 +24,3 @@ export declare class LowSync<T = unknown> { | ||
write(): void; | ||
update(fn: (data: T) => unknown): void; | ||
} |
@@ -24,2 +24,6 @@ function checkArgs(adapter, defaultData) { | ||
} | ||
async update(fn) { | ||
fn(this.data); | ||
await this.write(); | ||
} | ||
} | ||
@@ -43,2 +47,6 @@ export class LowSync { | ||
} | ||
update(fn) { | ||
fn(this.data); | ||
this.write(); | ||
} | ||
} |
/// <reference types="node" resolution-mode="require"/> | ||
import fs from 'node:fs'; | ||
import { PathLike } from 'node:fs'; | ||
import { Low, LowSync } from '../core/Low.js'; | ||
export declare function JSONPreset<Data>(filename: fs.PathLike, defaultData: Data): Promise<Low<Data>>; | ||
export declare function JSONSyncPreset<Data>(filename: fs.PathLike, defaultData: Data): LowSync<Data>; | ||
export declare function JSONFilePreset<Data>(filename: PathLike, defaultData: Data): Promise<Low<Data>>; | ||
export declare function JSONFileSyncPreset<Data>(filename: PathLike, defaultData: Data): LowSync<Data>; |
import { Memory, MemorySync } from '../adapters/Memory.js'; | ||
import { JSONFile, JSONFileSync } from '../adapters/node/JSONFile.js'; | ||
import { Low, LowSync } from '../core/Low.js'; | ||
export async function JSONPreset(filename, defaultData) { | ||
export async function JSONFilePreset(filename, defaultData) { | ||
const adapter = process.env.NODE_ENV === 'test' | ||
@@ -12,3 +12,3 @@ ? new Memory() | ||
} | ||
export function JSONSyncPreset(filename, defaultData) { | ||
export function JSONFileSyncPreset(filename, defaultData) { | ||
const adapter = process.env.NODE_ENV === 'test' | ||
@@ -15,0 +15,0 @@ ? new MemorySync() |
{ | ||
"name": "lowdb", | ||
"version": "6.1.1", | ||
"version": "7.0.0", | ||
"description": "Tiny local JSON database for Node, Electron and the browser", | ||
@@ -53,3 +53,3 @@ "keywords": [ | ||
"scripts": { | ||
"test": "xv --loader=ts-node/esm src", | ||
"test": "node --import tsx/esm --test src/**/*.test.ts src/**/**/*.test.ts", | ||
"lint": "eslint src --ext .ts --ignore-path .gitignore", | ||
@@ -62,15 +62,15 @@ "build": "del-cli lib && tsc", | ||
"dependencies": { | ||
"steno": "^3.1.1" | ||
"steno": "^4.0.2" | ||
}, | ||
"devDependencies": { | ||
"@commitlint/cli": "^17.7.2", | ||
"@commitlint/config-conventional": "^17.7.0", | ||
"@commitlint/prompt-cli": "^17.7.2", | ||
"@commitlint/cli": "^18.4.3", | ||
"@commitlint/config-conventional": "^18.4.3", | ||
"@commitlint/prompt-cli": "^18.4.3", | ||
"@sindresorhus/tsconfig": "^5.0.0", | ||
"@types/express": "^4.17.19", | ||
"@types/lodash": "^4.14.199", | ||
"@types/node": "^20.8.5", | ||
"@types/express": "^4.17.21", | ||
"@types/lodash": "^4.14.202", | ||
"@types/node": "^20.10.5", | ||
"@typicode/eslint-config": "^1.2.0", | ||
"del-cli": "^5.1.0", | ||
"eslint": "^8.51.0", | ||
"eslint": "^8.56.0", | ||
"express-async-handler": "^1.2.0", | ||
@@ -80,9 +80,9 @@ "husky": "^8.0.3", | ||
"tempy": "^3.1.0", | ||
"ts-node": "^10.9.1", | ||
"typescript": "^5.2.2", | ||
"xv": "^2.1.1" | ||
"ts-node": "^10.9.2", | ||
"tsx": "^4.7.0", | ||
"typescript": "^5.3.3" | ||
}, | ||
"engines": { | ||
"node": ">=16" | ||
"node": ">=18" | ||
} | ||
} |
@@ -5,13 +5,13 @@ # lowdb [![](http://img.shields.io/npm/dm/lowdb.svg?style=flat)](https://www.npmjs.org/package/lowdb) [![Node.js CI](https://github.com/typicode/lowdb/actions/workflows/node.js.yml/badge.svg)](https://github.com/typicode/lowdb/actions/workflows/node.js.yml) | ||
Read or create `db.json` | ||
```js | ||
// Read or create db.json | ||
const db = await JSONPreset('db.json', { posts: [] }) | ||
const db = await JSONFilePreset('db.json', { posts: [] }) | ||
``` | ||
// Edit db.json content using plain JavaScript | ||
db.data | ||
.posts | ||
.push({ id: 1, title: 'lowdb is awesome' }) | ||
Update data using `Array.prototype.*` and automatically write to `db.json` | ||
// Save to file | ||
db.write() | ||
```js | ||
const post = { id: 1, title: 'lowdb is awesome', views: 100 } | ||
await db.update(({ posts }) => posts.push(post)) | ||
``` | ||
@@ -23,3 +23,3 @@ | ||
"posts": [ | ||
{ "id": 1, "title": "lowdb is awesome" } | ||
{ "id": 1, "title": "lowdb is awesome", "views": 100 } | ||
] | ||
@@ -29,2 +29,14 @@ } | ||
In the same spirit, query using native `Array.prototype.*` | ||
```js | ||
const { posts } = db.data | ||
const first = posts.at(0) | ||
const results = posts.filter((post) => post.title.includes('lowdb')) | ||
const post1 = posts.find((post) => post.id === 1) | ||
const sortedPosts = posts.toSorted((a, b) => a.views - b.views) | ||
``` | ||
It's that simple. | ||
## Sponsors | ||
@@ -51,3 +63,3 @@ | ||
- **TypeScript** | ||
- **plain JavaScript** | ||
- **Plain JavaScript** | ||
- Safe atomic writes | ||
@@ -57,2 +69,3 @@ - Hackable: | ||
- Extend it with lodash, ramda, ... for super powers! | ||
- Automatically switches to fast in-memory mode during tests | ||
@@ -70,17 +83,14 @@ ## Install | ||
```js | ||
import { JSONPreset } from 'lowdb/node' | ||
import { JSONFilePreset } from 'lowdb/node' | ||
// Read or create db.json | ||
const defaultData = { posts: [] } | ||
const db = await JSONPreset('db.json', defaultData) | ||
const db = await JSONFilePreset('db.json', defaultData) | ||
// Create and query items using plain JavaScript | ||
// Update db.json | ||
await db.update(({ posts }) => posts.push('hello world')) | ||
// Alternatively you can call db.write() explicitely later | ||
// to write to db.json | ||
db.data.posts.push('hello world') | ||
const firstPost = db.data.posts[0] | ||
// If you don't want to type db.data everytime, you can use destructuring assignment | ||
const { posts } = db.data | ||
posts.push('hello world') | ||
// Finally write db.data content to file | ||
await db.write() | ||
@@ -106,3 +116,3 @@ ``` | ||
const defaultData: Data = { messages: [] } | ||
const db = await JSONFile<Data>('db.json') | ||
const db = await JSONPreset<Data>('db.json', defaultData) | ||
@@ -115,3 +125,3 @@ db.data.messages.push('foo') // ✅ Success | ||
You can extend lowdb with Lodash (or other libraries). | ||
You can extend lowdb with Lodash (or other libraries). To be able to extend it, we're not using `JSONPreset` here. Instead, we're using lower components. | ||
@@ -141,2 +151,3 @@ ```ts | ||
const adapter = new JSONFile<Data>('db.json', defaultData) | ||
const db = new LowWithLodash(adapter) | ||
@@ -159,4 +170,4 @@ await db.read() | ||
- `JSONPreset(filename, defaultData)` | ||
- `JSONSyncPreset(filename, defaultData)` | ||
- `JSONFilePreset(filename, defaultData)` | ||
- `JSONFileSyncPreset(filename, defaultData)` | ||
- `LocalStoragePreset(name, defaultData)` | ||
@@ -173,3 +184,3 @@ - `SessionStoragePreset(name, defaultData)` | ||
#### `new Low(adapter)` | ||
#### `new Low(adapter, defaultData)` | ||
@@ -185,3 +196,3 @@ ```js | ||
#### `new LowSync(adapterSync)` | ||
#### `new LowSync(adapterSync, defaultData)` | ||
@@ -222,2 +233,14 @@ ```js | ||
#### `db.update(fn)` | ||
Calls `fn()` then `db.write()`. | ||
```js | ||
db.update((data) => { | ||
// make changes to data | ||
// ... | ||
}) | ||
// files.json will be updated | ||
``` | ||
### Properties | ||
@@ -273,2 +296,4 @@ | ||
### Utility adapters | ||
#### `TextFile` `TextFileSync` | ||
@@ -278,2 +303,18 @@ | ||
#### `DataFile` `DataFileSync` | ||
Adapters for easily supporting other data formats or adding behaviors (encrypt, compress...). | ||
```js | ||
import { DataFile } from 'lowdb' | ||
new DataFile(filename, { | ||
parse: YAML.parse, | ||
stringify: YAML.stringify | ||
}) | ||
new DataFile(filename, { | ||
parse: (data) => { decypt(JSON.parse(data)) }, | ||
stringify: (str) => { encrypt(JSON.stringify(str)) } | ||
}) | ||
``` | ||
### Third-party adapters | ||
@@ -280,0 +321,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
22783
29
368
405
+ Addedsteno@4.0.2(transitive)
- Removedsteno@3.2.0(transitive)
Updatedsteno@^4.0.2