@jin-qu/jinqu 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Umut Özel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,212 @@
1
+ # Jinqu - LINQ for Javascript
2
+
3
+ [![Build and Test](https://github.com/jin-qu/jinqu/actions/workflows/build.yml/badge.svg)](https://github.com/jin-qu/jinqu/actions/workflows/build.yml)
4
+ [![codecov](https://codecov.io/gh/jin-qu/jinqu/graph/badge.svg?token=KkhZnOc44l)](https://codecov.io/gh/jin-qu/jinqu)
5
+ [![Codacy Badge](https://app.codacy.com/project/badge/Grade/5cc1af8cf2304b4aa5362c33225b380f)](https://www.codacy.com/gh/jin-qu/jinqu/dashboard?utm_source=github.com&utm_medium=referral&utm_content=jin-qu/jinqu&utm_campaign=Badge_Grade)
6
+ <a href="https://snyk.io/test/npm/jinqu"><img src="https://snyk.io/test/npm/jinqu/badge.svg" alt="Known Vulnerabilities" data-canonical-src="https://snyk.io/test/npm/jinqu" style="max-width:100%;"></a>
7
+
8
+ [![npm version](https://img.shields.io/npm/v/jinqu)](https://www.npmjs.com/package/jinqu)
9
+ [![npm downloads](https://img.shields.io/npm/dm/jinqu.svg)](https://www.npmjs.com/package/jinqu)
10
+
11
+ [![GitHub issues](https://img.shields.io/github/issues/jin-qu/jinqu.svg)](https://github.com/jin-qu/jinqu/issues)
12
+ [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/jin-qu/jinqu/main/LICENSE)
13
+ [![GitHub stars](https://img.shields.io/github/stars/jin-qu/jinqu.svg?style=social&label=Star)](https://github.com/jin-qu/jinqu)
14
+ [![GitHub forks](https://img.shields.io/github/forks/jin-qu/jinqu.svg?style=social&label=Fork)](https://github.com/jin-qu/jinqu)
15
+
16
+ Jinqu, based on the LINQ design, is the ultimate querying API for Javscript & Typescript. It provides:
17
+
18
+ * LINQ syntax
19
+ * Lazy (i.e. deferred) Evaluation
20
+ * Local and Remote Evaluation w/ provider model for libraries implementing remote evaluation (e.g. `jinqu-odata`)
21
+ * Static Typing (in Typescript)
22
+ * Dynamic queries (in strings)
23
+ * Even works on IE 11 (with transpilation)
24
+
25
+ Jinqu works perfectly in both Javascript and Typescript, but is optimized for Typescript. Jinqu is itself written in Typescript.
26
+
27
+ ## Installation
28
+
29
+ > npm install jinqu
30
+
31
+ ## Code Examples
32
+
33
+ First, make sure you've imported jinqu. This will add **asQueryable** method to Array Prototype.
34
+
35
+ ```typescript
36
+ import 'jinqu'
37
+ ```
38
+
39
+ We need to call **asQueryable** to create a query for an Array.
40
+
41
+ ```typescript
42
+ const array = [1,2,3,4,5]
43
+ const query = array.asQueryable().where(c => n % 2 == 0).toArray()
44
+ for (var n of query)
45
+ console.log (n) // outputs 2,4
46
+ ```
47
+
48
+ If you want to use query methods directly, you need to install and import **jinqu-array-extensions** package.
49
+
50
+ > npm i jinqu-array-extensions
51
+
52
+ ```typescript
53
+ import 'jinqu-array-extensions'
54
+ ```
55
+
56
+ You actually only need to do this once, such as in the entry point for your application, to ensure the Array prototype extensions are set up.
57
+
58
+ Now let's filter an array:
59
+
60
+ ```typescript
61
+ const array = [1,2,3,4,5]
62
+ const query = array.where(c => n % 2 == 0).toArray()
63
+ for (var n of query)
64
+ console.log (n) // outputs 2,4
65
+ ```
66
+
67
+ We can *chain* query operators:
68
+
69
+ ```typescript
70
+ const array = [1,2,3,4,5]
71
+ const query = array
72
+ .where(c => n % 2 == 0)
73
+ .orderByDescending (n => n)
74
+ .toArray()
75
+ for (var n of query)
76
+ console.log (n) // outputs 4,2
77
+ ```
78
+
79
+ Importantly, results aren't evaluated until `toArray` is called.
80
+
81
+ ## Dynamic Expressions
82
+
83
+ ```JavaScript
84
+ const filtered = orders.where('c => c.id > value', { value: 3 })
85
+ ```
86
+
87
+ The additional argument is a *variable scope* that lets you pass in variables dynamically.
88
+
89
+ ## Supported Query Operators
90
+
91
+ The full range of LINQ operators are supported:
92
+
93
+ ```typescript
94
+ where
95
+ ofType
96
+ cast
97
+ select
98
+ selectMany
99
+ join
100
+ groupJoin
101
+ orderBy
102
+ orderByDescending
103
+ thenBy
104
+ thenByDescending
105
+ take
106
+ takeWhile
107
+ skip
108
+ skipWhile
109
+ groupBy
110
+ distinct
111
+ concat
112
+ zip
113
+ union
114
+ intersect
115
+ except
116
+ defaultIfEmpty
117
+ reverse
118
+ first
119
+ firstOrDefault
120
+ last
121
+ lastOrDefault
122
+ single
123
+ singleOrDefault
124
+ elementAt
125
+ elementAtOrDefault
126
+ contains
127
+ sequenceEqual
128
+ any
129
+ all
130
+ count
131
+ min
132
+ max
133
+ sum
134
+ average
135
+ aggregate
136
+ toArray
137
+ ```
138
+
139
+ As well as:
140
+
141
+ ```typescript
142
+ ofGuardedType
143
+ ```
144
+
145
+ And also:
146
+
147
+ ```typescript
148
+ range
149
+ repeat
150
+ ```
151
+
152
+ ## Remote Query Providers
153
+
154
+ Jinqu has the following remote providers:
155
+
156
+ * [Jinqu-OData](https://github.com/jin-qu/jinqu-odata) - Query OData endpoints
157
+ * [Linquest](https://github.com/jin-qu/linquest) - Query Remote LINQ endpoints
158
+
159
+ Remote queries always return promises so are awaited. So rather than `toArray` to obtain the results of the query, you'll call `toArrayAsync`:
160
+
161
+ ```typescript
162
+ const result = await remoteQuery.toArrayAsync()
163
+ for (var item of result) {
164
+ // do stuff
165
+ }
166
+ ```
167
+
168
+ ## Array Prototype Extensions
169
+
170
+ Jinqu query operators build queries with a simple model: they take a query type as an input, transform it, and output another query type. However, the very first operator in a query needs to take an array type as the original source for the query. To make this work, jinqu extends the Array prototype.
171
+
172
+ Extending the array prototype is very convenient, but occasionally has conflict issues with Array's built-in prototype or other 3rd party prototype extensions.
173
+
174
+ To overcome this, you can call `asQueryable` or the convenience `q` for short, to ensure you're working with an `IQuery<T>` type:
175
+
176
+ ```typescript
177
+ [1,2,3].asQueryable().reverse()
178
+ [1,2,3].q().reverse() // same as above
179
+ ```
180
+
181
+ In addition, the `concat`, `join`, and `reverse` methdos (which are built into the Array prototype), have special support: call `concatWith`, `joinWith`, and `reverseTo`, to start a query with these operators on the array type.
182
+
183
+ ## ofType and ofGuardedType
184
+
185
+ `ofType` and `ofGuardedType` filter elements of a specified type. The type arguments you must supply are a little different to what you might expect if you come from a C# background, but will make sense to you when you get a feel for the Typescript type system.
186
+
187
+ * `ofType` takes either a:
188
+ * constructor to filter class instances
189
+ * default value to filter primitive types
190
+ * `ofGuardedType` takes a:
191
+ * Typescript type guard (See [Typescript Advanced Types](https://www.typescriptlang.org/docs/handbook/advanced-types.html)) to filter values by a condition indicative of type
192
+
193
+ Their usage is as follows:
194
+
195
+ ```typescript
196
+ class Panda {
197
+ constructor (public id: number) {}
198
+ }
199
+
200
+ function isNumber(x: any): x is number {
201
+ return typeof x === "number"
202
+ }
203
+
204
+ const array = ["1", 2, new Panda(3), "4", 5, new Panda(6)]
205
+ const justPandas = array.ofType(Panda) // panda 3, panda 6 - using constructor type filter
206
+ const justStrings = array.ofType("") // "1", "4" - using default value type filter
207
+ const justNumbers = array.ofGuardedType(isNumber) // 2, 5 - using type guard filter
208
+ ```
209
+
210
+ ## License
211
+
212
+ jinqu is licensed with the [MIT License](LICENSE).
@@ -0,0 +1,11 @@
1
+ import { Ctor, IQuery } from "./lib/shared";
2
+ declare global {
3
+ interface Array<T> {
4
+ asQueryable(ctor?: Ctor<T>): IQuery<T>;
5
+ }
6
+ }
7
+ export * from "./lib/ajax";
8
+ export * from "./lib/array-query-provider";
9
+ export * from "./lib/query-part";
10
+ export * from "./lib/query";
11
+ export * from "./lib/shared";
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ var array_query_provider_1 = require("./lib/array-query-provider");
18
+ Array.prototype.asQueryable = function (ctor) {
19
+ var query = new array_query_provider_1.ArrayQueryProvider(this).createQuery();
20
+ return ctor ? query.cast(ctor) : query;
21
+ };
22
+ __exportStar(require("./lib/ajax"), exports);
23
+ __exportStar(require("./lib/array-query-provider"), exports);
24
+ __exportStar(require("./lib/query-part"), exports);
25
+ __exportStar(require("./lib/query"), exports);
26
+ __exportStar(require("./lib/shared"), exports);
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mEAAgE;AAShE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,UAAS,IAAmB;IACtD,IAAM,KAAK,GAAG,IAAI,yCAAkB,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IACzD,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3C,CAAC,CAAC;AAEF,6CAA2B;AAC3B,6DAA2C;AAC3C,mDAAiC;AACjC,8CAA4B;AAC5B,+CAA6B"}
@@ -0,0 +1,26 @@
1
+ import { Value } from "./shared";
2
+ export interface QueryParameter {
3
+ key: string;
4
+ value: string;
5
+ }
6
+ export declare const AjaxFuncs: {
7
+ includeResponse: string;
8
+ options: string;
9
+ };
10
+ export interface AjaxOptions {
11
+ $url?: string;
12
+ $method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
13
+ $params?: QueryParameter[];
14
+ $data?: unknown;
15
+ $timeout?: number;
16
+ $headers?: {
17
+ [key: string]: string;
18
+ };
19
+ }
20
+ export interface AjaxResponse<TResponse> {
21
+ response: TResponse;
22
+ }
23
+ export interface IAjaxProvider<TResponse, TOptions extends AjaxOptions = AjaxOptions> {
24
+ ajax<T>(options: TOptions): PromiseLike<Value<T> & AjaxResponse<TResponse>>;
25
+ }
26
+ export declare function mergeAjaxOptions(o1?: AjaxOptions | null, o2?: AjaxOptions | null): AjaxOptions;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AjaxFuncs = void 0;
4
+ exports.mergeAjaxOptions = mergeAjaxOptions;
5
+ exports.AjaxFuncs = {
6
+ includeResponse: "includeResponse",
7
+ options: "options",
8
+ };
9
+ function mergeAjaxOptions(o1, o2) {
10
+ if (o1 == null)
11
+ return o2;
12
+ if (o2 == null)
13
+ return o1;
14
+ return {
15
+ $data: Object.assign({}, o1.$data, o2.$data),
16
+ $headers: Object.assign({}, o1.$headers, o2.$headers),
17
+ $method: o2.$method || o1.$method,
18
+ $params: (o1.$params || []).concat(o2.$params || []),
19
+ $timeout: o2.$timeout || o1.$timeout,
20
+ $url: o2.$url != null ? o2.$url : o1.$url,
21
+ };
22
+ }
23
+ //# sourceMappingURL=ajax.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ajax.js","sourceRoot":"","sources":["../../lib/ajax.ts"],"names":[],"mappings":";;;AA4BA,4CAYC;AAlCY,QAAA,SAAS,GAAG;IACrB,eAAe,EAAE,iBAAiB;IAClC,OAAO,EAAE,SAAS;CACrB,CAAC;AAmBF,SAAgB,gBAAgB,CAAC,EAAuB,EAAE,EAAuB;IAC7E,IAAI,EAAE,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAC1B,IAAI,EAAE,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAE1B,OAAO;QACH,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC;QAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC;QACrD,OAAO,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO;QACjC,OAAO,EAAE,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC;QACpD,QAAQ,EAAE,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,QAAQ;QACpC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI;KAC5C,CAAC;AACN,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Query } from "./query";
2
+ import { Ctor, IQueryPart, IQueryProvider } from "./shared";
3
+ export declare class ArrayQueryProvider implements IQueryProvider {
4
+ private readonly items?;
5
+ constructor(items?: unknown[] | IterableIterator<unknown> | null);
6
+ createQuery<T>(parts?: IQueryPart[], ctor?: Ctor<T>): Query<T>;
7
+ execute<TResult = unknown>(parts?: IQueryPart[] | null): TResult;
8
+ executeAsync<TResult = unknown>(parts: IQueryPart[]): PromiseLike<TResult>;
9
+ handlePart(items: IterableIterator<unknown>, part: IQueryPart): any;
10
+ multiOrderBy(items: IterableIterator<unknown>, keySelectors: IQueryPart[]): ArrayIterator<unknown>;
11
+ }