@keyv/sqlite 4.0.4 → 4.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -35,12 +35,18 @@ __export(index_exports, {
35
35
  default: () => index_default
36
36
  });
37
37
  module.exports = __toCommonJS(index_exports);
38
- var import_events = __toESM(require("events"), 1);
39
- var import_util = require("util");
38
+ var import_node_events = __toESM(require("events"), 1);
39
+ var import_node_util = require("util");
40
40
  var import_keyv = __toESM(require("keyv"), 1);
41
41
  var import_sqlite3 = __toESM(require("sqlite3"), 1);
42
- var toString = (input) => String(input).search(/^[a-zA-Z]+$/) < 0 ? "_" + input : input;
43
- var KeyvSqlite = class extends import_events.default {
42
+ var toTableString = (input) => {
43
+ const sanitized = String(input).replace(/[^a-zA-Z0-9_]/g, "");
44
+ if (sanitized.length === 0) {
45
+ throw new Error("Invalid table name: must contain alphanumeric characters");
46
+ }
47
+ return /^[a-zA-Z]/.test(sanitized) ? sanitized : `_${sanitized}`;
48
+ };
49
+ var KeyvSqlite = class extends import_node_events.default {
44
50
  ttlSupport;
45
51
  opts;
46
52
  namespace;
@@ -73,16 +79,31 @@ var KeyvSqlite = class extends import_events.default {
73
79
  resolve(database);
74
80
  }
75
81
  });
76
- }).then((database) => ({ query: (0, import_util.promisify)(database.all).bind(database), close: (0, import_util.promisify)(database.close).bind(database) }));
82
+ }).then((database) => ({
83
+ // @ts-expect-error
84
+ query: (0, import_node_util.promisify)(database.all).bind(database),
85
+ // @ts-expect-error
86
+ close: (0, import_node_util.promisify)(database.close).bind(database)
87
+ }));
77
88
  this.opts = {
78
89
  table: "keyv",
79
90
  keySize: 255,
80
91
  ...options
81
92
  };
82
- this.opts.table = toString(this.opts.table);
83
- const createTable = `CREATE TABLE IF NOT EXISTS ${this.opts.table}(key VARCHAR(${Number(this.opts.keySize)}) PRIMARY KEY, value TEXT )`;
84
- const connected = this.opts.connect().then(async (database) => database.query(createTable).then(() => database)).catch((error) => this.emit("error", error));
85
- this.query = async (sqlString, ...parameter) => connected.then(async (database) => database.query(sqlString, ...parameter));
93
+ this.opts.table = toTableString(this.opts.table);
94
+ const keySize = Number(this.opts.keySize);
95
+ if (!Number.isFinite(keySize) || keySize <= 0 || keySize > 65535) {
96
+ throw new Error(
97
+ "Invalid keySize: must be a positive number between 1 and 65535"
98
+ );
99
+ }
100
+ const createTable = `CREATE TABLE IF NOT EXISTS ${this.opts.table}(key VARCHAR(${keySize}) PRIMARY KEY, value TEXT )`;
101
+ const connected = this.opts.connect().then(
102
+ async (database) => database.query(createTable).then(() => database)
103
+ ).catch((error) => this.emit("error", error));
104
+ this.query = async (sqlString, ...parameter) => connected.then(
105
+ async (database) => database.query(sqlString, ...parameter)
106
+ );
86
107
  this.close = async () => connected.then((database) => database.close());
87
108
  }
88
109
  async get(key) {
@@ -98,10 +119,13 @@ var KeyvSqlite = class extends import_events.default {
98
119
  const select = `SELECT * FROM ${this.opts.table} WHERE key IN (SELECT value FROM json_each(?))`;
99
120
  const rows = await this.query(select, JSON.stringify(keys));
100
121
  return keys.map((key) => {
101
- const row = rows.find((row2) => row2.key === key);
122
+ const row = rows.find(
123
+ (row2) => row2.key === key
124
+ );
102
125
  return row ? row.value : void 0;
103
126
  });
104
127
  }
128
+ // biome-ignore lint/suspicious/noExplicitAny: type format
105
129
  async set(key, value) {
106
130
  const upsert = `INSERT INTO ${this.opts.table} (key, value)
107
131
  VALUES(?, ?)
@@ -137,7 +161,12 @@ var KeyvSqlite = class extends import_events.default {
137
161
  const limit = Number.parseInt(this.opts.iterationLimit, 10) || 10;
138
162
  async function* iterate(offset, options, query) {
139
163
  const select = `SELECT * FROM ${options.table} WHERE key LIKE ? LIMIT ? OFFSET ?`;
140
- const iterator = await query(select, [`${namespace ? namespace + ":" : ""}%`, limit, offset]);
164
+ const iterator = await query(select, [
165
+ // biome-ignore lint/style/useTemplate: need to fix
166
+ `${namespace ? namespace + ":" : ""}%`,
167
+ limit,
168
+ offset
169
+ ]);
141
170
  const entries = [...iterator];
142
171
  if (entries.length === 0) {
143
172
  return;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import EventEmitter from 'events';
1
+ import EventEmitter from 'node:events';
2
2
  import Keyv, { KeyvStoreAdapter, StoredData } from 'keyv';
3
3
 
4
4
  type DbQuery = (sqlString: string, ...parameter: unknown[]) => Promise<any>;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import EventEmitter from 'events';
1
+ import EventEmitter from 'node:events';
2
2
  import Keyv, { KeyvStoreAdapter, StoredData } from 'keyv';
3
3
 
4
4
  type DbQuery = (sqlString: string, ...parameter: unknown[]) => Promise<any>;
package/dist/index.js CHANGED
@@ -3,7 +3,13 @@ import EventEmitter from "events";
3
3
  import { promisify } from "util";
4
4
  import Keyv from "keyv";
5
5
  import sqlite3 from "sqlite3";
6
- var toString = (input) => String(input).search(/^[a-zA-Z]+$/) < 0 ? "_" + input : input;
6
+ var toTableString = (input) => {
7
+ const sanitized = String(input).replace(/[^a-zA-Z0-9_]/g, "");
8
+ if (sanitized.length === 0) {
9
+ throw new Error("Invalid table name: must contain alphanumeric characters");
10
+ }
11
+ return /^[a-zA-Z]/.test(sanitized) ? sanitized : `_${sanitized}`;
12
+ };
7
13
  var KeyvSqlite = class extends EventEmitter {
8
14
  ttlSupport;
9
15
  opts;
@@ -37,16 +43,31 @@ var KeyvSqlite = class extends EventEmitter {
37
43
  resolve(database);
38
44
  }
39
45
  });
40
- }).then((database) => ({ query: promisify(database.all).bind(database), close: promisify(database.close).bind(database) }));
46
+ }).then((database) => ({
47
+ // @ts-expect-error
48
+ query: promisify(database.all).bind(database),
49
+ // @ts-expect-error
50
+ close: promisify(database.close).bind(database)
51
+ }));
41
52
  this.opts = {
42
53
  table: "keyv",
43
54
  keySize: 255,
44
55
  ...options
45
56
  };
46
- this.opts.table = toString(this.opts.table);
47
- const createTable = `CREATE TABLE IF NOT EXISTS ${this.opts.table}(key VARCHAR(${Number(this.opts.keySize)}) PRIMARY KEY, value TEXT )`;
48
- const connected = this.opts.connect().then(async (database) => database.query(createTable).then(() => database)).catch((error) => this.emit("error", error));
49
- this.query = async (sqlString, ...parameter) => connected.then(async (database) => database.query(sqlString, ...parameter));
57
+ this.opts.table = toTableString(this.opts.table);
58
+ const keySize = Number(this.opts.keySize);
59
+ if (!Number.isFinite(keySize) || keySize <= 0 || keySize > 65535) {
60
+ throw new Error(
61
+ "Invalid keySize: must be a positive number between 1 and 65535"
62
+ );
63
+ }
64
+ const createTable = `CREATE TABLE IF NOT EXISTS ${this.opts.table}(key VARCHAR(${keySize}) PRIMARY KEY, value TEXT )`;
65
+ const connected = this.opts.connect().then(
66
+ async (database) => database.query(createTable).then(() => database)
67
+ ).catch((error) => this.emit("error", error));
68
+ this.query = async (sqlString, ...parameter) => connected.then(
69
+ async (database) => database.query(sqlString, ...parameter)
70
+ );
50
71
  this.close = async () => connected.then((database) => database.close());
51
72
  }
52
73
  async get(key) {
@@ -62,10 +83,13 @@ var KeyvSqlite = class extends EventEmitter {
62
83
  const select = `SELECT * FROM ${this.opts.table} WHERE key IN (SELECT value FROM json_each(?))`;
63
84
  const rows = await this.query(select, JSON.stringify(keys));
64
85
  return keys.map((key) => {
65
- const row = rows.find((row2) => row2.key === key);
86
+ const row = rows.find(
87
+ (row2) => row2.key === key
88
+ );
66
89
  return row ? row.value : void 0;
67
90
  });
68
91
  }
92
+ // biome-ignore lint/suspicious/noExplicitAny: type format
69
93
  async set(key, value) {
70
94
  const upsert = `INSERT INTO ${this.opts.table} (key, value)
71
95
  VALUES(?, ?)
@@ -101,7 +125,12 @@ var KeyvSqlite = class extends EventEmitter {
101
125
  const limit = Number.parseInt(this.opts.iterationLimit, 10) || 10;
102
126
  async function* iterate(offset, options, query) {
103
127
  const select = `SELECT * FROM ${options.table} WHERE key LIKE ? LIMIT ? OFFSET ?`;
104
- const iterator = await query(select, [`${namespace ? namespace + ":" : ""}%`, limit, offset]);
128
+ const iterator = await query(select, [
129
+ // biome-ignore lint/style/useTemplate: need to fix
130
+ `${namespace ? namespace + ":" : ""}%`,
131
+ limit,
132
+ offset
133
+ ]);
105
134
  const entries = [...iterator];
106
135
  if (entries.length === 0) {
107
136
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keyv/sqlite",
3
- "version": "4.0.4",
3
+ "version": "4.0.6",
4
4
  "description": "SQLite storage adapter for Keyv",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -12,24 +12,6 @@
12
12
  "import": "./dist/index.js"
13
13
  }
14
14
  },
15
- "xo": {
16
- "rules": {
17
- "import/no-named-as-default": "off",
18
- "unicorn/prefer-module": "off",
19
- "n/file-extension-in-import": "off",
20
- "unicorn/prefer-event-target": "off",
21
- "unicorn/prefer-node-protocol": "off",
22
- "promise/prefer-await-to-then": "off",
23
- "@typescript-eslint/use-unknown-in-catch-callback-variable": "off",
24
- "import/extensions": "off",
25
- "@typescript-eslint/no-unsafe-argument": "off",
26
- "@typescript-eslint/no-unsafe-assignment": "off",
27
- "@typescript-eslint/no-unsafe-call": "off",
28
- "@typescript-eslint/no-unsafe-return": "off",
29
- "import/no-extraneous-dependencies": "off",
30
- "unicorn/prevent-abbreviations": "off"
31
- }
32
- },
33
15
  "repository": {
34
16
  "type": "git",
35
17
  "url": "git+https://github.com/jaredwray/keyv.git"
@@ -56,13 +38,16 @@
56
38
  "sqlite3": "^5.1.7"
57
39
  },
58
40
  "peerDependencies": {
59
- "keyv": "^5.3.3"
41
+ "keyv": "^5.5.3"
60
42
  },
61
43
  "devDependencies": {
44
+ "@biomejs/biome": "^2.2.5",
45
+ "@faker-js/faker": "^10.0.0",
46
+ "@vitest/coverage-v8": "^3.2.4",
62
47
  "rimraf": "^6.0.1",
63
- "tsd": "^0.32.0",
64
- "xo": "^0.60.0",
65
- "@keyv/test-suite": "^2.0.7"
48
+ "tsd": "^0.33.0",
49
+ "vitest": "^3.2.4",
50
+ "@keyv/test-suite": "^2.1.1"
66
51
  },
67
52
  "tsd": {
68
53
  "directory": "test"
@@ -76,8 +61,10 @@
76
61
  ],
77
62
  "scripts": {
78
63
  "build": "rimraf ./dist && tsup src/index.ts --format cjs,esm --dts --clean",
79
- "test": "xo --fix && vitest run --coverage",
80
- "test:ci": "xo && vitest --run --sequence.setupFiles=list",
64
+ "lint": "biome check --write --error-on-warnings",
65
+ "lint:ci": "biome check --error-on-warnings",
66
+ "test": "pnpm lint && vitest run --coverage",
67
+ "test:ci": "pnpm lint:ci && vitest --run --sequence.setupFiles=list --coverage",
81
68
  "clean": "rimraf ./node_modules ./coverage ./test/testdb.sqlite ./dist"
82
69
  }
83
70
  }