qast 1.1.0 → 2.0.0
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/README.md +312 -6
- package/README.zh-CN.md +520 -0
- package/dist/adapters/drizzle.d.ts +66 -0
- package/dist/adapters/drizzle.d.ts.map +1 -0
- package/dist/adapters/drizzle.js +222 -0
- package/dist/adapters/drizzle.js.map +1 -0
- package/dist/adapters/knex.d.ts +22 -0
- package/dist/adapters/knex.d.ts.map +1 -0
- package/dist/adapters/knex.js +158 -0
- package/dist/adapters/knex.js.map +1 -0
- package/dist/adapters/mongoose.d.ts +15 -0
- package/dist/adapters/mongoose.d.ts.map +1 -0
- package/dist/adapters/mongoose.js +152 -0
- package/dist/adapters/mongoose.js.map +1 -0
- package/dist/adapters/prisma.d.ts +5 -2
- package/dist/adapters/prisma.d.ts.map +1 -1
- package/dist/adapters/prisma.js +103 -4
- package/dist/adapters/prisma.js.map +1 -1
- package/dist/adapters/sequelize.d.ts +26 -8
- package/dist/adapters/sequelize.d.ts.map +1 -1
- package/dist/adapters/sequelize.js +168 -7
- package/dist/adapters/sequelize.js.map +1 -1
- package/dist/adapters/typeorm.d.ts +32 -2
- package/dist/adapters/typeorm.d.ts.map +1 -1
- package/dist/adapters/typeorm.js +169 -3
- package/dist/adapters/typeorm.js.map +1 -1
- package/dist/builder/query-builder.d.ts +139 -0
- package/dist/builder/query-builder.d.ts.map +1 -0
- package/dist/builder/query-builder.js +320 -0
- package/dist/builder/query-builder.js.map +1 -0
- package/dist/errors.d.ts +18 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +127 -9
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +90 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +142 -16
- package/dist/index.js.map +1 -1
- package/dist/integrations/express.d.ts +14 -0
- package/dist/integrations/express.d.ts.map +1 -0
- package/dist/integrations/express.js +33 -0
- package/dist/integrations/express.js.map +1 -0
- package/dist/integrations/fastify.d.ts +17 -0
- package/dist/integrations/fastify.d.ts.map +1 -0
- package/dist/integrations/fastify.js +35 -0
- package/dist/integrations/fastify.js.map +1 -0
- package/dist/integrations/hono.d.ts +14 -0
- package/dist/integrations/hono.d.ts.map +1 -0
- package/dist/integrations/hono.js +30 -0
- package/dist/integrations/hono.js.map +1 -0
- package/dist/integrations/nestjs.d.ts +23 -0
- package/dist/integrations/nestjs.d.ts.map +1 -0
- package/dist/integrations/nestjs.js +137 -0
- package/dist/integrations/nestjs.js.map +1 -0
- package/dist/parser/parser.d.ts +15 -7
- package/dist/parser/parser.d.ts.map +1 -1
- package/dist/parser/parser.js +117 -15
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/tokenizer.d.ts +11 -1
- package/dist/parser/tokenizer.d.ts.map +1 -1
- package/dist/parser/tokenizer.js +67 -10
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/parser/validator.d.ts +44 -1
- package/dist/parser/validator.d.ts.map +1 -1
- package/dist/parser/validator.js +210 -2
- package/dist/parser/validator.js.map +1 -1
- package/dist/types/ast.d.ts +102 -3
- package/dist/types/ast.d.ts.map +1 -1
- package/dist/types/ast.js +21 -0
- package/dist/types/ast.js.map +1 -1
- package/dist/utils/ast-utils.d.ts +43 -0
- package/dist/utils/ast-utils.d.ts.map +1 -0
- package/dist/utils/ast-utils.js +205 -0
- package/dist/utils/ast-utils.js.map +1 -0
- package/dist/utils/cache.d.ts +47 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +132 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/serializer.d.ts +6 -0
- package/dist/utils/serializer.d.ts.map +1 -0
- package/dist/utils/serializer.js +140 -0
- package/dist/utils/serializer.js.map +1 -0
- package/package.json +31 -8
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.qastExpressMiddleware = qastExpressMiddleware;
|
|
4
|
+
const index_1 = require("../index");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
/**
|
|
7
|
+
* Express middleware for parsing QAST queries
|
|
8
|
+
*/
|
|
9
|
+
function qastExpressMiddleware(options) {
|
|
10
|
+
return (req, res, next) => {
|
|
11
|
+
try {
|
|
12
|
+
const queryString = req.query.filter;
|
|
13
|
+
if (queryString) {
|
|
14
|
+
const qastQuery = (0, index_1.parseQueryFull)(queryString, options);
|
|
15
|
+
req.qastQuery = qastQuery;
|
|
16
|
+
req.qastFilter = qastQuery.filter; // For backward compatibility
|
|
17
|
+
}
|
|
18
|
+
next();
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
if (error instanceof errors_1.ValidationError) {
|
|
22
|
+
res.status(400).json({
|
|
23
|
+
error: error.message,
|
|
24
|
+
details: error.getSnippet ? error.getSnippet() : undefined,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
next(error);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=express.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/integrations/express.ts"],"names":[],"mappings":";;AAeA,sDAuBC;AArCD,oCAA4E;AAC5E,sCAA4C;AAU5C;;GAEG;AACH,SAAgB,qBAAqB,CAAC,OAAsB;IAC1D,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAQ,EAAE;QAC/D,IAAI,CAAC;YACH,MAAM,WAAW,GAAI,GAAG,CAAC,KAAa,CAAC,MAA4B,CAAC;YAEpE,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,SAAS,GAAG,IAAA,sBAAc,EAAC,WAAW,EAAE,OAAO,CAAC,CAAC;gBACtD,GAAmB,CAAC,SAAS,GAAG,SAAS,CAAC;gBAC1C,GAAmB,CAAC,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,6BAA6B;YACnF,CAAC;YAED,IAAI,EAAE,CAAC;QACT,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,wBAAe,EAAE,CAAC;gBACrC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACnB,KAAK,EAAE,KAAK,CAAC,OAAO;oBACpB,OAAO,EAAG,KAAa,CAAC,UAAU,CAAC,CAAC,CAAE,KAAa,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS;iBAC7E,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,KAAK,CAAC,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FastifyRequest, FastifyPluginOptions } from 'fastify';
|
|
2
|
+
import { ParseOptions, QueryAST, QastNode } from '../index';
|
|
3
|
+
/**
|
|
4
|
+
* Fastify request with parsed QAST filter
|
|
5
|
+
*/
|
|
6
|
+
export interface QastFastifyRequest extends FastifyRequest {
|
|
7
|
+
qastFilter?: QastNode;
|
|
8
|
+
qastQuery?: QueryAST;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Fastify plugin for QAST query parsing
|
|
12
|
+
*/
|
|
13
|
+
export declare function qastPlugin(fastify: any, options: FastifyPluginOptions & {
|
|
14
|
+
parseOptions?: ParseOptions;
|
|
15
|
+
}): Promise<void>;
|
|
16
|
+
export default qastPlugin;
|
|
17
|
+
//# sourceMappingURL=fastify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../../src/integrations/fastify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAgB,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAkB,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAG5E;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACxD,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,SAAS,CAAC,EAAE,QAAQ,CAAC;CACtB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,oBAAoB,GAAG;IAAE,YAAY,CAAC,EAAE,YAAY,CAAA;CAAE,GAC9D,OAAO,CAAC,IAAI,CAAC,CAyBf;AAGD,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.qastPlugin = qastPlugin;
|
|
4
|
+
const index_1 = require("../index");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
/**
|
|
7
|
+
* Fastify plugin for QAST query parsing
|
|
8
|
+
*/
|
|
9
|
+
async function qastPlugin(fastify, options) {
|
|
10
|
+
const parseOptions = options.parseOptions;
|
|
11
|
+
fastify.decorateRequest('qastFilter', null);
|
|
12
|
+
fastify.decorateRequest('qastQuery', null);
|
|
13
|
+
fastify.addHook('onRequest', async (request, reply) => {
|
|
14
|
+
const queryString = request.query?.filter;
|
|
15
|
+
if (queryString) {
|
|
16
|
+
try {
|
|
17
|
+
request.qastQuery = (0, index_1.parseQueryFull)(queryString, parseOptions);
|
|
18
|
+
request.qastFilter = request.qastQuery.filter;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
if (error instanceof errors_1.ValidationError) {
|
|
22
|
+
reply.code(400).send({
|
|
23
|
+
error: error.message,
|
|
24
|
+
suggestions: error.getSuggestions(),
|
|
25
|
+
});
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// Export plugin with default name
|
|
34
|
+
exports.default = qastPlugin;
|
|
35
|
+
//# sourceMappingURL=fastify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../src/integrations/fastify.ts"],"names":[],"mappings":";;AAeA,gCA4BC;AA1CD,oCAA4E;AAC5E,sCAA4C;AAU5C;;GAEG;AACI,KAAK,UAAU,UAAU,CAC9B,OAAY,EACZ,OAA+D;IAE/D,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAE1C,OAAO,CAAC,eAAe,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC5C,OAAO,CAAC,eAAe,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAE3C,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,OAA2B,EAAE,KAAmB,EAAE,EAAE;QACtF,MAAM,WAAW,GAAI,OAAO,CAAC,KAA6B,EAAE,MAA4B,CAAC;QAEzF,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,OAAO,CAAC,SAAS,GAAG,IAAA,sBAAc,EAAC,WAAW,EAAE,YAAY,CAAC,CAAC;gBAC9D,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC;YAChD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,wBAAe,EAAE,CAAC;oBACrC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;wBACnB,KAAK,EAAE,KAAK,CAAC,OAAO;wBACpB,WAAW,EAAE,KAAK,CAAC,cAAc,EAAE;qBACpC,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,kCAAkC;AAClC,kBAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Context, Next } from 'hono';
|
|
2
|
+
import { ParseOptions, QueryAST, QastNode } from '../index';
|
|
3
|
+
/**
|
|
4
|
+
* Hono context with parsed QAST filter
|
|
5
|
+
*/
|
|
6
|
+
export interface QastContext extends Context {
|
|
7
|
+
qastFilter?: QastNode;
|
|
8
|
+
qastQuery?: QueryAST;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Hono middleware for parsing QAST queries
|
|
12
|
+
*/
|
|
13
|
+
export declare function qastMiddleware(options?: ParseOptions): (c: QastContext, next: Next) => Promise<void>;
|
|
14
|
+
//# sourceMappingURL=hono.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hono.d.ts","sourceRoot":"","sources":["../../src/integrations/hono.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAkB,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAG5E;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,OAAO;IAC1C,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,SAAS,CAAC,EAAE,QAAQ,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,YAAY,IACrC,GAAG,WAAW,EAAE,MAAM,IAAI,KAAG,OAAO,CAAC,IAAI,CAAC,CAuBzD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.qastMiddleware = qastMiddleware;
|
|
4
|
+
const index_1 = require("../index");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
/**
|
|
7
|
+
* Hono middleware for parsing QAST queries
|
|
8
|
+
*/
|
|
9
|
+
function qastMiddleware(options) {
|
|
10
|
+
return async (c, next) => {
|
|
11
|
+
const queryString = c.req.query('filter') || undefined;
|
|
12
|
+
if (queryString) {
|
|
13
|
+
try {
|
|
14
|
+
c.qastQuery = (0, index_1.parseQueryFull)(queryString, options);
|
|
15
|
+
c.qastFilter = c.qastQuery.filter;
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (error instanceof errors_1.ValidationError) {
|
|
19
|
+
return c.json({
|
|
20
|
+
error: error.message,
|
|
21
|
+
suggestions: error.getSuggestions(),
|
|
22
|
+
}, 400);
|
|
23
|
+
}
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
await next();
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=hono.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hono.js","sourceRoot":"","sources":["../../src/integrations/hono.ts"],"names":[],"mappings":";;AAeA,wCAwBC;AAtCD,oCAA4E;AAC5E,sCAA4C;AAU5C;;GAEG;AACH,SAAgB,cAAc,CAAC,OAAsB;IACnD,OAAO,KAAK,EAAE,CAAc,EAAE,IAAU,EAAiB,EAAE;QACzD,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC;QAEvD,IAAI,WAAW,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,CAAC,CAAC,SAAS,GAAG,IAAA,sBAAc,EAAC,WAAW,EAAE,OAAO,CAAC,CAAC;gBACnD,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC;YACpC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,wBAAe,EAAE,CAAC;oBACrC,OAAO,CAAC,CAAC,IAAI,CACX;wBACE,KAAK,EAAE,KAAK,CAAC,OAAO;wBACpB,WAAW,EAAE,KAAK,CAAC,cAAc,EAAE;qBACpC,EACD,GAAG,CACG,CAAC;gBACX,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QAED,MAAM,IAAI,EAAE,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PipeTransform, ArgumentMetadata } from '@nestjs/common';
|
|
2
|
+
import { ParseOptions, QueryAST, QastNode } from '../index';
|
|
3
|
+
/**
|
|
4
|
+
* NestJS pipe for parsing QAST queries from query parameters
|
|
5
|
+
*/
|
|
6
|
+
export declare class QastPipe implements PipeTransform {
|
|
7
|
+
private readonly options?;
|
|
8
|
+
constructor(options?: ParseOptions | undefined);
|
|
9
|
+
transform(value: any, _metadata: ArgumentMetadata): QastNode;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* NestJS pipe for parsing full QAST queries (with sorting and pagination)
|
|
13
|
+
*/
|
|
14
|
+
export declare class QastFullPipe implements PipeTransform {
|
|
15
|
+
private readonly options?;
|
|
16
|
+
constructor(options?: ParseOptions | undefined);
|
|
17
|
+
transform(value: any, _metadata: ArgumentMetadata): QueryAST;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* NestJS decorator for extracting query filter from request
|
|
21
|
+
*/
|
|
22
|
+
export declare function QastQuery(_options?: ParseOptions): ParameterDecorator;
|
|
23
|
+
//# sourceMappingURL=nestjs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nestjs.d.ts","sourceRoot":"","sources":["../../src/integrations/nestjs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAc,gBAAgB,EAAuB,MAAM,gBAAgB,CAAC;AAClG,OAAO,EAA8B,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGxF;;GAEG;AACH,qBACa,QAAS,YAAW,aAAa;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAR,OAAO,CAAC,EAAE,YAAY,YAAA;IAEnD,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,gBAAgB,GAAG,QAAQ;CAiB7D;AAED;;GAEG;AACH,qBACa,YAAa,YAAW,aAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAR,OAAO,CAAC,EAAE,YAAY,YAAA;IAEnD,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,gBAAgB,GAAG,QAAQ;CAiB7D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,QAAQ,CAAC,EAAE,YAAY,GAAG,kBAAkB,CAKrE"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
+
var _, done = false;
|
|
8
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
+
var context = {};
|
|
10
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
+
if (kind === "accessor") {
|
|
15
|
+
if (result === void 0) continue;
|
|
16
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
+
}
|
|
21
|
+
else if (_ = accept(result)) {
|
|
22
|
+
if (kind === "field") initializers.unshift(_);
|
|
23
|
+
else descriptor[key] = _;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
29
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
+
var useValue = arguments.length > 2;
|
|
31
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
+
}
|
|
34
|
+
return useValue ? value : void 0;
|
|
35
|
+
};
|
|
36
|
+
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
37
|
+
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
38
|
+
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
39
|
+
};
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.QastFullPipe = exports.QastPipe = void 0;
|
|
42
|
+
exports.QastQuery = QastQuery;
|
|
43
|
+
const common_1 = require("@nestjs/common");
|
|
44
|
+
const index_1 = require("../index");
|
|
45
|
+
const errors_1 = require("../errors");
|
|
46
|
+
/**
|
|
47
|
+
* NestJS pipe for parsing QAST queries from query parameters
|
|
48
|
+
*/
|
|
49
|
+
let QastPipe = (() => {
|
|
50
|
+
let _classDecorators = [(0, common_1.Injectable)()];
|
|
51
|
+
let _classDescriptor;
|
|
52
|
+
let _classExtraInitializers = [];
|
|
53
|
+
let _classThis;
|
|
54
|
+
var QastPipe = _classThis = class {
|
|
55
|
+
constructor(options) {
|
|
56
|
+
this.options = options;
|
|
57
|
+
}
|
|
58
|
+
transform(value, _metadata) {
|
|
59
|
+
if (typeof value !== 'string') {
|
|
60
|
+
throw new common_1.BadRequestException('Query filter must be a string');
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
return (0, index_1.parseQuery)(value, this.options);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (error instanceof errors_1.ValidationError || error instanceof errors_1.ParseError) {
|
|
67
|
+
throw new common_1.BadRequestException({
|
|
68
|
+
message: error.message,
|
|
69
|
+
suggestions: error.getSuggestions ? error.getSuggestions() : [],
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
throw new common_1.BadRequestException('Invalid query format');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
__setFunctionName(_classThis, "QastPipe");
|
|
77
|
+
(() => {
|
|
78
|
+
const _metadata_1 = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
79
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata_1 }, null, _classExtraInitializers);
|
|
80
|
+
QastPipe = _classThis = _classDescriptor.value;
|
|
81
|
+
if (_metadata_1) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata_1 });
|
|
82
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
83
|
+
})();
|
|
84
|
+
return QastPipe = _classThis;
|
|
85
|
+
})();
|
|
86
|
+
exports.QastPipe = QastPipe;
|
|
87
|
+
/**
|
|
88
|
+
* NestJS pipe for parsing full QAST queries (with sorting and pagination)
|
|
89
|
+
*/
|
|
90
|
+
let QastFullPipe = (() => {
|
|
91
|
+
let _classDecorators = [(0, common_1.Injectable)()];
|
|
92
|
+
let _classDescriptor;
|
|
93
|
+
let _classExtraInitializers = [];
|
|
94
|
+
let _classThis;
|
|
95
|
+
var QastFullPipe = _classThis = class {
|
|
96
|
+
constructor(options) {
|
|
97
|
+
this.options = options;
|
|
98
|
+
}
|
|
99
|
+
transform(value, _metadata) {
|
|
100
|
+
if (typeof value !== 'string') {
|
|
101
|
+
throw new common_1.BadRequestException('Query filter must be a string');
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
return (0, index_1.parseQueryFull)(value, this.options);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if (error instanceof errors_1.ValidationError || error instanceof errors_1.ParseError) {
|
|
108
|
+
throw new common_1.BadRequestException({
|
|
109
|
+
message: error.message,
|
|
110
|
+
suggestions: error.getSuggestions ? error.getSuggestions() : [],
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
throw new common_1.BadRequestException('Invalid query format');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
__setFunctionName(_classThis, "QastFullPipe");
|
|
118
|
+
(() => {
|
|
119
|
+
const _metadata_1 = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
120
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata_1 }, null, _classExtraInitializers);
|
|
121
|
+
QastFullPipe = _classThis = _classDescriptor.value;
|
|
122
|
+
if (_metadata_1) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata_1 });
|
|
123
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
124
|
+
})();
|
|
125
|
+
return QastFullPipe = _classThis;
|
|
126
|
+
})();
|
|
127
|
+
exports.QastFullPipe = QastFullPipe;
|
|
128
|
+
/**
|
|
129
|
+
* NestJS decorator for extracting query filter from request
|
|
130
|
+
*/
|
|
131
|
+
function QastQuery(_options) {
|
|
132
|
+
return (_target, _propertyKey, _parameterIndex) => {
|
|
133
|
+
// This is a simple decorator - actual implementation would use NestJS's metadata system
|
|
134
|
+
// In practice, you'd use it with @Query('filter') and the QastPipe
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=nestjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nestjs.js","sourceRoot":"","sources":["../../src/integrations/nestjs.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,8BAKC;AAhED,2CAAkG;AAClG,oCAAwF;AACxF,sCAAwD;AAExD;;GAEG;IAEU,QAAQ;4BADpB,IAAA,mBAAU,GAAE;;;;;QAEX,YAA6B,OAAsB;YAAtB,YAAO,GAAP,OAAO,CAAe;QAAG,CAAC;QAEvD,SAAS,CAAC,KAAU,EAAE,SAA2B;YAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,MAAM,IAAI,4BAAmB,CAAC,+BAA+B,CAAC,CAAC;YACjE,CAAC;YAED,IAAI,CAAC;gBACH,OAAO,IAAA,kBAAU,EAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,wBAAe,IAAI,KAAK,YAAY,mBAAU,EAAE,CAAC;oBACpE,MAAM,IAAI,4BAAmB,CAAC;wBAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,WAAW,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE;qBAChE,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM,IAAI,4BAAmB,CAAC,sBAAsB,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;;;;;QAnBH,+KAoBC;;;QApBY,uDAAQ;;;;AAAR,4BAAQ;AAsBrB;;GAEG;IAEU,YAAY;4BADxB,IAAA,mBAAU,GAAE;;;;;QAEX,YAA6B,OAAsB;YAAtB,YAAO,GAAP,OAAO,CAAe;QAAG,CAAC;QAEvD,SAAS,CAAC,KAAU,EAAE,SAA2B;YAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,MAAM,IAAI,4BAAmB,CAAC,+BAA+B,CAAC,CAAC;YACjE,CAAC;YAED,IAAI,CAAC;gBACH,OAAO,IAAA,sBAAc,EAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,wBAAe,IAAI,KAAK,YAAY,mBAAU,EAAE,CAAC;oBACpE,MAAM,IAAI,4BAAmB,CAAC;wBAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,WAAW,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE;qBAChE,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM,IAAI,4BAAmB,CAAC,sBAAsB,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;;;;;QAnBH,+KAoBC;;;QApBY,uDAAY;;;;AAAZ,oCAAY;AAsBzB;;GAEG;AACH,SAAgB,SAAS,CAAC,QAAuB;IAC/C,OAAO,CAAC,OAAY,EAAE,YAAyC,EAAE,eAAuB,EAAE,EAAE;QAC1F,wFAAwF;QACxF,mEAAmE;IACrE,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/parser/parser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Token } from './tokenizer';
|
|
2
|
-
import { QastNode } from '../types/ast';
|
|
2
|
+
import { QastNode, QueryAST } from '../types/ast';
|
|
3
3
|
/**
|
|
4
4
|
* Parser for QAST query strings
|
|
5
5
|
* Grammar:
|
|
@@ -25,11 +25,11 @@ export declare class Parser {
|
|
|
25
25
|
*/
|
|
26
26
|
private check;
|
|
27
27
|
/**
|
|
28
|
-
* Parse a factor: IDENTIFIER OPERATOR VALUE
|
|
28
|
+
* Parse a factor: IDENTIFIER OPERATOR VALUE | IDENTIFIER between VALUE and VALUE | IDENTIFIER (isNull|isNotNull)
|
|
29
29
|
*/
|
|
30
30
|
private parseFactor;
|
|
31
31
|
/**
|
|
32
|
-
* Parse a term: factor | "(" expression ")"
|
|
32
|
+
* Parse a term: factor | "(" expression ")" | "not" term
|
|
33
33
|
*/
|
|
34
34
|
private parseTerm;
|
|
35
35
|
/**
|
|
@@ -38,12 +38,20 @@ export declare class Parser {
|
|
|
38
38
|
*/
|
|
39
39
|
private parseExpression;
|
|
40
40
|
/**
|
|
41
|
-
* Parse
|
|
41
|
+
* Parse orderBy clause: orderBy field (asc|desc) (, field (asc|desc))*
|
|
42
42
|
*/
|
|
43
|
-
|
|
43
|
+
private parseOrderBy;
|
|
44
|
+
/**
|
|
45
|
+
* Parse the query and return the QueryAST
|
|
46
|
+
*/
|
|
47
|
+
parse(): QueryAST;
|
|
44
48
|
}
|
|
45
49
|
/**
|
|
46
|
-
* Parse a query string into
|
|
50
|
+
* Parse a query string into a QueryAST
|
|
51
|
+
*/
|
|
52
|
+
export declare function parseQueryString(query: string): QueryAST;
|
|
53
|
+
/**
|
|
54
|
+
* Parse a query string into just the filter AST (backward compatibility)
|
|
47
55
|
*/
|
|
48
|
-
export declare function
|
|
56
|
+
export declare function parseQueryStringFilter(query: string): QastNode;
|
|
49
57
|
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/parser/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,EAAa,MAAM,aAAa,CAAC;AAC1D,OAAO,
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/parser/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,EAAa,MAAM,aAAa,CAAC;AAC1D,OAAO,EACL,QAAQ,EAMR,QAAQ,EAGT,MAAM,cAAc,CAAC;AAGtB;;;;;;GAMG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAQ;gBAEhB,MAAM,EAAE,KAAK,EAAE;IAM3B;;OAEG;IACH,OAAO,CAAC,OAAO;IASf;;OAEG;IACH,OAAO,CAAC,MAAM;IAYd;;OAEG;IACH,OAAO,CAAC,KAAK;IAIb;;OAEG;IACH,OAAO,CAAC,WAAW;IAsEnB;;OAEG;IACH,OAAO,CAAC,SAAS;IAuBjB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAiCvB;;OAEG;IACH,OAAO,CAAC,YAAY;IA+BpB;;OAEG;IACI,KAAK,IAAI,QAAQ;CAoCzB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAYxD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAG9D"}
|
package/dist/parser/parser.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Parser = void 0;
|
|
4
4
|
exports.parseQueryString = parseQueryString;
|
|
5
|
+
exports.parseQueryStringFilter = parseQueryStringFilter;
|
|
5
6
|
const tokenizer_1 = require("./tokenizer");
|
|
6
7
|
const errors_1 = require("../errors");
|
|
7
8
|
/**
|
|
@@ -48,22 +49,52 @@ class Parser {
|
|
|
48
49
|
return this.currentToken.type === type;
|
|
49
50
|
}
|
|
50
51
|
/**
|
|
51
|
-
* Parse a factor: IDENTIFIER OPERATOR VALUE
|
|
52
|
+
* Parse a factor: IDENTIFIER OPERATOR VALUE | IDENTIFIER between VALUE and VALUE | IDENTIFIER (isNull|isNotNull)
|
|
52
53
|
*/
|
|
53
54
|
parseFactor() {
|
|
54
55
|
// Get field name (identifier)
|
|
55
56
|
const fieldToken = this.expect(tokenizer_1.TokenType.IDENTIFIER, 'Expected field name (identifier)');
|
|
56
57
|
const field = fieldToken.value;
|
|
58
|
+
// Check for isNull/isNotNull
|
|
59
|
+
if (this.check(tokenizer_1.TokenType.IS_NULL)) {
|
|
60
|
+
this.advance();
|
|
61
|
+
return {
|
|
62
|
+
type: 'NULL_CHECK',
|
|
63
|
+
field,
|
|
64
|
+
isNull: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (this.check(tokenizer_1.TokenType.IS_NOT_NULL)) {
|
|
68
|
+
this.advance();
|
|
69
|
+
return {
|
|
70
|
+
type: 'NULL_CHECK',
|
|
71
|
+
field,
|
|
72
|
+
isNull: false,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// Check for between operator
|
|
76
|
+
if (this.check(tokenizer_1.TokenType.BETWEEN)) {
|
|
77
|
+
this.advance(); // Skip 'between'
|
|
78
|
+
const minToken = this.expect(tokenizer_1.TokenType.VALUE, 'Expected value after between');
|
|
79
|
+
this.expect(tokenizer_1.TokenType.AND_KEYWORD, 'Expected "and" after between value');
|
|
80
|
+
const maxToken = this.expect(tokenizer_1.TokenType.VALUE, 'Expected value after and');
|
|
81
|
+
return {
|
|
82
|
+
type: 'BETWEEN',
|
|
83
|
+
field,
|
|
84
|
+
min: minToken.value,
|
|
85
|
+
max: maxToken.value,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
57
88
|
// Get operator
|
|
58
|
-
const operatorToken = this.expect(tokenizer_1.TokenType.OPERATOR, 'Expected operator
|
|
89
|
+
const operatorToken = this.expect(tokenizer_1.TokenType.OPERATOR, 'Expected operator');
|
|
59
90
|
const op = operatorToken.value;
|
|
60
91
|
// Get value
|
|
61
92
|
const valueToken = this.expect(tokenizer_1.TokenType.VALUE, 'Expected value');
|
|
62
93
|
const value = valueToken.value;
|
|
63
94
|
// Validate operator and value combination
|
|
64
|
-
if (op === 'in') {
|
|
95
|
+
if (op === 'in' || op === 'notIn') {
|
|
65
96
|
if (!Array.isArray(value)) {
|
|
66
|
-
throw new errors_1.ParseError(`Operator '
|
|
97
|
+
throw new errors_1.ParseError(`Operator '${op}' requires an array value, got ${typeof value} at position ${valueToken.position}`);
|
|
67
98
|
}
|
|
68
99
|
}
|
|
69
100
|
return {
|
|
@@ -74,9 +105,18 @@ class Parser {
|
|
|
74
105
|
};
|
|
75
106
|
}
|
|
76
107
|
/**
|
|
77
|
-
* Parse a term: factor | "(" expression ")"
|
|
108
|
+
* Parse a term: factor | "(" expression ")" | "not" term
|
|
78
109
|
*/
|
|
79
110
|
parseTerm() {
|
|
111
|
+
// Check for NOT operator
|
|
112
|
+
if (this.check(tokenizer_1.TokenType.NOT)) {
|
|
113
|
+
this.advance(); // Skip 'not'
|
|
114
|
+
const operand = this.parseTerm();
|
|
115
|
+
return {
|
|
116
|
+
type: 'NOT',
|
|
117
|
+
operand,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
80
120
|
if (this.check(tokenizer_1.TokenType.PAREN_OPEN)) {
|
|
81
121
|
// Handle parentheses: "(" expression ")"
|
|
82
122
|
this.advance(); // Skip '('
|
|
@@ -96,10 +136,17 @@ class Parser {
|
|
|
96
136
|
parseExpression() {
|
|
97
137
|
let left = this.parseTerm();
|
|
98
138
|
// Process logical operators (left-associative)
|
|
99
|
-
|
|
139
|
+
// Note: "and" is tokenized as AND_KEYWORD, but we treat it as a logical operator here
|
|
140
|
+
while ((this.check(tokenizer_1.TokenType.LOGICAL_OP) || this.check(tokenizer_1.TokenType.AND_KEYWORD)) &&
|
|
100
141
|
this.currentToken.type !== tokenizer_1.TokenType.EOF) {
|
|
101
142
|
const logicalOpToken = this.currentToken;
|
|
102
|
-
|
|
143
|
+
let logicalOp;
|
|
144
|
+
if (this.check(tokenizer_1.TokenType.AND_KEYWORD)) {
|
|
145
|
+
logicalOp = 'AND';
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
logicalOp = logicalOpToken.value.toUpperCase();
|
|
149
|
+
}
|
|
103
150
|
this.advance(); // Skip logical operator
|
|
104
151
|
const right = this.parseTerm();
|
|
105
152
|
// Create logical node (left-associative)
|
|
@@ -112,24 +159,72 @@ class Parser {
|
|
|
112
159
|
return left;
|
|
113
160
|
}
|
|
114
161
|
/**
|
|
115
|
-
* Parse
|
|
162
|
+
* Parse orderBy clause: orderBy field (asc|desc) (, field (asc|desc))*
|
|
163
|
+
*/
|
|
164
|
+
parseOrderBy() {
|
|
165
|
+
const orderBy = [];
|
|
166
|
+
// Parse first field
|
|
167
|
+
const fieldToken = this.expect(tokenizer_1.TokenType.IDENTIFIER, 'Expected field name after orderBy');
|
|
168
|
+
let direction = 'asc';
|
|
169
|
+
if (this.check(tokenizer_1.TokenType.ASC) || this.check(tokenizer_1.TokenType.DESC)) {
|
|
170
|
+
direction = this.currentToken.value.toLowerCase();
|
|
171
|
+
this.advance();
|
|
172
|
+
}
|
|
173
|
+
orderBy.push({ field: fieldToken.value, direction });
|
|
174
|
+
// Parse additional fields
|
|
175
|
+
while (this.check(tokenizer_1.TokenType.COMMA)) {
|
|
176
|
+
this.advance(); // Skip comma
|
|
177
|
+
const nextFieldToken = this.expect(tokenizer_1.TokenType.IDENTIFIER, 'Expected field name after comma');
|
|
178
|
+
let nextDirection = 'asc';
|
|
179
|
+
if (this.check(tokenizer_1.TokenType.ASC) || this.check(tokenizer_1.TokenType.DESC)) {
|
|
180
|
+
nextDirection = this.currentToken.value.toLowerCase();
|
|
181
|
+
this.advance();
|
|
182
|
+
}
|
|
183
|
+
orderBy.push({ field: nextFieldToken.value, direction: nextDirection });
|
|
184
|
+
}
|
|
185
|
+
return orderBy;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Parse the query and return the QueryAST
|
|
116
189
|
*/
|
|
117
190
|
parse() {
|
|
118
191
|
if (this.tokens.length === 1 && this.tokens[0].type === tokenizer_1.TokenType.EOF) {
|
|
119
192
|
throw new errors_1.ParseError('Empty query string');
|
|
120
193
|
}
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
194
|
+
const filter = this.parseExpression();
|
|
195
|
+
const result = { filter };
|
|
196
|
+
// Parse optional clauses
|
|
197
|
+
while (this.currentToken.type !== tokenizer_1.TokenType.EOF) {
|
|
198
|
+
if (this.check(tokenizer_1.TokenType.ORDER_BY)) {
|
|
199
|
+
this.advance(); // Skip 'orderBy'
|
|
200
|
+
result.orderBy = this.parseOrderBy();
|
|
201
|
+
}
|
|
202
|
+
else if (this.check(tokenizer_1.TokenType.LIMIT)) {
|
|
203
|
+
this.advance(); // Skip 'limit'
|
|
204
|
+
const limitToken = this.expect(tokenizer_1.TokenType.VALUE, 'Expected number after limit');
|
|
205
|
+
if (typeof limitToken.value !== 'number' || limitToken.value < 0) {
|
|
206
|
+
throw new errors_1.ParseError(`Limit must be a non-negative number, got ${limitToken.value} at position ${limitToken.position}`);
|
|
207
|
+
}
|
|
208
|
+
result.limit = limitToken.value;
|
|
209
|
+
}
|
|
210
|
+
else if (this.check(tokenizer_1.TokenType.OFFSET)) {
|
|
211
|
+
this.advance(); // Skip 'offset'
|
|
212
|
+
const offsetToken = this.expect(tokenizer_1.TokenType.VALUE, 'Expected number after offset');
|
|
213
|
+
if (typeof offsetToken.value !== 'number' || offsetToken.value < 0) {
|
|
214
|
+
throw new errors_1.ParseError(`Offset must be a non-negative number, got ${offsetToken.value} at position ${offsetToken.position}`);
|
|
215
|
+
}
|
|
216
|
+
result.offset = offsetToken.value;
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
throw new errors_1.ParseError(`Unexpected token: ${this.currentToken.type} at position ${this.currentToken.position}. Expected orderBy, limit, offset, or end of query.`);
|
|
220
|
+
}
|
|
126
221
|
}
|
|
127
|
-
return
|
|
222
|
+
return result;
|
|
128
223
|
}
|
|
129
224
|
}
|
|
130
225
|
exports.Parser = Parser;
|
|
131
226
|
/**
|
|
132
|
-
* Parse a query string into
|
|
227
|
+
* Parse a query string into a QueryAST
|
|
133
228
|
*/
|
|
134
229
|
function parseQueryString(query) {
|
|
135
230
|
try {
|
|
@@ -145,4 +240,11 @@ function parseQueryString(query) {
|
|
|
145
240
|
throw new errors_1.ParseError(`Failed to parse query: ${error instanceof Error ? error.message : String(error)}`);
|
|
146
241
|
}
|
|
147
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Parse a query string into just the filter AST (backward compatibility)
|
|
245
|
+
*/
|
|
246
|
+
function parseQueryStringFilter(query) {
|
|
247
|
+
const queryAST = parseQueryString(query);
|
|
248
|
+
return queryAST.filter;
|
|
249
|
+
}
|
|
148
250
|
//# sourceMappingURL=parser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/parser/parser.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/parser/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,16 @@ export declare enum TokenType {
|
|
|
11
11
|
BRACKET_OPEN = "BRACKET_OPEN",
|
|
12
12
|
BRACKET_CLOSE = "BRACKET_CLOSE",
|
|
13
13
|
COMMA = "COMMA",
|
|
14
|
+
NOT = "NOT",
|
|
15
|
+
BETWEEN = "BETWEEN",
|
|
16
|
+
AND_KEYWORD = "AND_KEYWORD",
|
|
17
|
+
IS_NULL = "IS_NULL",
|
|
18
|
+
IS_NOT_NULL = "IS_NOT_NULL",
|
|
19
|
+
ORDER_BY = "ORDER_BY",
|
|
20
|
+
LIMIT = "LIMIT",
|
|
21
|
+
OFFSET = "OFFSET",
|
|
22
|
+
ASC = "ASC",
|
|
23
|
+
DESC = "DESC",
|
|
14
24
|
EOF = "EOF"
|
|
15
25
|
}
|
|
16
26
|
/**
|
|
@@ -42,7 +52,7 @@ export declare class Tokenizer {
|
|
|
42
52
|
*/
|
|
43
53
|
private peek;
|
|
44
54
|
/**
|
|
45
|
-
* Read an identifier (field name)
|
|
55
|
+
* Read an identifier (field name, supports nested fields with dots)
|
|
46
56
|
*/
|
|
47
57
|
private readIdentifier;
|
|
48
58
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../../src/parser/tokenizer.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,oBAAY,SAAS;IACnB,UAAU,eAAe;IACzB,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,UAAU,eAAe;IACzB,UAAU,eAAe;IACzB,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,KAAK,UAAU;IACf,GAAG,QAAQ;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IAC9D,QAAQ,EAAE,MAAM,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../../src/parser/tokenizer.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,oBAAY,SAAS;IACnB,UAAU,eAAe;IACzB,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,UAAU,eAAe;IACzB,UAAU,eAAe;IACzB,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,OAAO,YAAY;IACnB,WAAW,gBAAgB;IAC3B,OAAO,YAAY;IACnB,WAAW,gBAAgB;IAC3B,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,MAAM,WAAW;IACjB,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,GAAG,QAAQ;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IAC9D,QAAQ,EAAE,MAAM,CAAC;CAClB;AA4CD;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAgB;gBAEvB,KAAK,EAAE,MAAM;IAMzB;;OAEG;IACH,OAAO,CAAC,OAAO;IASf;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;IACH,OAAO,CAAC,IAAI;IAOZ;;OAEG;IACH,OAAO,CAAC,cAAc;IAWtB;;OAEG;IACH,OAAO,CAAC,UAAU;IA2ClB;;OAEG;IACH,OAAO,CAAC,UAAU;IAoClB;;OAEG;IACH,OAAO,CAAC,WAAW;IAkBnB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAehB;;OAEG;IACH,OAAO,CAAC,SAAS;IAoDjB;;OAEG;IACI,SAAS,IAAI,KAAK;IAwKzB;;OAEG;IACI,QAAQ,IAAI,KAAK,EAAE;CAU3B"}
|