@technicity/data-service-generator 0.5.3 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generation/generate.js +12 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/runtime/lib/shared.js +84 -42
- package/dist/runtime/lib/stringifyWhere.js +3 -0
- package/dist/traverseFieldArgs.d.ts +2 -0
- package/dist/traverseFieldArgs.js +13 -0
- package/package.json +1 -1
|
@@ -679,6 +679,11 @@ async function getJSONSchemaWhere(table) {
|
|
|
679
679
|
properties: { $like: { type: "string", minLength: 1 } },
|
|
680
680
|
additionalProperties: false,
|
|
681
681
|
},
|
|
682
|
+
{
|
|
683
|
+
type: "object",
|
|
684
|
+
properties: { $nlike: { type: "string", minLength: 1 } },
|
|
685
|
+
additionalProperties: false,
|
|
686
|
+
},
|
|
682
687
|
{
|
|
683
688
|
type: "object",
|
|
684
689
|
properties: { $in: { type: "array", items: v } },
|
|
@@ -814,14 +819,17 @@ function getTypeShared() {
|
|
|
814
819
|
last: number;
|
|
815
820
|
after?: string;
|
|
816
821
|
before?: string;
|
|
822
|
+
} | {
|
|
823
|
+
limit: number;
|
|
824
|
+
offset?: number;
|
|
817
825
|
}
|
|
818
826
|
|
|
819
827
|
export type ListPaginated<T> = {
|
|
820
828
|
paginationInfo: {
|
|
821
|
-
hasPreviousPage
|
|
822
|
-
hasNextPage
|
|
823
|
-
startCursor
|
|
824
|
-
endCursor
|
|
829
|
+
hasPreviousPage?: boolean,
|
|
830
|
+
hasNextPage?: boolean,
|
|
831
|
+
startCursor?: string | number,
|
|
832
|
+
endCursor?: string | number,
|
|
825
833
|
totalCount: number,
|
|
826
834
|
},
|
|
827
835
|
results: Array<T>,
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SDKNotFoundError = exports.generate = void 0;
|
|
3
|
+
exports.traverseFieldArgs = exports.SDKNotFoundError = exports.generate = void 0;
|
|
4
4
|
var generate_1 = require("./generation/generate");
|
|
5
5
|
Object.defineProperty(exports, "generate", { enumerable: true, get: function () { return generate_1.generate; } });
|
|
6
6
|
var SDKNotFoundError_1 = require("./runtime/lib/SDKNotFoundError");
|
|
7
7
|
Object.defineProperty(exports, "SDKNotFoundError", { enumerable: true, get: function () { return SDKNotFoundError_1.SDKNotFoundError; } });
|
|
8
|
+
var traverseFieldArgs_1 = require("./traverseFieldArgs");
|
|
9
|
+
Object.defineProperty(exports, "traverseFieldArgs", { enumerable: true, get: function () { return traverseFieldArgs_1.traverseFieldArgs; } });
|
|
@@ -88,29 +88,57 @@ async function getData(input, dbCall, formatQuery, dialect) {
|
|
|
88
88
|
const context = {};
|
|
89
89
|
const action = input.action;
|
|
90
90
|
const primaryKey = input.artifacts[input.resource].primaryKey;
|
|
91
|
+
let paginationType;
|
|
92
|
+
let limit = undefined;
|
|
93
|
+
let offset = undefined;
|
|
91
94
|
let rowWithMatchingCursor = undefined;
|
|
92
95
|
if (action === "findManyPaginated") {
|
|
93
96
|
if (input.args?.$paginate == null) {
|
|
94
97
|
throw new Error("$paginate required but not supplied");
|
|
95
98
|
}
|
|
96
|
-
if (input
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
: input.args.$paginate.before;
|
|
101
|
-
rowWithMatchingCursor = await dbCall(formatQuery("SELECT * FROM ?? WHERE ?? = ?", [
|
|
102
|
-
input.resource,
|
|
103
|
-
primaryKey,
|
|
104
|
-
cursor_1.decodeCursor(cursor),
|
|
105
|
-
])).then((xs) => xs[0]);
|
|
99
|
+
if (typeof input?.args?.$paginate?.limit === "number") {
|
|
100
|
+
paginationType = "limit-offset";
|
|
101
|
+
limit = input.args.$paginate.limit;
|
|
102
|
+
offset = input.args.$paginate.offset;
|
|
106
103
|
}
|
|
104
|
+
else {
|
|
105
|
+
paginationType = "cursor";
|
|
106
|
+
limit = (typeof input?.args?.$paginate?.first === "number"
|
|
107
|
+
? input?.args?.$paginate?.first
|
|
108
|
+
: input?.args?.$paginate?.last);
|
|
109
|
+
// + 1 to peek if there is more data
|
|
110
|
+
limit += 1;
|
|
111
|
+
if (input.args.$paginate.after != null ||
|
|
112
|
+
input.args.$paginate.before != null) {
|
|
113
|
+
const cursor = input.args.$paginate.after != null
|
|
114
|
+
? input.args.$paginate.after
|
|
115
|
+
: input.args.$paginate.before;
|
|
116
|
+
rowWithMatchingCursor = await dbCall(formatQuery("SELECT * FROM ?? WHERE ?? = ?", [
|
|
117
|
+
input.resource,
|
|
118
|
+
primaryKey,
|
|
119
|
+
cursor_1.decodeCursor(cursor),
|
|
120
|
+
])).then((xs) => xs[0]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else if (action === "findMany") {
|
|
125
|
+
limit = input?.args?.$limit;
|
|
107
126
|
}
|
|
108
127
|
// we need to read the query AST and build a new "SQL AST" from which the SQL and
|
|
109
128
|
// const sqlAST = queryAST.queryASTToSqlAST(resolveInfo, options, context);
|
|
110
129
|
const fields = input.fields ?? getScalarFields(input.resource, input.artifacts);
|
|
111
|
-
const orderByListPaginatedRootResult =
|
|
112
|
-
|
|
113
|
-
|
|
130
|
+
const orderByListPaginatedRootResult =
|
|
131
|
+
// MSSQL's OFFSET and FETCH requires ORDER BY, so we need to provide a fallback
|
|
132
|
+
dialect === "mssql" && paginationType === "limit-offset"
|
|
133
|
+
? {
|
|
134
|
+
orderBy: getOrderBy_1.getOrderBy(input.args, primaryKey)?.orderBy ?? [
|
|
135
|
+
{ column: primaryKey, direction: "asc" },
|
|
136
|
+
],
|
|
137
|
+
flip: false,
|
|
138
|
+
}
|
|
139
|
+
: action === "findManyPaginated"
|
|
140
|
+
? getOrderBy_1.getOrderBy(input.args, primaryKey)
|
|
141
|
+
: undefined;
|
|
114
142
|
const grabMany = action === "findMany" ||
|
|
115
143
|
action === "findManyPaginated" ||
|
|
116
144
|
action === "updateMany" ||
|
|
@@ -134,23 +162,21 @@ async function getData(input, dbCall, formatQuery, dialect) {
|
|
|
134
162
|
}
|
|
135
163
|
// TODO - remove if limit support added for mysql dialect
|
|
136
164
|
if (action === "findMany" || action === "findManyPaginated") {
|
|
137
|
-
let limit = undefined;
|
|
138
|
-
if (action === "findManyPaginated") {
|
|
139
|
-
limit = (typeof input?.args?.$paginate?.first === "number"
|
|
140
|
-
? input?.args?.$paginate?.first
|
|
141
|
-
: input?.args?.$paginate?.last);
|
|
142
|
-
// + 1 to peek if there is more data
|
|
143
|
-
limit += 1;
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
limit = input?.args?.$limit;
|
|
147
|
-
}
|
|
148
165
|
if (typeof limit === "number") {
|
|
149
|
-
|
|
150
|
-
|
|
166
|
+
const escape = stringifyWhere_1.getEscape(dialect);
|
|
167
|
+
if (dialect === "mssql") {
|
|
168
|
+
if (typeof offset === "number") {
|
|
169
|
+
sql += ` OFFSET ${escape(offset)} ROWS FETCH NEXT ${escape(limit)} ROWS ONLY`;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
sql = sql.replace("SELECT", `SELECT TOP ${escape(limit)}`);
|
|
173
|
+
}
|
|
151
174
|
}
|
|
152
175
|
else {
|
|
153
|
-
sql
|
|
176
|
+
sql += ` LIMIT ${escape(limit)}`;
|
|
177
|
+
if (typeof offset === "number") {
|
|
178
|
+
sql += ` OFFSET ${escape(offset)}`;
|
|
179
|
+
}
|
|
154
180
|
}
|
|
155
181
|
}
|
|
156
182
|
}
|
|
@@ -194,6 +220,8 @@ async function getData(input, dbCall, formatQuery, dialect) {
|
|
|
194
220
|
// We don't want the where clause to include cursor-related stuff
|
|
195
221
|
delete argsTotalCount.$paginate.after;
|
|
196
222
|
delete argsTotalCount.$paginate.before;
|
|
223
|
+
// We don't need offset
|
|
224
|
+
delete argsTotalCount.$paginate.offset;
|
|
197
225
|
}
|
|
198
226
|
}
|
|
199
227
|
const sqlASTTotalCount = getSqlAst_1.getSqlAst({
|
|
@@ -213,9 +241,16 @@ async function getData(input, dbCall, formatQuery, dialect) {
|
|
|
213
241
|
// getOrderBy adds an element if paginating, so deleting args.$orderBy
|
|
214
242
|
// isn't sufficient.
|
|
215
243
|
delete sqlASTTotalCount.orderBy;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
244
|
+
const totalCount = await getTotalCount(sqlASTTotalCount, dbCall, context, options);
|
|
245
|
+
if (paginationType === "cursor") {
|
|
246
|
+
data = wrapListPaginationCursor(data, input.args, orderByListPaginatedRootResult.flip, (xs) => {
|
|
247
|
+
postProcess(xs, fields, shouldRemoveExtraKeys);
|
|
248
|
+
}, input.artifacts[input.resource].primaryKey, totalCount);
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
postProcess(data, fields, shouldRemoveExtraKeys);
|
|
252
|
+
data = wrapListPaginationLimitOffset(data, totalCount);
|
|
253
|
+
}
|
|
219
254
|
}
|
|
220
255
|
return data;
|
|
221
256
|
}
|
|
@@ -224,10 +259,13 @@ async function getData(input, dbCall, formatQuery, dialect) {
|
|
|
224
259
|
}
|
|
225
260
|
return data;
|
|
226
261
|
}
|
|
262
|
+
function wrapListPaginationLimitOffset(data, totalCount) {
|
|
263
|
+
return { paginationInfo: { totalCount }, results: data };
|
|
264
|
+
}
|
|
227
265
|
// Not recursive at the moment; only supported at the root.
|
|
228
266
|
// TODO - remove if support for pagination for mysql dialect
|
|
229
267
|
// is added (I doubt it)
|
|
230
|
-
|
|
268
|
+
function wrapListPaginationCursor(data, args, flip, cb, primaryKey, totalCount) {
|
|
231
269
|
const limit = flip ? args.$paginate.last : args.$paginate.first;
|
|
232
270
|
const hasMoreResults = data.length === limit + 1;
|
|
233
271
|
if (hasMoreResults) {
|
|
@@ -243,6 +281,19 @@ async function wrapListPaginated(data, args, flip, cb, sqlASTTotalCount, dbCall,
|
|
|
243
281
|
const endKey = data?.[data.length - 1]?.[primaryKey];
|
|
244
282
|
const startCursor = startKey == null ? null : cursor_1.encodeCursor(startKey);
|
|
245
283
|
const endCursor = endKey == null ? null : cursor_1.encodeCursor(endKey);
|
|
284
|
+
cb(data);
|
|
285
|
+
return {
|
|
286
|
+
paginationInfo: {
|
|
287
|
+
hasPreviousPage,
|
|
288
|
+
hasNextPage,
|
|
289
|
+
startCursor,
|
|
290
|
+
endCursor,
|
|
291
|
+
totalCount,
|
|
292
|
+
},
|
|
293
|
+
results: data,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
async function getTotalCount(sqlASTTotalCount, dbCall, context, options) {
|
|
246
297
|
// Replace field selection with `COUNT(*)`
|
|
247
298
|
const fieldNameTotalCount = "totalCount";
|
|
248
299
|
sqlASTTotalCount.children = [
|
|
@@ -255,17 +306,7 @@ async function wrapListPaginated(data, args, flip, cb, sqlASTTotalCount, dbCall,
|
|
|
255
306
|
];
|
|
256
307
|
const { sql: sqlTotalCount } = await util_1.compileSqlAST(sqlASTTotalCount, context, options);
|
|
257
308
|
const totalCount = await dbCall(sqlTotalCount).then((xs) => xs[0][fieldNameTotalCount]);
|
|
258
|
-
|
|
259
|
-
return {
|
|
260
|
-
paginationInfo: {
|
|
261
|
-
hasPreviousPage,
|
|
262
|
-
hasNextPage,
|
|
263
|
-
startCursor,
|
|
264
|
-
endCursor,
|
|
265
|
-
totalCount,
|
|
266
|
-
},
|
|
267
|
-
results: data,
|
|
268
|
-
};
|
|
309
|
+
return totalCount;
|
|
269
310
|
}
|
|
270
311
|
async function create(input, dbCall, formatQuery, dialect) {
|
|
271
312
|
async function _create() {
|
|
@@ -667,6 +708,7 @@ const ops = [
|
|
|
667
708
|
"$in",
|
|
668
709
|
"$nin",
|
|
669
710
|
"$like",
|
|
711
|
+
"$nlike",
|
|
670
712
|
"$btwn",
|
|
671
713
|
"$nbtwn",
|
|
672
714
|
];
|
|
@@ -111,6 +111,9 @@ function _stringifyWhere(where, table, escapeId, escape, result) {
|
|
|
111
111
|
if (operator === "$like") {
|
|
112
112
|
return `${table}.${escapeId(k)} LIKE ${printValue(operand)}`;
|
|
113
113
|
}
|
|
114
|
+
if (operator === "$nlike") {
|
|
115
|
+
return `${table}.${escapeId(k)} NOT LIKE ${printValue(operand)}`;
|
|
116
|
+
}
|
|
114
117
|
if (operator === "$in") {
|
|
115
118
|
if (operand.length === 0) {
|
|
116
119
|
// Would do "FALSE" instead, as it's more readable, but it
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.traverseFieldArgs = void 0;
|
|
4
|
+
function traverseFieldArgs(fields, cb) {
|
|
5
|
+
for (let x of fields) {
|
|
6
|
+
if (typeof x !== "object") {
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
x.args = cb(x.args);
|
|
10
|
+
traverseFieldArgs(x.fields, cb);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.traverseFieldArgs = traverseFieldArgs;
|