s3db.js 19.4.2 → 19.4.4-next.033a879c

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 (42) hide show
  1. package/dist/cli/index.js +12 -44
  2. package/dist/connection-string.class.js +13 -24
  3. package/dist/database.class.js +1 -9
  4. package/dist/plugins/api/middlewares/validator.js +4 -7
  5. package/dist/plugins/backup/multi-backup-driver.class.js +0 -8
  6. package/dist/plugins/identity/concerns/interactive-wizard.js +71 -68
  7. package/dist/plugins/identity/concerns/onboarding-manager.js +3 -3
  8. package/dist/plugins/identity/index.js +1 -9
  9. package/dist/plugins/identity/ui/layouts/base.js +0 -1
  10. package/dist/plugins/metrics.plugin.js +4 -10
  11. package/dist/plugins/puppeteer.plugin.js +0 -11
  12. package/dist/s3db-lite.cjs +16 -43
  13. package/dist/s3db-lite.d.ts +0 -5
  14. package/dist/s3db-lite.es.js +16 -43
  15. package/dist/s3db.cjs +47852 -317
  16. package/dist/s3db.d.ts +1 -18
  17. package/dist/s3db.es.js +47855 -321
  18. package/dist/schema.class.js +0 -8
  19. package/dist/types/database.class.d.ts +0 -2
  20. package/dist/types/plugins/api/middlewares/validator.d.ts +10 -10
  21. package/dist/types/plugins/backup/multi-backup-driver.class.d.ts +0 -1
  22. package/dist/types/plugins/identity/concerns/interactive-wizard.d.ts +2 -4
  23. package/dist/types/plugins/identity/index.d.ts +1 -4
  24. package/dist/types/plugins/identity/ui/layouts/base.d.ts +0 -1
  25. package/dist/types/plugins/metrics.plugin.d.ts +0 -5
  26. package/dist/types/plugins/puppeteer.plugin.d.ts +0 -3
  27. package/dist/types/schema.class.d.ts +0 -3
  28. package/mcp/tools/debugging.js +5 -6
  29. package/mcp/tools/debugging.ts +4 -5
  30. package/package.json +2 -7
  31. package/src/cli/index.ts +26 -44
  32. package/src/connection-string.class.ts +12 -24
  33. package/src/database.class.ts +1 -14
  34. package/src/plugins/api/middlewares/validator.ts +10 -18
  35. package/src/plugins/backup/multi-backup-driver.class.ts +0 -12
  36. package/src/plugins/identity/concerns/interactive-wizard.ts +74 -81
  37. package/src/plugins/identity/concerns/onboarding-manager.ts +3 -3
  38. package/src/plugins/identity/index.ts +2 -13
  39. package/src/plugins/identity/ui/layouts/base.ts +0 -2
  40. package/src/plugins/metrics.plugin.ts +3 -19
  41. package/src/plugins/puppeteer.plugin.ts +0 -15
  42. package/src/schema.class.ts +0 -9
@@ -53249,11 +53249,18 @@ class ConnectionString {
53249
53249
  this.secretAccessKey = undefined;
53250
53250
  // Parse pathname
53251
53251
  let pathname = uri.pathname || '';
53252
+ let isRelativePath = false;
53252
53253
  // Handle Windows paths (file:///C:/path/to/data)
53253
53254
  if (uri.hostname && uri.hostname.match(/^[a-zA-Z]$/)) {
53254
53255
  // Windows drive letter in hostname (file://C:/path)
53255
53256
  pathname = `${uri.hostname}:${pathname}`;
53256
53257
  }
53258
+ else if (uri.hostname === '.' || uri.hostname === '..') {
53259
+ // Relative path: file://./path or file://../path
53260
+ // URL parser puts . or .. in hostname, reconstruct the relative path
53261
+ pathname = `${uri.hostname}${pathname}`;
53262
+ isRelativePath = true;
53263
+ }
53257
53264
  else if (uri.hostname && uri.hostname !== 'localhost') {
53258
53265
  // UNC path (file://server/share/path)
53259
53266
  pathname = `//${uri.hostname}${pathname}`;
@@ -53273,37 +53280,19 @@ class ConnectionString {
53273
53280
  suggestion: 'Use file:///absolute/path or file://./relative/path'
53274
53281
  });
53275
53282
  }
53276
- // Parse path segments: /basePath/bucket/keyPrefix
53277
- const segments = decodedPath.split('/').filter(Boolean);
53278
- if (segments.length === 0) {
53279
- throw new ConnectionStringError('file:// connection string requires a path', {
53280
- input: uri.href,
53281
- suggestion: 'Use file:///absolute/path or file://./relative/path'
53282
- });
53283
- }
53284
- // For relative paths starting with ./ or ../
53285
- if (decodedPath.startsWith('./') || decodedPath.startsWith('../')) {
53283
+ // For relative paths (detected from hostname or starting with ./ or ../)
53284
+ if (isRelativePath || decodedPath.startsWith('./') || decodedPath.startsWith('../')) {
53286
53285
  this.basePath = path.resolve(decodedPath);
53287
53286
  this.bucket = 's3db';
53288
53287
  this.keyPrefix = '';
53289
53288
  }
53290
- else if (segments.length === 1) {
53291
- this.basePath = path.resolve('/', segments[0]);
53289
+ else {
53290
+ // Absolute path: use the entire path as basePath
53291
+ // This is the intuitive behavior - file:///path/to/data means "use /path/to/data"
53292
+ this.basePath = path.resolve(decodedPath);
53292
53293
  this.bucket = 's3db';
53293
53294
  this.keyPrefix = '';
53294
53295
  }
53295
- else if (segments.length === 2) {
53296
- const [baseSegment, bucketSegment] = segments;
53297
- this.basePath = path.resolve('/', baseSegment);
53298
- this.bucket = bucketSegment;
53299
- this.keyPrefix = '';
53300
- }
53301
- else {
53302
- const [baseSegment, bucketSegment, ...prefixSegments] = segments;
53303
- this.basePath = path.resolve('/', baseSegment);
53304
- this.bucket = bucketSegment;
53305
- this.keyPrefix = prefixSegments.join('/');
53306
- }
53307
53296
  // Set synthetic endpoint for compatibility
53308
53297
  this.endpoint = `file://${this.basePath}`;
53309
53298
  this.region = 'local';
@@ -65087,14 +65076,6 @@ class Schema {
65087
65076
  }
65088
65077
  return cloned;
65089
65078
  }
65090
- async validate(resourceItem, { mutateOriginal = false } = {}) {
65091
- if (process.env.NODE_ENV === 'development') {
65092
- console.warn('[DEPRECATION] Schema.validate() is deprecated. Use ResourceValidator.validate() instead.');
65093
- }
65094
- const data = mutateOriginal ? resourceItem : lodashEs.cloneDeep(resourceItem);
65095
- const result = await this.validator(data);
65096
- return result;
65097
- }
65098
65079
  async mapper(resourceItem) {
65099
65080
  let obj = lodashEs.cloneDeep(resourceItem);
65100
65081
  obj = await this.applyHooksActions(obj, "beforeMap");
@@ -70671,8 +70652,8 @@ class Database extends SafeEventEmitter {
70671
70652
  })();
70672
70653
  this.version = '1';
70673
70654
  this.s3dbVersion = (() => {
70674
- const [ok, , version] = tryFnSync(() => (typeof globalThis['19.4.2'] !== 'undefined' && globalThis['19.4.2'] !== '19.4.2'
70675
- ? globalThis['19.4.2']
70655
+ const [ok, , version] = tryFnSync(() => (typeof globalThis['19.4.4-next.033a879c'] !== 'undefined' && globalThis['19.4.4-next.033a879c'] !== '19.4.4-next.033a879c'
70656
+ ? globalThis['19.4.4-next.033a879c']
70676
70657
  : 'latest'));
70677
70658
  return ok ? version : 'latest';
70678
70659
  })();
@@ -70696,7 +70677,7 @@ class Database extends SafeEventEmitter {
70696
70677
  });
70697
70678
  this.savedMetadata = null;
70698
70679
  this.databaseOptions = options;
70699
- const executorPoolConfig = options?.executorPool ?? options?.operationsPool;
70680
+ const executorPoolConfig = options?.executorPool;
70700
70681
  this._parallelism = this._normalizeParallelism(options?.parallelism ?? executorPoolConfig?.concurrency, 10);
70701
70682
  this.logLevel = options.logLevel || options.loggerOptions?.level || 'info';
70702
70683
  const loggerOptions = { ...(options.loggerOptions || {}) };
@@ -70717,11 +70698,6 @@ class Database extends SafeEventEmitter {
70717
70698
  });
70718
70699
  }
70719
70700
  this._childLoggerLevels = options.loggerOptions?.childLevels || {};
70720
- if (options?.operationsPool && !options?.executorPool) {
70721
- this.logger.warn('⚠️ "operationsPool" is deprecated in s3db.js v16.x. ' +
70722
- 'Use "executorPool" instead. ' +
70723
- 'Migration: https://s3db.js/docs/migration/v16-to-v17');
70724
- }
70725
70701
  this.executorPool = this._normalizeOperationsPool(executorPoolConfig, this._parallelism);
70726
70702
  if (options?.taskExecutorMonitoring) {
70727
70703
  this.executorPool.monitoring = this._deepMerge(this.executorPool.monitoring || {}, options.taskExecutorMonitoring);
@@ -70882,9 +70858,6 @@ class Database extends SafeEventEmitter {
70882
70858
  this.executorPool.concurrency = normalized;
70883
70859
  }
70884
70860
  }
70885
- get operationsPool() {
70886
- return this.executorPool;
70887
- }
70888
70861
  get config() {
70889
70862
  return {
70890
70863
  version: this.version,
@@ -172,9 +172,6 @@ declare class Schema {
172
172
  export(): SchemaExport;
173
173
  _exportAttributes(attrs: unknown): SchemaAttributes;
174
174
  applyHooksActions(resourceItem: Record<string, unknown>, hook: keyof SchemaHooks): Promise<Record<string, unknown>>;
175
- validate(resourceItem: Record<string, unknown>, { mutateOriginal }?: {
176
- mutateOriginal?: boolean | undefined;
177
- }): Promise<true | Record<string, unknown>[]>;
178
175
  mapper(resourceItem: Record<string, unknown>): Promise<Record<string, unknown>>;
179
176
  unmapper(mappedResourceItem: Record<string, unknown>, mapOverride?: AttributeMapping, pluginMapOverride?: AttributeMapping): Promise<Record<string, unknown>>;
180
177
  getAttributeDefinition(key: string): unknown;
@@ -1771,7 +1768,6 @@ interface DatabaseOptions {
1771
1768
  metadataWriteDelay?: number;
1772
1769
  parallelism?: number | string;
1773
1770
  executorPool?: ExecutorPoolConfig | false;
1774
- operationsPool?: ExecutorPoolConfig | false;
1775
1771
  taskExecutorMonitoring?: TaskExecutorMonitoringConfig;
1776
1772
  logLevel?: LogLevel;
1777
1773
  loggerOptions?: LoggerConfig;
@@ -1825,7 +1821,6 @@ declare class Database extends SafeEventEmitter {
1825
1821
  get parallelism(): number;
1826
1822
  set parallelism(value: number | string);
1827
1823
  setConcurrency(value: number | string): void;
1828
- get operationsPool(): ExecutorPoolConfig;
1829
1824
  get config(): {
1830
1825
  version: string;
1831
1826
  s3dbVersion: string;
@@ -53226,11 +53226,18 @@ class ConnectionString {
53226
53226
  this.secretAccessKey = undefined;
53227
53227
  // Parse pathname
53228
53228
  let pathname = uri.pathname || '';
53229
+ let isRelativePath = false;
53229
53230
  // Handle Windows paths (file:///C:/path/to/data)
53230
53231
  if (uri.hostname && uri.hostname.match(/^[a-zA-Z]$/)) {
53231
53232
  // Windows drive letter in hostname (file://C:/path)
53232
53233
  pathname = `${uri.hostname}:${pathname}`;
53233
53234
  }
53235
+ else if (uri.hostname === '.' || uri.hostname === '..') {
53236
+ // Relative path: file://./path or file://../path
53237
+ // URL parser puts . or .. in hostname, reconstruct the relative path
53238
+ pathname = `${uri.hostname}${pathname}`;
53239
+ isRelativePath = true;
53240
+ }
53234
53241
  else if (uri.hostname && uri.hostname !== 'localhost') {
53235
53242
  // UNC path (file://server/share/path)
53236
53243
  pathname = `//${uri.hostname}${pathname}`;
@@ -53250,37 +53257,19 @@ class ConnectionString {
53250
53257
  suggestion: 'Use file:///absolute/path or file://./relative/path'
53251
53258
  });
53252
53259
  }
53253
- // Parse path segments: /basePath/bucket/keyPrefix
53254
- const segments = decodedPath.split('/').filter(Boolean);
53255
- if (segments.length === 0) {
53256
- throw new ConnectionStringError('file:// connection string requires a path', {
53257
- input: uri.href,
53258
- suggestion: 'Use file:///absolute/path or file://./relative/path'
53259
- });
53260
- }
53261
- // For relative paths starting with ./ or ../
53262
- if (decodedPath.startsWith('./') || decodedPath.startsWith('../')) {
53260
+ // For relative paths (detected from hostname or starting with ./ or ../)
53261
+ if (isRelativePath || decodedPath.startsWith('./') || decodedPath.startsWith('../')) {
53263
53262
  this.basePath = path.resolve(decodedPath);
53264
53263
  this.bucket = 's3db';
53265
53264
  this.keyPrefix = '';
53266
53265
  }
53267
- else if (segments.length === 1) {
53268
- this.basePath = path.resolve('/', segments[0]);
53266
+ else {
53267
+ // Absolute path: use the entire path as basePath
53268
+ // This is the intuitive behavior - file:///path/to/data means "use /path/to/data"
53269
+ this.basePath = path.resolve(decodedPath);
53269
53270
  this.bucket = 's3db';
53270
53271
  this.keyPrefix = '';
53271
53272
  }
53272
- else if (segments.length === 2) {
53273
- const [baseSegment, bucketSegment] = segments;
53274
- this.basePath = path.resolve('/', baseSegment);
53275
- this.bucket = bucketSegment;
53276
- this.keyPrefix = '';
53277
- }
53278
- else {
53279
- const [baseSegment, bucketSegment, ...prefixSegments] = segments;
53280
- this.basePath = path.resolve('/', baseSegment);
53281
- this.bucket = bucketSegment;
53282
- this.keyPrefix = prefixSegments.join('/');
53283
- }
53284
53273
  // Set synthetic endpoint for compatibility
53285
53274
  this.endpoint = `file://${this.basePath}`;
53286
53275
  this.region = 'local';
@@ -65064,14 +65053,6 @@ class Schema {
65064
65053
  }
65065
65054
  return cloned;
65066
65055
  }
65067
- async validate(resourceItem, { mutateOriginal = false } = {}) {
65068
- if (process.env.NODE_ENV === 'development') {
65069
- console.warn('[DEPRECATION] Schema.validate() is deprecated. Use ResourceValidator.validate() instead.');
65070
- }
65071
- const data = mutateOriginal ? resourceItem : cloneDeep(resourceItem);
65072
- const result = await this.validator(data);
65073
- return result;
65074
- }
65075
65056
  async mapper(resourceItem) {
65076
65057
  let obj = cloneDeep(resourceItem);
65077
65058
  obj = await this.applyHooksActions(obj, "beforeMap");
@@ -70648,8 +70629,8 @@ class Database extends SafeEventEmitter {
70648
70629
  })();
70649
70630
  this.version = '1';
70650
70631
  this.s3dbVersion = (() => {
70651
- const [ok, , version] = tryFnSync(() => (typeof globalThis['19.4.2'] !== 'undefined' && globalThis['19.4.2'] !== '19.4.2'
70652
- ? globalThis['19.4.2']
70632
+ const [ok, , version] = tryFnSync(() => (typeof globalThis['19.4.4-next.033a879c'] !== 'undefined' && globalThis['19.4.4-next.033a879c'] !== '19.4.4-next.033a879c'
70633
+ ? globalThis['19.4.4-next.033a879c']
70653
70634
  : 'latest'));
70654
70635
  return ok ? version : 'latest';
70655
70636
  })();
@@ -70673,7 +70654,7 @@ class Database extends SafeEventEmitter {
70673
70654
  });
70674
70655
  this.savedMetadata = null;
70675
70656
  this.databaseOptions = options;
70676
- const executorPoolConfig = options?.executorPool ?? options?.operationsPool;
70657
+ const executorPoolConfig = options?.executorPool;
70677
70658
  this._parallelism = this._normalizeParallelism(options?.parallelism ?? executorPoolConfig?.concurrency, 10);
70678
70659
  this.logLevel = options.logLevel || options.loggerOptions?.level || 'info';
70679
70660
  const loggerOptions = { ...(options.loggerOptions || {}) };
@@ -70694,11 +70675,6 @@ class Database extends SafeEventEmitter {
70694
70675
  });
70695
70676
  }
70696
70677
  this._childLoggerLevels = options.loggerOptions?.childLevels || {};
70697
- if (options?.operationsPool && !options?.executorPool) {
70698
- this.logger.warn('⚠️ "operationsPool" is deprecated in s3db.js v16.x. ' +
70699
- 'Use "executorPool" instead. ' +
70700
- 'Migration: https://s3db.js/docs/migration/v16-to-v17');
70701
- }
70702
70678
  this.executorPool = this._normalizeOperationsPool(executorPoolConfig, this._parallelism);
70703
70679
  if (options?.taskExecutorMonitoring) {
70704
70680
  this.executorPool.monitoring = this._deepMerge(this.executorPool.monitoring || {}, options.taskExecutorMonitoring);
@@ -70859,9 +70835,6 @@ class Database extends SafeEventEmitter {
70859
70835
  this.executorPool.concurrency = normalized;
70860
70836
  }
70861
70837
  }
70862
- get operationsPool() {
70863
- return this.executorPool;
70864
- }
70865
70838
  get config() {
70866
70839
  return {
70867
70840
  version: this.version,