@adonis-agora/filter 1.0.0-rc.0 → 1.0.0-rc.1

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 (33) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/commands/make_filter_client.d.ts.map +1 -1
  3. package/dist/commands/make_filter_client.js +10 -14
  4. package/dist/commands/make_filter_client.js.map +1 -1
  5. package/dist/providers/filter_provider.d.ts +4 -0
  6. package/dist/providers/filter_provider.d.ts.map +1 -1
  7. package/dist/providers/filter_provider.js +28 -0
  8. package/dist/providers/filter_provider.js.map +1 -1
  9. package/dist/src/dev_tools/contract.d.ts +61 -0
  10. package/dist/src/dev_tools/contract.d.ts.map +1 -0
  11. package/dist/src/dev_tools/contract.js +12 -0
  12. package/dist/src/dev_tools/contract.js.map +1 -0
  13. package/dist/src/dev_tools/explain.d.ts +88 -0
  14. package/dist/src/dev_tools/explain.d.ts.map +1 -0
  15. package/dist/src/dev_tools/explain.js +168 -0
  16. package/dist/src/dev_tools/explain.js.map +1 -0
  17. package/dist/src/dev_tools/query_string.d.ts +8 -0
  18. package/dist/src/dev_tools/query_string.d.ts.map +1 -0
  19. package/dist/src/dev_tools/query_string.js +102 -0
  20. package/dist/src/dev_tools/query_string.js.map +1 -0
  21. package/dist/src/dev_tools/tools.d.ts +25 -0
  22. package/dist/src/dev_tools/tools.d.ts.map +1 -0
  23. package/dist/src/dev_tools/tools.js +147 -0
  24. package/dist/src/dev_tools/tools.js.map +1 -0
  25. package/dist/src/index.d.ts +4 -1
  26. package/dist/src/index.d.ts.map +1 -1
  27. package/dist/src/index.js +4 -1
  28. package/dist/src/index.js.map +1 -1
  29. package/dist/src/manifest.d.ts +33 -0
  30. package/dist/src/manifest.d.ts.map +1 -0
  31. package/dist/src/manifest.js +50 -0
  32. package/dist/src/manifest.js.map +1 -0
  33. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @adonis-agora/filter
2
2
 
3
+ ## 1.0.0-rc.1
4
+
5
+ ### Minor Changes
6
+
7
+ - [#145](https://github.com/DavideCarvalho/adonis-agora-filter/pull/145) [`7548c56`](https://github.com/DavideCarvalho/adonis-agora-filter/commit/7548c56e9ac622723ebcdca9a9253ef3068fdc2b) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Dev MCP tools on `@adonis-agora/agent`'s `/mcp/agora` endpoint (gated by its `devTools.authorize`): `filter_list_specs`, `filter_get_spec`, `filter_explain_query` (dry run of a query string against a spec, no database). New exports `explainFilterQuery`, `parseQueryString` and `loadFilterManifest`; `make:filter-client` now also reads a default `{ filters }` export or `filters` in the `filter` config.
8
+
3
9
  ## 1.0.0-rc.0
4
10
 
5
11
  ### Major Changes
@@ -1 +1 @@
1
- {"version":3,"file":"make_filter_client.d.ts","sourceRoot":"","sources":["../../commands/make_filter_client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAQ,WAAW,EAAS,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI/D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,WAAW;;IACvD,OAAgB,WAAW,SAAwB;IACnD,OAAgB,WAAW,SAC4C;IACvE,OAAgB,OAAO,EAAE,cAAc,CAAsB;IAOrD,UAAU,EAAE,MAAM,CAAC;IAMnB,MAAM,EAAE,MAAM,CAAC;IAER,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAelC;CAuBF"}
1
+ {"version":3,"file":"make_filter_client.d.ts","sourceRoot":"","sources":["../../commands/make_filter_client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAQ,WAAW,EAAS,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAK/D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,WAAW;;IACvD,OAAgB,WAAW,SAAwB;IACnD,OAAgB,WAAW,SAC4C;IACvE,OAAgB,OAAO,EAAE,cAAc,CAAsB;IAOrD,UAAU,EAAE,MAAM,CAAC;IAMnB,MAAM,EAAE,MAAM,CAAC;IAER,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAelC;CAiBF"}
@@ -8,6 +8,7 @@ import { mkdir, writeFile } from 'node:fs/promises';
8
8
  import { isAbsolute, join } from 'node:path';
9
9
  import { args, BaseCommand, flags } from '@adonisjs/core/ace';
10
10
  import { generateFilterClients } from '../src/generate_client.js';
11
+ import { loadFilterManifest } from '../src/manifest.js';
11
12
  /**
12
13
  * `node ace make:filter-client [entrypoint]` — the idiomatic AdonisJS equivalent
13
14
  * of the NestJS `nestjs-filter` codegen bin.
@@ -49,24 +50,19 @@ export default class MakeFilterClient extends BaseCommand {
49
50
  }
50
51
  this.logger.success(`Generated ${generated.length} filter client(s) into ${this.output}.`);
51
52
  }
52
- /** Import the entrypoint module and read its `filters` manifest (named or default export). */
53
+ /** Load the `filters` manifest with the loader the doctor and the dev tools share. */
53
54
  async #loadManifest() {
54
- const url = this.app.makeURL(this.entrypoint).href;
55
- let mod;
56
- try {
57
- mod = (await import(url));
58
- }
59
- catch (error) {
60
- this.logger.error(`Could not import filter manifest "${this.entrypoint}": ${String(error)}`);
55
+ const load = await loadFilterManifest(this.app, this.entrypoint);
56
+ if (load.status === 'loaded')
57
+ return load.manifest;
58
+ if (load.status === 'failed' || load.status === 'missing') {
59
+ const reason = load.status === 'failed' ? load.error : 'the module was not found';
60
+ this.logger.error(`Could not import filter manifest "${this.entrypoint}": ${reason}`);
61
61
  this.exitCode = 1;
62
62
  return undefined;
63
63
  }
64
- const manifest = (mod.filters ?? mod.default);
65
- if (!manifest || Object.keys(manifest).length === 0) {
66
- this.logger.warning(`No \`filters\` manifest exported from "${this.entrypoint}" — nothing to generate.`);
67
- return undefined;
68
- }
69
- return manifest;
64
+ this.logger.warning(`No \`filters\` manifest exported from "${this.entrypoint}" — nothing to generate.`);
65
+ return undefined;
70
66
  }
71
67
  }
72
68
  __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"make_filter_client.js","sourceRoot":"","sources":["../../commands/make_filter_client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"make_filter_client.js","sourceRoot":"","sources":["../../commands/make_filter_client.ts"],"names":[],"mappings":"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"}
@@ -15,12 +15,16 @@ import type { ApplicationService } from '@adonisjs/core/types';
15
15
  * const page = await User.query().filterPaginate(userFilter, ctx)
16
16
  * ```
17
17
  *
18
+ * It also registers the filter developer tools on `@adonis-agora/agent`'s dev MCP endpoint when
19
+ * that is installed.
20
+ *
18
21
  * Register it in `adonisrc.ts` (`providers`). The free functions
19
22
  * (`applyFilterFromRequest`, `applyCursorFromRequest`) work without it — this
20
23
  * provider only adds the chainable sugar, so `@adonisjs/lucid` is loaded lazily
21
24
  * here (not a hard dependency of the package).
22
25
  */
23
26
  export default class FilterProvider {
27
+ #private;
24
28
  protected app: ApplicationService;
25
29
  constructor(app: ApplicationService);
26
30
  boot(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"filter_provider.d.ts","sourceRoot":"","sources":["../../providers/filter_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;IACrB,SAAS,CAAC,GAAG,EAAE,kBAAkB;IAA7C,YAAsB,GAAG,EAAE,kBAAkB,EAAI;IAE3C,IAAI,kBAGT;CACF"}
1
+ {"version":3,"file":"filter_provider.d.ts","sourceRoot":"","sources":["../../providers/filter_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAK/D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;;IACrB,SAAS,CAAC,GAAG,EAAE,kBAAkB;IAA7C,YAAsB,GAAG,EAAE,kBAAkB,EAAI;IAE3C,IAAI,kBAIT;CA2BF"}
@@ -1,4 +1,6 @@
1
+ import { registerFilterDevTools } from '../src/dev_tools/tools.js';
1
2
  import { registerFilterMacros } from '../src/lucid_macros.js';
3
+ import { loadFilterManifest } from '../src/manifest.js';
2
4
  /**
3
5
  * Wires `@adonis-agora/filter`'s chainable Lucid macros into the application.
4
6
  *
@@ -15,6 +17,9 @@ import { registerFilterMacros } from '../src/lucid_macros.js';
15
17
  * const page = await User.query().filterPaginate(userFilter, ctx)
16
18
  * ```
17
19
  *
20
+ * It also registers the filter developer tools on `@adonis-agora/agent`'s dev MCP endpoint when
21
+ * that is installed.
22
+ *
18
23
  * Register it in `adonisrc.ts` (`providers`). The free functions
19
24
  * (`applyFilterFromRequest`, `applyCursorFromRequest`) work without it — this
20
25
  * provider only adds the chainable sugar, so `@adonisjs/lucid` is loaded lazily
@@ -28,6 +33,29 @@ export default class FilterProvider {
28
33
  async boot() {
29
34
  const { ModelQueryBuilder } = await import('@adonisjs/lucid/orm');
30
35
  registerFilterMacros(ModelQueryBuilder);
36
+ await this.#registerDevTools();
37
+ }
38
+ /**
39
+ * Registers the filter developer tools on `@adonis-agora/agent`'s dev MCP endpoint
40
+ * (`/mcp/agora`) when it is installed. They read the `filters` manifest of config/filter.ts at
41
+ * call time.
42
+ */
43
+ async #registerDevTools() {
44
+ const container = this.app.container;
45
+ if (typeof container.hasBinding !== 'function')
46
+ return;
47
+ if (this.app.config.get('filter', {})?.devTools === false) {
48
+ return;
49
+ }
50
+ const outcome = await registerFilterDevTools(this.app.container, {
51
+ manifest: () => loadFilterManifest(this.app),
52
+ });
53
+ if (outcome === 'unsupported' || outcome === 'failed') {
54
+ const logger = (await this.app.container.make('logger').catch(() => undefined));
55
+ logger?.debug(outcome === 'unsupported'
56
+ ? '[@adonis-agora/filter] dev tools not registered: the installed @adonis-agora/agent cannot gate libs without a console (needs devTools.authorize support)'
57
+ : '[@adonis-agora/filter] dev tools could not be registered');
58
+ }
31
59
  }
32
60
  }
33
61
  //# sourceMappingURL=filter_provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter_provider.js","sourceRoot":"","sources":["../../providers/filter_provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;IACX,GAAG;IAAzB,YAAsB,GAAuB;mBAAvB,GAAG;IAAuB,CAAC;IAEjD,KAAK,CAAC,IAAI;QACR,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAClE,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAC1C,CAAC;CACF"}
1
+ {"version":3,"file":"filter_provider.js","sourceRoot":"","sources":["../../providers/filter_provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;IACX,GAAG;IAAzB,YAAsB,GAAuB;mBAAvB,GAAG;IAAuB,CAAC;IAEjD,KAAK,CAAC,IAAI;QACR,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAClE,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;QACxC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,iBAAiB;QACrB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAA0D,CAAC;QACtF,IAAI,OAAO,SAAS,CAAC,UAAU,KAAK,UAAU;YAAE,OAAO;QACvD,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAqC,QAAQ,EAAE,EAAE,CAAC,EAAE,QAAQ,KAAK,KAAK,EAAE,CAAC;YAC9F,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,SAAkB,EAAE;YACxE,QAAQ,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC;SAC7C,CAAC,CAAC;QACH,IAAI,OAAO,KAAK,aAAa,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;YACtD,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAEjE,CAAC;YACd,MAAM,EAAE,KAAK,CACX,OAAO,KAAK,aAAa;gBACvB,CAAC,CAAC,0JAA0J;gBAC5J,CAAC,CAAC,0DAA0D,CAC/D,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * A local, structural copy of the dev-tools registration contract (version 1) served by
3
+ * `@adonis-agora/agent`'s MCP provider at `/mcp/agora`. filter never imports the agent: it
4
+ * registers into the `'agora.devTools'` container binding when it exists.
5
+ *
6
+ * filter has no console, so it registers WITHOUT its own `authorize`: the endpoint-level
7
+ * `devTools.authorize` (config/mcp.ts) gates its tools. That needs a hub that says
8
+ * `supports('endpoint-authorize')`.
9
+ */
10
+ /** The container binding the hub lives at. */
11
+ export declare const DEV_TOOLS_BINDING = "agora.devTools";
12
+ export interface DevToolsHub {
13
+ readonly version: 1;
14
+ register(lib: DevToolsLib): void;
15
+ /** Optional capability probe. filter needs `'endpoint-authorize'`. */
16
+ supports?(capability: string): boolean;
17
+ }
18
+ export interface DevToolsLib {
19
+ lib: string;
20
+ title: string;
21
+ /** Omitted: the endpoint's `devTools.authorize` decides. */
22
+ authorize?: (ctx: unknown) => Promise<unknown>;
23
+ tools: DevTool[];
24
+ }
25
+ export interface DevToolInputProperty {
26
+ type: 'string' | 'number' | 'integer' | 'boolean' | 'array';
27
+ description?: string;
28
+ enum?: readonly string[];
29
+ items?: {
30
+ type: 'string';
31
+ };
32
+ minimum?: number;
33
+ maximum?: number;
34
+ }
35
+ export interface DevToolInputSchema {
36
+ type: 'object';
37
+ properties: Record<string, DevToolInputProperty>;
38
+ required?: string[];
39
+ }
40
+ export interface DevToolsCaller {
41
+ id: string;
42
+ via: 'token' | 'session' | 'open';
43
+ }
44
+ export interface DevToolCall {
45
+ ctx: unknown;
46
+ caller: DevToolsCaller;
47
+ limits: {
48
+ maxRows: number;
49
+ maxBytes: number;
50
+ };
51
+ }
52
+ export interface DevTool {
53
+ name: string;
54
+ kind: 'read' | 'action';
55
+ description: string;
56
+ input: DevToolInputSchema;
57
+ destructive?: boolean;
58
+ available?(): boolean | Promise<boolean>;
59
+ run(input: Record<string, unknown>, call: DevToolCall): Promise<unknown>;
60
+ }
61
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../src/dev_tools/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,8CAA8C;AAC9C,eAAO,MAAM,iBAAiB,mBAAmB,CAAC;AAElD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,sEAAsE;IACtE,QAAQ,CAAC,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;CACxC;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACjD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1E"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * A local, structural copy of the dev-tools registration contract (version 1) served by
3
+ * `@adonis-agora/agent`'s MCP provider at `/mcp/agora`. filter never imports the agent: it
4
+ * registers into the `'agora.devTools'` container binding when it exists.
5
+ *
6
+ * filter has no console, so it registers WITHOUT its own `authorize`: the endpoint-level
7
+ * `devTools.authorize` (config/mcp.ts) gates its tools. That needs a hub that says
8
+ * `supports('endpoint-authorize')`.
9
+ */
10
+ /** The container binding the hub lives at. */
11
+ export const DEV_TOOLS_BINDING = 'agora.devTools';
12
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../../src/dev_tools/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,8CAA8C;AAC9C,MAAM,CAAC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC"}
@@ -0,0 +1,88 @@
1
+ import type { FilterSpec } from '../filter_spec.js';
2
+ import type { QueryBuilderLike } from '../lucid_adapter.js';
3
+ import type { FilterInput } from '../types.js';
4
+ /** One query-builder call a dry run recorded. */
5
+ export interface RecordedCall {
6
+ method: string;
7
+ args: unknown[];
8
+ }
9
+ /** What a request part (one filter, one sort…) does under the spec. */
10
+ export interface ExplainIssue {
11
+ part: 'filter' | 'sort' | 'distinct' | 'search' | 'size';
12
+ /** The field (or the raw value) the issue is about. */
13
+ subject: string;
14
+ message: string;
15
+ /** `rejected`: the request fails; `dropped`: silently ignored; `clamped`/`ignored`: adjusted. */
16
+ effect: 'rejected' | 'dropped' | 'clamped' | 'ignored';
17
+ }
18
+ /** The result of {@link explainFilterQuery}. */
19
+ export interface FilterQueryExplanation {
20
+ /** What the query string decodes to (`ctx.request.qs()`). */
21
+ decoded: Record<string, unknown>;
22
+ /** The filters, sorts, search and pagination the server reads from it. */
23
+ parsed: FilterInput;
24
+ /** `true` when the request would be refused (a 4xx from `InvalidColumnFilterError`). */
25
+ rejected: boolean;
26
+ rejection: string | null;
27
+ issues: ExplainIssue[];
28
+ /** The query-builder calls the request filters, search and sort produce (no tenant scope). */
29
+ calls: RecordedCall[];
30
+ pagination: {
31
+ page: number;
32
+ size: number;
33
+ } | null;
34
+ /** What the server adds on its own, outside the client's control. */
35
+ serverScope: {
36
+ tenantColumn: string | null;
37
+ defaultFilters: unknown[];
38
+ };
39
+ }
40
+ /**
41
+ * A query builder that records every call instead of running SQL: the dry-run target. Callback
42
+ * arguments (sub-queries, `whereHas`) are run against a nested recorder and kept as `calls`.
43
+ */
44
+ export declare function recordingBuilder(calls?: RecordedCall[]): {
45
+ qb: QueryBuilderLike;
46
+ calls: RecordedCall[];
47
+ };
48
+ /**
49
+ * Dry-run a query string against a spec, through the same parse, alias, validation, allow-list
50
+ * and builder code a request runs, with no database: what is kept, what is dropped or refused, and
51
+ * the builder calls it would make.
52
+ */
53
+ export declare function explainFilterQuery(spec: FilterSpec, query: string): FilterQueryExplanation;
54
+ /** The spec as data: allow-lists with field types and operators, relations and defaults. */
55
+ export declare function describeSpec(spec: FilterSpec, name: string): {
56
+ name: string;
57
+ filterable: import("../filter_spec.js").RelationColumns;
58
+ sortable: import("../filter_spec.js").RelationColumns;
59
+ /** Every filterable path, relation-dotted (`'*'` lists contribute none). */
60
+ filterablePaths: string[];
61
+ sortablePaths: string[];
62
+ operators: import("../operators.js").FilterOperator[];
63
+ operatorAliases: {
64
+ [x: string]: import("../operators.js").FilterOperator;
65
+ };
66
+ searchable: string[];
67
+ fullText: {
68
+ column: string | readonly string[];
69
+ } | null;
70
+ fieldTypes: Readonly<Record<string, import("../generate_client.js").FilterFieldTypeInfo>>;
71
+ relations: Record<string, {
72
+ filterable: unknown;
73
+ sortable: unknown;
74
+ relations: unknown;
75
+ }>;
76
+ maxDepth: number;
77
+ aliases: import("../field_aliases.js").FieldAliases;
78
+ computed: {
79
+ [k: string]: string;
80
+ };
81
+ tenantColumn: string | null;
82
+ defaultFilters: unknown[];
83
+ defaultSort: import("../types.js").SortItem[];
84
+ defaultSize: number | null;
85
+ maxSize: number | null;
86
+ throwOnInvalid: boolean;
87
+ };
88
+ //# sourceMappingURL=explain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../../src/dev_tools/explain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAI5D,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,aAAa,CAAC;AAG7D,iDAAiD;AACjD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB;AAED,uEAAuE;AACvE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC;IACzD,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,iGAAiG;IACjG,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;CACxD;AAED,gDAAgD;AAChD,MAAM,WAAW,sBAAsB;IACrC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,0EAA0E;IAC1E,MAAM,EAAE,WAAW,CAAC;IACpB,wFAAwF;IACxF,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,8FAA8F;IAC9F,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAClD,qEAAqE;IACrE,WAAW,EAAE;QAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,cAAc,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;CACzE;AAgBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,GAAE,YAAY,EAAO,GAAG;IAC5D,EAAE,EAAE,gBAAgB,CAAC;IACrB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB,CAiBA;AAWD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,sBAAsB,CAkE1F;AAED,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM;;;;IAKvD,4EAA4E;;;;;;;;;;;;;oBA8BhD,OAAO;kBAAY,OAAO;mBAAa,OAAO;;;;;;;;;;;;;EAJ7E"}
@@ -0,0 +1,168 @@
1
+ import { specToFilterConfig } from '../filter_spec.js';
2
+ import { filterableFieldPaths, sortableFieldPaths } from '../generate_client.js';
3
+ import { FILTER_OPERATORS, OPERATOR_ALIASES } from '../operators.js';
4
+ import { parseFilterRequest } from '../parse_request.js';
5
+ import { applyFilter } from '../runner.js';
6
+ import { parseQueryString } from './query_string.js';
7
+ const MAX_VALUE = 200;
8
+ function show(value) {
9
+ if (typeof value === 'string')
10
+ return value.length > MAX_VALUE ? `${value.slice(0, MAX_VALUE)}…` : value;
11
+ if (Array.isArray(value))
12
+ return value.slice(0, 50).map(show);
13
+ if (value !== null && typeof value === 'object') {
14
+ const out = {};
15
+ for (const [k, v] of Object.entries(value).slice(0, 50))
16
+ out[k] = show(v);
17
+ return out;
18
+ }
19
+ return value;
20
+ }
21
+ /**
22
+ * A query builder that records every call instead of running SQL: the dry-run target. Callback
23
+ * arguments (sub-queries, `whereHas`) are run against a nested recorder and kept as `calls`.
24
+ */
25
+ export function recordingBuilder(calls = []) {
26
+ const qb = new Proxy({}, {
27
+ get(_target, prop) {
28
+ if (typeof prop !== 'string' || prop === 'then')
29
+ return undefined;
30
+ return (...args) => {
31
+ const recorded = args.map((arg) => {
32
+ if (typeof arg !== 'function')
33
+ return show(arg);
34
+ const nested = recordingBuilder();
35
+ arg(nested.qb);
36
+ return { callback: nested.calls };
37
+ });
38
+ calls.push({ method: prop, args: recorded });
39
+ return qb;
40
+ };
41
+ },
42
+ });
43
+ return { qb, calls };
44
+ }
45
+ function attempt(input, config) {
46
+ try {
47
+ applyFilter(recordingBuilder().qb, input, config);
48
+ return null;
49
+ }
50
+ catch (error) {
51
+ return error instanceof Error ? error.message : String(error);
52
+ }
53
+ }
54
+ /**
55
+ * Dry-run a query string against a spec, through the same parse, alias, validation, allow-list
56
+ * and builder code a request runs, with no database: what is kept, what is dropped or refused, and
57
+ * the builder calls it would make.
58
+ */
59
+ export function explainFilterQuery(spec, query) {
60
+ const decoded = parseQueryString(query);
61
+ const parsed = parseFilterRequest(decoded);
62
+ const config = specToFilterConfig(spec);
63
+ const strict = { ...config, throwOnInvalid: true };
64
+ const input = (!parsed.sort || parsed.sort.length === 0) && spec.defaultSort.length > 0
65
+ ? { ...parsed, sort: [...spec.defaultSort] }
66
+ : parsed;
67
+ const issues = [];
68
+ const check = (part, subject, single) => {
69
+ const asConfigured = attempt(single, config);
70
+ if (asConfigured !== null) {
71
+ issues.push({ part, subject, message: asConfigured, effect: 'rejected' });
72
+ return;
73
+ }
74
+ const asStrict = attempt(single, strict);
75
+ if (asStrict !== null)
76
+ issues.push({ part, subject, message: asStrict, effect: 'dropped' });
77
+ };
78
+ for (const filter of parsed.filters ?? []) {
79
+ const subject = filter.field || (filter.AND ? 'AND group' : filter.OR ? 'OR group' : '?');
80
+ check('filter', subject, { filters: [filter] });
81
+ }
82
+ for (const sort of parsed.sort ?? [])
83
+ check('sort', sort.field, { sort: [sort] });
84
+ for (const field of parsed.distinct ?? [])
85
+ check('distinct', field, { distinct: [field] });
86
+ if (parsed.search !== undefined && !spec.fullText && spec.searchable.length === 0) {
87
+ issues.push({
88
+ part: 'search',
89
+ subject: parsed.search,
90
+ message: 'the spec declares no `searchable` fields or `fullText`, so `search` does nothing',
91
+ effect: 'ignored',
92
+ });
93
+ }
94
+ const maxSize = spec.maxSize ?? 100;
95
+ if (parsed.size !== undefined && (parsed.size > maxSize || parsed.size < 1)) {
96
+ issues.push({
97
+ part: 'size',
98
+ subject: String(parsed.size),
99
+ message: `size is clamped to 1..${maxSize}`,
100
+ effect: 'clamped',
101
+ });
102
+ }
103
+ const recorder = recordingBuilder();
104
+ let rejection = null;
105
+ let pagination = null;
106
+ try {
107
+ pagination = applyFilter(recorder.qb, input, config);
108
+ }
109
+ catch (error) {
110
+ rejection = error instanceof Error ? error.message : String(error);
111
+ }
112
+ return {
113
+ decoded,
114
+ parsed,
115
+ rejected: rejection !== null,
116
+ rejection,
117
+ issues,
118
+ calls: rejection === null ? recorder.calls : [],
119
+ pagination,
120
+ serverScope: {
121
+ tenantColumn: spec.tenant?.column ?? null,
122
+ defaultFilters: spec.defaultFilters.map(show),
123
+ },
124
+ };
125
+ }
126
+ /** The spec as data: allow-lists with field types and operators, relations and defaults. */
127
+ export function describeSpec(spec, name) {
128
+ return {
129
+ name,
130
+ filterable: spec.filterable,
131
+ sortable: spec.sortable,
132
+ /** Every filterable path, relation-dotted (`'*'` lists contribute none). */
133
+ filterablePaths: filterableFieldPaths(spec),
134
+ sortablePaths: sortableFieldPaths(spec),
135
+ operators: [...FILTER_OPERATORS],
136
+ operatorAliases: { ...OPERATOR_ALIASES },
137
+ searchable: [...spec.searchable],
138
+ fullText: spec.fullText ? { column: spec.fullText.column } : null,
139
+ fieldTypes: spec.fieldTypes ?? {},
140
+ relations: describeRelations(spec.relations),
141
+ maxDepth: spec.maxDepth,
142
+ aliases: spec.aliases ?? {},
143
+ computed: spec.computed
144
+ ? Object.fromEntries(Object.entries(spec.computed).map(([key, source]) => [
145
+ key,
146
+ typeof source === 'string' ? source : '(function)',
147
+ ]))
148
+ : {},
149
+ tenantColumn: spec.tenant?.column ?? null,
150
+ defaultFilters: spec.defaultFilters.map(show),
151
+ defaultSort: [...spec.defaultSort],
152
+ defaultSize: spec.defaultSize ?? null,
153
+ maxSize: spec.maxSize ?? null,
154
+ throwOnInvalid: spec.throwOnInvalid,
155
+ };
156
+ }
157
+ function describeRelations(relations) {
158
+ const out = {};
159
+ for (const [key, rel] of Object.entries(relations)) {
160
+ out[key] = {
161
+ filterable: rel.filterable,
162
+ sortable: rel.sortable ?? rel.filterable,
163
+ relations: rel.relations ? describeRelations(rel.relations) : {},
164
+ };
165
+ }
166
+ return out;
167
+ }
168
+ //# sourceMappingURL=explain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain.js","sourceRoot":"","sources":["../../../src/dev_tools/explain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * A small, safe decoder for a filter query string (`filter[name][contains]=Al&sort=-age&page=2`)
3
+ * into the nested object `ctx.request.qs()` returns: bracket keys become nested objects, numeric
4
+ * indexes and `[]` become arrays. Used by the dev tools, which receive the query as a string.
5
+ */
6
+ /** Decode `query` (with or without a leading `?`) into a nested object. */
7
+ export declare function parseQueryString(query: string): Record<string, unknown>;
8
+ //# sourceMappingURL=query_string.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query_string.d.ts","sourceRoot":"","sources":["../../../src/dev_tools/query_string.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiDH,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA+BvE"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * A small, safe decoder for a filter query string (`filter[name][contains]=Al&sort=-age&page=2`)
3
+ * into the nested object `ctx.request.qs()` returns: bracket keys become nested objects, numeric
4
+ * indexes and `[]` become arrays. Used by the dev tools, which receive the query as a string.
5
+ */
6
+ const BLOCKED = new Set(['__proto__', 'constructor', 'prototype']);
7
+ const MAX_PARAMS = 1000;
8
+ const MAX_DEPTH = 20;
9
+ function decode(part) {
10
+ try {
11
+ return decodeURIComponent(part.replace(/\+/g, ' '));
12
+ }
13
+ catch {
14
+ return part;
15
+ }
16
+ }
17
+ /** `filter[name][contains]` → `['filter', 'name', 'contains']`; `a[]` → `['a', '']`. */
18
+ function keyPath(key) {
19
+ const open = key.indexOf('[');
20
+ if (open === -1)
21
+ return [key];
22
+ const path = [key.slice(0, open)];
23
+ const re = /\[([^\]]*)\]/g;
24
+ re.lastIndex = open;
25
+ let end = open;
26
+ for (let match = re.exec(key); match !== null; match = re.exec(key)) {
27
+ if (match.index !== end)
28
+ break;
29
+ path.push(match[1]);
30
+ end = re.lastIndex;
31
+ if (path.length > MAX_DEPTH)
32
+ return null;
33
+ }
34
+ if (end !== key.length)
35
+ path.push(key.slice(end));
36
+ return path;
37
+ }
38
+ /** Objects whose keys are all array indexes become arrays (in index order). */
39
+ function compact(value) {
40
+ if (value === null || typeof value !== 'object')
41
+ return value;
42
+ const node = value;
43
+ for (const key of Object.keys(node))
44
+ node[key] = compact(node[key]);
45
+ const keys = Object.keys(node);
46
+ if (keys.length > 0 && keys.every((k) => /^\d+$/.test(k))) {
47
+ return keys
48
+ .map(Number)
49
+ .sort((a, b) => a - b)
50
+ .map((k) => node[String(k)]);
51
+ }
52
+ return node;
53
+ }
54
+ /** Decode `query` (with or without a leading `?`) into a nested object. */
55
+ export function parseQueryString(query) {
56
+ const root = {};
57
+ const text = query.startsWith('?') ? query.slice(1) : query;
58
+ const pairs = text.split('&').filter((p) => p !== '');
59
+ for (const pair of pairs.slice(0, MAX_PARAMS)) {
60
+ const eq = pair.indexOf('=');
61
+ const rawKey = decode(eq === -1 ? pair : pair.slice(0, eq));
62
+ const value = eq === -1 ? '' : decode(pair.slice(eq + 1));
63
+ const path = keyPath(rawKey);
64
+ if (path === null || path[0] === '' || path.some((seg) => BLOCKED.has(seg)))
65
+ continue;
66
+ let node = root;
67
+ for (let i = 0; i < path.length; i++) {
68
+ let seg = path[i];
69
+ const last = i === path.length - 1;
70
+ if (seg === '')
71
+ seg = String(Object.keys(node).length);
72
+ if (last) {
73
+ const existing = node[seg];
74
+ if (existing === undefined)
75
+ node[seg] = value;
76
+ else if (Array.isArray(existing))
77
+ existing.push(value);
78
+ else if (typeof existing === 'string')
79
+ node[seg] = [existing, value];
80
+ break;
81
+ }
82
+ const next = node[seg];
83
+ if (next === undefined || typeof next !== 'object' || next === null || Array.isArray(next)) {
84
+ node[seg] = Object.create(null);
85
+ }
86
+ node = node[seg];
87
+ }
88
+ }
89
+ return toPlain(compact(root));
90
+ }
91
+ /** Null-prototype nodes back to plain objects (so `toEqual` and spreading behave). */
92
+ function toPlain(value) {
93
+ if (Array.isArray(value))
94
+ return value.map(toPlain);
95
+ if (value === null || typeof value !== 'object')
96
+ return value;
97
+ const out = {};
98
+ for (const [key, inner] of Object.entries(value))
99
+ out[key] = toPlain(inner);
100
+ return out;
101
+ }
102
+ //# sourceMappingURL=query_string.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query_string.js","sourceRoot":"","sources":["../../../src/dev_tools/query_string.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { ManifestLoad } from '../manifest.js';
2
+ import type { DevTool } from './contract.js';
3
+ /** How the tools reach the app's `filters` manifest (resolved at call time). */
4
+ export interface FilterDevToolsDeps {
5
+ manifest: () => Promise<ManifestLoad>;
6
+ }
7
+ /** One page of `items` in the `{ items, next }` shape every dev-tools list returns. */
8
+ export declare function pageOf<T>(items: readonly T[], input: Record<string, unknown>): {
9
+ items: T[];
10
+ next: number | null;
11
+ };
12
+ /** The filter developer tools (all read-only, no database). */
13
+ export declare function filterDevTools(deps: FilterDevToolsDeps): DevTool[];
14
+ /** The slice of the AdonisJS container {@link registerFilterDevTools} uses. */
15
+ export interface DevToolsContainer {
16
+ hasBinding(binding: string): boolean;
17
+ make(binding: string): Promise<unknown>;
18
+ }
19
+ /**
20
+ * Register the filter tools into the dev-tools hub, when the agent's MCP provider bound one and it
21
+ * can gate a lib without a console (`supports('endpoint-authorize')`). Never throws: returns why it
22
+ * did not register.
23
+ */
24
+ export declare function registerFilterDevTools(container: DevToolsContainer, deps: FilterDevToolsDeps): Promise<'registered' | 'no-hub' | 'unsupported' | 'failed'>;
25
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/dev_tools/tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAqC,MAAM,eAAe,CAAC;AAIhF,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;CACvC;AAwBD,uFAAuF;AACvF,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAKzE,KAAK;IACL,IAAI;EAEP;AA6BD,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,EAAE,CAkElE;AAED,+EAA+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACrC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACzC;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,iBAAiB,EAC5B,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,YAAY,GAAG,QAAQ,GAAG,aAAa,GAAG,QAAQ,CAAC,CAa7D"}
@@ -0,0 +1,147 @@
1
+ import { DEV_TOOLS_BINDING } from './contract.js';
2
+ import { describeSpec, explainFilterQuery } from './explain.js';
3
+ const limit = {
4
+ type: 'integer',
5
+ description: 'How many items to return (default 20, max 100).',
6
+ minimum: 1,
7
+ maximum: 100,
8
+ };
9
+ const page = {
10
+ type: 'integer',
11
+ description: 'Page number, from 1 (the `next` of the previous answer).',
12
+ minimum: 1,
13
+ };
14
+ const name = {
15
+ type: 'string',
16
+ description: 'The spec name: a key of the `filters` manifest in config/filter.ts.',
17
+ };
18
+ function intOf(value, fallback, max = Number.MAX_SAFE_INTEGER) {
19
+ return typeof value === 'number' && Number.isFinite(value)
20
+ ? Math.max(1, Math.min(max, Math.floor(value)))
21
+ : fallback;
22
+ }
23
+ /** One page of `items` in the `{ items, next }` shape every dev-tools list returns. */
24
+ export function pageOf(items, input) {
25
+ const size = intOf(input.limit, 20, 100);
26
+ const number = intOf(input.page, 1);
27
+ const start = (number - 1) * size;
28
+ return {
29
+ items: items.slice(start, start + size),
30
+ next: start + size < items.length ? number + 1 : null,
31
+ };
32
+ }
33
+ function problem(load) {
34
+ switch (load.status) {
35
+ case 'missing':
36
+ return `No ${load.entrypoint.replace(/\.js$/, '.ts')}: declare an exported \`filters\` manifest there to list your specs.`;
37
+ case 'empty':
38
+ return `${load.entrypoint.replace(/\.js$/, '.ts')} exports no \`filters\` manifest of defineFilter specs.`;
39
+ case 'failed':
40
+ return `${load.entrypoint.replace(/\.js$/, '.ts')} failed to load: ${load.error}`;
41
+ }
42
+ }
43
+ async function manifestOrThrow(deps) {
44
+ const load = await deps.manifest();
45
+ if (load.status !== 'loaded')
46
+ throw new Error(problem(load));
47
+ return load.manifest;
48
+ }
49
+ async function entryOf(deps, input) {
50
+ const key = typeof input.name === 'string' ? input.name.trim() : '';
51
+ if (key === '')
52
+ throw new Error('`name` is required: a spec name from filter_list_specs');
53
+ const manifest = await manifestOrThrow(deps);
54
+ if (!Object.hasOwn(manifest, key)) {
55
+ throw new Error(`No spec "${key}". Known: ${Object.keys(manifest).sort().join(', ')}`);
56
+ }
57
+ return { key, entry: manifest[key] };
58
+ }
59
+ /** The filter developer tools (all read-only, no database). */
60
+ export function filterDevTools(deps) {
61
+ return [
62
+ {
63
+ name: 'filter_list_specs',
64
+ kind: 'read',
65
+ description: 'The filter specs declared in the `filters` manifest of config/filter.ts: name, how many ' +
66
+ 'filterable/sortable fields, searchable fields and relations. Paged: { items, next }.',
67
+ input: { type: 'object', properties: { limit, page } },
68
+ async run(input) {
69
+ const load = await deps.manifest();
70
+ if (load.status !== 'loaded')
71
+ return { items: [], next: null, hint: problem(load) };
72
+ const items = Object.entries(load.manifest)
73
+ .sort(([a], [b]) => a.localeCompare(b))
74
+ .map(([key, entry]) => {
75
+ const spec = describeSpec(entry.spec, key);
76
+ return {
77
+ name: key,
78
+ filterable: spec.filterable === '*' ? '*' : spec.filterablePaths.length,
79
+ sortable: spec.sortable === '*' ? '*' : spec.sortablePaths.length,
80
+ searchable: spec.searchable,
81
+ relations: Object.keys(spec.relations),
82
+ tenantScoped: spec.tenantColumn !== null,
83
+ };
84
+ });
85
+ return pageOf(items, input);
86
+ },
87
+ },
88
+ {
89
+ name: 'filter_get_spec',
90
+ kind: 'read',
91
+ description: 'One filter spec in full: filterable and sortable paths (relation-dotted), field types, ' +
92
+ 'operators, searchable/full-text, relations, maxDepth, aliases, computed fields, tenant ' +
93
+ 'column, default filters/sort and page sizes.',
94
+ input: { type: 'object', properties: { name }, required: ['name'] },
95
+ async run(input) {
96
+ const { key, entry } = await entryOf(deps, input);
97
+ return { ...describeSpec(entry.spec, key), clientFieldTypes: entry.fieldTypes ?? {} };
98
+ },
99
+ },
100
+ {
101
+ name: 'filter_explain_query',
102
+ kind: 'read',
103
+ description: 'Dry-run a query string (filter[name][contains]=Al&sort=-age&page=2) against a spec, with ' +
104
+ 'no database: what the server parses, which filters/sorts are dropped or make the request ' +
105
+ 'fail and why, the query-builder calls it would make, and the resolved page/size.',
106
+ input: {
107
+ type: 'object',
108
+ properties: {
109
+ name,
110
+ query: {
111
+ type: 'string',
112
+ description: 'The query string, with or without the leading `?`.',
113
+ },
114
+ },
115
+ required: ['name', 'query'],
116
+ },
117
+ async run(input) {
118
+ const { key, entry } = await entryOf(deps, input);
119
+ const query = typeof input.query === 'string' ? input.query : '';
120
+ return { spec: key, ...explainFilterQuery(entry.spec, query) };
121
+ },
122
+ },
123
+ ];
124
+ }
125
+ /**
126
+ * Register the filter tools into the dev-tools hub, when the agent's MCP provider bound one and it
127
+ * can gate a lib without a console (`supports('endpoint-authorize')`). Never throws: returns why it
128
+ * did not register.
129
+ */
130
+ export async function registerFilterDevTools(container, deps) {
131
+ if (!container.hasBinding(DEV_TOOLS_BINDING))
132
+ return 'no-hub';
133
+ try {
134
+ const hub = (await container.make(DEV_TOOLS_BINDING));
135
+ if (hub?.version !== 1)
136
+ return 'unsupported';
137
+ if (typeof hub.supports !== 'function' || !hub.supports('endpoint-authorize')) {
138
+ return 'unsupported';
139
+ }
140
+ hub.register({ lib: 'filter', title: 'Query filters', tools: filterDevTools(deps) });
141
+ return 'registered';
142
+ }
143
+ catch {
144
+ return 'failed';
145
+ }
146
+ }
147
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/dev_tools/tools.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAOhE,MAAM,KAAK,GAAyB;IAClC,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,iDAAiD;IAC9D,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,GAAG;CACb,CAAC;AACF,MAAM,IAAI,GAAyB;IACjC,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,0DAA0D;IACvE,OAAO,EAAE,CAAC;CACX,CAAC;AACF,MAAM,IAAI,GAAyB;IACjC,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,qEAAqE;CACnF,CAAC;AAEF,SAAS,KAAK,CAAC,KAAc,EAAE,QAAgB,EAAE,GAAG,GAAG,MAAM,CAAC,gBAAgB;IAC5E,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QACxD,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/C,CAAC,CAAC,QAAQ,CAAC;AACf,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,MAAM,CAAI,KAAmB,EAAE,KAA8B;IAC3E,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;IAClC,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;QACvC,IAAI,EAAE,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;KACtD,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,IAAiD;IAChE,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;QACpB,KAAK,SAAS;YACZ,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,sEAAsE,CAAC;QAC7H,KAAK,OAAO;YACV,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,yDAAyD,CAAC;QAC7G,KAAK,QAAQ;YACX,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,oBAAoB,IAAI,CAAC,KAAK,EAAE,CAAC;IACtF,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAwB;IACrD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7D,OAAO,IAAI,CAAC,QAAQ,CAAC;AACvB,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,IAAwB,EAAE,KAA8B;IAC7E,MAAM,GAAG,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,IAAI,GAAG,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC1F,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,YAAY,GAAG,aAAa,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAiC,EAAE,CAAC;AACvE,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,cAAc,CAAC,IAAwB;IACrD,OAAO;QACL;YACE,IAAI,EAAE,mBAAmB;YACzB,IAAI,EAAE,MAAM;YACZ,WAAW,EACT,0FAA0F;gBAC1F,sFAAsF;YACxF,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACtD,KAAK,CAAC,GAAG,CAAC,KAAK;gBACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACnC,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ;oBAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpF,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;qBACxC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;qBACtC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;oBACpB,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;oBAC3C,OAAO;wBACL,IAAI,EAAE,GAAG;wBACT,UAAU,EAAE,IAAI,CAAC,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM;wBACvE,QAAQ,EAAE,IAAI,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM;wBACjE,UAAU,EAAE,IAAI,CAAC,UAAU;wBAC3B,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;wBACtC,YAAY,EAAE,IAAI,CAAC,YAAY,KAAK,IAAI;qBACzC,CAAC;gBACJ,CAAC,CAAC,CAAC;gBACL,OAAO,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC9B,CAAC;SACF;QACD;YACE,IAAI,EAAE,iBAAiB;YACvB,IAAI,EAAE,MAAM;YACZ,WAAW,EACT,yFAAyF;gBACzF,yFAAyF;gBACzF,8CAA8C;YAChD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE;YACnE,KAAK,CAAC,GAAG,CAAC,KAAK;gBACb,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAClD,OAAO,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;YACxF,CAAC;SACF;QACD;YACE,IAAI,EAAE,sBAAsB;YAC5B,IAAI,EAAE,MAAM;YACZ,WAAW,EACT,2FAA2F;gBAC3F,2FAA2F;gBAC3F,kFAAkF;YACpF,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,IAAI;oBACJ,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,WAAW,EAAE,oDAAoD;qBAClE;iBACF;gBACD,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;aAC5B;YACD,KAAK,CAAC,GAAG,CAAC,KAAK;gBACb,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAClD,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;YACjE,CAAC;SACF;KACF,CAAC;AACJ,CAAC;AAQD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,SAA4B,EAC5B,IAAwB;IAExB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,iBAAiB,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAA4B,CAAC;QACjF,IAAI,GAAG,EAAE,OAAO,KAAK,CAAC;YAAE,OAAO,aAAa,CAAC;QAC7C,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,UAAU,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC9E,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrF,OAAO,YAAY,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export declare const VERSION = "1.0.0-rc.0";
2
+ export declare const VERSION = "1.0.0-rc.1";
3
3
  /**
4
4
  * The hook `node ace add @adonis-agora/filter` runs: ace looks for `configure` on the package's
5
5
  * main entry. It registers the provider and the commands barrel in `adonisrc.ts`.
@@ -19,6 +19,8 @@ export type { ApplyCustomFilterOptions, CustomFilterClass } from './custom_filte
19
19
  export { applyCustomFilter } from './custom_filter.js';
20
20
  export type { DualDecorator, StandardDecoratorContext } from './decorators.js';
21
21
  export { filterable, filterFor, searchable, sortable } from './decorators.js';
22
+ export { type ExplainIssue, explainFilterQuery, type FilterQueryExplanation, type RecordedCall, } from './dev_tools/explain.js';
23
+ export { parseQueryString } from './dev_tools/query_string.js';
22
24
  export { escapeLike } from './escape-like.js';
23
25
  export type { FieldAliases } from './field_aliases.js';
24
26
  export { remapDistinctAliases, remapFilterAliases, remapSortAliases, resolveFieldAlias, } from './field_aliases.js';
@@ -35,6 +37,7 @@ export { groupByCountFromRequest } from './group_by_count.js';
35
37
  export { applyColumnFilters, applyComputedField, applyComputedSort, applyDistinct, applyFullTextSearch, applyGroupByCount, applyKeyset, applySearch, applySort, applyVectorSimilarity, type FullTextSearchOptions, type QueryBuilderLike, resolveComputedExpression, type VectorDistanceMetric, type VectorSimilarityOptions, } from './lucid_adapter.js';
36
38
  export type { MacroableQueryBuilder } from './lucid_macros.js';
37
39
  export { registerFilterMacros } from './lucid_macros.js';
40
+ export { DEFAULT_MANIFEST_ENTRYPOINT, loadFilterManifest, type ManifestApp, type ManifestLoad, } from './manifest.js';
38
41
  export type { NormalizeOptions } from './normalizer.js';
39
42
  export { normalizeInput } from './normalizer.js';
40
43
  export type { ColumnFilter, FilterOperator, FilterOperatorAlias, FilterOperatorInput, } from './operators.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/dist/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export const VERSION = '1.0.0-rc.0';
2
+ export const VERSION = '1.0.0-rc.1';
3
3
  /**
4
4
  * The hook `node ace add @adonis-agora/filter` runs: ace looks for `configure` on the package's
5
5
  * main entry. It registers the provider and the commands barrel in `adonisrc.ts`.
@@ -13,6 +13,8 @@ export { BaseModelFilter } from './base_model_filter.js';
13
13
  export { buildCursorPage, buildKeyset, decodeCursor, encodeCursor, extractCursorValues, reverseKeyset, } from './cursor.js';
14
14
  export { applyCustomFilter } from './custom_filter.js';
15
15
  export { filterable, filterFor, searchable, sortable } from './decorators.js';
16
+ export { explainFilterQuery, } from './dev_tools/explain.js';
17
+ export { parseQueryString } from './dev_tools/query_string.js';
16
18
  export { escapeLike } from './escape-like.js';
17
19
  export { remapDistinctAliases, remapFilterAliases, remapSortAliases, resolveFieldAlias, } from './field_aliases.js';
18
20
  export { dispatchKeys, isFilterClass, methodForKey, specFromFilterClass, } from './filter_class.js';
@@ -22,6 +24,7 @@ export { filterableFieldPaths, generateFilterClient, generateFilterClients, sort
22
24
  export { groupByCountFromRequest } from './group_by_count.js';
23
25
  export { applyColumnFilters, applyComputedField, applyComputedSort, applyDistinct, applyFullTextSearch, applyGroupByCount, applyKeyset, applySearch, applySort, applyVectorSimilarity, resolveComputedExpression, } from './lucid_adapter.js';
24
26
  export { registerFilterMacros } from './lucid_macros.js';
27
+ export { DEFAULT_MANIFEST_ENTRYPOINT, loadFilterManifest, } from './manifest.js';
25
28
  export { normalizeInput } from './normalizer.js';
26
29
  export { FILTER_OPERATORS, OPERATOR_ALIASES } from './operators.js';
27
30
  export { parseDistinct, parseFilterRequest, parseGroupByCount, parseSort, toColumnFilters, } from './parse_request.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,YAAY,CAAC;AAEpC;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAMzD,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EACL,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAS3B,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AASnD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,SAAS,EACT,qBAAqB,EAGrB,yBAAyB,GAG1B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAOjD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,SAAS,EACT,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAgBxD,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,YAAY,CAAC;AAEpC;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAMzD,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EACL,eAAe,EACf,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAEL,kBAAkB,GAGnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAS3B,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AASnD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,SAAS,EACT,qBAAqB,EAGrB,yBAAyB,GAG1B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,GAGnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAOjD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,SAAS,EACT,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAgBxD,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { FilterClientManifest } from './generate_client.js';
2
+ /** Where the app declares its `filters` manifest by default (`config/filter.ts`). */
3
+ export declare const DEFAULT_MANIFEST_ENTRYPOINT = "config/filter.js";
4
+ /** The slice of the AdonisJS application {@link loadFilterManifest} reads. */
5
+ export interface ManifestApp {
6
+ makeURL(...paths: string[]): URL;
7
+ config?: {
8
+ get<T>(key: string, fallback?: T): T;
9
+ };
10
+ }
11
+ /** What {@link loadFilterManifest} found. */
12
+ export type ManifestLoad = {
13
+ status: 'loaded';
14
+ manifest: FilterClientManifest;
15
+ entrypoint: string;
16
+ } | {
17
+ status: 'missing';
18
+ entrypoint: string;
19
+ } | {
20
+ status: 'empty';
21
+ entrypoint: string;
22
+ } | {
23
+ status: 'failed';
24
+ entrypoint: string;
25
+ error: string;
26
+ };
27
+ /**
28
+ * Load the app's `filters` manifest: the named `filters` export of `config/filter.ts`, its default
29
+ * export (a manifest, or `{ filters }`), then `filters` in the `filter` config. The one loader
30
+ * `make:filter-client`, the doctor and the dev tools share.
31
+ */
32
+ export declare function loadFilterManifest(app: ManifestApp, entrypoint?: string): Promise<ManifestLoad>;
33
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,qFAAqF;AACrF,eAAO,MAAM,2BAA2B,qBAAqB,CAAC;AAE9D,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IACjC,MAAM,CAAC,EAAE;QAAE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC;CACnD;AAED,6CAA6C;AAC7C,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,oBAAoB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAwB5D;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,WAAW,EAChB,UAAU,SAA8B,GACvC,OAAO,CAAC,YAAY,CAAC,CAsBvB"}
@@ -0,0 +1,50 @@
1
+ /** Where the app declares its `filters` manifest by default (`config/filter.ts`). */
2
+ export const DEFAULT_MANIFEST_ENTRYPOINT = 'config/filter.js';
3
+ function isManifest(value) {
4
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
5
+ return false;
6
+ const entries = Object.values(value);
7
+ return (entries.length > 0 &&
8
+ entries.every((entry) => entry !== null &&
9
+ typeof entry === 'object' &&
10
+ typeof entry.spec?.isFilterable === 'function'));
11
+ }
12
+ function isMissingModule(error, url) {
13
+ const { code, message } = (error ?? {});
14
+ if (code !== 'ERR_MODULE_NOT_FOUND' && code !== 'MODULE_NOT_FOUND')
15
+ return false;
16
+ const text = typeof message === 'string' ? message : '';
17
+ const file = url.replace(/^file:\/\//, '').replace(/\.js$/, '');
18
+ return text.includes(file) || text.includes(url);
19
+ }
20
+ /**
21
+ * Load the app's `filters` manifest: the named `filters` export of `config/filter.ts`, its default
22
+ * export (a manifest, or `{ filters }`), then `filters` in the `filter` config. The one loader
23
+ * `make:filter-client`, the doctor and the dev tools share.
24
+ */
25
+ export async function loadFilterManifest(app, entrypoint = DEFAULT_MANIFEST_ENTRYPOINT) {
26
+ const url = app.makeURL(entrypoint).href;
27
+ let mod;
28
+ try {
29
+ mod = (await import(url));
30
+ }
31
+ catch (error) {
32
+ if (!isMissingModule(error, url)) {
33
+ return {
34
+ status: 'failed',
35
+ entrypoint,
36
+ error: error instanceof Error ? error.message : String(error),
37
+ };
38
+ }
39
+ }
40
+ const fromConfig = app.config?.get('filter', undefined);
41
+ const fromDefault = mod?.default?.filters;
42
+ for (const candidate of [mod?.filters, mod?.default, fromDefault, fromConfig?.filters]) {
43
+ if (isManifest(candidate))
44
+ return { status: 'loaded', manifest: candidate, entrypoint };
45
+ }
46
+ if (mod === undefined && fromConfig?.filters === undefined)
47
+ return { status: 'missing', entrypoint };
48
+ return { status: 'empty', entrypoint };
49
+ }
50
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/manifest.ts"],"names":[],"mappings":"AAEA,qFAAqF;AACrF,MAAM,CAAC,MAAM,2BAA2B,GAAG,kBAAkB,CAAC;AAe9D,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtF,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,KAAgC,CAAC,CAAC;IAChE,OAAO,CACL,OAAO,CAAC,MAAM,GAAG,CAAC;QAClB,OAAO,CAAC,KAAK,CACX,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,KAAK,IAAI;YACd,OAAO,KAAK,KAAK,QAAQ;YACzB,OAAQ,KAA+C,CAAC,IAAI,EAAE,YAAY,KAAK,UAAU,CAC5F,CACF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAc,EAAE,GAAW;IAClD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAA0C,CAAC;IACjF,IAAI,IAAI,KAAK,sBAAsB,IAAI,IAAI,KAAK,kBAAkB;QAAE,OAAO,KAAK,CAAC;IACjF,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChE,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,GAAgB,EAChB,UAAU,GAAG,2BAA2B;IAExC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;IACzC,IAAI,GAAwC,CAAC;IAC7C,IAAI,CAAC;QACH,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAA4B,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;YACjC,OAAO;gBACL,MAAM,EAAE,QAAQ;gBAChB,UAAU;gBACV,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAoC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC3F,MAAM,WAAW,GAAI,GAAG,EAAE,OAA6C,EAAE,OAAO,CAAC;IACjF,KAAK,MAAM,SAAS,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;QACvF,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IAC1F,CAAC;IACD,IAAI,GAAG,KAAK,SAAS,IAAI,UAAU,EAAE,OAAO,KAAK,SAAS;QACxD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IAC3C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;AACzC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonis-agora/filter",
3
- "version": "1.0.0-rc.0",
3
+ "version": "1.0.0-rc.1",
4
4
  "description": "Server-side query filtering/sorting/pagination for AdonisJS — Spatie-style input, a Lucid adapter, and field allow-listing. Part of the Agora ecosystem.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -83,7 +83,7 @@
83
83
  "@adonisjs/lucid": "22.4.2",
84
84
  "@tanstack/intent": "0.5.6",
85
85
  "@types/luxon": "3.7.6",
86
- "@types/node": "26.6.5",
86
+ "@types/node": "26.6.6",
87
87
  "@types/pg": "8.23.1",
88
88
  "luxon": "3.7.2",
89
89
  "pg": "8.23.1",