keyv-registry 1.0.2 → 2.0.0
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/README.md +14 -3
- package/dist/cjs/loadAdapter.d.cts +1 -1
- package/dist/cjs/loadAdapter.d.ts +1 -1
- package/dist/cjs/loadAdapter.js +7 -25
- package/dist/cjs/loadAdapter.js.map +1 -1
- package/dist/cjs/registry.js +1 -3
- package/dist/cjs/registry.js.map +1 -1
- package/dist/cjs/utils.js +9 -20
- package/dist/cjs/utils.js.map +1 -1
- package/dist/cjs/worker.js +1 -3
- package/dist/cjs/worker.js.map +1 -1
- package/dist/esm/loadAdapter.d.ts +1 -1
- package/dist/esm/loadAdapter.js +7 -25
- package/dist/esm/loadAdapter.js.map +1 -1
- package/package.json +13 -3
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# keyv-registry
|
|
2
2
|
|
|
3
|
-
Protocol-based Keyv adapter registry
|
|
3
|
+
Protocol-based Keyv adapter registry.
|
|
4
4
|
|
|
5
|
-
Create Keyv stores from URI strings
|
|
5
|
+
Create Keyv stores from URI strings, resolving each adapter from the modules installed alongside your application.
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
9
|
- **URI-based configuration**: Use familiar connection strings like `redis://localhost:6379`
|
|
10
|
-
- **
|
|
10
|
+
- **No bundled adapters**: install only the adapter you use; keyv-registry itself depends on nothing but keyv
|
|
11
11
|
- **Extensible registry**: Register custom protocols or override defaults
|
|
12
12
|
- **Dual-boot API**: Supports both Promise and callback patterns
|
|
13
13
|
- **URI parameter mapping**: Query params automatically converted to adapter options
|
|
@@ -19,6 +19,17 @@ Create Keyv stores from URI strings with automatic adapter resolution and on-dem
|
|
|
19
19
|
npm install keyv-registry
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
Adapters are not bundled. Install the one your protocol needs alongside it:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @keyv/redis # redis://, rediss://
|
|
26
|
+
npm install keyv-file # file://
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`memory://` is built in and needs no package.
|
|
30
|
+
|
|
31
|
+
Adapters are resolved with `require()`, so an adapter only has to be installed somewhere Node resolves from your application: your project's `node_modules`, or globally beside a globally installed CLI. A protocol whose adapter is missing fails with the name of the package to install.
|
|
32
|
+
|
|
22
33
|
## Usage
|
|
23
34
|
|
|
24
35
|
### Promise API
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LoadAdapterCallback } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Load an adapter
|
|
3
|
+
* Load an adapter from the modules installed alongside the consumer
|
|
4
4
|
*/
|
|
5
5
|
export default function loadAdapter(packageName: string, exportName: string | undefined, callback: LoadAdapterCallback): void;
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LoadAdapterCallback } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Load an adapter
|
|
3
|
+
* Load an adapter from the modules installed alongside the consumer
|
|
4
4
|
*/
|
|
5
5
|
export default function loadAdapter(packageName: string, exportName: string | undefined, callback: LoadAdapterCallback): void;
|
|
6
6
|
/**
|
package/dist/cjs/loadAdapter.js
CHANGED
|
@@ -13,15 +13,12 @@ _export(exports, {
|
|
|
13
13
|
return clearAdapterCache;
|
|
14
14
|
},
|
|
15
15
|
get /**
|
|
16
|
-
* Load an adapter
|
|
16
|
+
* Load an adapter from the modules installed alongside the consumer
|
|
17
17
|
*/ default () {
|
|
18
18
|
return loadAdapter;
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
21
|
var _nodemodule = /*#__PURE__*/ _interop_require_default(require("node:module"));
|
|
22
|
-
var _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
23
|
-
var _nodeurl = /*#__PURE__*/ _interop_require_default(require("node:url"));
|
|
24
|
-
var _installmodulelinked = /*#__PURE__*/ _interop_require_default(require("install-module-linked"));
|
|
25
22
|
function _interop_require_default(obj) {
|
|
26
23
|
return obj && obj.__esModule ? obj : {
|
|
27
24
|
default: obj
|
|
@@ -29,9 +26,6 @@ function _interop_require_default(obj) {
|
|
|
29
26
|
}
|
|
30
27
|
// Create require function for ESM compatibility
|
|
31
28
|
var _require = typeof require === 'undefined' ? _nodemodule.default.createRequire(require("url").pathToFileURL(__filename).toString()) : require;
|
|
32
|
-
// Determine node_modules path
|
|
33
|
-
var _dirname = _nodepath.default.dirname(typeof __filename === 'undefined' ? _nodeurl.default.fileURLToPath(require("url").pathToFileURL(__filename).toString()) : __filename);
|
|
34
|
-
var nodeModulesPath = _nodepath.default.join(_dirname, '..', '..', 'node_modules');
|
|
35
29
|
// Cache loaded adapters
|
|
36
30
|
var adapterCache = new Map();
|
|
37
31
|
function loadAdapter(packageName, exportName, callback) {
|
|
@@ -41,29 +35,17 @@ function loadAdapter(packageName, exportName, callback) {
|
|
|
41
35
|
callback(null, adapterCache.get(cacheKey));
|
|
42
36
|
return;
|
|
43
37
|
}
|
|
44
|
-
|
|
38
|
+
var Adapter;
|
|
45
39
|
try {
|
|
46
40
|
var _mod_default;
|
|
47
41
|
var mod = _require(packageName);
|
|
48
|
-
|
|
49
|
-
adapterCache.set(cacheKey, Adapter);
|
|
50
|
-
callback(null, Adapter);
|
|
51
|
-
return;
|
|
42
|
+
Adapter = exportName ? mod[exportName] : (_mod_default = mod.default) !== null && _mod_default !== void 0 ? _mod_default : mod;
|
|
52
43
|
} catch (unused) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (err) return callback(err);
|
|
56
|
-
try {
|
|
57
|
-
var _mod_default;
|
|
58
|
-
var mod = _require(packageName);
|
|
59
|
-
var Adapter = exportName ? mod[exportName] : (_mod_default = mod.default) !== null && _mod_default !== void 0 ? _mod_default : mod;
|
|
60
|
-
adapterCache.set(cacheKey, Adapter);
|
|
61
|
-
callback(null, Adapter);
|
|
62
|
-
} catch (loadErr) {
|
|
63
|
-
callback(loadErr);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
44
|
+
callback(new Error('Adapter "'.concat(packageName, '" is not installed. Install it alongside this package: npm install ').concat(packageName)));
|
|
45
|
+
return;
|
|
66
46
|
}
|
|
47
|
+
adapterCache.set(cacheKey, Adapter);
|
|
48
|
+
callback(null, Adapter);
|
|
67
49
|
}
|
|
68
50
|
function clearAdapterCache() {
|
|
69
51
|
adapterCache.clear();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/loadAdapter.ts"],"sourcesContent":["import Module from 'node:module';\nimport
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/loadAdapter.ts"],"sourcesContent":["import Module from 'node:module';\nimport type { LoadAdapterCallback } from './types.ts';\n\n// Create require function for ESM compatibility\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\n\n// Cache loaded adapters\nconst adapterCache = new Map<string, unknown>();\n\n/**\n * Load an adapter from the modules installed alongside the consumer\n */\nexport default function loadAdapter(packageName: string, exportName: string | undefined, callback: LoadAdapterCallback): void {\n const cacheKey = `${packageName}:${exportName ?? 'default'}`;\n\n // Return cached adapter if available\n if (adapterCache.has(cacheKey)) {\n callback(null, adapterCache.get(cacheKey));\n return;\n }\n\n let Adapter: unknown;\n try {\n const mod = _require(packageName);\n Adapter = exportName ? mod[exportName] : (mod.default ?? mod);\n } catch {\n callback(new Error(`Adapter \"${packageName}\" is not installed. Install it alongside this package: npm install ${packageName}`));\n return;\n }\n\n adapterCache.set(cacheKey, Adapter);\n callback(null, Adapter);\n}\n\n/**\n * Clear the adapter cache (useful for testing)\n */\nexport function clearAdapterCache(): void {\n adapterCache.clear();\n}\n"],"names":["clearAdapterCache","loadAdapter","_require","require","Module","createRequire","adapterCache","Map","packageName","exportName","callback","cacheKey","has","get","Adapter","mod","default","Error","set","clear"],"mappings":";;;;;;;;;;;QAqCgBA;eAAAA;;QA5BhB;;CAEC,GACD;eAAwBC;;;iEAZL;;;;;;AAGnB,gDAAgD;AAChD,IAAMC,WAAW,OAAOC,YAAY,cAAcC,mBAAM,CAACC,aAAa,CAAC,uDAAmBF;AAE1F,wBAAwB;AACxB,IAAMG,eAAe,IAAIC;AAKV,SAASN,YAAYO,WAAmB,EAAEC,UAA8B,EAAEC,QAA6B;IACpH,IAAMC,WAAW,AAbnB,AAaoB,UAAEH,aAAY,KAA2B,OAAxBC,uBAAAA,wBAAAA,aAAc;IAEjD,qCAAqC;IACrC,IAAIH,aAAaM,GAAG,CAACD,WAAW;QAC9BD,SAAS,MAAMJ,aAAaO,GAAG,CAACF;QAChC;IACF;IAEA,IAAIG;IACJ,IAAI;YAEwCC;QAD1C,IAAMA,MAAMb,SAASM;QACrBM,UAAUL,aAAaM,GAAG,CAACN,WAAW,IAAIM,eAAAA,IAAIC,OAAO,cAAXD,0BAAAA,eAAeA;IAC3D,EAAE,eAAM;QACNL,SAAS,IAAIO,MAAM,AAAC,YAA4FT,OAAjFA,aAAY,uEAAiF,OAAZA;QAChH;IACF;IAEAF,aAAaY,GAAG,CAACP,UAAUG;IAC3BJ,SAAS,MAAMI;AACjB;AAKO,SAASd;IACdM,aAAaa,KAAK;AACpB"}
|
package/dist/cjs/registry.js
CHANGED
package/dist/cjs/registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/registry.ts"],"sourcesContent":["import type { AdapterConfig } from './types.ts';\nimport { resolveFilePath } from './utils.ts';\n\n/**\n * Protocol registry mapping URI protocols to adapter configurations\n */\nconst PROTOCOL_REGISTRY: Record<string, AdapterConfig> = {\n // Official @keyv adapters\n 'redis:': { package: '@keyv/redis', mode: 'string' },\n 'rediss:': { package: '@keyv/redis', mode: 'string' },\n 'postgresql:': { package: '@keyv/postgres', mode: 'options', optionsMapper: (url) => ({ uri: url.toString() }) },\n 'postgres:': { package: '@keyv/postgres', mode: 'options', optionsMapper: (url) => ({ uri: url.toString() }) },\n 'mysql:': { package: '@keyv/mysql', mode: 'options', optionsMapper: (url) => ({ uri: url.toString() }) },\n 'sqlite:': { package: '@keyv/sqlite', mode: 'options', optionsMapper: (url) => ({ uri: url.toString() }) },\n 'mongodb:': { package: '@keyv/mongo', mode: 'options', optionsMapper: (url) => ({ url: url.toString() }) },\n 'mongodb+srv:': { package: '@keyv/mongo', mode: 'options', optionsMapper: (url) => ({ url: url.toString() }) },\n 'memcache:': { package: '@keyv/memcache', mode: 'string' },\n 'etcd:': { package: '@keyv/etcd', mode: 'options', optionsMapper: (url) => ({ url: url.toString() }) },\n\n // Third-party adapters\n 'file:': {\n package: 'keyv-file',\n exportName: 'KeyvFile',\n optionsMapper: (url: URL) => ({ filename: resolveFilePath(url) }),\n },\n\n // Built-in (no package needed)\n 'memory:': { package: null },\n\n // Future/custom adapters\n 'duckdb:': {\n package: 'keyv-duckdb',\n optionsMapper: (url: URL) => ({ filename: resolveFilePath(url) }),\n },\n};\n\n/**\n * Register or override a protocol adapter\n */\nexport function registerAdapter(protocol: string, config: AdapterConfig): void {\n const normalizedProtocol = protocol.endsWith(':') ? protocol : `${protocol}:`;\n PROTOCOL_REGISTRY[normalizedProtocol] = config;\n}\n\n/**\n * Get the current registry (read-only copy)\n */\nexport function getRegistry(): Readonly<Record<string, AdapterConfig>> {\n return { ...PROTOCOL_REGISTRY };\n}\n\n/**\n * Get adapter config for a protocol\n */\nexport function getAdapterConfig(protocol: string): AdapterConfig | undefined {\n return PROTOCOL_REGISTRY[protocol];\n}\n"],"names":["getAdapterConfig","getRegistry","registerAdapter","PROTOCOL_REGISTRY","package","mode","optionsMapper","url","uri","toString","exportName","filename","resolveFilePath","protocol","config","normalizedProtocol","endsWith"],"mappings":";;;;;;;;;;;QAsDgBA;eAAAA;;QAPAC;eAAAA;;QARAC;eAAAA;;;uBAtCgB
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/registry.ts"],"sourcesContent":["import type { AdapterConfig } from './types.ts';\nimport { resolveFilePath } from './utils.ts';\n\n/**\n * Protocol registry mapping URI protocols to adapter configurations\n */\nconst PROTOCOL_REGISTRY: Record<string, AdapterConfig> = {\n // Official @keyv adapters\n 'redis:': { package: '@keyv/redis', mode: 'string' },\n 'rediss:': { package: '@keyv/redis', mode: 'string' },\n 'postgresql:': { package: '@keyv/postgres', mode: 'options', optionsMapper: (url) => ({ uri: url.toString() }) },\n 'postgres:': { package: '@keyv/postgres', mode: 'options', optionsMapper: (url) => ({ uri: url.toString() }) },\n 'mysql:': { package: '@keyv/mysql', mode: 'options', optionsMapper: (url) => ({ uri: url.toString() }) },\n 'sqlite:': { package: '@keyv/sqlite', mode: 'options', optionsMapper: (url) => ({ uri: url.toString() }) },\n 'mongodb:': { package: '@keyv/mongo', mode: 'options', optionsMapper: (url) => ({ url: url.toString() }) },\n 'mongodb+srv:': { package: '@keyv/mongo', mode: 'options', optionsMapper: (url) => ({ url: url.toString() }) },\n 'memcache:': { package: '@keyv/memcache', mode: 'string' },\n 'etcd:': { package: '@keyv/etcd', mode: 'options', optionsMapper: (url) => ({ url: url.toString() }) },\n\n // Third-party adapters\n 'file:': {\n package: 'keyv-file',\n exportName: 'KeyvFile',\n optionsMapper: (url: URL) => ({ filename: resolveFilePath(url) }),\n },\n\n // Built-in (no package needed)\n 'memory:': { package: null },\n\n // Future/custom adapters\n 'duckdb:': {\n package: 'keyv-duckdb',\n optionsMapper: (url: URL) => ({ filename: resolveFilePath(url) }),\n },\n};\n\n/**\n * Register or override a protocol adapter\n */\nexport function registerAdapter(protocol: string, config: AdapterConfig): void {\n const normalizedProtocol = protocol.endsWith(':') ? protocol : `${protocol}:`;\n PROTOCOL_REGISTRY[normalizedProtocol] = config;\n}\n\n/**\n * Get the current registry (read-only copy)\n */\nexport function getRegistry(): Readonly<Record<string, AdapterConfig>> {\n return { ...PROTOCOL_REGISTRY };\n}\n\n/**\n * Get adapter config for a protocol\n */\nexport function getAdapterConfig(protocol: string): AdapterConfig | undefined {\n return PROTOCOL_REGISTRY[protocol];\n}\n"],"names":["getAdapterConfig","getRegistry","registerAdapter","PROTOCOL_REGISTRY","package","mode","optionsMapper","url","uri","toString","exportName","filename","resolveFilePath","protocol","config","normalizedProtocol","endsWith"],"mappings":";;;;;;;;;;;QAsDgBA;eAAAA;;QAPAC;eAAAA;;QARAC;eAAAA;;;uBAtCgB;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEhC;;CAEC,GACD,IAAMC,oBAAmD;IACvD,0BAA0B;IAC1B,UAAU;QAAEC,SAAS;QAAeC,MAAM;IAAS;IACnD,WAAW;QAAED,SAAS;QAAeC,MAAM;IAAS;IACpD,eAAe;QAAED,SAAS;QAAkBC,MAAM;QAAWC,eAAe,SAAfA,cAAgBC;mBAAS;gBAAEC,KAAKD,IAAIE,QAAQ;YAAG;;IAAG;IAC/G,aAAa;QAAEL,SAAS;QAAkBC,MAAM;QAAWC,eAAe,SAAfA,cAAgBC;mBAAS;gBAAEC,KAAKD,IAAIE,QAAQ;YAAG;;IAAG;IAC7G,UAAU;QAAEL,SAAS;QAAeC,MAAM;QAAWC,eAAe,SAAfA,cAAgBC;mBAAS;gBAAEC,KAAKD,IAAIE,QAAQ;YAAG;;IAAG;IACvG,WAAW;QAAEL,SAAS;QAAgBC,MAAM;QAAWC,eAAe,SAAfA,cAAgBC;mBAAS;gBAAEC,KAAKD,IAAIE,QAAQ;YAAG;;IAAG;IACzG,YAAY;QAAEL,SAAS;QAAeC,MAAM;QAAWC,eAAe,SAAfA,cAAgBC;mBAAS;gBAAEA,KAAKA,IAAIE,QAAQ;YAAG;;IAAG;IACzG,gBAAgB;QAAEL,SAAS;QAAeC,MAAM;QAAWC,eAAe,SAAfA,cAAgBC;mBAAS;gBAAEA,KAAKA,IAAIE,QAAQ;YAAG;;IAAG;IAC7G,aAAa;QAAEL,SAAS;QAAkBC,MAAM;IAAS;IACzD,SAAS;QAAED,SAAS;QAAcC,MAAM;QAAWC,eAAe,SAAfA,cAAgBC;mBAAS;gBAAEA,KAAKA,IAAIE,QAAQ;YAAG;;IAAG;IAErG,uBAAuB;IACvB,SAAS;QACPL,SAAS;QACTM,YAAY;QACZJ,eAAe,SAAfA,cAAgBC;mBAAc;gBAAEI,UAAUC,IAAAA,wBAAe,EAACL;YAAK;;IACjE;IAEA,+BAA+B;IAC/B,WAAW;QAAEH,SAAS;IAAK;IAE3B,yBAAyB;IACzB,WAAW;QACTA,SAAS;QACTE,eAAe,SAAfA,cAAgBC;mBAAc;gBAAEI,UAAUC,IAAAA,wBAAe,EAACL;YAAK;;IACjE;AACF;AAKO,SAASL,gBAAgBW,QAAgB,EAAEC,MAAqB;IACrE,IAAMC,qBAAqBF,SAASG,QAAQ,CAAC,OAAOH,WAAW,AAAC,GAAW,OAATA,UAAS;IAC3EV,iBAAiB,CAACY,mBAAmB,GAAGD;AAC1C;AAKO,SAASb;IACd,OAAO,mBAAKE;AACd;AAKO,SAASH,iBAAiBa,QAAgB;IAC/C,OAAOV,iBAAiB,CAACU,SAAS;AACpC"}
|
package/dist/cjs/utils.js
CHANGED
|
@@ -36,18 +36,12 @@ function _getRequireWildcardCache(nodeInterop) {
|
|
|
36
36
|
})(nodeInterop);
|
|
37
37
|
}
|
|
38
38
|
function _interop_require_wildcard(obj, nodeInterop) {
|
|
39
|
-
if (!nodeInterop && obj && obj.__esModule)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
default: obj
|
|
45
|
-
};
|
|
46
|
-
}
|
|
39
|
+
if (!nodeInterop && obj && obj.__esModule) return obj;
|
|
40
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") return {
|
|
41
|
+
default: obj
|
|
42
|
+
};
|
|
47
43
|
var cache = _getRequireWildcardCache(nodeInterop);
|
|
48
|
-
if (cache && cache.has(obj))
|
|
49
|
-
return cache.get(obj);
|
|
50
|
-
}
|
|
44
|
+
if (cache && cache.has(obj)) return cache.get(obj);
|
|
51
45
|
var newObj = {
|
|
52
46
|
__proto__: null
|
|
53
47
|
};
|
|
@@ -55,17 +49,12 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
55
49
|
for(var key in obj){
|
|
56
50
|
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
57
51
|
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
58
|
-
if (desc && (desc.get || desc.set))
|
|
59
|
-
|
|
60
|
-
} else {
|
|
61
|
-
newObj[key] = obj[key];
|
|
62
|
-
}
|
|
52
|
+
if (desc && (desc.get || desc.set)) Object.defineProperty(newObj, key, desc);
|
|
53
|
+
else newObj[key] = obj[key];
|
|
63
54
|
}
|
|
64
55
|
}
|
|
65
56
|
newObj.default = obj;
|
|
66
|
-
if (cache)
|
|
67
|
-
cache.set(obj, newObj);
|
|
68
|
-
}
|
|
57
|
+
if (cache) cache.set(obj, newObj);
|
|
69
58
|
return newObj;
|
|
70
59
|
}
|
|
71
60
|
function _iterable_to_array_limit(arr, i) {
|
|
@@ -93,7 +82,7 @@ function _iterable_to_array_limit(arr, i) {
|
|
|
93
82
|
return _arr;
|
|
94
83
|
}
|
|
95
84
|
function _non_iterable_rest() {
|
|
96
|
-
throw new TypeError("Invalid attempt to destructure non-iterable instance
|
|
85
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
97
86
|
}
|
|
98
87
|
function _sliced_to_array(arr, i) {
|
|
99
88
|
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
package/dist/cjs/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/utils.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\n/**\n * Resolve file path from URL, handling ~ and . prefixes\n */\nexport function resolveFilePath(url: URL): string {\n let filePath = url.pathname;\n\n // Handle ~ for home directory\n if (url.host === '~') {\n filePath = path.join(os.homedir(), filePath.slice(1));\n }\n // Handle . for current directory\n else if (url.host === '.') {\n filePath = path.join(process.cwd(), filePath.slice(1));\n }\n\n // Ensure directory exists\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n\n return filePath;\n}\n\n/**\n * Parse URL search params into options object with type conversion\n */\nexport function parseUriOptions(url: URL): Record<string, unknown> {\n const options: Record<string, unknown> = {};\n\n for (const [key, value] of url.searchParams) {\n // Auto-convert types\n if (value === 'true') options[key] = true;\n else if (value === 'false') options[key] = false;\n else if (/^\\d+$/.test(value)) options[key] = Number.parseInt(value, 10);\n else if (/^\\d+\\.\\d+$/.test(value)) options[key] = Number.parseFloat(value);\n else options[key] = value;\n }\n\n return options;\n}\n"],"names":["parseUriOptions","resolveFilePath","url","filePath","pathname","host","path","join","os","homedir","slice","process","cwd","fs","mkdirSync","dirname","recursive","options","searchParams","key","value","test","Number","parseInt","parseFloat"],"mappings":";;;;;;;;;;;QA4BgBA;eAAAA;;QArBAC;eAAAA;;;8DAPI;8DACA;gEACE
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/utils.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\n/**\n * Resolve file path from URL, handling ~ and . prefixes\n */\nexport function resolveFilePath(url: URL): string {\n let filePath = url.pathname;\n\n // Handle ~ for home directory\n if (url.host === '~') {\n filePath = path.join(os.homedir(), filePath.slice(1));\n }\n // Handle . for current directory\n else if (url.host === '.') {\n filePath = path.join(process.cwd(), filePath.slice(1));\n }\n\n // Ensure directory exists\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n\n return filePath;\n}\n\n/**\n * Parse URL search params into options object with type conversion\n */\nexport function parseUriOptions(url: URL): Record<string, unknown> {\n const options: Record<string, unknown> = {};\n\n for (const [key, value] of url.searchParams) {\n // Auto-convert types\n if (value === 'true') options[key] = true;\n else if (value === 'false') options[key] = false;\n else if (/^\\d+$/.test(value)) options[key] = Number.parseInt(value, 10);\n else if (/^\\d+\\.\\d+$/.test(value)) options[key] = Number.parseFloat(value);\n else options[key] = value;\n }\n\n return options;\n}\n"],"names":["parseUriOptions","resolveFilePath","url","filePath","pathname","host","path","join","os","homedir","slice","process","cwd","fs","mkdirSync","dirname","recursive","options","searchParams","key","value","test","Number","parseInt","parseFloat"],"mappings":";;;;;;;;;;;QA4BgBA;eAAAA;;QArBAC;eAAAA;;;8DAPI;8DACA;gEACE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKf,SAASA,gBAAgBC,GAAQ;IACtC,IAAIC,WAAWD,IAAIE,QAAQ;IAE3B,8BAA8B;IAC9B,IAAIF,IAAIG,IAAI,KAAK,KAAK;QACpBF,WAAWG,UAAKC,IAAI,CAACC,QAAGC,OAAO,IAAIN,SAASO,KAAK,CAAC;IACpD,OAEK,IAAIR,IAAIG,IAAI,KAAK,KAAK;QACzBF,WAAWG,UAAKC,IAAI,CAACI,QAAQC,GAAG,IAAIT,SAASO,KAAK,CAAC;IACrD;IAEA,0BAA0B;IAC1BG,QAAGC,SAAS,CAACR,UAAKS,OAAO,CAACZ,WAAW;QAAEa,WAAW;IAAK;IAEvD,OAAOb;AACT;AAKO,SAASH,gBAAgBE,GAAQ;IACtC,IAAMe,UAAmC,CAAC;QAErC,kCAAA,2BAAA;;QAAL,QAAK,YAAsBf,IAAIgB,YAAY,qBAAtC,SAAA,6BAAA,QAAA,yBAAA,iCAAwC;YAAxC,mCAAA,iBAAOC,sBAAKC;YACf,qBAAqB;YACrB,IAAIA,UAAU,QAAQH,OAAO,CAACE,IAAI,GAAG;iBAChC,IAAIC,UAAU,SAASH,OAAO,CAACE,IAAI,GAAG;iBACtC,IAAI,QAAQE,IAAI,CAACD,QAAQH,OAAO,CAACE,IAAI,GAAGG,OAAOC,QAAQ,CAACH,OAAO;iBAC/D,IAAI,aAAaC,IAAI,CAACD,QAAQH,OAAO,CAACE,IAAI,GAAGG,OAAOE,UAAU,CAACJ;iBAC/DH,OAAO,CAACE,IAAI,GAAGC;QACtB;;QAPK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IASL,OAAOH;AACT"}
|
package/dist/cjs/worker.js
CHANGED
package/dist/cjs/worker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/worker.ts"],"sourcesContent":["import Keyv from 'keyv';\nimport loadAdapter from './loadAdapter.ts';\nimport { getAdapterConfig } from './registry.ts';\nimport type { CreateStoreCallback, CreateStoreOptions } from './types.ts';\nimport { parseUriOptions } from './utils.ts';\n\n/**\n * Core worker function that creates a Keyv store\n */\nexport default function worker<T>(uri: string, options: CreateStoreOptions, callback: CreateStoreCallback<T>): void {\n // Passthrough: pre-instantiated adapter provided\n if (options.store) {\n try {\n const keyv = new Keyv<T>({ ...options });\n callback(null, keyv);\n } catch (err) {\n callback(err as Error);\n }\n return;\n }\n\n // Parse URI\n let url: URL;\n try {\n url = new URL(uri);\n } catch (_err) {\n callback(new Error(`Invalid URI: ${uri}`));\n return;\n }\n\n const config = getAdapterConfig(url.protocol);\n\n if (!config) {\n callback(new Error(`Unknown protocol: ${url.protocol}. Use registerAdapter() to add support.`));\n return;\n }\n\n // Memory store - no package needed\n if (config.package === null) {\n try {\n const keyv = new Keyv<T>({ ...parseUriOptions(url), ...options });\n callback(null, keyv);\n } catch (err) {\n callback(err as Error);\n }\n return;\n }\n\n // Load adapter (install if needed)\n loadAdapter(config.package, config.exportName, (err, AdapterClass) => {\n if (err) return callback(err);\n\n try {\n // Build adapter options: URI params + custom mapper + user options\n const adapterOptions = {\n ...parseUriOptions(url),\n ...(config.optionsMapper?.(url) ?? {}),\n ...options,\n };\n\n // Remove store from adapter options to avoid confusion\n const { store: _, ...cleanAdapterOptions } = adapterOptions;\n\n if (config.mode === 'string') {\n const storeInstance = new (AdapterClass as new (uri: string, options: Record<string, unknown>) => unknown)(uri, cleanAdapterOptions);\n const keyv = new Keyv<T>({ store: storeInstance, ...options });\n callback(null, keyv);\n return;\n }\n\n const storeInstance = new (AdapterClass as new (options: Record<string, unknown>) => unknown)(cleanAdapterOptions);\n const keyv = new Keyv<T>({ store: storeInstance, ...options });\n\n callback(null, keyv);\n } catch (createErr) {\n callback(createErr as Error);\n }\n });\n}\n"],"names":["worker","uri","options","callback","store","keyv","Keyv","err","url","URL","_err","Error","config","getAdapterConfig","protocol","package","parseUriOptions","loadAdapter","exportName","AdapterClass","adapterOptions","optionsMapper","_","cleanAdapterOptions","mode","storeInstance","createErr"],"mappings":";;;;+BAMA;;CAEC,GACD;;;eAAwBA;;;2DATP;oEACO;0BACS;uBAED
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/worker.ts"],"sourcesContent":["import Keyv from 'keyv';\nimport loadAdapter from './loadAdapter.ts';\nimport { getAdapterConfig } from './registry.ts';\nimport type { CreateStoreCallback, CreateStoreOptions } from './types.ts';\nimport { parseUriOptions } from './utils.ts';\n\n/**\n * Core worker function that creates a Keyv store\n */\nexport default function worker<T>(uri: string, options: CreateStoreOptions, callback: CreateStoreCallback<T>): void {\n // Passthrough: pre-instantiated adapter provided\n if (options.store) {\n try {\n const keyv = new Keyv<T>({ ...options });\n callback(null, keyv);\n } catch (err) {\n callback(err as Error);\n }\n return;\n }\n\n // Parse URI\n let url: URL;\n try {\n url = new URL(uri);\n } catch (_err) {\n callback(new Error(`Invalid URI: ${uri}`));\n return;\n }\n\n const config = getAdapterConfig(url.protocol);\n\n if (!config) {\n callback(new Error(`Unknown protocol: ${url.protocol}. Use registerAdapter() to add support.`));\n return;\n }\n\n // Memory store - no package needed\n if (config.package === null) {\n try {\n const keyv = new Keyv<T>({ ...parseUriOptions(url), ...options });\n callback(null, keyv);\n } catch (err) {\n callback(err as Error);\n }\n return;\n }\n\n // Load adapter (install if needed)\n loadAdapter(config.package, config.exportName, (err, AdapterClass) => {\n if (err) return callback(err);\n\n try {\n // Build adapter options: URI params + custom mapper + user options\n const adapterOptions = {\n ...parseUriOptions(url),\n ...(config.optionsMapper?.(url) ?? {}),\n ...options,\n };\n\n // Remove store from adapter options to avoid confusion\n const { store: _, ...cleanAdapterOptions } = adapterOptions;\n\n if (config.mode === 'string') {\n const storeInstance = new (AdapterClass as new (uri: string, options: Record<string, unknown>) => unknown)(uri, cleanAdapterOptions);\n const keyv = new Keyv<T>({ store: storeInstance, ...options });\n callback(null, keyv);\n return;\n }\n\n const storeInstance = new (AdapterClass as new (options: Record<string, unknown>) => unknown)(cleanAdapterOptions);\n const keyv = new Keyv<T>({ store: storeInstance, ...options });\n\n callback(null, keyv);\n } catch (createErr) {\n callback(createErr as Error);\n }\n });\n}\n"],"names":["worker","uri","options","callback","store","keyv","Keyv","err","url","URL","_err","Error","config","getAdapterConfig","protocol","package","parseUriOptions","loadAdapter","exportName","AdapterClass","adapterOptions","optionsMapper","_","cleanAdapterOptions","mode","storeInstance","createErr"],"mappings":";;;;+BAMA;;CAEC,GACD;;;eAAwBA;;;2DATP;oEACO;0BACS;uBAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKjB,SAASA,OAAUC,GAAW,EAAEC,OAA2B,EAAEC,QAAgC;IAC1G,iDAAiD;IACjD,IAAID,QAAQE,KAAK,EAAE;QACjB,IAAI;YACF,IAAMC,OAAO,IAAIC,aAAI,CAAI,mBAAKJ;YAC9BC,SAAS,MAAME;QACjB,EAAE,OAAOE,KAAK;YACZJ,SAASI;QACX;QACA;IACF;IAEA,YAAY;IACZ,IAAIC;IACJ,IAAI;QACFA,MAAM,IAAIC,IAAIR;IAChB,EAAE,OAAOS,MAAM;QACbP,SAAS,IAAIQ,MAAM,AAAC,gBAAmB,OAAJV;QACnC;IACF;IAEA,IAAMW,SAASC,IAAAA,4BAAgB,EAACL,IAAIM,QAAQ;IAE5C,IAAI,CAACF,QAAQ;QACXT,SAAS,IAAIQ,MAAM,AAAC,qBAAiC,OAAbH,IAAIM,QAAQ,EAAC;QACrD;IACF;IAEA,mCAAmC;IACnC,IAAIF,OAAOG,OAAO,KAAK,MAAM;QAC3B,IAAI;YACF,IAAMV,QAAO,IAAIC,aAAI,CAAI,mBAAKU,IAAAA,wBAAe,EAACR,MAASN;YACvDC,SAAS,MAAME;QACjB,EAAE,OAAOE,KAAK;YACZJ,SAASI;QACX;QACA;IACF;IAEA,mCAAmC;IACnCU,IAAAA,sBAAW,EAACL,OAAOG,OAAO,EAAEH,OAAOM,UAAU,EAAE,SAACX,KAAKY;QACnD,IAAIZ,KAAK,OAAOJ,SAASI;QAEzB,IAAI;;gBAIIK;YAHN,mEAAmE;YACnE,IAAMQ,iBAAiB,mBAClBJ,IAAAA,wBAAe,EAACR,eACfI,wBAAAA,OAAOS,aAAa,cAApBT,4CAAAA,2BAAAA,QAAuBJ,2CAAQ,CAAC,GACjCN;YAGL,uDAAuD;YACvD,IAAQE,AAAOkB,IAA8BF,eAArChB,OAAamB,iDAAwBH;;;YAE7C,IAAIR,OAAOY,IAAI,KAAK,UAAU;gBAC5B,IAAMC,gBAAgB,IAAKN,aAAgFlB,KAAKsB;gBAChH,IAAMlB,OAAO,IAAIC,aAAI,CAAI;oBAAEF,OAAOqB;mBAAkBvB;gBACpDC,SAAS,MAAME;gBACf;YACF;YAEA,IAAMoB,iBAAgB,IAAKN,aAAmEI;YAC9F,IAAMlB,QAAO,IAAIC,aAAI,CAAI;gBAAEF,OAAOqB;eAAkBvB;YAEpDC,SAAS,MAAME;QACjB,EAAE,OAAOqB,WAAW;YAClBvB,SAASuB;QACX;IACF;AACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LoadAdapterCallback } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Load an adapter
|
|
3
|
+
* Load an adapter from the modules installed alongside the consumer
|
|
4
4
|
*/
|
|
5
5
|
export default function loadAdapter(packageName: string, exportName: string | undefined, callback: LoadAdapterCallback): void;
|
|
6
6
|
/**
|
package/dist/esm/loadAdapter.js
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import Module from 'node:module';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import url from 'node:url';
|
|
4
|
-
import installModule from 'install-module-linked';
|
|
5
2
|
// Create require function for ESM compatibility
|
|
6
3
|
const _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;
|
|
7
|
-
// Determine node_modules path
|
|
8
|
-
const _dirname = path.dirname(typeof __filename === 'undefined' ? url.fileURLToPath(import.meta.url) : __filename);
|
|
9
|
-
const nodeModulesPath = path.join(_dirname, '..', '..', 'node_modules');
|
|
10
4
|
// Cache loaded adapters
|
|
11
5
|
const adapterCache = new Map();
|
|
12
6
|
/**
|
|
13
|
-
* Load an adapter
|
|
7
|
+
* Load an adapter from the modules installed alongside the consumer
|
|
14
8
|
*/ export default function loadAdapter(packageName, exportName, callback) {
|
|
15
9
|
const cacheKey = `${packageName}:${exportName !== null && exportName !== void 0 ? exportName : 'default'}`;
|
|
16
10
|
// Return cached adapter if available
|
|
@@ -18,29 +12,17 @@ const adapterCache = new Map();
|
|
|
18
12
|
callback(null, adapterCache.get(cacheKey));
|
|
19
13
|
return;
|
|
20
14
|
}
|
|
21
|
-
|
|
15
|
+
let Adapter;
|
|
22
16
|
try {
|
|
23
17
|
var _mod_default;
|
|
24
18
|
const mod = _require(packageName);
|
|
25
|
-
|
|
26
|
-
adapterCache.set(cacheKey, Adapter);
|
|
27
|
-
callback(null, Adapter);
|
|
28
|
-
return;
|
|
19
|
+
Adapter = exportName ? mod[exportName] : (_mod_default = mod.default) !== null && _mod_default !== void 0 ? _mod_default : mod;
|
|
29
20
|
} catch {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (err) return callback(err);
|
|
33
|
-
try {
|
|
34
|
-
var _mod_default;
|
|
35
|
-
const mod = _require(packageName);
|
|
36
|
-
const Adapter = exportName ? mod[exportName] : (_mod_default = mod.default) !== null && _mod_default !== void 0 ? _mod_default : mod;
|
|
37
|
-
adapterCache.set(cacheKey, Adapter);
|
|
38
|
-
callback(null, Adapter);
|
|
39
|
-
} catch (loadErr) {
|
|
40
|
-
callback(loadErr);
|
|
41
|
-
}
|
|
42
|
-
});
|
|
21
|
+
callback(new Error(`Adapter "${packageName}" is not installed. Install it alongside this package: npm install ${packageName}`));
|
|
22
|
+
return;
|
|
43
23
|
}
|
|
24
|
+
adapterCache.set(cacheKey, Adapter);
|
|
25
|
+
callback(null, Adapter);
|
|
44
26
|
}
|
|
45
27
|
/**
|
|
46
28
|
* Clear the adapter cache (useful for testing)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/loadAdapter.ts"],"sourcesContent":["import Module from 'node:module';\nimport
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/loadAdapter.ts"],"sourcesContent":["import Module from 'node:module';\nimport type { LoadAdapterCallback } from './types.ts';\n\n// Create require function for ESM compatibility\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\n\n// Cache loaded adapters\nconst adapterCache = new Map<string, unknown>();\n\n/**\n * Load an adapter from the modules installed alongside the consumer\n */\nexport default function loadAdapter(packageName: string, exportName: string | undefined, callback: LoadAdapterCallback): void {\n const cacheKey = `${packageName}:${exportName ?? 'default'}`;\n\n // Return cached adapter if available\n if (adapterCache.has(cacheKey)) {\n callback(null, adapterCache.get(cacheKey));\n return;\n }\n\n let Adapter: unknown;\n try {\n const mod = _require(packageName);\n Adapter = exportName ? mod[exportName] : (mod.default ?? mod);\n } catch {\n callback(new Error(`Adapter \"${packageName}\" is not installed. Install it alongside this package: npm install ${packageName}`));\n return;\n }\n\n adapterCache.set(cacheKey, Adapter);\n callback(null, Adapter);\n}\n\n/**\n * Clear the adapter cache (useful for testing)\n */\nexport function clearAdapterCache(): void {\n adapterCache.clear();\n}\n"],"names":["Module","_require","require","createRequire","url","adapterCache","Map","loadAdapter","packageName","exportName","callback","cacheKey","has","get","Adapter","mod","default","Error","set","clearAdapterCache","clear"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AAGjC,gDAAgD;AAChD,MAAMC,WAAW,OAAOC,YAAY,cAAcF,OAAOG,aAAa,CAAC,YAAYC,GAAG,IAAIF;AAE1F,wBAAwB;AACxB,MAAMG,eAAe,IAAIC;AAEzB;;CAEC,GACD,eAAe,SAASC,YAAYC,WAAmB,EAAEC,UAA8B,EAAEC,QAA6B;IACpH,MAAMC,WAAW,GAAGH,YAAY,CAAC,EAAEC,uBAAAA,wBAAAA,aAAc,WAAW;IAE5D,qCAAqC;IACrC,IAAIJ,aAAaO,GAAG,CAACD,WAAW;QAC9BD,SAAS,MAAML,aAAaQ,GAAG,CAACF;QAChC;IACF;IAEA,IAAIG;IACJ,IAAI;YAEwCC;QAD1C,MAAMA,MAAMd,SAASO;QACrBM,UAAUL,aAAaM,GAAG,CAACN,WAAW,IAAIM,eAAAA,IAAIC,OAAO,cAAXD,0BAAAA,eAAeA;IAC3D,EAAE,OAAM;QACNL,SAAS,IAAIO,MAAM,CAAC,SAAS,EAAET,YAAY,mEAAmE,EAAEA,aAAa;QAC7H;IACF;IAEAH,aAAaa,GAAG,CAACP,UAAUG;IAC3BJ,SAAS,MAAMI;AACjB;AAEA;;CAEC,GACD,OAAO,SAASK;IACdd,aAAae,KAAK;AACpB"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keyv-registry",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Protocol-based Keyv adapter registry
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Protocol-based Keyv adapter registry",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"keyv",
|
|
7
7
|
"registry",
|
|
@@ -44,17 +44,27 @@
|
|
|
44
44
|
"version": "tsds version"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"install-module-linked": "^1.0.0",
|
|
48
47
|
"keyv": "^5.0.0"
|
|
49
48
|
},
|
|
50
49
|
"devDependencies": {
|
|
50
|
+
"@keyv/etcd": "*",
|
|
51
|
+
"@keyv/redis": "*",
|
|
52
|
+
"@keyv/sqlite": "*",
|
|
51
53
|
"@types/mocha": "*",
|
|
52
54
|
"@types/node": "*",
|
|
55
|
+
"fs-remove-compat": "^1.0.4",
|
|
56
|
+
"keyv-file": "*",
|
|
53
57
|
"node-version-use": "*",
|
|
54
58
|
"ts-dev-stack": "*",
|
|
55
59
|
"tsds-config": "*"
|
|
56
60
|
},
|
|
57
61
|
"engines": {
|
|
58
62
|
"node": ">=16"
|
|
63
|
+
},
|
|
64
|
+
"allowScripts": {
|
|
65
|
+
"node-filename-to-dist-paths": true,
|
|
66
|
+
"node-semvers": true,
|
|
67
|
+
"node-version-use": true,
|
|
68
|
+
"thread-sleep-compat": true
|
|
59
69
|
}
|
|
60
70
|
}
|