rxdb-server 17.0.0-beta.9 → 17.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.
|
@@ -71,12 +71,18 @@ function mergeServerDocumentFieldsMonad(serverOnlyFields) {
|
|
|
71
71
|
// useFields.push('_attachments');
|
|
72
72
|
useFields = (0, _core.uniqueArray)(useFields);
|
|
73
73
|
return (clientDoc, serverDoc) => {
|
|
74
|
+
var ret = (0, _core.flatClone)(clientDoc);
|
|
74
75
|
if (!serverDoc) {
|
|
75
|
-
|
|
76
|
+
// Initialize server-only fields to null for new documents
|
|
77
|
+
useFields.forEach(field => {
|
|
78
|
+
ret[field] = null;
|
|
79
|
+
});
|
|
80
|
+
return ret;
|
|
76
81
|
}
|
|
77
|
-
var ret = (0, _core.flatClone)(clientDoc);
|
|
78
82
|
useFields.forEach(field => {
|
|
79
|
-
|
|
83
|
+
// Only copy if field exists on serverDoc to avoid creating
|
|
84
|
+
// properties with undefined value (which break deepEqual key count)
|
|
85
|
+
ret[field] = field in serverDoc ? serverDoc[field] : null;
|
|
80
86
|
});
|
|
81
87
|
return ret;
|
|
82
88
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","names":["_core","require","setCors","server","path","cors","useCors","adapter","serverApp","AUTH_PER_REQUEST","WeakMap","getAuthDataByRequest","request","response","getFromMapOrCreate","headers","getRequestHeaders","authData","authHandler","err","closeConnection","defaultMatchingQuery","selector","skip","sort","getDocAllowedMatcher","endpoint","useQuery","queryModifier","normalizeMangoQuery","collection","schema","jsonSchema","docDataMatcher","getQueryMatcher","docContainsServerOnlyFields","serverOnlyFields","doc","has","find","field","removeServerOnlyFieldsMonad","serverOnlyFieldsStencil","_meta","undefined","_rev","_attachments","forEach","docData","Object","assign","mergeServerDocumentFieldsMonad","useFields","slice","uniqueArray","clientDoc","serverDoc","ret","flatClone","doesContainRegexQuerySelector","Array","isArray","found","item","entries","key","value"],"sources":["../../../../src/plugins/server/helper.ts"],"sourcesContent":["import { RxServer } from './rx-server';\nimport type {\n Request,\n Response,\n NextFunction\n} from 'express';\nimport type { RxServerAdapter, RxServerAuthData, RxServerEndpoint } from './types';\nimport {\n FilledMangoQuery,\n MangoQuerySelector,\n RxDocumentData,\n flatClone,\n getFromMapOrCreate,\n getQueryMatcher,\n normalizeMangoQuery,\n uniqueArray\n} from 'rxdb/plugins/core';\n\nexport function setCors(\n server: RxServer<any, any>,\n path: string,\n cors?: string\n) {\n let useCors = cors;\n if (!useCors) {\n useCors = server.cors;\n }\n if (useCors) {\n server.adapter.setCors(server.serverApp, path, useCors);\n }\n}\n\n\nconst AUTH_PER_REQUEST = new WeakMap<any, Promise<any>>();\n\nexport async function getAuthDataByRequest<AuthType, RequestType, ResponseType>(\n server: RxServer<any, AuthType>,\n request: RequestType,\n response: ResponseType\n): Promise<RxServerAuthData<AuthType> | false> {\n return getFromMapOrCreate(\n AUTH_PER_REQUEST,\n request,\n async () => {\n try {\n const headers = server.adapter.getRequestHeaders(request);\n const authData = await server.authHandler(headers);\n return authData;\n } catch (err) {\n server.adapter.closeConnection(response, 401, 'Unauthorized');\n return false;\n }\n }\n );\n};\n\nconst defaultMatchingQuery: FilledMangoQuery<any> = {\n selector: {},\n skip: 0,\n sort: []\n} as const;\n\nexport function getDocAllowedMatcher<RxDocType, AuthType>(\n endpoint: RxServerEndpoint<AuthType, RxDocType>,\n authData: RxServerAuthData<AuthType>\n) {\n const useQuery: FilledMangoQuery<RxDocType> = endpoint.queryModifier ? endpoint.queryModifier(\n authData,\n normalizeMangoQuery(\n endpoint.collection.schema.jsonSchema,\n {}\n )\n ) : defaultMatchingQuery;\n const docDataMatcher = getQueryMatcher(endpoint.collection.schema.jsonSchema, useQuery);\n return docDataMatcher;\n}\n\n\nexport function docContainsServerOnlyFields(\n serverOnlyFields: string[],\n doc: any\n) {\n const has = serverOnlyFields.find(field => {\n return typeof doc[field] !== 'undefined'\n });\n return has;\n}\n\nexport function removeServerOnlyFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n const serverOnlyFieldsStencil: any = {\n _meta: undefined,\n _rev: undefined,\n _attachments: undefined\n };\n serverOnlyFields.forEach(field => serverOnlyFieldsStencil[field] = undefined);\n return (\n docData?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!docData) {\n return docData;\n }\n return Object.assign({}, docData, serverOnlyFieldsStencil);\n }\n}\n\nexport function mergeServerDocumentFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n let useFields = serverOnlyFields.slice(0);\n // useFields.push('_rev');\n // useFields.push('_meta');\n // useFields.push('_attachments');\n useFields = uniqueArray(useFields);\n\n return (\n clientDoc: RxDocType | RxDocumentData<RxDocType>,\n serverDoc?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!serverDoc) {\n
|
|
1
|
+
{"version":3,"file":"helper.js","names":["_core","require","setCors","server","path","cors","useCors","adapter","serverApp","AUTH_PER_REQUEST","WeakMap","getAuthDataByRequest","request","response","getFromMapOrCreate","headers","getRequestHeaders","authData","authHandler","err","closeConnection","defaultMatchingQuery","selector","skip","sort","getDocAllowedMatcher","endpoint","useQuery","queryModifier","normalizeMangoQuery","collection","schema","jsonSchema","docDataMatcher","getQueryMatcher","docContainsServerOnlyFields","serverOnlyFields","doc","has","find","field","removeServerOnlyFieldsMonad","serverOnlyFieldsStencil","_meta","undefined","_rev","_attachments","forEach","docData","Object","assign","mergeServerDocumentFieldsMonad","useFields","slice","uniqueArray","clientDoc","serverDoc","ret","flatClone","doesContainRegexQuerySelector","Array","isArray","found","item","entries","key","value"],"sources":["../../../../src/plugins/server/helper.ts"],"sourcesContent":["import { RxServer } from './rx-server';\nimport type {\n Request,\n Response,\n NextFunction\n} from 'express';\nimport type { RxServerAdapter, RxServerAuthData, RxServerEndpoint } from './types';\nimport {\n FilledMangoQuery,\n MangoQuerySelector,\n RxDocumentData,\n flatClone,\n getFromMapOrCreate,\n getQueryMatcher,\n normalizeMangoQuery,\n uniqueArray\n} from 'rxdb/plugins/core';\n\nexport function setCors(\n server: RxServer<any, any>,\n path: string,\n cors?: string\n) {\n let useCors = cors;\n if (!useCors) {\n useCors = server.cors;\n }\n if (useCors) {\n server.adapter.setCors(server.serverApp, path, useCors);\n }\n}\n\n\nconst AUTH_PER_REQUEST = new WeakMap<any, Promise<any>>();\n\nexport async function getAuthDataByRequest<AuthType, RequestType, ResponseType>(\n server: RxServer<any, AuthType>,\n request: RequestType,\n response: ResponseType\n): Promise<RxServerAuthData<AuthType> | false> {\n return getFromMapOrCreate(\n AUTH_PER_REQUEST,\n request,\n async () => {\n try {\n const headers = server.adapter.getRequestHeaders(request);\n const authData = await server.authHandler(headers);\n return authData;\n } catch (err) {\n server.adapter.closeConnection(response, 401, 'Unauthorized');\n return false;\n }\n }\n );\n};\n\nconst defaultMatchingQuery: FilledMangoQuery<any> = {\n selector: {},\n skip: 0,\n sort: []\n} as const;\n\nexport function getDocAllowedMatcher<RxDocType, AuthType>(\n endpoint: RxServerEndpoint<AuthType, RxDocType>,\n authData: RxServerAuthData<AuthType>\n) {\n const useQuery: FilledMangoQuery<RxDocType> = endpoint.queryModifier ? endpoint.queryModifier(\n authData,\n normalizeMangoQuery(\n endpoint.collection.schema.jsonSchema,\n {}\n )\n ) : defaultMatchingQuery;\n const docDataMatcher = getQueryMatcher(endpoint.collection.schema.jsonSchema, useQuery);\n return docDataMatcher;\n}\n\n\nexport function docContainsServerOnlyFields(\n serverOnlyFields: string[],\n doc: any\n) {\n const has = serverOnlyFields.find(field => {\n return typeof doc[field] !== 'undefined'\n });\n return has;\n}\n\nexport function removeServerOnlyFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n const serverOnlyFieldsStencil: any = {\n _meta: undefined,\n _rev: undefined,\n _attachments: undefined\n };\n serverOnlyFields.forEach(field => serverOnlyFieldsStencil[field] = undefined);\n return (\n docData?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!docData) {\n return docData;\n }\n return Object.assign({}, docData, serverOnlyFieldsStencil);\n }\n}\n\nexport function mergeServerDocumentFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n let useFields = serverOnlyFields.slice(0);\n // useFields.push('_rev');\n // useFields.push('_meta');\n // useFields.push('_attachments');\n useFields = uniqueArray(useFields);\n\n return (\n clientDoc: RxDocType | RxDocumentData<RxDocType>,\n serverDoc?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n const ret = flatClone(clientDoc);\n if (!serverDoc) {\n // Initialize server-only fields to null for new documents\n useFields.forEach(field => {\n (ret as any)[field] = null;\n });\n return ret;\n }\n useFields.forEach(field => {\n // Only copy if field exists on serverDoc to avoid creating\n // properties with undefined value (which break deepEqual key count)\n (ret as any)[field] = field in (serverDoc as any) ? (serverDoc as any)[field] : null;\n });\n return ret;\n }\n}\n\n\n/**\n * $regex queries are dangerous because they can dos-attack the server.\n * \n * @param selector \n */\nexport function doesContainRegexQuerySelector(selector: MangoQuerySelector<any> | any): boolean {\n if (!selector) {\n return false;\n }\n if (Array.isArray(selector)) {\n const found = !!selector.find(item => doesContainRegexQuerySelector(item));\n return found;\n }\n\n if (typeof selector !== 'object') {\n return false;\n }\n\n const entries = Object.entries(selector);\n for (const [key, value] of entries) {\n if (key === '$regex') {\n return true;\n } else {\n const has = doesContainRegexQuerySelector(value);\n if (has) {\n return true;\n }\n }\n }\n\n return false;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -59,12 +59,18 @@ export function mergeServerDocumentFieldsMonad(serverOnlyFields) {
|
|
|
59
59
|
// useFields.push('_attachments');
|
|
60
60
|
useFields = uniqueArray(useFields);
|
|
61
61
|
return (clientDoc, serverDoc) => {
|
|
62
|
+
var ret = flatClone(clientDoc);
|
|
62
63
|
if (!serverDoc) {
|
|
63
|
-
|
|
64
|
+
// Initialize server-only fields to null for new documents
|
|
65
|
+
useFields.forEach(field => {
|
|
66
|
+
ret[field] = null;
|
|
67
|
+
});
|
|
68
|
+
return ret;
|
|
64
69
|
}
|
|
65
|
-
var ret = flatClone(clientDoc);
|
|
66
70
|
useFields.forEach(field => {
|
|
67
|
-
|
|
71
|
+
// Only copy if field exists on serverDoc to avoid creating
|
|
72
|
+
// properties with undefined value (which break deepEqual key count)
|
|
73
|
+
ret[field] = field in serverDoc ? serverDoc[field] : null;
|
|
68
74
|
});
|
|
69
75
|
return ret;
|
|
70
76
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","names":["flatClone","getFromMapOrCreate","getQueryMatcher","normalizeMangoQuery","uniqueArray","setCors","server","path","cors","useCors","adapter","serverApp","AUTH_PER_REQUEST","WeakMap","getAuthDataByRequest","request","response","headers","getRequestHeaders","authData","authHandler","err","closeConnection","defaultMatchingQuery","selector","skip","sort","getDocAllowedMatcher","endpoint","useQuery","queryModifier","collection","schema","jsonSchema","docDataMatcher","docContainsServerOnlyFields","serverOnlyFields","doc","has","find","field","removeServerOnlyFieldsMonad","serverOnlyFieldsStencil","_meta","undefined","_rev","_attachments","forEach","docData","Object","assign","mergeServerDocumentFieldsMonad","useFields","slice","clientDoc","serverDoc","ret","doesContainRegexQuerySelector","Array","isArray","found","item","entries","key","value"],"sources":["../../../../src/plugins/server/helper.ts"],"sourcesContent":["import { RxServer } from './rx-server';\nimport type {\n Request,\n Response,\n NextFunction\n} from 'express';\nimport type { RxServerAdapter, RxServerAuthData, RxServerEndpoint } from './types';\nimport {\n FilledMangoQuery,\n MangoQuerySelector,\n RxDocumentData,\n flatClone,\n getFromMapOrCreate,\n getQueryMatcher,\n normalizeMangoQuery,\n uniqueArray\n} from 'rxdb/plugins/core';\n\nexport function setCors(\n server: RxServer<any, any>,\n path: string,\n cors?: string\n) {\n let useCors = cors;\n if (!useCors) {\n useCors = server.cors;\n }\n if (useCors) {\n server.adapter.setCors(server.serverApp, path, useCors);\n }\n}\n\n\nconst AUTH_PER_REQUEST = new WeakMap<any, Promise<any>>();\n\nexport async function getAuthDataByRequest<AuthType, RequestType, ResponseType>(\n server: RxServer<any, AuthType>,\n request: RequestType,\n response: ResponseType\n): Promise<RxServerAuthData<AuthType> | false> {\n return getFromMapOrCreate(\n AUTH_PER_REQUEST,\n request,\n async () => {\n try {\n const headers = server.adapter.getRequestHeaders(request);\n const authData = await server.authHandler(headers);\n return authData;\n } catch (err) {\n server.adapter.closeConnection(response, 401, 'Unauthorized');\n return false;\n }\n }\n );\n};\n\nconst defaultMatchingQuery: FilledMangoQuery<any> = {\n selector: {},\n skip: 0,\n sort: []\n} as const;\n\nexport function getDocAllowedMatcher<RxDocType, AuthType>(\n endpoint: RxServerEndpoint<AuthType, RxDocType>,\n authData: RxServerAuthData<AuthType>\n) {\n const useQuery: FilledMangoQuery<RxDocType> = endpoint.queryModifier ? endpoint.queryModifier(\n authData,\n normalizeMangoQuery(\n endpoint.collection.schema.jsonSchema,\n {}\n )\n ) : defaultMatchingQuery;\n const docDataMatcher = getQueryMatcher(endpoint.collection.schema.jsonSchema, useQuery);\n return docDataMatcher;\n}\n\n\nexport function docContainsServerOnlyFields(\n serverOnlyFields: string[],\n doc: any\n) {\n const has = serverOnlyFields.find(field => {\n return typeof doc[field] !== 'undefined'\n });\n return has;\n}\n\nexport function removeServerOnlyFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n const serverOnlyFieldsStencil: any = {\n _meta: undefined,\n _rev: undefined,\n _attachments: undefined\n };\n serverOnlyFields.forEach(field => serverOnlyFieldsStencil[field] = undefined);\n return (\n docData?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!docData) {\n return docData;\n }\n return Object.assign({}, docData, serverOnlyFieldsStencil);\n }\n}\n\nexport function mergeServerDocumentFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n let useFields = serverOnlyFields.slice(0);\n // useFields.push('_rev');\n // useFields.push('_meta');\n // useFields.push('_attachments');\n useFields = uniqueArray(useFields);\n\n return (\n clientDoc: RxDocType | RxDocumentData<RxDocType>,\n serverDoc?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!serverDoc) {\n
|
|
1
|
+
{"version":3,"file":"helper.js","names":["flatClone","getFromMapOrCreate","getQueryMatcher","normalizeMangoQuery","uniqueArray","setCors","server","path","cors","useCors","adapter","serverApp","AUTH_PER_REQUEST","WeakMap","getAuthDataByRequest","request","response","headers","getRequestHeaders","authData","authHandler","err","closeConnection","defaultMatchingQuery","selector","skip","sort","getDocAllowedMatcher","endpoint","useQuery","queryModifier","collection","schema","jsonSchema","docDataMatcher","docContainsServerOnlyFields","serverOnlyFields","doc","has","find","field","removeServerOnlyFieldsMonad","serverOnlyFieldsStencil","_meta","undefined","_rev","_attachments","forEach","docData","Object","assign","mergeServerDocumentFieldsMonad","useFields","slice","clientDoc","serverDoc","ret","doesContainRegexQuerySelector","Array","isArray","found","item","entries","key","value"],"sources":["../../../../src/plugins/server/helper.ts"],"sourcesContent":["import { RxServer } from './rx-server';\nimport type {\n Request,\n Response,\n NextFunction\n} from 'express';\nimport type { RxServerAdapter, RxServerAuthData, RxServerEndpoint } from './types';\nimport {\n FilledMangoQuery,\n MangoQuerySelector,\n RxDocumentData,\n flatClone,\n getFromMapOrCreate,\n getQueryMatcher,\n normalizeMangoQuery,\n uniqueArray\n} from 'rxdb/plugins/core';\n\nexport function setCors(\n server: RxServer<any, any>,\n path: string,\n cors?: string\n) {\n let useCors = cors;\n if (!useCors) {\n useCors = server.cors;\n }\n if (useCors) {\n server.adapter.setCors(server.serverApp, path, useCors);\n }\n}\n\n\nconst AUTH_PER_REQUEST = new WeakMap<any, Promise<any>>();\n\nexport async function getAuthDataByRequest<AuthType, RequestType, ResponseType>(\n server: RxServer<any, AuthType>,\n request: RequestType,\n response: ResponseType\n): Promise<RxServerAuthData<AuthType> | false> {\n return getFromMapOrCreate(\n AUTH_PER_REQUEST,\n request,\n async () => {\n try {\n const headers = server.adapter.getRequestHeaders(request);\n const authData = await server.authHandler(headers);\n return authData;\n } catch (err) {\n server.adapter.closeConnection(response, 401, 'Unauthorized');\n return false;\n }\n }\n );\n};\n\nconst defaultMatchingQuery: FilledMangoQuery<any> = {\n selector: {},\n skip: 0,\n sort: []\n} as const;\n\nexport function getDocAllowedMatcher<RxDocType, AuthType>(\n endpoint: RxServerEndpoint<AuthType, RxDocType>,\n authData: RxServerAuthData<AuthType>\n) {\n const useQuery: FilledMangoQuery<RxDocType> = endpoint.queryModifier ? endpoint.queryModifier(\n authData,\n normalizeMangoQuery(\n endpoint.collection.schema.jsonSchema,\n {}\n )\n ) : defaultMatchingQuery;\n const docDataMatcher = getQueryMatcher(endpoint.collection.schema.jsonSchema, useQuery);\n return docDataMatcher;\n}\n\n\nexport function docContainsServerOnlyFields(\n serverOnlyFields: string[],\n doc: any\n) {\n const has = serverOnlyFields.find(field => {\n return typeof doc[field] !== 'undefined'\n });\n return has;\n}\n\nexport function removeServerOnlyFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n const serverOnlyFieldsStencil: any = {\n _meta: undefined,\n _rev: undefined,\n _attachments: undefined\n };\n serverOnlyFields.forEach(field => serverOnlyFieldsStencil[field] = undefined);\n return (\n docData?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n if (!docData) {\n return docData;\n }\n return Object.assign({}, docData, serverOnlyFieldsStencil);\n }\n}\n\nexport function mergeServerDocumentFieldsMonad<RxDocType>(serverOnlyFields: string[]) {\n let useFields = serverOnlyFields.slice(0);\n // useFields.push('_rev');\n // useFields.push('_meta');\n // useFields.push('_attachments');\n useFields = uniqueArray(useFields);\n\n return (\n clientDoc: RxDocType | RxDocumentData<RxDocType>,\n serverDoc?: RxDocType | RxDocumentData<RxDocType>\n ) => {\n const ret = flatClone(clientDoc);\n if (!serverDoc) {\n // Initialize server-only fields to null for new documents\n useFields.forEach(field => {\n (ret as any)[field] = null;\n });\n return ret;\n }\n useFields.forEach(field => {\n // Only copy if field exists on serverDoc to avoid creating\n // properties with undefined value (which break deepEqual key count)\n (ret as any)[field] = field in (serverDoc as any) ? (serverDoc as any)[field] : null;\n });\n return ret;\n }\n}\n\n\n/**\n * $regex queries are dangerous because they can dos-attack the server.\n * \n * @param selector \n */\nexport function doesContainRegexQuerySelector(selector: MangoQuerySelector<any> | any): boolean {\n if (!selector) {\n return false;\n }\n if (Array.isArray(selector)) {\n const found = !!selector.find(item => doesContainRegexQuerySelector(item));\n return found;\n }\n\n if (typeof selector !== 'object') {\n return false;\n }\n\n const entries = Object.entries(selector);\n for (const [key, value] of entries) {\n if (key === '$regex') {\n return true;\n } else {\n const has = doesContainRegexQuerySelector(value);\n if (has) {\n return true;\n }\n }\n }\n\n return false;\n}\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rxdb-server",
|
|
3
|
-
"version": "17.0.0
|
|
3
|
+
"version": "17.0.0",
|
|
4
4
|
"description": "RxDB Server Plugin",
|
|
5
5
|
"license": "SSPL",
|
|
6
6
|
"author": "pubkey",
|
|
@@ -78,10 +78,10 @@
|
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
80
|
"@types/express": "5.0.6",
|
|
81
|
-
"array-push-at-sort-position": "
|
|
81
|
+
"array-push-at-sort-position": "5.0.0",
|
|
82
82
|
"async-test-util": "2.5.0",
|
|
83
83
|
"cors": "2.8.6",
|
|
84
|
-
"eth-crypto": "
|
|
84
|
+
"eth-crypto": "4.0.0",
|
|
85
85
|
"eventsource": "4.1.0",
|
|
86
86
|
"percom": "1.1.3",
|
|
87
87
|
"web-locks": "0.0.9",
|
|
@@ -103,14 +103,14 @@
|
|
|
103
103
|
"@babel/plugin-transform-template-literals": "7.27.1",
|
|
104
104
|
"@babel/plugin-transform-typescript": "7.28.6",
|
|
105
105
|
"@babel/polyfill": "7.12.1",
|
|
106
|
-
"@babel/preset-env": "7.29.
|
|
106
|
+
"@babel/preset-env": "7.29.2",
|
|
107
107
|
"@babel/preset-typescript": "7.28.5",
|
|
108
108
|
"@babel/types": "7.29.0",
|
|
109
|
-
"@faker-js/faker": "10.
|
|
109
|
+
"@faker-js/faker": "10.4.0",
|
|
110
110
|
"@types/mocha": "10.0.10",
|
|
111
|
-
"@types/node": "24.
|
|
111
|
+
"@types/node": "24.12.0",
|
|
112
112
|
"@types/websql": "0.0.30",
|
|
113
|
-
"babel-loader": "10.
|
|
113
|
+
"babel-loader": "10.1.1",
|
|
114
114
|
"babel-plugin-transform-class-properties": "6.24.1",
|
|
115
115
|
"concurrently": "9.2.1",
|
|
116
116
|
"cross-env": "10.1.0",
|
|
@@ -127,18 +127,18 @@
|
|
|
127
127
|
"karma-spec-reporter": "0.0.36",
|
|
128
128
|
"karma-typescript": "5.5.4",
|
|
129
129
|
"karma-webpack": "5.0.1",
|
|
130
|
-
"mini-css-extract-plugin": "2.10.
|
|
130
|
+
"mini-css-extract-plugin": "2.10.2",
|
|
131
131
|
"minify-all-js": "0.1.9",
|
|
132
132
|
"mocha": "11.7.5",
|
|
133
133
|
"rimraf": "6.1.3",
|
|
134
|
-
"rxdb": "17.0.0
|
|
134
|
+
"rxdb": "17.0.0",
|
|
135
135
|
"rxjs": "7.8.2",
|
|
136
136
|
"ts-loader": "9.5.4",
|
|
137
137
|
"ts-node": "10.9.2",
|
|
138
138
|
"typescript": "5.9.3",
|
|
139
|
-
"webpack": "5.105.
|
|
140
|
-
"webpack-bundle-analyzer": "5.
|
|
141
|
-
"webpack-cli": "
|
|
139
|
+
"webpack": "5.105.4",
|
|
140
|
+
"webpack-bundle-analyzer": "5.3.0",
|
|
141
|
+
"webpack-cli": "7.0.2",
|
|
142
142
|
"webpack-dev-server": "5.2.3"
|
|
143
143
|
}
|
|
144
144
|
}
|