@atscript/moost-db 0.1.128 → 0.1.130

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/dist/index.cjs CHANGED
@@ -37,6 +37,7 @@ function badRequest(path, message, top = message) {
37
37
  //#region src/validation-interceptor.ts
38
38
  const dbErrorCodeToStatus = {
39
39
  CONFLICT: 409,
40
+ CAS_MISMATCH: 409,
40
41
  TX_WAIT_TIMEOUT: 503
41
42
  };
42
43
  function transformValidationError(error, reply) {
@@ -1816,6 +1817,32 @@ let AsDbReadableController = class AsDbReadableController extends AsReadableCont
1816
1817
  const fragment = { $or: this._searchFallbackFields.map((f) => ({ [f]: { $regex: rx } })) };
1817
1818
  return filter && Object.keys(filter).length > 0 ? { $and: [filter, fragment] } : fragment;
1818
1819
  }
1820
+ /**
1821
+ * The controls a grouped query hands to the adapter. `$search` has two
1822
+ * implementations and exactly one layer may consume it:
1823
+ *
1824
+ * - **native text search** — the adapter applies the term before grouping, so
1825
+ * `$search` / `$index` ride through untouched.
1826
+ * - **no native search** — the term is this layer's to deal with, so the
1827
+ * controls are dropped before dispatch; leaving them would make the core
1828
+ * reject a query it has no way to run.
1829
+ *
1830
+ * Note the second case is deliberately broader than `applySearchFallback`:
1831
+ * that method only rewrites the term when `@db.column.searchable` fields
1832
+ * exist, whereas this drops the controls whenever the source is not natively
1833
+ * searchable. On a table with neither, the term is ignored — which is exactly
1834
+ * what the LEAF path already does for the same table (`_resolveReadStrategy`
1835
+ * falls through to `plain`). Rejecting here instead would make a grouped
1836
+ * query 400 where the leaf list happily returns rows: a new divergence, in
1837
+ * the same shape as the one this whole path exists to remove.
1838
+ */
1839
+ _aggregateControls(controls) {
1840
+ if (controls.$search === void 0 || this.readable.isSearchable()) return controls;
1841
+ const rest = { ...controls };
1842
+ delete rest.$search;
1843
+ delete rest.$index;
1844
+ return rest;
1845
+ }
1819
1846
  async _resolveReadStrategy(controls) {
1820
1847
  const searchTerm = controls.$search;
1821
1848
  const indexName = controls.$index;
@@ -1881,6 +1908,7 @@ let AsDbReadableController = class AsDbReadableController extends AsReadableCont
1881
1908
  this._coerceActionsControl(controls);
1882
1909
  const groupBy = controls.$groupBy;
1883
1910
  if (groupBy?.length && controls.$with?.length) return new _moostjs_event_http.HttpError(400, "Cannot combine $with and $groupBy in the same query");
1911
+ if (groupBy?.length && controls.$vector !== void 0) return new _moostjs_event_http.HttpError(400, "Cannot combine $vector and $groupBy in the same query");
1884
1912
  const error = this.validateParsed(parsed, "query");
1885
1913
  if (error) return error;
1886
1914
  if (groupBy?.length) {
@@ -1893,7 +1921,7 @@ let AsDbReadableController = class AsDbReadableController extends AsReadableCont
1893
1921
  const filter = this.applySearchFallback(await this.transformFilter(parsed.filter), controls);
1894
1922
  return this.readable.aggregate({
1895
1923
  filter,
1896
- controls,
1924
+ controls: this._aggregateControls(controls),
1897
1925
  insights: parsed.insights
1898
1926
  });
1899
1927
  }
package/dist/index.d.cts CHANGED
@@ -393,6 +393,26 @@ declare class AsDbReadableController<T extends TAtscriptAnnotatedType = TAtscrip
393
393
  * (native wins) and the request isn't a vector search (`$vector` consumes the term).
394
394
  */
395
395
  protected applySearchFallback(filter: FilterExpr | undefined, controls: Record<string, unknown>): FilterExpr | undefined;
396
+ /**
397
+ * The controls a grouped query hands to the adapter. `$search` has two
398
+ * implementations and exactly one layer may consume it:
399
+ *
400
+ * - **native text search** — the adapter applies the term before grouping, so
401
+ * `$search` / `$index` ride through untouched.
402
+ * - **no native search** — the term is this layer's to deal with, so the
403
+ * controls are dropped before dispatch; leaving them would make the core
404
+ * reject a query it has no way to run.
405
+ *
406
+ * Note the second case is deliberately broader than `applySearchFallback`:
407
+ * that method only rewrites the term when `@db.column.searchable` fields
408
+ * exist, whereas this drops the controls whenever the source is not natively
409
+ * searchable. On a table with neither, the term is ignored — which is exactly
410
+ * what the LEAF path already does for the same table (`_resolveReadStrategy`
411
+ * falls through to `plain`). Rejecting here instead would make a grouped
412
+ * query 400 where the leaf list happily returns rows: a new divergence, in
413
+ * the same shape as the one this whole path exists to remove.
414
+ */
415
+ private _aggregateControls;
396
416
  private _resolveReadStrategy;
397
417
  /**
398
418
  * Shared `query` / `pages` pipeline: prepare actions augmentation + read
package/dist/index.d.mts CHANGED
@@ -393,6 +393,26 @@ declare class AsDbReadableController<T extends TAtscriptAnnotatedType = TAtscrip
393
393
  * (native wins) and the request isn't a vector search (`$vector` consumes the term).
394
394
  */
395
395
  protected applySearchFallback(filter: FilterExpr | undefined, controls: Record<string, unknown>): FilterExpr | undefined;
396
+ /**
397
+ * The controls a grouped query hands to the adapter. `$search` has two
398
+ * implementations and exactly one layer may consume it:
399
+ *
400
+ * - **native text search** — the adapter applies the term before grouping, so
401
+ * `$search` / `$index` ride through untouched.
402
+ * - **no native search** — the term is this layer's to deal with, so the
403
+ * controls are dropped before dispatch; leaving them would make the core
404
+ * reject a query it has no way to run.
405
+ *
406
+ * Note the second case is deliberately broader than `applySearchFallback`:
407
+ * that method only rewrites the term when `@db.column.searchable` fields
408
+ * exist, whereas this drops the controls whenever the source is not natively
409
+ * searchable. On a table with neither, the term is ignored — which is exactly
410
+ * what the LEAF path already does for the same table (`_resolveReadStrategy`
411
+ * falls through to `plain`). Rejecting here instead would make a grouped
412
+ * query 400 where the leaf list happily returns rows: a new divergence, in
413
+ * the same shape as the one this whole path exists to remove.
414
+ */
415
+ private _aggregateControls;
396
416
  private _resolveReadStrategy;
397
417
  /**
398
418
  * Shared `query` / `pages` pipeline: prepare actions augmentation + read
package/dist/index.mjs CHANGED
@@ -36,6 +36,7 @@ function badRequest(path, message, top = message) {
36
36
  //#region src/validation-interceptor.ts
37
37
  const dbErrorCodeToStatus = {
38
38
  CONFLICT: 409,
39
+ CAS_MISMATCH: 409,
39
40
  TX_WAIT_TIMEOUT: 503
40
41
  };
41
42
  function transformValidationError(error, reply) {
@@ -1815,6 +1816,32 @@ let AsDbReadableController = class AsDbReadableController extends AsReadableCont
1815
1816
  const fragment = { $or: this._searchFallbackFields.map((f) => ({ [f]: { $regex: rx } })) };
1816
1817
  return filter && Object.keys(filter).length > 0 ? { $and: [filter, fragment] } : fragment;
1817
1818
  }
1819
+ /**
1820
+ * The controls a grouped query hands to the adapter. `$search` has two
1821
+ * implementations and exactly one layer may consume it:
1822
+ *
1823
+ * - **native text search** — the adapter applies the term before grouping, so
1824
+ * `$search` / `$index` ride through untouched.
1825
+ * - **no native search** — the term is this layer's to deal with, so the
1826
+ * controls are dropped before dispatch; leaving them would make the core
1827
+ * reject a query it has no way to run.
1828
+ *
1829
+ * Note the second case is deliberately broader than `applySearchFallback`:
1830
+ * that method only rewrites the term when `@db.column.searchable` fields
1831
+ * exist, whereas this drops the controls whenever the source is not natively
1832
+ * searchable. On a table with neither, the term is ignored — which is exactly
1833
+ * what the LEAF path already does for the same table (`_resolveReadStrategy`
1834
+ * falls through to `plain`). Rejecting here instead would make a grouped
1835
+ * query 400 where the leaf list happily returns rows: a new divergence, in
1836
+ * the same shape as the one this whole path exists to remove.
1837
+ */
1838
+ _aggregateControls(controls) {
1839
+ if (controls.$search === void 0 || this.readable.isSearchable()) return controls;
1840
+ const rest = { ...controls };
1841
+ delete rest.$search;
1842
+ delete rest.$index;
1843
+ return rest;
1844
+ }
1818
1845
  async _resolveReadStrategy(controls) {
1819
1846
  const searchTerm = controls.$search;
1820
1847
  const indexName = controls.$index;
@@ -1880,6 +1907,7 @@ let AsDbReadableController = class AsDbReadableController extends AsReadableCont
1880
1907
  this._coerceActionsControl(controls);
1881
1908
  const groupBy = controls.$groupBy;
1882
1909
  if (groupBy?.length && controls.$with?.length) return new HttpError(400, "Cannot combine $with and $groupBy in the same query");
1910
+ if (groupBy?.length && controls.$vector !== void 0) return new HttpError(400, "Cannot combine $vector and $groupBy in the same query");
1883
1911
  const error = this.validateParsed(parsed, "query");
1884
1912
  if (error) return error;
1885
1913
  if (groupBy?.length) {
@@ -1892,7 +1920,7 @@ let AsDbReadableController = class AsDbReadableController extends AsReadableCont
1892
1920
  const filter = this.applySearchFallback(await this.transformFilter(parsed.filter), controls);
1893
1921
  return this.readable.aggregate({
1894
1922
  filter,
1895
- controls,
1923
+ controls: this._aggregateControls(controls),
1896
1924
  insights: parsed.insights
1897
1925
  });
1898
1926
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/moost-db",
3
- "version": "0.1.128",
3
+ "version": "0.1.130",
4
4
  "description": "Generic database controller for Moost with Atscript.",
5
5
  "keywords": [
6
6
  "annotations",
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@uniqu/url": "^0.1.8",
47
- "@atscript/db-memory": "^0.1.128"
47
+ "@atscript/db-memory": "^0.1.130"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@atscript/core": "^0.1.92",
@@ -64,7 +64,7 @@
64
64
  "@wooksjs/event-core": "^0.7.23",
65
65
  "@wooksjs/http-body": "^0.7.23",
66
66
  "moost": "^0.6.37",
67
- "@atscript/db": "^0.1.128"
67
+ "@atscript/db": "^0.1.130"
68
68
  },
69
69
  "scripts": {
70
70
  "postinstall": "asc -f dts",