@scriptdb/dmr 1.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.
Files changed (3) hide show
  1. package/README.md +245 -0
  2. package/dist/index.js +45 -0
  3. package/package.json +40 -0
package/README.md ADDED
@@ -0,0 +1,245 @@
1
+ # @scriptdb/dmr
2
+
3
+ Database Module Resolver for the script database, providing dynamic module loading and resolution capabilities for database-related modules.
4
+
5
+ ## Features
6
+
7
+ - **Dynamic module loading**: Load modules from directories at runtime
8
+ - **Module registry**: Maintain a registry of all loaded modules
9
+ - **Require-like functionality**: Access modules using a require-like API
10
+ - **Import functionality**: Access modules using an import-like API
11
+ - **Context creation**: Create a context with all loaded modules
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ bun add @scriptdb/dmr
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ```typescript
22
+ import { DatabaseModuleResolver } from '@scriptdb/dmr';
23
+
24
+ // Resolve modules from a directory
25
+ const context = await DatabaseModuleResolver('./database-modules');
26
+
27
+ // Access modules directly from the context
28
+ const userModule = context.user;
29
+ const authModule = context.auth;
30
+
31
+ // Or use the require-like functionality
32
+ const utils = context.require('utils');
33
+ ```
34
+
35
+ ## API Reference
36
+
37
+ ### DatabaseModuleResolver(basePath)
38
+
39
+ Resolves and loads modules from the specified directory, creating a context with all loaded modules.
40
+
41
+ ```typescript
42
+ await DatabaseModuleResolver(basePath: string): Promise<Record<string, any>>
43
+ ```
44
+
45
+ - `basePath` (string): The base directory path where modules are located
46
+
47
+ Returns a promise that resolves with a context object containing all loaded modules.
48
+
49
+ ### Context Methods
50
+
51
+ #### require(moduleName)
52
+
53
+ Loads a module by name.
54
+
55
+ ```typescript
56
+ context.require(moduleName: string): any
57
+ ```
58
+
59
+ - `moduleName` (string): The name of the module to load
60
+
61
+ Returns the module's default export if available, otherwise the module itself.
62
+
63
+ #### import(moduleName)
64
+
65
+ Asynchronously loads a module by name.
66
+
67
+ ```typescript
68
+ context.import(moduleName: string): Promise<{ default: any }>
69
+ ```
70
+
71
+ - `moduleName` (string): The name of the module to load
72
+
73
+ Returns a promise that resolves with an object containing the module's default export.
74
+
75
+ ## Module Structure
76
+
77
+ To be compatible with the Database Module Resolver, your modules should be TypeScript files (.ts) in the specified directory:
78
+
79
+ ```
80
+ database-modules/
81
+ ├── user.ts # User module
82
+ ├── auth.ts # Authentication module
83
+ ├── utils.ts # Utility module
84
+ └── index.ts # Optional main entry point
85
+ ```
86
+
87
+ Each module can export functions, classes, or objects:
88
+
89
+ ```typescript
90
+ // database-modules/user.ts
91
+ export interface User {
92
+ id: number;
93
+ name: string;
94
+ email: string;
95
+ }
96
+
97
+ export class UserService {
98
+ async getUser(id: number): Promise<User> {
99
+ // Implementation here
100
+ return { id, name: 'John Doe', email: 'john@example.com' };
101
+ }
102
+ }
103
+
104
+ export default new UserService();
105
+ ```
106
+
107
+ ## Examples
108
+
109
+ ### Basic Module Loading
110
+
111
+ ```typescript
112
+ import { DatabaseModuleResolver } from '@scriptdb/dmr';
113
+
114
+ // Load modules from the ./database-modules directory
115
+ const context = await DatabaseModuleResolver('./database-modules');
116
+
117
+ // Access modules directly
118
+ const userModule = context.user;
119
+ if (userModule && userModule.getUser) {
120
+ const user = await userModule.getUser(1);
121
+ console.log(user);
122
+ }
123
+
124
+ // Use the require-like functionality
125
+ const utils = context.require('utils');
126
+ if (utils && utils.formatDate) {
127
+ const formattedDate = utils.formatDate(new Date());
128
+ console.log(formattedDate);
129
+ }
130
+ ```
131
+
132
+ ### Module with Default Export
133
+
134
+ ```typescript
135
+ // database-modules/database.ts
136
+ export class Database {
137
+ private connection: any;
138
+
139
+ constructor() {
140
+ // Initialize connection
141
+ }
142
+
143
+ async query(sql: string, params?: any[]) {
144
+ // Execute query
145
+ return { sql, params, results: [] };
146
+ }
147
+
148
+ async close() {
149
+ // Close connection
150
+ }
151
+ }
152
+
153
+ export default new Database();
154
+
155
+ // main.ts
156
+ import { DatabaseModuleResolver } from '@scriptdb/dmr';
157
+
158
+ const context = await DatabaseModuleResolver('./database-modules');
159
+
160
+ // Access the default export
161
+ const db = context.database;
162
+ const result = await db.query('SELECT * FROM users');
163
+ console.log(result);
164
+ ```
165
+
166
+ ### Using the Import Functionality
167
+
168
+ ```typescript
169
+ import { DatabaseModuleResolver } from '@scriptdb/dmr';
170
+
171
+ const context = await DatabaseModuleResolver('./database-modules');
172
+
173
+ // Use the import functionality to load a module
174
+ const module = await context.import('auth');
175
+ const authService = module.default;
176
+
177
+ if (authService && authService.authenticate) {
178
+ const result = await authService.authenticate('username', 'password');
179
+ console.log(result);
180
+ }
181
+ ```
182
+
183
+ ### Advanced Usage with Type Safety
184
+
185
+ ```typescript
186
+ import { DatabaseModuleResolver } from '@scriptdb/dmr';
187
+
188
+ interface ModuleContext {
189
+ user?: {
190
+ getUser: (id: number) => Promise<{ id: number; name: string }>;
191
+ };
192
+ auth?: {
193
+ authenticate: (username: string, password: string) => Promise<boolean>;
194
+ };
195
+ utils?: {
196
+ formatDate: (date: Date) => string;
197
+ };
198
+ require: (moduleName: string) => any;
199
+ import: (moduleName: string) => Promise<{ default: any }>;
200
+ }
201
+
202
+ const context = await DatabaseModuleResolver('./database-modules') as ModuleContext;
203
+
204
+ if (context.user && context.auth) {
205
+ const user = await context.user.getUser(1);
206
+ const isAuthenticated = await context.auth.authenticate('username', 'password');
207
+
208
+ console.log(`User: ${user.name}, Authenticated: ${isAuthenticated}`);
209
+ }
210
+ ```
211
+
212
+ ## Error Handling
213
+
214
+ The Database Module Resolver will throw an error if:
215
+
216
+ - The specified directory doesn't exist
217
+ - There are syntax errors in the module code
218
+ - A module is not found when using require() or import()
219
+
220
+ ```typescript
221
+ import { DatabaseModuleResolver } from '@scriptdb/dmr';
222
+
223
+ try {
224
+ const context = await DatabaseModuleResolver('./non-existent-directory');
225
+ } catch (error) {
226
+ console.error('Failed to load modules:', error.message);
227
+ }
228
+
229
+ try {
230
+ const module = context.require('non-existent-module');
231
+ } catch (error) {
232
+ console.error('Module not found:', error.message);
233
+ }
234
+ ```
235
+
236
+ ## Security Considerations
237
+
238
+ - Only load modules from trusted sources
239
+ - Validate module functionality before use
240
+ - Consider implementing a sandboxed environment for untrusted modules
241
+ - Limit module access to sensitive resources
242
+
243
+ ## License
244
+
245
+ MIT
package/dist/index.js ADDED
@@ -0,0 +1,45 @@
1
+ // src/index.ts
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ async function DatabaseModuleResolver(baseBase) {
5
+ const DIR = baseBase;
6
+ const moduleRegistry = new Map;
7
+ const files = fs.readdirSync(DIR).filter((f) => f.endsWith(".ts")).map((f) => path.join(DIR, f));
8
+ for (const filePath of files) {
9
+ const moduleName = path.basename(filePath, ".ts");
10
+ moduleRegistry.set(moduleName, await import(path.resolve(filePath)));
11
+ }
12
+ const context = {
13
+ require: (moduleName) => {
14
+ const module = moduleRegistry.get(moduleName);
15
+ if (!module) {
16
+ throw new Error(`Module '${moduleName}' not found`);
17
+ }
18
+ return module.default || module;
19
+ },
20
+ import: async (moduleName) => {
21
+ const module = moduleRegistry.get(moduleName);
22
+ if (!module) {
23
+ throw new Error(`Module '${moduleName}' not found`);
24
+ }
25
+ return {
26
+ default: module.default || module
27
+ };
28
+ }
29
+ };
30
+ for (const [name, moduleExports] of moduleRegistry) {
31
+ if (moduleExports.default) {
32
+ context[name] = moduleExports.default;
33
+ } else if (moduleExports[name]) {
34
+ context[name] = moduleExports[name];
35
+ } else {
36
+ context[name] = moduleExports;
37
+ }
38
+ }
39
+ return context;
40
+ }
41
+ var src_default = DatabaseModuleResolver;
42
+ export {
43
+ src_default as default,
44
+ DatabaseModuleResolver
45
+ };
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@scriptdb/dmr",
3
+ "version": "1.0.0",
4
+ "description": "DMR module resolver for script database",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "dev": "bun --watch src/index.ts",
20
+ "build": "bun build src/index.ts --outdir dist --target node --format esm --splitting",
21
+ "build:cjs": "bun build src/index.ts --outdir dist --target node --format cjs --outfile dist/index.js",
22
+ "build:types": "tsc --emitDeclarationOnly --project tsconfig.build.json",
23
+ "build:all": "bun run build && bun run build:cjs && bun run build:types",
24
+ "test": "bun test",
25
+ "lint": "bun run lint:src",
26
+ "lint:src": "eslint src --ext .ts,.tsx",
27
+ "lint:fix": "eslint src --ext .ts,.tsx --fix",
28
+ "typecheck": "tsc --noEmit",
29
+ "clean": "rm -rf dist"
30
+ },
31
+ "devDependencies": {
32
+ "@types/bun": "^1.3.2",
33
+ "@types/node": "^20.0.0",
34
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
35
+ "@typescript-eslint/parser": "^6.0.0",
36
+ "bun-types": "latest",
37
+ "eslint": "^8.0.0",
38
+ "typescript": "^5.0.0"
39
+ }
40
+ }