@fjell/express-router 4.4.55 → 4.4.57

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.
@@ -1,6 +1,6 @@
1
1
  const clean = (obj) => {
2
2
  return Object.fromEntries(
3
- Object.entries(obj).filter(([_, v]) => v !== void 0)
3
+ Object.entries(obj).filter(([, v]) => v !== void 0)
4
4
  );
5
5
  };
6
6
  const stringifyJSON = function(obj, visited = /* @__PURE__ */ new Set()) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/util/general.ts"],
4
- "sourcesContent": ["\n/* eslint-disable no-undefined */\nexport const clean = (obj: any) => {\n return Object.fromEntries(\n Object.entries(obj).filter(([_, v]) => v !== undefined)\n );\n}\n\n//Recursive implementation of jSON.stringify;\nexport const stringifyJSON = function (obj: any, visited: Set<any> = new Set()): string {\n const arrOfKeyVals: string[] = [];\n const arrVals: string[] = [];\n let objKeys: string[] = [];\n\n /*********CHECK FOR PRIMITIVE TYPES**********/\n if (typeof obj === 'number' || typeof obj === 'boolean' || obj === null)\n return '' + obj;\n else if (typeof obj === 'string')\n return '\"' + obj + '\"';\n\n /*********DETECT CIRCULAR REFERENCES**********/\n if (obj instanceof Object && visited.has(obj)) {\n return '\"(circular)\"';\n }\n\n /*********CHECK FOR ARRAY**********/\n else if (Array.isArray(obj)) {\n //check for empty array\n if (obj[0] === undefined)\n return '[]';\n else {\n // Add array to visited before processing its elements\n visited.add(obj);\n obj.forEach(function (el) {\n arrVals.push(stringifyJSON(el, visited));\n });\n // Remove array from visited after processing to prevent memory leaks\n visited.delete(obj);\n return '[' + arrVals + ']';\n }\n }\n /*********CHECK FOR OBJECT**********/\n else if (obj instanceof Object) {\n // Add object to visited before processing its properties\n visited.add(obj);\n //get object keys\n objKeys = Object.keys(obj);\n //set key output;\n objKeys.forEach(function (key) {\n const keyOut = '\"' + key + '\":';\n const keyValOut = obj[key];\n //skip functions and undefined properties\n if (keyValOut instanceof Function || keyValOut === undefined)\n return; // Skip this entry entirely instead of pushing an empty string\n else if (typeof keyValOut === 'string')\n arrOfKeyVals.push(keyOut + '\"' + keyValOut + '\"');\n else if (typeof keyValOut === 'boolean' || typeof keyValOut === 'number' || keyValOut === null)\n arrOfKeyVals.push(keyOut + keyValOut);\n //check for nested objects, call recursively until no more objects\n else if (keyValOut instanceof Object) {\n arrOfKeyVals.push(keyOut + stringifyJSON(keyValOut, visited));\n }\n });\n // Remove object from visited after processing to prevent memory leaks\n visited.delete(obj);\n return '{' + arrOfKeyVals + '}';\n }\n return '';\n};\n"],
5
- "mappings": "AAEO,MAAM,QAAQ,CAAC,QAAa;AACjC,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,MAAM,MAAS;AAAA,EACxD;AACF;AAGO,MAAM,gBAAgB,SAAU,KAAU,UAAoB,oBAAI,IAAI,GAAW;AACtF,QAAM,eAAyB,CAAC;AAChC,QAAM,UAAoB,CAAC;AAC3B,MAAI,UAAoB,CAAC;AAGzB,MAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,aAAa,QAAQ;AACjE,WAAO,KAAK;AAAA,WACL,OAAO,QAAQ;AACtB,WAAO,MAAM,MAAM;AAGrB,MAAI,eAAe,UAAU,QAAQ,IAAI,GAAG,GAAG;AAC7C,WAAO;AAAA,EACT,WAGS,MAAM,QAAQ,GAAG,GAAG;AAE3B,QAAI,IAAI,CAAC,MAAM;AACb,aAAO;AAAA,SACJ;AAEH,cAAQ,IAAI,GAAG;AACf,UAAI,QAAQ,SAAU,IAAI;AACxB,gBAAQ,KAAK,cAAc,IAAI,OAAO,CAAC;AAAA,MACzC,CAAC;AAED,cAAQ,OAAO,GAAG;AAClB,aAAO,MAAM,UAAU;AAAA,IACzB;AAAA,EACF,WAES,eAAe,QAAQ;AAE9B,YAAQ,IAAI,GAAG;AAEf,cAAU,OAAO,KAAK,GAAG;AAEzB,YAAQ,QAAQ,SAAU,KAAK;AAC7B,YAAM,SAAS,MAAM,MAAM;AAC3B,YAAM,YAAY,IAAI,GAAG;AAEzB,UAAI,qBAAqB,YAAY,cAAc;AACjD;AAAA,eACO,OAAO,cAAc;AAC5B,qBAAa,KAAK,SAAS,MAAM,YAAY,GAAG;AAAA,eACzC,OAAO,cAAc,aAAa,OAAO,cAAc,YAAY,cAAc;AACxF,qBAAa,KAAK,SAAS,SAAS;AAAA,eAE7B,qBAAqB,QAAQ;AACpC,qBAAa,KAAK,SAAS,cAAc,WAAW,OAAO,CAAC;AAAA,MAC9D;AAAA,IACF,CAAC;AAED,YAAQ,OAAO,GAAG;AAClB,WAAO,MAAM,eAAe;AAAA,EAC9B;AACA,SAAO;AACT;",
4
+ "sourcesContent": ["\n/* eslint-disable no-undefined */\nexport const clean = (obj: any) => {\n return Object.fromEntries(\n Object.entries(obj).filter(([, v]) => v !== undefined)\n );\n}\n\n//Recursive implementation of jSON.stringify;\nexport const stringifyJSON = function (obj: any, visited: Set<any> = new Set()): string {\n const arrOfKeyVals: string[] = [];\n const arrVals: string[] = [];\n let objKeys: string[] = [];\n\n /*********CHECK FOR PRIMITIVE TYPES**********/\n if (typeof obj === 'number' || typeof obj === 'boolean' || obj === null)\n return '' + obj;\n else if (typeof obj === 'string')\n return '\"' + obj + '\"';\n\n /*********DETECT CIRCULAR REFERENCES**********/\n if (obj instanceof Object && visited.has(obj)) {\n return '\"(circular)\"';\n }\n\n /*********CHECK FOR ARRAY**********/\n else if (Array.isArray(obj)) {\n //check for empty array\n if (obj[0] === undefined)\n return '[]';\n else {\n // Add array to visited before processing its elements\n visited.add(obj);\n obj.forEach(function (el) {\n arrVals.push(stringifyJSON(el, visited));\n });\n // Remove array from visited after processing to prevent memory leaks\n visited.delete(obj);\n return '[' + arrVals + ']';\n }\n }\n /*********CHECK FOR OBJECT**********/\n else if (obj instanceof Object) {\n // Add object to visited before processing its properties\n visited.add(obj);\n //get object keys\n objKeys = Object.keys(obj);\n //set key output;\n objKeys.forEach(function (key) {\n const keyOut = '\"' + key + '\":';\n const keyValOut = obj[key];\n //skip functions and undefined properties\n if (keyValOut instanceof Function || keyValOut === undefined)\n return; // Skip this entry entirely instead of pushing an empty string\n else if (typeof keyValOut === 'string')\n arrOfKeyVals.push(keyOut + '\"' + keyValOut + '\"');\n else if (typeof keyValOut === 'boolean' || typeof keyValOut === 'number' || keyValOut === null)\n arrOfKeyVals.push(keyOut + keyValOut);\n //check for nested objects, call recursively until no more objects\n else if (keyValOut instanceof Object) {\n arrOfKeyVals.push(keyOut + stringifyJSON(keyValOut, visited));\n }\n });\n // Remove object from visited after processing to prevent memory leaks\n visited.delete(obj);\n return '{' + arrOfKeyVals + '}';\n }\n return '';\n};\n"],
5
+ "mappings": "AAEO,MAAM,QAAQ,CAAC,QAAa;AACjC,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS;AAAA,EACvD;AACF;AAGO,MAAM,gBAAgB,SAAU,KAAU,UAAoB,oBAAI,IAAI,GAAW;AACtF,QAAM,eAAyB,CAAC;AAChC,QAAM,UAAoB,CAAC;AAC3B,MAAI,UAAoB,CAAC;AAGzB,MAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,aAAa,QAAQ;AACjE,WAAO,KAAK;AAAA,WACL,OAAO,QAAQ;AACtB,WAAO,MAAM,MAAM;AAGrB,MAAI,eAAe,UAAU,QAAQ,IAAI,GAAG,GAAG;AAC7C,WAAO;AAAA,EACT,WAGS,MAAM,QAAQ,GAAG,GAAG;AAE3B,QAAI,IAAI,CAAC,MAAM;AACb,aAAO;AAAA,SACJ;AAEH,cAAQ,IAAI,GAAG;AACf,UAAI,QAAQ,SAAU,IAAI;AACxB,gBAAQ,KAAK,cAAc,IAAI,OAAO,CAAC;AAAA,MACzC,CAAC;AAED,cAAQ,OAAO,GAAG;AAClB,aAAO,MAAM,UAAU;AAAA,IACzB;AAAA,EACF,WAES,eAAe,QAAQ;AAE9B,YAAQ,IAAI,GAAG;AAEf,cAAU,OAAO,KAAK,GAAG;AAEzB,YAAQ,QAAQ,SAAU,KAAK;AAC7B,YAAM,SAAS,MAAM,MAAM;AAC3B,YAAM,YAAY,IAAI,GAAG;AAEzB,UAAI,qBAAqB,YAAY,cAAc;AACjD;AAAA,eACO,OAAO,cAAc;AAC5B,qBAAa,KAAK,SAAS,MAAM,YAAY,GAAG;AAAA,eACzC,OAAO,cAAc,aAAa,OAAO,cAAc,YAAY,cAAc;AACxF,qBAAa,KAAK,SAAS,SAAS;AAAA,eAE7B,qBAAqB,QAAQ;AACpC,qBAAa,KAAK,SAAS,cAAc,WAAW,OAAO,CAAC;AAAA,MAC9D;AAAA,IACF,CAAC;AAED,YAAQ,OAAO,GAAG;AAClB,WAAO,MAAM,eAAe;AAAA,EAC9B;AACA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,25 +1,25 @@
1
1
  {
2
2
  "name": "@fjell/express-router",
3
- "version": "4.4.55",
4
- "license": "Apache-2.0",
3
+ "description": "Express Router for Fjell",
4
+ "version": "4.4.57",
5
5
  "keywords": [
6
6
  "express",
7
7
  "router",
8
8
  "fjell"
9
9
  ],
10
- "description": "Express Router for Fjell",
10
+ "license": "Apache-2.0",
11
11
  "engines": {
12
12
  "node": ">=21"
13
13
  },
14
- "main": "dist/index.js",
15
- "module": "dist/index.js",
14
+ "type": "module",
15
+ "main": "./dist/index.js",
16
+ "module": "./dist/index.js",
16
17
  "exports": {
17
18
  ".": {
18
19
  "types": "./dist/index.d.ts",
19
20
  "import": "./dist/index.js"
20
21
  }
21
22
  },
22
- "type": "module",
23
23
  "scripts": {
24
24
  "build": "npm run clean && node build.js",
25
25
  "dev": "nodemon --watch src --ext ts --exec 'npm run build'",
@@ -34,17 +34,17 @@
34
34
  "docs:test": "cd docs && npm run test"
35
35
  },
36
36
  "dependencies": {
37
- "@fjell/core": "^4.4.49",
38
- "@fjell/lib": "^4.4.57",
39
- "@fjell/logging": "^4.4.49",
40
- "@fjell/registry": "^4.4.51",
37
+ "@fjell/core": "^4.4.51",
38
+ "@fjell/lib": "^4.4.59",
39
+ "@fjell/logging": "^4.4.50",
40
+ "@fjell/registry": "^4.4.53",
41
41
  "deepmerge": "^4.3.1",
42
42
  "express": "^5.1.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@eslint/eslintrc": "^3.3.1",
46
46
  "@eslint/js": "^9.33.0",
47
- "@fjell/eslint-config": "^1.1.25",
47
+ "@fjell/eslint-config": "^1.1.28",
48
48
  "@tsconfig/recommended": "^1.0.10",
49
49
  "@types/express": "^5.0.3",
50
50
  "@types/node": "^24.2.1",
package/MIGRATION_v3.md DELETED
@@ -1,255 +0,0 @@
1
- # Migration Guide: v2.x to v3.0
2
-
3
- ## Overview
4
-
5
- Version 3.0 of `@fjell/express-router` adopts the standardized Operations interface from `@fjell/core`. This provides a unified interface across all Fjell packages and enables better type safety and cross-package compatibility.
6
-
7
- ## Breaking Changes
8
-
9
- ### Operations Interface
10
-
11
- The router now works directly with the `Operations` interface from `@fjell/core`, which is implemented by `@fjell/lib`, `@fjell/cache`, and other Fjell packages.
12
-
13
- **Good News**: This is a non-breaking change for most users since `@fjell/lib` already implements the core Operations interface.
14
-
15
- ## What You Need to Do
16
-
17
- ### Step 1: Update Dependencies
18
-
19
- Update to the latest versions of Fjell packages:
20
-
21
- ```bash
22
- npm install @fjell/core@latest @fjell/lib@latest @fjell/express-router@latest
23
- ```
24
-
25
- ### Step 2: Verify Your Code (Usually No Changes Needed)
26
-
27
- Your existing code should continue to work without modifications:
28
-
29
- ```typescript
30
- // This continues to work in v3.0
31
- import { PItemRouter, CItemRouter } from '@fjell/express-router';
32
- import { createLibrary } from '@fjell/lib';
33
- import { createRegistry } from '@fjell/registry';
34
-
35
- const registry = createRegistry();
36
- const library = createLibrary(
37
- registry,
38
- { keyType: 'user' },
39
- userOperations,
40
- userOptions
41
- );
42
-
43
- const userRouter = new PItemRouter(library, 'user');
44
- app.use('/api/users', userRouter.getRouter());
45
- ```
46
-
47
- ### Step 3: Optional - Use Type Imports from Core
48
-
49
- You can now import types directly from `@fjell/core` if needed:
50
-
51
- ```typescript
52
- import { Operations, OperationParams, AffectedKeys } from '@fjell/core';
53
- import type { Item } from '@fjell/core';
54
-
55
- // Your Operations implementation
56
- const myOperations: Operations<Item<'user'>, 'user'> = {
57
- // ... implementation
58
- };
59
- ```
60
-
61
- ## Benefits of v3.0
62
-
63
- ### 1. Unified Interface
64
-
65
- Works with any package that implements `@fjell/core` Operations:
66
-
67
- ```typescript
68
- import { PItemRouter } from '@fjell/express-router';
69
- import { createLibrary } from '@fjell/lib';
70
- import { createCache } from '@fjell/cache';
71
-
72
- // Works with @fjell/lib
73
- const library = createLibrary(registry, { keyType: 'user' }, ops, opts);
74
- const libRouter = new PItemRouter(library, 'user');
75
-
76
- // Works with @fjell/cache
77
- const cache = createCache(library);
78
- const cacheRouter = new PItemRouter(cache as any, 'user');
79
- ```
80
-
81
- ### 2. Better Type Safety
82
-
83
- Enhanced TypeScript support with explicit method types from core:
84
-
85
- ```typescript
86
- import type { GetMethod, CreateMethod } from '@fjell/core';
87
-
88
- // Core types are available for advanced use cases
89
- const getHandler: GetMethod<User, 'user'> = async (key) => {
90
- // Handler implementation
91
- };
92
- ```
93
-
94
- ### 3. Consistent API
95
-
96
- Same routing behavior across all Operations implementations:
97
-
98
- - `GET /items` → `operations.all()`
99
- - `GET /items/:id` → `operations.get(key)`
100
- - `POST /items` → `operations.create(item)`
101
- - `PUT /items/:id` → `operations.update(key, item)`
102
- - `DELETE /items/:id` → `operations.remove(key)`
103
- - `POST /items/:id/action` → `operations.action(key, action, params)`
104
- - `GET /items/:id/facet` → `operations.facet(key, facet, params)`
105
- - `POST /items/action` → `operations.allAction(action, params)`
106
- - `GET /items/facet` → `operations.allFacet(facet, params)`
107
-
108
- ### 4. Cross-Package Compatibility
109
-
110
- Works seamlessly with all Fjell packages:
111
-
112
- - `@fjell/lib` - Server-side operations
113
- - `@fjell/cache` - Caching layer
114
- - `@fjell/client-api` - HTTP client
115
- - `@fjell/providers` - React UI components
116
-
117
- ## What Hasn't Changed
118
-
119
- - Router creation API remains the same
120
- - Route configuration is identical
121
- - Router-level handlers work as before
122
- - Middleware integration unchanged
123
- - Error handling unchanged
124
- - All existing options and configurations continue to work
125
-
126
- ## Examples
127
-
128
- ### Basic Router (No Changes Required)
129
-
130
- ```typescript
131
- import express from 'express';
132
- import { PItemRouter } from '@fjell/express-router';
133
- import { createLibrary } from '@fjell/lib';
134
- import { createRegistry } from '@fjell/registry';
135
-
136
- const app = express();
137
- const registry = createRegistry();
138
-
139
- // Create library
140
- const userLibrary = createLibrary(
141
- registry,
142
- { keyType: 'user' },
143
- userOperations,
144
- userOptions
145
- );
146
-
147
- // Create router (same as v2.x)
148
- const userRouter = new PItemRouter(userLibrary, 'user');
149
- app.use('/api/users', userRouter.getRouter());
150
-
151
- app.listen(3000);
152
- ```
153
-
154
- ### Nested Routers (No Changes Required)
155
-
156
- ```typescript
157
- // Parent router
158
- const organizationRouter = new PItemRouter(orgLibrary, 'organization');
159
-
160
- // Child router
161
- const departmentRouter = new CItemRouter(
162
- deptLibrary,
163
- 'department',
164
- organizationRouter
165
- );
166
-
167
- // Mount routers (same as v2.x)
168
- app.use('/api/organizations', organizationRouter.getRouter());
169
- app.use(
170
- '/api/organizations/:organizationPk/departments',
171
- departmentRouter.getRouter()
172
- );
173
- ```
174
-
175
- ### Router-Level Handlers (No Changes Required)
176
-
177
- ```typescript
178
- const userRouter = new PItemRouter(userLibrary, 'user', {
179
- actions: {
180
- activate: async (ik, params, { req, res }) => {
181
- // Handler implementation (same as v2.x)
182
- const user = await userLibrary.operations.get(ik);
183
- await activateUser(user);
184
- res.json({ success: true });
185
- }
186
- },
187
- facets: {
188
- profile: async (ik, params, { req, res }) => {
189
- // Handler implementation (same as v2.x)
190
- const user = await userLibrary.operations.get(ik);
191
- const profile = await getProfile(user);
192
- res.json(profile);
193
- }
194
- }
195
- });
196
- ```
197
-
198
- ## Troubleshooting
199
-
200
- ### Type Errors
201
-
202
- If you encounter type errors after upgrading:
203
-
204
- 1. Ensure all Fjell packages are updated to their latest versions
205
- 2. Check that `@fjell/core` is installed
206
- 3. Clear your TypeScript cache: `rm -rf node_modules/.cache`
207
- 4. Rebuild: `npm run build`
208
-
209
- ### Import Errors
210
-
211
- If you have import errors:
212
-
213
- ```typescript
214
- // If this fails:
215
- import type { Operations } from '@fjell/express-router';
216
-
217
- // Use this instead:
218
- import type { Operations } from '@fjell/core';
219
- // or
220
- import type { Operations } from '@fjell/lib';
221
- ```
222
-
223
- ### Runtime Errors
224
-
225
- If your Operations object doesn't work with the router:
226
-
227
- 1. Verify it implements all required methods from `@fjell/core` Operations
228
- 2. Check that method signatures match the core interface
229
- 3. Ensure return types are correct (e.g., `action` and `allAction` return `[result, affectedKeys]`)
230
-
231
- ## Migration Checklist
232
-
233
- - [ ] Update `@fjell/core` to latest version
234
- - [ ] Update `@fjell/lib` to latest version
235
- - [ ] Update `@fjell/express-router` to v3.0+
236
- - [ ] Update other Fjell packages to latest versions
237
- - [ ] Run `npm install`
238
- - [ ] Run tests: `npm test`
239
- - [ ] Run build: `npm run build`
240
- - [ ] Verify application starts correctly
241
- - [ ] Test API endpoints work as expected
242
-
243
- ## Need Help?
244
-
245
- - **Documentation**: [README.md](./README.md)
246
- - **Examples**: [examples/](./examples/)
247
- - **Issues**: [GitHub Issues](https://github.com/getfjell/express-router/issues)
248
- - **Discussions**: [GitHub Discussions](https://github.com/getfjell/express-router/discussions)
249
-
250
- ## Summary
251
-
252
- Version 3.0 is a **seamless upgrade** for most users. The router now uses the standardized Operations interface from `@fjell/core`, providing better type safety and cross-package compatibility, but your existing code should continue to work without modifications.
253
-
254
- Simply update your dependencies and you're ready to go! 🎉
255
-
package/build.js DELETED
@@ -1,4 +0,0 @@
1
- import buildMultiFile from '@fjell/eslint-config/esbuild/multi-file';
2
-
3
- // Multi-file compilation - compiles each TypeScript file separately
4
- buildMultiFile();
@@ -1,44 +0,0 @@
1
- import { DocsConfig } from '@fjell/docs-template';
2
-
3
- const config: DocsConfig = {
4
- projectName: 'Fjell Express Router',
5
- basePath: '/express-router/',
6
- port: 3004,
7
- branding: {
8
- theme: 'express-router',
9
- tagline: 'Express Router for Fjell',
10
- backgroundImage: '/pano.png',
11
- github: 'https://github.com/getfjell/express-router',
12
- npm: 'https://www.npmjs.com/package/@fjell/express-router'
13
- },
14
- sections: [
15
- {
16
- id: 'overview',
17
- title: 'Getting Started',
18
- subtitle: 'Express Router for Fjell',
19
- file: '/README.md'
20
- },
21
- {
22
- id: 'examples',
23
- title: 'Examples',
24
- subtitle: 'Code examples & usage patterns',
25
- file: '/examples-README.md'
26
- }
27
- ],
28
- filesToCopy: [
29
- {
30
- source: '../README.md',
31
- destination: 'public/README.md'
32
- },
33
- {
34
- source: '../examples/README.md',
35
- destination: 'public/examples-README.md'
36
- }
37
- ],
38
- plugins: [],
39
- version: {
40
- source: 'package.json'
41
- }
42
- }
43
-
44
- export default config
package/docs/index.html DELETED
@@ -1,18 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
-
4
- <head>
5
- <meta charset="UTF-8" />
6
- <link rel="icon" type="image/svg+xml" href="/fjell-icon.svg" />
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
- <title>Fjell Express Router - Express Router for Fjell</title>
9
- <meta name="description"
10
- content="Express Router for Fjell - A powerful Express.js router integration for the Fjell framework">
11
- </head>
12
-
13
- <body>
14
- <div id="root"></div>
15
- <script type="module" src="/src/main.tsx"></script>
16
- </body>
17
-
18
- </html>
package/docs/package.json DELETED
@@ -1,34 +0,0 @@
1
- {
2
- "name": "fjell-express-router-docs",
3
- "private": true,
4
- "version": "0.0.0",
5
- "type": "module",
6
- "scripts": {
7
- "copy-docs": "node node_modules/@fjell/docs-template/dist/scripts/copy-docs.js",
8
- "dev": "npm run copy-docs && vite",
9
- "build": "npm run copy-docs && vite build",
10
- "preview": "vite preview",
11
- "test": "vitest run --coverage",
12
- "test:watch": "vitest --watch"
13
- },
14
- "dependencies": {
15
- "@fjell/docs-template": "^1.0.24",
16
- "react": "^19.1.0",
17
- "react-dom": "^19.1.0"
18
- },
19
- "devDependencies": {
20
- "@testing-library/jest-dom": "^6.6.3",
21
- "@testing-library/react": "^16.3.0",
22
- "@testing-library/user-event": "^14.6.1",
23
- "@types/react": "^19.1.8",
24
- "@types/react-dom": "^19.1.6",
25
- "@types/react-syntax-highlighter": "^15.5.13",
26
- "@vitejs/plugin-react": "^4.6.0",
27
- "@vitest/coverage-v8": "^3.2.4",
28
- "@vitest/ui": "^3.2.4",
29
- "jsdom": "^26.1.0",
30
- "typescript": "^5.8.3",
31
- "vite": "^7.0.0",
32
- "vitest": "^3.2.4"
33
- }
34
- }