@harperfast/harper-pro 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/core/bin/harper.js +1 -1
  2. package/core/bin/run.js +2 -2
  3. package/core/components/Application.ts +6 -3
  4. package/core/components/componentLoader.ts +19 -11
  5. package/core/components/operations.js +13 -13
  6. package/core/components/operationsValidation.js +3 -3
  7. package/core/config/configUtils.js +20 -4
  8. package/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +3 -2
  9. package/core/resources/Resource.ts +17 -6
  10. package/core/resources/RocksTransactionLogStore.ts +8 -1
  11. package/core/resources/analytics/write.ts +6 -0
  12. package/core/resources/databases.ts +3 -2
  13. package/core/security/jsLoader.ts +127 -46
  14. package/core/server/REST.ts +20 -11
  15. package/core/server/http.ts +2 -2
  16. package/core/server/itc/serverHandlers.js +1 -1
  17. package/core/static/defaultConfig.yaml +1 -1
  18. package/core/utility/hdbTerms.ts +1 -0
  19. package/core/utility/logging/harper_logger.js +22 -1
  20. package/core/utility/logging/readLog.js +2 -2
  21. package/core/utility/npmUtilities.js +2 -2
  22. package/core/validation/configValidator.js +16 -8
  23. package/core/validation/readLogValidator.js +2 -2
  24. package/dist/core/bin/harper.js +1 -1
  25. package/dist/core/bin/run.js +2 -2
  26. package/dist/core/bin/run.js.map +1 -1
  27. package/dist/core/components/Application.js +7 -2
  28. package/dist/core/components/Application.js.map +1 -1
  29. package/dist/core/components/componentLoader.js +19 -9
  30. package/dist/core/components/componentLoader.js.map +1 -1
  31. package/dist/core/components/operations.js +13 -13
  32. package/dist/core/components/operations.js.map +1 -1
  33. package/dist/core/components/operationsValidation.js +3 -3
  34. package/dist/core/components/operationsValidation.js.map +1 -1
  35. package/dist/core/config/configUtils.js +23 -3
  36. package/dist/core/config/configUtils.js.map +1 -1
  37. package/dist/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +3 -2
  38. package/dist/core/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js.map +1 -1
  39. package/dist/core/resources/Resource.js +11 -4
  40. package/dist/core/resources/Resource.js.map +1 -1
  41. package/dist/core/resources/RocksTransactionLogStore.js +8 -1
  42. package/dist/core/resources/RocksTransactionLogStore.js.map +1 -1
  43. package/dist/core/resources/analytics/write.js +6 -0
  44. package/dist/core/resources/analytics/write.js.map +1 -1
  45. package/dist/core/resources/databases.js +3 -2
  46. package/dist/core/resources/databases.js.map +1 -1
  47. package/dist/core/security/jsLoader.js +114 -40
  48. package/dist/core/security/jsLoader.js.map +1 -1
  49. package/dist/core/server/REST.js +17 -10
  50. package/dist/core/server/REST.js.map +1 -1
  51. package/dist/core/server/http.js +1 -1
  52. package/dist/core/server/http.js.map +1 -1
  53. package/dist/core/server/itc/serverHandlers.js +1 -1
  54. package/dist/core/server/itc/serverHandlers.js.map +1 -1
  55. package/dist/core/utility/hdbTerms.js +1 -0
  56. package/dist/core/utility/hdbTerms.js.map +1 -1
  57. package/dist/core/utility/logging/harper_logger.js +24 -1
  58. package/dist/core/utility/logging/harper_logger.js.map +1 -1
  59. package/dist/core/utility/logging/readLog.js +2 -2
  60. package/dist/core/utility/logging/readLog.js.map +1 -1
  61. package/dist/core/utility/npmUtilities.js +2 -2
  62. package/dist/core/utility/npmUtilities.js.map +1 -1
  63. package/dist/core/validation/configValidator.js +18 -8
  64. package/dist/core/validation/configValidator.js.map +1 -1
  65. package/dist/core/validation/readLogValidator.js +2 -2
  66. package/dist/core/validation/readLogValidator.js.map +1 -1
  67. package/dist/replication/nodeIdMapping.js +1 -1
  68. package/dist/replication/nodeIdMapping.js.map +1 -1
  69. package/npm-shrinkwrap.json +454 -453
  70. package/package.json +7 -4
  71. package/replication/nodeIdMapping.ts +1 -1
  72. package/static/defaultConfig.yaml +3 -0
  73. package/studio/web/assets/{index-BckVDix4.js → index-ClD_q6ya.js} +5 -5
  74. package/studio/web/assets/{index-BckVDix4.js.map → index-ClD_q6ya.js.map} +1 -1
  75. package/studio/web/assets/{index.lazy-iG1_8dzm.js → index.lazy-CXzU1gVu.js} +2 -2
  76. package/studio/web/assets/{index.lazy-iG1_8dzm.js.map → index.lazy-CXzU1gVu.js.map} +1 -1
  77. package/studio/web/assets/{profile-CzjslUXv.js → profile-DCNVg5yY.js} +2 -2
  78. package/studio/web/assets/{profile-CzjslUXv.js.map → profile-DCNVg5yY.js.map} +1 -1
  79. package/studio/web/assets/{status-BP4TQJDR.js → status-CoGlcjSB.js} +2 -2
  80. package/studio/web/assets/{status-BP4TQJDR.js.map → status-CoGlcjSB.js.map} +1 -1
  81. package/studio/web/index.html +1 -1
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env -S node --disable-warning=ExperimentalWarning --experimental-vm-modules
1
+ #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
4
  const fs = require('node:fs');
package/core/bin/run.js CHANGED
@@ -266,7 +266,7 @@ function startupLog(portResolutions) {
266
266
  ? `, TCP: ${env.get(CONFIG_PARAMS.THREADS_DEBUG_PORT)}\n`
267
267
  : '\n';
268
268
  }
269
- const logFilePath = path.join(env.get(CONFIG_PARAMS.LOGGING_ROOT), 'hdb.log');
269
+ const logFilePath = path.join(configUtils.getConfigPath(CONFIG_PARAMS.LOGGING_ROOT), 'hdb.log');
270
270
  logMsg += `${pad('Logging:')}level: ${env.get(CONFIG_PARAMS.LOGGING_LEVEL)}, location: ${
271
271
  logFilePath + (env.get(CONFIG_PARAMS.LOGGING_STDSTREAMS) ? ', stdout/err' : '')
272
272
  }\n`;
@@ -292,7 +292,7 @@ function startupLog(portResolutions) {
292
292
  ? `enabled for ${env.get(CONFIG_PARAMS.OPERATIONSAPI_NETWORK_CORSACCESSLIST)}`
293
293
  : 'disabled'
294
294
  }`;
295
- logMsg += `, unix socket: ${env.get(CONFIG_PARAMS.OPERATIONSAPI_NETWORK_DOMAINSOCKET)}\n`;
295
+ logMsg += `, unix socket: ${configUtils.getConfigPath(CONFIG_PARAMS.OPERATIONSAPI_NETWORK_DOMAINSOCKET)}\n`;
296
296
  if (env.get(CONFIG_PARAMS.OPERATIONSAPI_NETWORK_PORT)) {
297
297
  logMsg +=
298
298
  pad('') +
@@ -1,5 +1,5 @@
1
1
  import { type Logger } from '../utility/logging/logger.ts';
2
- import { getConfigObj, getConfigValue } from '../config/configUtils.js';
2
+ import { getConfigObj, getConfigValue, getConfigPath } from '../config/configUtils.js';
3
3
  import { CONFIG_PARAMS } from '../utility/hdbTerms.js';
4
4
  import logger from '../utility/logging/harper_logger.js';
5
5
 
@@ -402,7 +402,9 @@ export class Application {
402
402
  this.payload = payload;
403
403
  this.packageIdentifier = packageIdentifier && derivePackageIdentifier(packageIdentifier);
404
404
  this.install = install;
405
- this.dirPath = join(getConfigValue(CONFIG_PARAMS.COMPONENTSROOT), name);
405
+ const componentsRoot = getConfigPath(CONFIG_PARAMS.COMPONENTSROOT);
406
+ if (!componentsRoot) throw new Error('componentsRoot is not configured');
407
+ this.dirPath = join(componentsRoot, name);
406
408
  this.logger = logger.loggerWithTag(name);
407
409
  this.packageManagerPrefix = getConfigValue(CONFIG_PARAMS.APPLICATIONS_PACKAGEMANAGERPREFIX);
408
410
  }
@@ -464,7 +466,8 @@ export async function installApplications() {
464
466
 
465
467
  const config = getConfigObj();
466
468
 
467
- const componentsRootDirPath = getConfigValue(CONFIG_PARAMS.COMPONENTSROOT);
469
+ const componentsRootDirPath = getConfigPath(CONFIG_PARAMS.COMPONENTSROOT);
470
+ if (!componentsRootDirPath) throw new Error('componentsRoot is not configured');
468
471
 
469
472
  // Ensure component directory exists
470
473
  await mkdir(componentsRootDirPath, { recursive: true });
@@ -27,7 +27,7 @@ import { getHdbBasePath } from '../utility/environment/environmentManager.js';
27
27
  import * as operationsServer from '../server/operationsServer.ts';
28
28
  import * as auth from '../security/auth.ts';
29
29
  import * as mqtt from '../server/mqtt.ts';
30
- import { getConfigObj, resolvePath } from '../config/configUtils.js';
30
+ import { getConfigObj, getConfigPath } from '../config/configUtils.js';
31
31
  import { createReuseportFd } from '../server/serverHelpers/Request.ts';
32
32
  import { ErrorResource } from '../resources/ErrorResource.ts';
33
33
  import { Scope } from './Scope.ts';
@@ -40,7 +40,7 @@ import { DEFAULT_CONFIG } from './DEFAULT_CONFIG.ts';
40
40
  import { PluginModule } from './PluginModule.ts';
41
41
  import { getEnvBuiltInComponents } from './Application.ts';
42
42
 
43
- const CF_ROUTES_DIR = resolvePath(env.get(CONFIG_PARAMS.COMPONENTSROOT));
43
+ const CF_ROUTES_DIR = getConfigPath(CONFIG_PARAMS.COMPONENTSROOT);
44
44
  let loadedComponents = new Map<any, any>();
45
45
  let watchesSetup;
46
46
  let resources;
@@ -147,20 +147,28 @@ function symlinkHarperModule(componentDirectory: string) {
147
147
  mkdirSync(nodeModulesDir);
148
148
  }
149
149
 
150
- // validate harperdb module
150
+ // validate harper module
151
151
  const harperModule = join(nodeModulesDir, 'harper');
152
152
  if (existsSync(harperModule)) {
153
- if (realpathSync(harperModule) === realpathSync(PACKAGE_ROOT)) {
154
- // if it exists and correctly linked, resolve
155
- return resolve();
153
+ if (realpathSync(harperModule) !== realpathSync(PACKAGE_ROOT)) {
154
+ // if it exists but is incorrectly linked, fix it
155
+ rmSync(harperModule, { recursive: true, force: true });
156
+ // create link to harper module
157
+ symlinkSync(PACKAGE_ROOT, harperModule, 'dir');
156
158
  }
157
-
158
- // Otherwise remove it then link
159
- rmSync(harperModule, { recursive: true, force: true });
159
+ } else {
160
+ // create link to harper module
161
+ symlinkSync(PACKAGE_ROOT, harperModule, 'dir');
162
+ }
163
+ // if there is a harperdb module, fix that too
164
+ const harperdbModule = join(nodeModulesDir, 'harperdb');
165
+ if (existsSync(harperdbModule) && realpathSync(harperdbModule) !== realpathSync(PACKAGE_ROOT)) {
166
+ // if it exists but is incorrectly linked, fix it
167
+ rmSync(harperdbModule, { recursive: true, force: true });
168
+ // create link to harper module
169
+ symlinkSync(PACKAGE_ROOT, harperdbModule, 'dir');
160
170
  }
161
171
 
162
- // create link to harperdb module
163
- symlinkSync(PACKAGE_ROOT, harperModule, 'dir');
164
172
  resolve();
165
173
  } finally {
166
174
  // finally release the lock
@@ -31,7 +31,7 @@ function customFunctionsStatus() {
31
31
  try {
32
32
  response = {
33
33
  port: env.get(hdbTerms.CONFIG_PARAMS.HTTP_PORT),
34
- directory: env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT),
34
+ directory: configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT),
35
35
  is_enabled: true,
36
36
  };
37
37
  } catch (err) {
@@ -54,7 +54,7 @@ function customFunctionsStatus() {
54
54
  function getCustomFunctions() {
55
55
  log.trace(`getting custom api endpoints`);
56
56
  let response = {};
57
- const dir = env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
57
+ const dir = configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
58
58
 
59
59
  try {
60
60
  const projectFolders = fg.sync(normalize(`${dir}/*`), { onlyDirectories: true });
@@ -103,7 +103,7 @@ function getCustomFunction(req) {
103
103
  }
104
104
 
105
105
  log.trace(`getting custom api endpoint file content`);
106
- const cfDir = env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
106
+ const cfDir = configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
107
107
  const { project, type, file } = req;
108
108
  const fileLocation = path.join(cfDir, project, type, file + '.js');
109
109
 
@@ -141,7 +141,7 @@ async function setCustomFunction(req) {
141
141
  }
142
142
 
143
143
  log.trace(`setting custom function file content`);
144
- const cfDir = env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
144
+ const cfDir = configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
145
145
  const { project, type, file, function_content } = req;
146
146
 
147
147
  try {
@@ -181,7 +181,7 @@ async function dropCustomFunction(req) {
181
181
  }
182
182
 
183
183
  log.trace(`dropping custom function file`);
184
- const cfDir = env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
184
+ const cfDir = configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
185
185
  const { project, type, file } = req;
186
186
 
187
187
  try {
@@ -216,7 +216,7 @@ async function addComponent(req) {
216
216
  }
217
217
 
218
218
  log.trace(`adding component`);
219
- const cfDir = env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
219
+ const cfDir = configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
220
220
  const { project, install_command, install_timeout } = req;
221
221
 
222
222
  const template = req.template || 'https://github.com/harperdb/application-template';
@@ -264,7 +264,7 @@ async function dropCustomFunctionProject(req) {
264
264
  }
265
265
 
266
266
  log.trace(`dropping custom function project`);
267
- const cfDir = env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
267
+ const cfDir = configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
268
268
  const { project } = req;
269
269
 
270
270
  let apps = env.get(hdbTerms.CONFIG_PARAMS.APPS);
@@ -318,7 +318,7 @@ async function packageComponent(req) {
318
318
  throw handleHDBError(validation, validation.message, HTTP_STATUS_CODES.BAD_REQUEST);
319
319
  }
320
320
 
321
- const cfDir = env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
321
+ const cfDir = configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
322
322
  const { project } = req;
323
323
  log.trace(`packaging component`, project);
324
324
 
@@ -507,8 +507,8 @@ async function getComponents() {
507
507
  }
508
508
  };
509
509
 
510
- const results = await walkDir(env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT), {
511
- name: env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT).split(path.sep).slice(-1).pop(),
510
+ const results = await walkDir(configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT), {
511
+ name: configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT).split(path.sep).slice(-1).pop(),
512
512
  entries: [],
513
513
  });
514
514
  for (let entry of results.entries) {
@@ -557,7 +557,7 @@ async function getComponentFile(req) {
557
557
  throw handleHDBError(validation, validation.message, HTTP_STATUS_CODES.BAD_REQUEST);
558
558
  }
559
559
 
560
- const compRoot = env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
560
+ const compRoot = configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
561
561
  const options = req.encoding ? { encoding: req.encoding } : { encoding: 'utf8' };
562
562
 
563
563
  try {
@@ -588,7 +588,7 @@ async function setComponentFile(req) {
588
588
  }
589
589
 
590
590
  const options = req.encoding ? { encoding: req.encoding } : { encoding: 'utf8' };
591
- const pathToComp = path.join(env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT), req.project, req.file);
591
+ const pathToComp = path.join(configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT), req.project, req.file);
592
592
  if (req.payload !== undefined) {
593
593
  await fs.ensureFile(pathToComp);
594
594
  await fs.outputFile(pathToComp, req.payload, options);
@@ -613,7 +613,7 @@ async function dropComponent(req) {
613
613
 
614
614
  const { project, file } = req;
615
615
  const projectPath = req.file ? path.join(project, file) : project;
616
- const pathToComponent = path.join(env.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT), projectPath);
616
+ const pathToComponent = path.join(configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT), projectPath);
617
617
 
618
618
  const componentSymlink = path.join(env.get(hdbTerms.CONFIG_PARAMS.ROOTPATH), 'node_modules', project);
619
619
  if (await fs.pathExists(componentSymlink)) {
@@ -4,9 +4,9 @@ const Joi = require('joi');
4
4
  const fs = require('fs-extra');
5
5
  const path = require('path');
6
6
  const validator = require('../validation/validationWrapper.js');
7
- const envMangr = require('../utility/environment/environmentManager.js');
8
7
  const hdbTerms = require('../utility/hdbTerms.ts');
9
8
  const hdbLogger = require('../utility/logging/harper_logger.js');
9
+ const configUtils = require('../config/configUtils.js');
10
10
  const { hdbErrors } = require('../utility/errors/hdbError.js');
11
11
  const { HDB_ERROR_MSGS } = hdbErrors;
12
12
 
@@ -34,7 +34,7 @@ module.exports = {
34
34
  */
35
35
  function checkProjectExists(checkExists, project, helpers) {
36
36
  try {
37
- const cfDir = envMangr.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
37
+ const cfDir = configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
38
38
  const projectDir = path.join(cfDir, project);
39
39
 
40
40
  if (!fs.existsSync(projectDir)) {
@@ -71,7 +71,7 @@ function checkFilePath(path, helpers) {
71
71
  */
72
72
  function checkFileExists(project, type, file, helpers) {
73
73
  try {
74
- const cfDir = envMangr.get(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
74
+ const cfDir = configUtils.getConfigPath(hdbTerms.CONFIG_PARAMS.COMPONENTSROOT);
75
75
  const filePath = path.join(cfDir, project, type, file + '.js');
76
76
  if (!fs.existsSync(filePath)) {
77
77
  return helpers.message(HDB_ERROR_MSGS.NO_FILE);
@@ -57,6 +57,7 @@ exports.deleteConfigFromFile = deleteConfigFromFile;
57
57
  exports.getConfigObj = getConfigObj;
58
58
  exports.resolvePath = resolvePath;
59
59
  exports.getFlatConfigObj = getFlatConfigObj;
60
+ exports.getConfigPath = getConfigPath;
60
61
 
61
62
  function resolvePath(relativePath) {
62
63
  if (relativePath?.startsWith('~/')) {
@@ -70,7 +71,23 @@ function resolvePath(relativePath) {
70
71
  return relativePath;
71
72
  }
72
73
  }
73
-
74
+ /**
75
+ * Get a config value and resolve it as a path relative to rootPath.
76
+ * Use this for any config param that represents a file/directory path.
77
+ * @param param
78
+ */
79
+ function getConfigPath(param) {
80
+ const env = require('../utility/environment/environmentManager.js');
81
+ const value = env.get(param);
82
+ if (!value || typeof value !== 'string') return value;
83
+ if (value.startsWith('~/')) {
84
+ return path.join(hdbUtils.getHomeDir(), value.slice(1));
85
+ }
86
+ if (path.isAbsolute(value)) return value;
87
+ const rootPath = env.getHdbBasePath();
88
+ if (!rootPath) return value;
89
+ return path.resolve(rootPath, value);
90
+ }
74
91
  /**
75
92
  * Builds the Harper config file using user inputs and default values from defaultConfig.yaml
76
93
  * @param args - any args that the user provided.
@@ -332,15 +349,14 @@ function initConfig(force = false) {
332
349
  * @param configFilePath
333
350
  */
334
351
  function checkForUpdatedConfig(configDoc, configFilePath) {
335
- const rootPath = configDoc.getIn(['rootPath']);
336
352
  let updateFile = false;
337
353
  if (!configDoc.hasIn(['storage', 'path'])) {
338
- configDoc.setIn(['storage', 'path'], path.join(rootPath, 'database'));
354
+ configDoc.setIn(['storage', 'path'], 'database');
339
355
  updateFile = true;
340
356
  }
341
357
 
342
358
  if (!configDoc.hasIn(['logging', 'rotation', 'path'])) {
343
- configDoc.setIn(['logging', 'rotation', 'path'], path.join(rootPath, 'log'));
359
+ configDoc.setIn(['logging', 'rotation', 'path'], 'log');
344
360
  updateFile = true;
345
361
  }
346
362
 
@@ -7,6 +7,7 @@ const path = require('path');
7
7
  const minimist = require('minimist');
8
8
  const fs = require('fs-extra');
9
9
  const _ = require('lodash');
10
+ const { getConfigPath } = require('../../../../config/configUtils.js');
10
11
  env.initSync();
11
12
 
12
13
  const { CONFIG_PARAMS, DATABASES_PARAM_CONFIG, SYSTEM_SCHEMA_NAME } = hdbTerms;
@@ -25,7 +26,7 @@ function getBaseSchemaPath() {
25
26
 
26
27
  if (env.getHdbBasePath() !== undefined) {
27
28
  BASE_SCHEMA_PATH =
28
- env.get(CONFIG_PARAMS.STORAGE_PATH) || path.join(env.getHdbBasePath(), hdbTerms.DATABASES_DIR_NAME);
29
+ getConfigPath(CONFIG_PARAMS.STORAGE_PATH) || path.join(env.getHdbBasePath(), hdbTerms.DATABASES_DIR_NAME);
29
30
  return BASE_SCHEMA_PATH;
30
31
  }
31
32
  }
@@ -52,7 +53,7 @@ function getTransactionAuditStoreBasePath() {
52
53
 
53
54
  if (env.getHdbBasePath() !== undefined) {
54
55
  TRANSACTION_STORE_PATH =
55
- env.get(hdbTerms.CONFIG_PARAMS.STORAGE_AUDIT_PATH) ||
56
+ getConfigPath(hdbTerms.CONFIG_PARAMS.STORAGE_AUDIT_PATH) ||
56
57
  path.join(env.getHdbBasePath(), hdbTerms.TRANSACTIONS_DIR_NAME);
57
58
  return TRANSACTION_STORE_PATH;
58
59
  }
@@ -683,15 +683,26 @@ function transactional(
683
683
  }
684
684
  }
685
685
  }
686
- function missingMethod(resource, method) {
687
- const error = new ClientError(`The ${resource.constructor.name} does not have a ${method} method implemented`, 405);
688
- error.allow = [];
686
+ const KNOWN_METHODS = ['get', 'head', 'put', 'post', 'delete', 'patch', 'query', 'move', 'copy'];
687
+ type ClientErrorWithMethods = ClientError & { allow: string[]; method: string };
688
+ export function missingMethod(resource: any, method: string) {
689
+ const error = new ClientError(
690
+ `The ${resource.constructor.name} does not have a ${method} method implemented`,
691
+ 405
692
+ ) as ClientErrorWithMethods;
693
+ error.allow = allowedMethods(resource);
689
694
  error.method = method;
690
- for (const method of ['get', 'put', 'post', 'delete', 'query', 'move', 'copy']) {
691
- if (typeof resource[method] === 'function') error.allow.push(method);
692
- }
693
695
  throw error;
694
696
  }
697
+
698
+ export function allowedMethods(resource: any) {
699
+ const allow = [];
700
+ for (const method of KNOWN_METHODS) {
701
+ if (typeof resource[method] === 'function') allow.push(method);
702
+ }
703
+ return allow;
704
+ }
705
+
695
706
  /**
696
707
  * This is responsible for handling a select query parameter/call that selects specific
697
708
  * properties from the returned record(s).
@@ -3,6 +3,7 @@ import { ExtendedIterable } from '@harperfast/extended-iterable';
3
3
  import { Decoder, readAuditEntry, ENTRY_DATAVIEW, AuditRecord, createAuditEntry } from './auditStore.ts';
4
4
  import { isMainThread } from 'node:worker_threads';
5
5
  import { EventEmitter } from 'node:events';
6
+ import { asBinary } from 'lmdb';
6
7
 
7
8
  if (!process.env.HARPER_NO_FLUSH_ON_EXIT && isMainThread) {
8
9
  // we want to be able to test log replay
@@ -81,7 +82,7 @@ export class RocksTransactionLogStore extends EventEmitter {
81
82
 
82
83
  putSync(suggestedKey: any, value: any, options: any) {
83
84
  if (typeof suggestedKey === 'symbol') {
84
- this.rootStore.putSync(suggestedKey, value, options);
85
+ this.rootStore.putSync(suggestedKey, asBinary(value), options);
85
86
  } else {
86
87
  this.put(suggestedKey, value, options);
87
88
  }
@@ -107,6 +108,12 @@ export class RocksTransactionLogStore extends EventEmitter {
107
108
  return this.rootStore.getSync(key);
108
109
  }
109
110
  }
111
+ getBinary(key: any) {
112
+ if (typeof key === 'number') {
113
+ throw new Error('Unsupported binary access by number');
114
+ }
115
+ return this.rootStore.getBinarySync(key);
116
+ }
110
117
  getEntry() {
111
118
  throw new Error('Not implemented');
112
119
  }
@@ -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));