@harperfast/harper 5.0.0-beta.6 → 5.0.0-beta.7
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/bin/harper.js +1 -1
- package/bin/run.js +2 -2
- package/components/Application.ts +6 -3
- package/components/componentLoader.ts +19 -11
- package/components/operations.js +13 -13
- package/components/operationsValidation.js +3 -3
- package/config/configUtils.js +20 -4
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +3 -2
- package/dist/bin/harper.d.ts +1 -1
- package/dist/bin/harper.js +1 -1
- package/dist/bin/run.js +2 -2
- package/dist/bin/run.js.map +1 -1
- package/dist/components/Application.js +7 -2
- package/dist/components/Application.js.map +1 -1
- package/dist/components/componentLoader.js +19 -9
- package/dist/components/componentLoader.js.map +1 -1
- package/dist/components/operations.js +13 -13
- package/dist/components/operations.js.map +1 -1
- package/dist/components/operationsValidation.js +3 -3
- package/dist/components/operationsValidation.js.map +1 -1
- package/dist/config/configUtils.d.ts +6 -0
- package/dist/config/configUtils.js +23 -3
- package/dist/config/configUtils.js.map +1 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +3 -2
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js.map +1 -1
- package/dist/resources/Resource.d.ts +2 -0
- package/dist/resources/Resource.js +11 -4
- package/dist/resources/Resource.js.map +1 -1
- package/dist/resources/RocksTransactionLogStore.d.ts +1 -0
- package/dist/resources/RocksTransactionLogStore.js +8 -1
- package/dist/resources/RocksTransactionLogStore.js.map +1 -1
- package/dist/resources/analytics/write.js +6 -0
- package/dist/resources/analytics/write.js.map +1 -1
- package/dist/resources/databases.js +3 -2
- package/dist/resources/databases.js.map +1 -1
- package/dist/security/jsLoader.js +114 -40
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/server/REST.js +17 -10
- package/dist/server/REST.js.map +1 -1
- package/dist/server/http.js +1 -1
- package/dist/server/http.js.map +1 -1
- package/dist/server/itc/serverHandlers.js +1 -1
- package/dist/server/itc/serverHandlers.js.map +1 -1
- package/dist/utility/hdbTerms.d.ts +1 -0
- package/dist/utility/hdbTerms.js +1 -0
- package/dist/utility/hdbTerms.js.map +1 -1
- package/dist/utility/logging/harper_logger.js +24 -1
- package/dist/utility/logging/harper_logger.js.map +1 -1
- package/dist/utility/logging/readLog.js +2 -2
- package/dist/utility/logging/readLog.js.map +1 -1
- package/dist/utility/npmUtilities.js +2 -2
- package/dist/utility/npmUtilities.js.map +1 -1
- package/dist/validation/configValidator.js +18 -8
- package/dist/validation/configValidator.js.map +1 -1
- package/dist/validation/readLogValidator.js +2 -2
- package/dist/validation/readLogValidator.js.map +1 -1
- package/package.json +3 -3
- package/resources/Resource.ts +17 -6
- package/resources/RocksTransactionLogStore.ts +8 -1
- package/resources/analytics/write.ts +6 -0
- package/resources/databases.ts +3 -2
- package/security/jsLoader.ts +127 -46
- package/server/REST.ts +20 -11
- package/server/http.ts +2 -2
- package/server/itc/serverHandlers.js +1 -1
- package/static/defaultConfig.yaml +1 -1
- package/studio/web/assets/{index-BckVDix4.js → index-ClD_q6ya.js} +5 -5
- package/studio/web/assets/{index-BckVDix4.js.map → index-ClD_q6ya.js.map} +1 -1
- package/studio/web/assets/{index.lazy-iG1_8dzm.js → index.lazy-CXzU1gVu.js} +2 -2
- package/studio/web/assets/{index.lazy-iG1_8dzm.js.map → index.lazy-CXzU1gVu.js.map} +1 -1
- package/studio/web/assets/{profile-CzjslUXv.js → profile-DCNVg5yY.js} +2 -2
- package/studio/web/assets/{profile-CzjslUXv.js.map → profile-DCNVg5yY.js.map} +1 -1
- package/studio/web/assets/{status-BP4TQJDR.js → status-CoGlcjSB.js} +2 -2
- package/studio/web/assets/{status-BP4TQJDR.js.map → status-CoGlcjSB.js.map} +1 -1
- package/studio/web/index.html +1 -1
- package/utility/hdbTerms.ts +1 -0
- package/utility/logging/harper_logger.js +22 -1
- package/utility/logging/readLog.js +2 -2
- package/utility/npmUtilities.js +2 -2
- package/validation/configValidator.js +16 -8
- package/validation/readLogValidator.js +2 -2
|
@@ -402,7 +402,12 @@ export async function getDirectorySizeAsync(dirPath: string): Promise<number> {
|
|
|
402
402
|
}
|
|
403
403
|
}
|
|
404
404
|
|
|
405
|
+
const DEFAULT_STORAGE_INTERVAL = 10;
|
|
406
|
+
let nodeStorageInterval = DEFAULT_STORAGE_INTERVAL;
|
|
407
|
+
let nodeStorageCycleCount = 0;
|
|
408
|
+
|
|
405
409
|
async function storeNodeStorageMetric(analyticsTable: Table) {
|
|
410
|
+
if (nodeStorageInterval <= 0 || ++nodeStorageCycleCount % nodeStorageInterval !== 1) return;
|
|
406
411
|
try {
|
|
407
412
|
const size = await getDirectorySizeAsync(getHdbBasePath());
|
|
408
413
|
storeMetric(analyticsTable, {
|
|
@@ -689,6 +694,7 @@ if (!parentPort) onMessageByType(ANALYTICS_REPORT_TYPE, recordAnalytics);
|
|
|
689
694
|
let scheduledTasksRunning;
|
|
690
695
|
function startScheduledTasks() {
|
|
691
696
|
scheduledTasksRunning = true;
|
|
697
|
+
nodeStorageInterval = envGet(CONFIG_PARAMS.ANALYTICS_STORAGEINTERVAL) ?? DEFAULT_STORAGE_INTERVAL;
|
|
692
698
|
const AGGREGATE_PERIOD = envGet(CONFIG_PARAMS.ANALYTICS_AGGREGATEPERIOD) * 1000;
|
|
693
699
|
if (AGGREGATE_PERIOD) {
|
|
694
700
|
setInterval(
|
package/resources/databases.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
import { makeTable } from './Table.ts';
|
|
13
13
|
import OpenEnvironmentObject from '../utility/lmdb/OpenEnvironmentObject.js';
|
|
14
14
|
import { CONFIG_PARAMS, LEGACY_DATABASES_DIR_NAME, DATABASES_DIR_NAME } from '../utility/hdbTerms.ts';
|
|
15
|
+
import { getConfigPath } from '../config/configUtils.js';
|
|
15
16
|
import { _assignPackageExport } from '../globals.js';
|
|
16
17
|
import { getIndexedValues } from '../utility/lmdb/commonUtility.js';
|
|
17
18
|
import * as signalling from '../utility/signalling.js';
|
|
@@ -176,7 +177,7 @@ export function getDatabases(): Databases {
|
|
|
176
177
|
if (process.env.SCHEMAS_DATA_PATH) schemaConfigs.data = { path: process.env.SCHEMAS_DATA_PATH };
|
|
177
178
|
databasePath =
|
|
178
179
|
process.env.STORAGE_PATH ||
|
|
179
|
-
|
|
180
|
+
getConfigPath(CONFIG_PARAMS.STORAGE_PATH) ||
|
|
180
181
|
(databasePath && (existsSync(databasePath) ? databasePath : join(getHdbBasePath(), LEGACY_DATABASES_DIR_NAME)));
|
|
181
182
|
if (!databasePath) return;
|
|
182
183
|
|
|
@@ -694,7 +695,7 @@ export function database({ database: databaseName, table: tableName }) {
|
|
|
694
695
|
tablePath ||
|
|
695
696
|
databaseConfig[databaseName]?.path ||
|
|
696
697
|
process.env.STORAGE_PATH ||
|
|
697
|
-
|
|
698
|
+
getConfigPath(CONFIG_PARAMS.STORAGE_PATH) ||
|
|
698
699
|
(existsSync(join(hdbBasePath, DATABASES_DIR_NAME))
|
|
699
700
|
? join(hdbBasePath, DATABASES_DIR_NAME)
|
|
700
701
|
: join(hdbBasePath, LEGACY_DATABASES_DIR_NAME));
|
package/security/jsLoader.ts
CHANGED
|
@@ -148,6 +148,7 @@ function parseJsonModule(source: string, url: string): any {
|
|
|
148
148
|
async function loadModuleWithVM(moduleUrl: string, scope: ApplicationScope) {
|
|
149
149
|
const moduleCache = new Map<string, Promise<SourceTextModule | SyntheticModule>>();
|
|
150
150
|
const linkingPromises = new Map<string, Promise<void>>();
|
|
151
|
+
const cjsCache = new Map<string, { exports: any }>();
|
|
151
152
|
|
|
152
153
|
// Create a secure context with limited globals
|
|
153
154
|
const contextObject = getGlobalObject(scope);
|
|
@@ -165,6 +166,9 @@ async function loadModuleWithVM(moduleUrl: string, scope: ApplicationScope) {
|
|
|
165
166
|
// block harper/* for now (reserving for potential future use)
|
|
166
167
|
throw new Error(`Module ${specifier} is not allowed, may only access the 'harper' module`);
|
|
167
168
|
}
|
|
169
|
+
if (parts[0] === 'file:') {
|
|
170
|
+
return specifier;
|
|
171
|
+
}
|
|
168
172
|
const resolved = createRequire(referrer).resolve(specifier);
|
|
169
173
|
if (isAbsolute(resolved)) {
|
|
170
174
|
return pathToFileURL(resolved).toString();
|
|
@@ -176,7 +180,16 @@ async function loadModuleWithVM(moduleUrl: string, scope: ApplicationScope) {
|
|
|
176
180
|
* Load a CommonJS module in our private context
|
|
177
181
|
*/
|
|
178
182
|
function loadCJS(url: string, source: string): { exports: any } {
|
|
183
|
+
// Check cache first to handle circular dependencies
|
|
184
|
+
if (cjsCache.has(url)) {
|
|
185
|
+
return cjsCache.get(url)!;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Create module object and cache it immediately (before execution)
|
|
189
|
+
// This allows circular dependencies to get a reference to the incomplete module
|
|
179
190
|
const cjsModule = { exports: {} };
|
|
191
|
+
cjsCache.set(url, cjsModule);
|
|
192
|
+
|
|
180
193
|
if (url.endsWith('.json')) {
|
|
181
194
|
cjsModule.exports = parseJsonModule(source, url);
|
|
182
195
|
return cjsModule;
|
|
@@ -204,7 +217,7 @@ async function loadModuleWithVM(moduleUrl: string, scope: ApplicationScope) {
|
|
|
204
217
|
filename: url,
|
|
205
218
|
async importModuleDynamically(specifier: string, script) {
|
|
206
219
|
const resolvedUrl = resolveModule(specifier, script.sourceURL);
|
|
207
|
-
const useContainment = specifier.startsWith('.') || scope.dependencyContainment;
|
|
220
|
+
const useContainment = specifier.startsWith('.') || scope.dependencyContainment !== false;
|
|
208
221
|
const dynamicModule = await loadModuleWithCache(resolvedUrl, useContainment);
|
|
209
222
|
return dynamicModule;
|
|
210
223
|
},
|
|
@@ -221,16 +234,18 @@ async function loadModuleWithVM(moduleUrl: string, scope: ApplicationScope) {
|
|
|
221
234
|
}
|
|
222
235
|
function loadCJSModule(url: string, source: string, usePrivateGlobal: boolean): SyntheticModule {
|
|
223
236
|
const cjsModule = usePrivateGlobal ? loadCJS(url, source) : { exports: require(url) };
|
|
224
|
-
|
|
237
|
+
let exports = cjsModule.exports;
|
|
238
|
+
if (exports.default === undefined) {
|
|
239
|
+
// provide the default export for compatibility
|
|
240
|
+
exports = { default: exports, ...exports };
|
|
241
|
+
}
|
|
242
|
+
const exportNames = Object.keys(exports);
|
|
243
|
+
|
|
225
244
|
const synModule = new SyntheticModule(
|
|
226
|
-
exportNames
|
|
245
|
+
exportNames,
|
|
227
246
|
function () {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
this.setExport(key, cjsModule.exports[key]);
|
|
231
|
-
}
|
|
232
|
-
} else {
|
|
233
|
-
this.setExport('default', cjsModule.exports);
|
|
247
|
+
for (const key of exportNames) {
|
|
248
|
+
this.setExport(key, exports[key]);
|
|
234
249
|
}
|
|
235
250
|
},
|
|
236
251
|
{ identifier: url, context }
|
|
@@ -239,13 +254,68 @@ async function loadModuleWithVM(moduleUrl: string, scope: ApplicationScope) {
|
|
|
239
254
|
return synModule;
|
|
240
255
|
}
|
|
241
256
|
|
|
257
|
+
/**
|
|
258
|
+
* Check if a package (or any of its dependencies) depends on harper
|
|
259
|
+
* Expects a file URL like: file:///path/to/node_modules/package-name/dist/index.js
|
|
260
|
+
*/
|
|
261
|
+
function packageDependsOnHarper(fileUrl: string): boolean {
|
|
262
|
+
try {
|
|
263
|
+
// Convert file:// URL to path
|
|
264
|
+
const filePath = fileURLToPath(fileUrl);
|
|
265
|
+
|
|
266
|
+
// Find the node_modules directory and package name
|
|
267
|
+
// Example: /path/to/node_modules/package-name/dist/index.js
|
|
268
|
+
// or: /path/to/node_modules/@scope/package-name/dist/index.js
|
|
269
|
+
const nodeModulesMarker = '/node_modules/';
|
|
270
|
+
const nodeModulesIndex = filePath.lastIndexOf(nodeModulesMarker);
|
|
271
|
+
if (nodeModulesIndex === -1) return false;
|
|
272
|
+
|
|
273
|
+
// Get the part after /node_modules/
|
|
274
|
+
const afterNodeModules = filePath.substring(nodeModulesIndex + nodeModulesMarker.length);
|
|
275
|
+
const parts = afterNodeModules.split('/');
|
|
276
|
+
|
|
277
|
+
// Handle scoped packages (@scope/package-name) vs regular packages (package-name)
|
|
278
|
+
const beforeNodeModules = filePath.substring(0, nodeModulesIndex);
|
|
279
|
+
const packageRoot = parts[0].startsWith('@')
|
|
280
|
+
? join(beforeNodeModules, 'node_modules', parts[0], parts[1])
|
|
281
|
+
: join(beforeNodeModules, 'node_modules', parts[0]);
|
|
282
|
+
|
|
283
|
+
// Read package.json from the package root
|
|
284
|
+
const packageJsonPath = join(packageRoot, 'package.json');
|
|
285
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
286
|
+
|
|
287
|
+
const deps = {
|
|
288
|
+
...packageJson.dependencies,
|
|
289
|
+
...packageJson.devDependencies,
|
|
290
|
+
...packageJson.peerDependencies,
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
// Check if harper is a direct dependency
|
|
294
|
+
return Object.keys(deps).some((dep) => HARPER_MODULE_IDS.has(dep));
|
|
295
|
+
} catch {
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
242
300
|
/**
|
|
243
301
|
* Linker function for module resolution during instantiation
|
|
244
302
|
*/
|
|
245
303
|
async function linker(specifier: string, referencingModule: SourceTextModule | SyntheticModule) {
|
|
246
304
|
const resolvedUrl = resolveModule(specifier, referencingModule.identifier);
|
|
247
305
|
|
|
248
|
-
|
|
306
|
+
// Determine if we should use VM containment for this module
|
|
307
|
+
let useContainment = specifier.startsWith('.'); // Always contain relative imports
|
|
308
|
+
|
|
309
|
+
if (!useContainment && scope.dependencyContainment !== false) {
|
|
310
|
+
// For npm packages, check if they depend on harper
|
|
311
|
+
if (resolvedUrl.startsWith('file://') && resolvedUrl.includes('node_modules')) {
|
|
312
|
+
useContainment = packageDependsOnHarper(resolvedUrl);
|
|
313
|
+
} else {
|
|
314
|
+
// Non-file URLs (bare specifiers) - use default behavior
|
|
315
|
+
useContainment = scope.dependencyContainment === true;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
249
319
|
// Return the module immediately (even if not yet linked) to support circular dependencies
|
|
250
320
|
return await getOrCreateModule(resolvedUrl, useContainment);
|
|
251
321
|
}
|
|
@@ -351,38 +421,25 @@ async function loadModuleWithVM(moduleUrl: string, scope: ApplicationScope) {
|
|
|
351
421
|
}
|
|
352
422
|
} else {
|
|
353
423
|
const replacedModule = checkAllowedModulePath(url, scope.verifyPath);
|
|
354
|
-
// For Node.js built-in modules (node:) and npm packages
|
|
424
|
+
// For Node.js built-in modules (node:) and npm packages without dependency containment
|
|
355
425
|
// Always try require first to properly handle CJS modules with named exports
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
function () {
|
|
363
|
-
if (exportNames.length > 0) {
|
|
364
|
-
for (const key of exportNames) {
|
|
365
|
-
this.setExport(key, cjsExports[key]);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
this.setExport('default', cjsExports);
|
|
369
|
-
},
|
|
370
|
-
{ identifier: url, context }
|
|
371
|
-
);
|
|
372
|
-
} catch {
|
|
373
|
-
// Fall back to dynamic import for ESM packages
|
|
374
|
-
const importedModule = await import(url);
|
|
375
|
-
const exportNames = Object.keys(importedModule);
|
|
376
|
-
module = new SyntheticModule(
|
|
377
|
-
exportNames,
|
|
378
|
-
function () {
|
|
379
|
-
for (const key of exportNames) {
|
|
380
|
-
this.setExport(key, importedModule[key]);
|
|
381
|
-
}
|
|
382
|
-
},
|
|
383
|
-
{ identifier: url, context }
|
|
384
|
-
);
|
|
426
|
+
// Fall back to dynamic import for ESM packages
|
|
427
|
+
let importedModule = replacedModule ?? (await import(url));
|
|
428
|
+
const cjsModule = importedModule['module.exports'];
|
|
429
|
+
if (cjsModule) {
|
|
430
|
+
// back-compat import
|
|
431
|
+
importedModule = importedModule.default ? { default: importedModule.default, ...cjsModule } : cjsModule;
|
|
385
432
|
}
|
|
433
|
+
const exportNames = Object.keys(importedModule);
|
|
434
|
+
module = new SyntheticModule(
|
|
435
|
+
exportNames,
|
|
436
|
+
function () {
|
|
437
|
+
for (const key of exportNames) {
|
|
438
|
+
this.setExport(key, importedModule[key]);
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
{ identifier: url, context }
|
|
442
|
+
);
|
|
386
443
|
}
|
|
387
444
|
|
|
388
445
|
return module;
|
|
@@ -533,6 +590,25 @@ function getHarperExports(scope: ApplicationScope) {
|
|
|
533
590
|
authenticateUser: server.authenticateUser,
|
|
534
591
|
operation: server.operation,
|
|
535
592
|
contentTypes,
|
|
593
|
+
Attribute: undefined,
|
|
594
|
+
Config: undefined,
|
|
595
|
+
ConfigValue: undefined,
|
|
596
|
+
Context: undefined,
|
|
597
|
+
FileAndURLPathConfig: undefined,
|
|
598
|
+
FilesOption: undefined,
|
|
599
|
+
FilesOptionObject: undefined,
|
|
600
|
+
IterableEventQueue: undefined,
|
|
601
|
+
Logger: undefined,
|
|
602
|
+
Query: undefined,
|
|
603
|
+
RecordObject: undefined,
|
|
604
|
+
RequestTargetOrId: undefined,
|
|
605
|
+
ResourceInterface: undefined,
|
|
606
|
+
Scope: undefined,
|
|
607
|
+
Session: undefined,
|
|
608
|
+
SourceContext: undefined,
|
|
609
|
+
SubscriptionRequest: undefined,
|
|
610
|
+
Table: undefined,
|
|
611
|
+
User: undefined,
|
|
536
612
|
};
|
|
537
613
|
}
|
|
538
614
|
const ALLOWED_NODE_BUILTIN_MODULES = env.get(CONFIG_PARAMS.APPLICATIONS_ALLOWEDBUILTINMODULES)
|
|
@@ -544,14 +620,19 @@ const ALLOWED_NODE_BUILTIN_MODULES = env.get(CONFIG_PARAMS.APPLICATIONS_ALLOWEDB
|
|
|
544
620
|
},
|
|
545
621
|
};
|
|
546
622
|
const ALLOWED_COMMANDS = new Set(env.get(CONFIG_PARAMS.APPLICATIONS_ALLOWEDSPAWNCOMMANDS) ?? []);
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
623
|
+
const child_processConstrained = {
|
|
624
|
+
exec: createSpawn(child_process.exec),
|
|
625
|
+
execFile: createSpawn(child_process.execFile),
|
|
626
|
+
fork: createSpawn(child_process.fork, true), // this is launching node, so deemed safe
|
|
627
|
+
spawn: createSpawn(child_process.spawn),
|
|
628
|
+
execSync: function () {
|
|
629
|
+
throw new Error('execSync is not allowed');
|
|
553
630
|
},
|
|
554
631
|
};
|
|
632
|
+
child_processConstrained.default = child_processConstrained;
|
|
633
|
+
const REPLACED_BUILTIN_MODULES = {
|
|
634
|
+
child_process: child_processConstrained,
|
|
635
|
+
};
|
|
555
636
|
/**
|
|
556
637
|
* Creates a ChildProcess-like object for an existing process
|
|
557
638
|
*/
|
package/server/REST.ts
CHANGED
|
@@ -4,7 +4,7 @@ import * as harperLogger from '../utility/logging/harper_logger.js';
|
|
|
4
4
|
import { ServerOptions } from 'http';
|
|
5
5
|
import { ServerError, ClientError } from '../utility/errors/hdbError.js';
|
|
6
6
|
import { Resources } from '../resources/Resources.ts';
|
|
7
|
-
import { Resource } from '../resources/Resource.ts';
|
|
7
|
+
import { Resource, missingMethod, allowedMethods } from '../resources/Resource.ts';
|
|
8
8
|
import { IterableEventQueue } from '../resources/IterableEventQueue.ts';
|
|
9
9
|
import { transaction } from '../resources/transaction.ts';
|
|
10
10
|
import { Headers, mergeHeaders } from '../server/serverHelpers/Headers.ts';
|
|
@@ -114,29 +114,38 @@ async function http(request: Context & Request, nextHandler) {
|
|
|
114
114
|
switch (method) {
|
|
115
115
|
case 'GET':
|
|
116
116
|
case 'HEAD':
|
|
117
|
-
return resource.get(target, request);
|
|
117
|
+
return resource.get ? resource.get(target, request) : missingMethod(resource, 'get');
|
|
118
118
|
case 'POST':
|
|
119
|
-
return resource.post(target, request.data, request);
|
|
119
|
+
return resource.post ? resource.post(target, request.data, request) : missingMethod(resource, 'post');
|
|
120
120
|
case 'PUT':
|
|
121
|
-
return resource.put(target, request.data, request);
|
|
121
|
+
return resource.put ? resource.put(target, request.data, request) : missingMethod(resource, 'put');
|
|
122
122
|
case 'DELETE':
|
|
123
|
-
return resource.delete(target, request);
|
|
123
|
+
return resource.delete ? resource.delete(target, request) : missingMethod(resource, 'delete');
|
|
124
124
|
case 'PATCH':
|
|
125
|
-
return resource.patch(target, request.data, request);
|
|
125
|
+
return resource.patch ? resource.patch(target, request.data, request) : missingMethod(resource, 'patch');
|
|
126
126
|
case 'OPTIONS': // used primarily for CORS
|
|
127
|
-
headers.setIfNone(
|
|
127
|
+
headers.setIfNone(
|
|
128
|
+
'Allow',
|
|
129
|
+
allowedMethods(resource)
|
|
130
|
+
.map((method) => method.toUpperCase())
|
|
131
|
+
.join(', ')
|
|
132
|
+
);
|
|
128
133
|
return;
|
|
129
134
|
case 'CONNECT':
|
|
130
135
|
// websockets? and event-stream
|
|
131
|
-
return resource.connect(target, null, request);
|
|
136
|
+
return resource.connect ? resource.connect(target, null, request) : missingMethod(resource, 'connect');
|
|
132
137
|
case 'TRACE':
|
|
133
138
|
return 'Harper is the terminating server';
|
|
134
139
|
case 'QUERY':
|
|
135
|
-
return resource.query(target, request.data, request);
|
|
140
|
+
return resource.query ? resource.query(target, request.data, request) : missingMethod(resource, 'query');
|
|
136
141
|
case 'COPY': // methods suggested from webdav RFC 4918
|
|
137
|
-
return resource.copy
|
|
142
|
+
return resource.copy
|
|
143
|
+
? resource.copy(target, headersObject.destination, request)
|
|
144
|
+
: missingMethod(resource, 'copy');
|
|
138
145
|
case 'MOVE':
|
|
139
|
-
return resource.move
|
|
146
|
+
return resource.move
|
|
147
|
+
? resource.move(target, headersObject.destination, request)
|
|
148
|
+
: missingMethod(resource, 'move');
|
|
140
149
|
case 'BREW': // RFC 2324
|
|
141
150
|
throw new ClientError("Harper is short and stout and can't brew coffee", 418);
|
|
142
151
|
default:
|
package/server/http.ts
CHANGED
|
@@ -8,7 +8,7 @@ import harperLogger from '../utility/logging/harper_logger.js';
|
|
|
8
8
|
import { parentPort } from 'node:worker_threads';
|
|
9
9
|
import env from '../utility/environment/environmentManager.js';
|
|
10
10
|
import * as terms from '../utility/hdbTerms.ts';
|
|
11
|
-
import {
|
|
11
|
+
import { getConfigPath } from '../config/configUtils.js';
|
|
12
12
|
import { getTicketKeys } from './threads/manageThreads.js';
|
|
13
13
|
import { createTLSSelector } from '../security/keys.js';
|
|
14
14
|
import { createSecureServer } from 'node:http2';
|
|
@@ -181,7 +181,7 @@ function getPorts(options) {
|
|
|
181
181
|
|
|
182
182
|
if (options?.usageType === 'operations-api' && env.get(terms.CONFIG_PARAMS.OPERATIONSAPI_NETWORK_DOMAINSOCKET)) {
|
|
183
183
|
ports.push({
|
|
184
|
-
port:
|
|
184
|
+
port: getConfigPath(terms.CONFIG_PARAMS.OPERATIONSAPI_NETWORK_DOMAINSOCKET),
|
|
185
185
|
secure: false,
|
|
186
186
|
});
|
|
187
187
|
}
|
|
@@ -149,7 +149,7 @@ async function componentStatusRequestHandler(event) {
|
|
|
149
149
|
if (originatorThreadId === undefined) {
|
|
150
150
|
hdbLogger.debug('No originator threadId, falling back to broadcast');
|
|
151
151
|
} else {
|
|
152
|
-
hdbLogger.
|
|
152
|
+
hdbLogger.debug(`Failed to send direct response to thread ${originatorThreadId}, falling back to broadcast`);
|
|
153
153
|
}
|
|
154
154
|
await sendItcEvent(responseMessage);
|
|
155
155
|
}
|