@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.
Files changed (81) hide show
  1. package/bin/harper.js +1 -1
  2. package/bin/run.js +2 -2
  3. package/components/Application.ts +6 -3
  4. package/components/componentLoader.ts +19 -11
  5. package/components/operations.js +13 -13
  6. package/components/operationsValidation.js +3 -3
  7. package/config/configUtils.js +20 -4
  8. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +3 -2
  9. package/dist/bin/harper.d.ts +1 -1
  10. package/dist/bin/harper.js +1 -1
  11. package/dist/bin/run.js +2 -2
  12. package/dist/bin/run.js.map +1 -1
  13. package/dist/components/Application.js +7 -2
  14. package/dist/components/Application.js.map +1 -1
  15. package/dist/components/componentLoader.js +19 -9
  16. package/dist/components/componentLoader.js.map +1 -1
  17. package/dist/components/operations.js +13 -13
  18. package/dist/components/operations.js.map +1 -1
  19. package/dist/components/operationsValidation.js +3 -3
  20. package/dist/components/operationsValidation.js.map +1 -1
  21. package/dist/config/configUtils.d.ts +6 -0
  22. package/dist/config/configUtils.js +23 -3
  23. package/dist/config/configUtils.js.map +1 -1
  24. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +3 -2
  25. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js.map +1 -1
  26. package/dist/resources/Resource.d.ts +2 -0
  27. package/dist/resources/Resource.js +11 -4
  28. package/dist/resources/Resource.js.map +1 -1
  29. package/dist/resources/RocksTransactionLogStore.d.ts +1 -0
  30. package/dist/resources/RocksTransactionLogStore.js +8 -1
  31. package/dist/resources/RocksTransactionLogStore.js.map +1 -1
  32. package/dist/resources/analytics/write.js +6 -0
  33. package/dist/resources/analytics/write.js.map +1 -1
  34. package/dist/resources/databases.js +3 -2
  35. package/dist/resources/databases.js.map +1 -1
  36. package/dist/security/jsLoader.js +114 -40
  37. package/dist/security/jsLoader.js.map +1 -1
  38. package/dist/server/REST.js +17 -10
  39. package/dist/server/REST.js.map +1 -1
  40. package/dist/server/http.js +1 -1
  41. package/dist/server/http.js.map +1 -1
  42. package/dist/server/itc/serverHandlers.js +1 -1
  43. package/dist/server/itc/serverHandlers.js.map +1 -1
  44. package/dist/utility/hdbTerms.d.ts +1 -0
  45. package/dist/utility/hdbTerms.js +1 -0
  46. package/dist/utility/hdbTerms.js.map +1 -1
  47. package/dist/utility/logging/harper_logger.js +24 -1
  48. package/dist/utility/logging/harper_logger.js.map +1 -1
  49. package/dist/utility/logging/readLog.js +2 -2
  50. package/dist/utility/logging/readLog.js.map +1 -1
  51. package/dist/utility/npmUtilities.js +2 -2
  52. package/dist/utility/npmUtilities.js.map +1 -1
  53. package/dist/validation/configValidator.js +18 -8
  54. package/dist/validation/configValidator.js.map +1 -1
  55. package/dist/validation/readLogValidator.js +2 -2
  56. package/dist/validation/readLogValidator.js.map +1 -1
  57. package/package.json +3 -3
  58. package/resources/Resource.ts +17 -6
  59. package/resources/RocksTransactionLogStore.ts +8 -1
  60. package/resources/analytics/write.ts +6 -0
  61. package/resources/databases.ts +3 -2
  62. package/security/jsLoader.ts +127 -46
  63. package/server/REST.ts +20 -11
  64. package/server/http.ts +2 -2
  65. package/server/itc/serverHandlers.js +1 -1
  66. package/static/defaultConfig.yaml +1 -1
  67. package/studio/web/assets/{index-BckVDix4.js → index-ClD_q6ya.js} +5 -5
  68. package/studio/web/assets/{index-BckVDix4.js.map → index-ClD_q6ya.js.map} +1 -1
  69. package/studio/web/assets/{index.lazy-iG1_8dzm.js → index.lazy-CXzU1gVu.js} +2 -2
  70. package/studio/web/assets/{index.lazy-iG1_8dzm.js.map → index.lazy-CXzU1gVu.js.map} +1 -1
  71. package/studio/web/assets/{profile-CzjslUXv.js → profile-DCNVg5yY.js} +2 -2
  72. package/studio/web/assets/{profile-CzjslUXv.js.map → profile-DCNVg5yY.js.map} +1 -1
  73. package/studio/web/assets/{status-BP4TQJDR.js → status-CoGlcjSB.js} +2 -2
  74. package/studio/web/assets/{status-BP4TQJDR.js.map → status-CoGlcjSB.js.map} +1 -1
  75. package/studio/web/index.html +1 -1
  76. package/utility/hdbTerms.ts +1 -0
  77. package/utility/logging/harper_logger.js +22 -1
  78. package/utility/logging/readLog.js +2 -2
  79. package/utility/npmUtilities.js +2 -2
  80. package/validation/configValidator.js +16 -8
  81. 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(
@@ -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
- envGet(CONFIG_PARAMS.STORAGE_PATH) ||
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
- envGet(CONFIG_PARAMS.STORAGE_PATH) ||
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));
@@ -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
- const exportNames = Object.keys(cjsModule.exports);
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.length > 0 ? exportNames : ['default'],
245
+ exportNames,
227
246
  function () {
228
- if (exportNames.length > 0) {
229
- for (const key of exportNames) {
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
- const useContainment = specifier.startsWith('.') || scope.dependencyContainment;
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
- try {
357
- const cjsExports = replacedModule ?? require(url);
358
- // It's a CJS module - expose all properties as named exports
359
- const exportNames = Object.keys(cjsExports);
360
- module = new SyntheticModule(
361
- exportNames.length > 0 ? [...exportNames, 'default'] : ['default'],
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 REPLACED_BUILTIN_MODULES = {
548
- child_process: {
549
- exec: createSpawn(child_process.exec),
550
- execFile: createSpawn(child_process.execFile),
551
- fork: createSpawn(child_process.fork, true), // this is launching node, so deemed safe
552
- spawn: createSpawn(child_process.spawn),
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('Allow', 'GET, HEAD, POST, PUT, DELETE, PATCH, OPTIONS, TRACE, QUERY, COPY, MOVE');
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(target, headersObject.destination, request);
142
+ return resource.copy
143
+ ? resource.copy(target, headersObject.destination, request)
144
+ : missingMethod(resource, 'copy');
138
145
  case 'MOVE':
139
- return resource.move(target, headersObject.destination, request);
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 { resolvePath } from '../config/configUtils.js';
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: resolvePath(env.get(terms.CONFIG_PARAMS.OPERATIONSAPI_NETWORK_DOMAINSOCKET)),
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.warn(`Failed to send direct response to thread ${originatorThreadId}, falling back to broadcast`);
152
+ hdbLogger.debug(`Failed to send direct response to thread ${originatorThreadId}, falling back to broadcast`);
153
153
  }
154
154
  await sendItcEvent(responseMessage);
155
155
  }
@@ -26,7 +26,7 @@ analytics:
26
26
  applications:
27
27
  lockdown: freeze
28
28
  containment: vm
29
- dependencyContainment: false
29
+ dependencyContainment: auto
30
30
  allowedSpawnCommands:
31
31
  - npm
32
32
  - node