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

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 (57) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/commands/agora_doctor.d.ts +23 -0
  3. package/dist/commands/agora_doctor.d.ts.map +1 -0
  4. package/dist/commands/agora_doctor.js +110 -0
  5. package/dist/commands/agora_doctor.js.map +1 -0
  6. package/dist/commands/filter_doctor.d.ts +8 -0
  7. package/dist/commands/filter_doctor.d.ts.map +1 -0
  8. package/dist/commands/filter_doctor.js +8 -0
  9. package/dist/commands/filter_doctor.js.map +1 -0
  10. package/dist/commands/main.d.ts +6 -4
  11. package/dist/commands/main.d.ts.map +1 -1
  12. package/dist/commands/main.js +6 -3
  13. package/dist/commands/main.js.map +1 -1
  14. package/dist/commands/make_filter_client.d.ts.map +1 -1
  15. package/dist/commands/make_filter_client.js +10 -14
  16. package/dist/commands/make_filter_client.js.map +1 -1
  17. package/dist/providers/filter_provider.d.ts +4 -0
  18. package/dist/providers/filter_provider.d.ts.map +1 -1
  19. package/dist/providers/filter_provider.js +31 -0
  20. package/dist/providers/filter_provider.js.map +1 -1
  21. package/dist/src/dev_tools/contract.d.ts +61 -0
  22. package/dist/src/dev_tools/contract.d.ts.map +1 -0
  23. package/dist/src/dev_tools/contract.js +12 -0
  24. package/dist/src/dev_tools/contract.js.map +1 -0
  25. package/dist/src/dev_tools/explain.d.ts +88 -0
  26. package/dist/src/dev_tools/explain.d.ts.map +1 -0
  27. package/dist/src/dev_tools/explain.js +168 -0
  28. package/dist/src/dev_tools/explain.js.map +1 -0
  29. package/dist/src/dev_tools/query_string.d.ts +8 -0
  30. package/dist/src/dev_tools/query_string.d.ts.map +1 -0
  31. package/dist/src/dev_tools/query_string.js +102 -0
  32. package/dist/src/dev_tools/query_string.js.map +1 -0
  33. package/dist/src/dev_tools/tools.d.ts +25 -0
  34. package/dist/src/dev_tools/tools.d.ts.map +1 -0
  35. package/dist/src/dev_tools/tools.js +147 -0
  36. package/dist/src/dev_tools/tools.js.map +1 -0
  37. package/dist/src/doctor/agora_doctor.d.ts +116 -0
  38. package/dist/src/doctor/agora_doctor.d.ts.map +1 -0
  39. package/dist/src/doctor/agora_doctor.js +685 -0
  40. package/dist/src/doctor/agora_doctor.js.map +1 -0
  41. package/dist/src/doctor/checks.d.ts +12 -0
  42. package/dist/src/doctor/checks.d.ts.map +1 -0
  43. package/dist/src/doctor/checks.js +173 -0
  44. package/dist/src/doctor/checks.js.map +1 -0
  45. package/dist/src/doctor/index.d.ts +5 -0
  46. package/dist/src/doctor/index.d.ts.map +1 -0
  47. package/dist/src/doctor/index.js +5 -0
  48. package/dist/src/doctor/index.js.map +1 -0
  49. package/dist/src/index.d.ts +4 -1
  50. package/dist/src/index.d.ts.map +1 -1
  51. package/dist/src/index.js +4 -1
  52. package/dist/src/index.js.map +1 -1
  53. package/dist/src/manifest.d.ts +33 -0
  54. package/dist/src/manifest.d.ts.map +1 -0
  55. package/dist/src/manifest.js +50 -0
  56. package/dist/src/manifest.js.map +1 -0
  57. package/package.json +9 -3
@@ -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":"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"}
@@ -0,0 +1,116 @@
1
+ import type { ApplicationService } from '@adonisjs/core/types';
2
+ /** The container binding the registry lives at. */
3
+ export declare const AGORA_DOCTOR_BINDING = "agora.doctor";
4
+ /** Bound as a VALUE under `'agora.doctor'`. Data only. */
5
+ export interface AgoraDoctorRegistry {
6
+ readonly version: 1;
7
+ readonly checks: AgoraDoctorCheck[];
8
+ }
9
+ export type AgoraDoctorStatus = 'ok' | 'warn' | 'error' | 'skip';
10
+ export interface AgoraDoctorCheck {
11
+ /** `'<lib>.<kebab>'`, unique and frozen for 1.x: `'durable.verify-tenant'`. */
12
+ id: string;
13
+ /** `'durable'`. The package is `@adonis-agora/<lib>` unless {@link package} says otherwise. */
14
+ lib: string;
15
+ /** The npm package, when it is not `@adonis-agora/<lib>`. */
16
+ package?: string;
17
+ title: string;
18
+ /** `'cheap'` (default) reads config, env and files only; `'deep'` touches a DB, Redis or the network. */
19
+ cost?: 'cheap' | 'deep';
20
+ run(app: ApplicationService): AgoraDoctorResult | AgoraDoctorResult[] | Promise<AgoraDoctorResult | AgoraDoctorResult[]>;
21
+ }
22
+ export interface AgoraDoctorResult {
23
+ status: AgoraDoctorStatus;
24
+ /** One line, no secrets, no stack. */
25
+ message: string;
26
+ /** One line: the exact change to make. */
27
+ fix?: string;
28
+ /** Absolute URL of the lib docs page. */
29
+ docs?: string;
30
+ }
31
+ /** One reported result. */
32
+ export interface AgoraDoctorReportEntry extends AgoraDoctorResult {
33
+ id: string;
34
+ lib: string;
35
+ title: string;
36
+ ms: number;
37
+ }
38
+ /** What `agora:doctor --json` prints. */
39
+ export interface AgoraDoctorReport {
40
+ version: 1;
41
+ env: string;
42
+ summary: Record<AgoraDoctorStatus, number>;
43
+ libs: Array<{
44
+ lib: string;
45
+ package: string;
46
+ version: string | null;
47
+ }>;
48
+ results: AgoraDoctorReportEntry[];
49
+ }
50
+ export interface AgoraDoctorOptions {
51
+ libs?: string[];
52
+ only?: string;
53
+ deep?: boolean;
54
+ /** The app was not booted (`--no-boot`): deep checks are reported as skipped, never run. */
55
+ noBoot?: boolean;
56
+ strict?: boolean;
57
+ /** Per-check budget in ms (default 5000, deep checks 15000). */
58
+ timeoutMs?: number;
59
+ deepTimeoutMs?: number;
60
+ }
61
+ /** A doctor problem that stops the run itself (exit 2). */
62
+ export declare class AgoraDoctorUsageError extends Error {
63
+ }
64
+ interface ContainerLike {
65
+ hasBinding(binding: string): boolean;
66
+ bindValue(binding: string, value: unknown): void;
67
+ make(binding: string): Promise<unknown>;
68
+ }
69
+ /**
70
+ * Add a lib's checks to the app's doctor registry, creating it when absent. Call it from a provider's
71
+ * `boot()` (Adonis does not await `register()`, so an async registration there can be lost). A
72
+ * registry of another version is left alone; a duplicate id is skipped.
73
+ */
74
+ export declare function registerDoctorChecks(container: ContainerLike, checks: readonly AgoraDoctorCheck[]): Promise<void>;
75
+ /** The registered checks; throws {@link AgoraDoctorUsageError} on a registry of another version. */
76
+ export declare function readDoctorChecks(container: ContainerLike): Promise<AgoraDoctorCheck[]>;
77
+ /**
78
+ * The checks of every installed `@adonis-agora/*` package that publishes a `./doctor` entry
79
+ * (`export const agoraDoctorChecks`), imported from the app root without booting providers. A
80
+ * package whose entry fails to load is reported as an error (`<lib>.doctor-entry`), never skipped.
81
+ */
82
+ export declare function discoverDoctorChecks(app: ApplicationService): Promise<AgoraDoctorCheck[]>;
83
+ /** The directory of `name` as Node would find it from `from` (walking up `node_modules`), real path. */
84
+ export declare function packageDir(name: string, from: string): Promise<string | null>;
85
+ /** The installed version of `name` resolved from `from`, or `null` when it is not installed. */
86
+ export declare function installedVersion(name: string, from: string): Promise<string | null>;
87
+ /**
88
+ * Whether `version` satisfies `range`, with node-semver's grammar and prereleases included (like
89
+ * `semver.satisfies(version, range, { includePrerelease: true })`). An unparsable range is `false`.
90
+ */
91
+ export declare function satisfies(version: string, range: string): boolean;
92
+ /**
93
+ * The environment shown in the report, from the app itself: `production` when `app.inProduction`,
94
+ * `test` when `app.inTest`, else the app's node environment, and `development` when that is unset.
95
+ */
96
+ export declare function environmentOf(app: Pick<ApplicationService, 'inProduction' | 'inTest' | 'nodeEnvironment'>): string;
97
+ /** Run the checks and build the report. Throws {@link AgoraDoctorUsageError} for an unknown `--only`. */
98
+ export declare function runAgoraDoctor(app: ApplicationService, registered: readonly AgoraDoctorCheck[], options?: AgoraDoctorOptions): Promise<{
99
+ report: AgoraDoctorReport;
100
+ exitCode: 0 | 1;
101
+ }>;
102
+ export interface Paint {
103
+ green(text: string): string;
104
+ yellow(text: string): string;
105
+ red(text: string): string;
106
+ dim(text: string): string;
107
+ bold(text: string): string;
108
+ }
109
+ /** The human report. `fancy` = colors and symbols (a TTY without `NO_COLOR`). */
110
+ export declare function renderAgoraDoctor(report: AgoraDoctorReport, options?: {
111
+ verbose?: boolean;
112
+ fancy?: boolean;
113
+ paint?: Paint;
114
+ }): string;
115
+ export {};
116
+ //# sourceMappingURL=agora_doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agora_doctor.d.ts","sourceRoot":"","sources":["../../../src/doctor/agora_doctor.ts"],"names":[],"mappings":"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"}