@metriport/shared 0.26.2 → 0.26.3
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/common/__tests__/normalize-oid.test.js +14 -0
- package/dist/common/__tests__/normalize-oid.test.js.map +1 -1
- package/dist/common/normalize-oid.d.ts +7 -0
- package/dist/common/normalize-oid.d.ts.map +1 -1
- package/dist/common/normalize-oid.js +60 -1
- package/dist/common/normalize-oid.js.map +1 -1
- package/dist/common/numbers.d.ts +13 -0
- package/dist/common/numbers.d.ts.map +1 -1
- package/dist/common/numbers.js +40 -1
- package/dist/common/numbers.js.map +1 -1
- package/dist/domain/__tests__/cursor-utils.test.d.ts +2 -0
- package/dist/domain/__tests__/cursor-utils.test.d.ts.map +1 -0
- package/dist/domain/__tests__/cursor-utils.test.js +216 -0
- package/dist/domain/__tests__/cursor-utils.test.js.map +1 -0
- package/dist/domain/__tests__/pagination-schema.test.d.ts +2 -0
- package/dist/domain/__tests__/pagination-schema.test.d.ts.map +1 -0
- package/dist/domain/__tests__/pagination-schema.test.js +165 -0
- package/dist/domain/__tests__/pagination-schema.test.js.map +1 -0
- package/dist/domain/cursor-utils.d.ts +20 -0
- package/dist/domain/cursor-utils.d.ts.map +1 -0
- package/dist/domain/cursor-utils.js +51 -0
- package/dist/domain/cursor-utils.js.map +1 -0
- package/dist/domain/pagination-v2.d.ts +230 -0
- package/dist/domain/pagination-v2.d.ts.map +1 -0
- package/dist/domain/pagination-v2.js +132 -0
- package/dist/domain/pagination-v2.js.map +1 -0
- package/dist/domain/pagination.d.ts +0 -2
- package/dist/domain/pagination.d.ts.map +1 -1
- package/dist/domain/pagination.js +3 -4
- package/dist/domain/pagination.js.map +1 -1
- package/dist/domain/tcm-encounter.d.ts +180 -9
- package/dist/domain/tcm-encounter.d.ts.map +1 -1
- package/dist/domain/tcm-encounter.js +13 -3
- package/dist/domain/tcm-encounter.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interface/external/ehr/athenahealth/cx-mapping.d.ts +54 -0
- package/dist/interface/external/ehr/athenahealth/cx-mapping.d.ts.map +1 -1
- package/dist/interface/external/ehr/athenahealth/jwt-token.d.ts +2 -2
- package/dist/interface/external/ehr/athenahealth/patient-mapping.d.ts +14 -0
- package/dist/interface/external/ehr/athenahealth/patient-mapping.d.ts.map +1 -0
- package/dist/interface/external/ehr/athenahealth/patient-mapping.js +11 -0
- package/dist/interface/external/ehr/athenahealth/patient-mapping.js.map +1 -0
- package/dist/interface/external/ehr/athenahealth/patient.d.ts +36 -2
- package/dist/interface/external/ehr/athenahealth/patient.d.ts.map +1 -1
- package/dist/interface/external/ehr/athenahealth/patient.js +5 -5
- package/dist/interface/external/ehr/athenahealth/patient.js.map +1 -1
- package/dist/interface/external/ehr/canvas/cx-mapping.d.ts +54 -0
- package/dist/interface/external/ehr/canvas/cx-mapping.d.ts.map +1 -1
- package/dist/interface/external/ehr/canvas/jwt-token.d.ts +6 -6
- package/dist/interface/external/ehr/eclinicalworks/jwt-token.d.ts +2 -2
- package/dist/interface/external/ehr/elation/cx-mapping.d.ts +54 -0
- package/dist/interface/external/ehr/elation/cx-mapping.d.ts.map +1 -1
- package/dist/interface/external/ehr/elation/jwt-token.d.ts +4 -4
- package/dist/interface/external/ehr/healthie/cx-mapping.d.ts +54 -0
- package/dist/interface/external/ehr/healthie/cx-mapping.d.ts.map +1 -1
- package/dist/interface/external/ehr/healthie/jwt-token.d.ts +2 -2
- package/dist/interface/external/ehr/healthie/lab.d.ts +32 -32
- package/dist/interface/external/ehr/shared.d.ts +100 -0
- package/dist/interface/external/ehr/shared.d.ts.map +1 -1
- package/dist/interface/external/ehr/shared.js +15 -1
- package/dist/interface/external/ehr/shared.js.map +1 -1
- package/package.json +2 -2
|
@@ -10,6 +10,7 @@ const invalidOid = "notAnOid";
|
|
|
10
10
|
const consecutiveDotsInvalidOid = "1.22.333..444";
|
|
11
11
|
const validOidWithTrailingString = "1.22.333.444SomeJunk";
|
|
12
12
|
const oidWithLeadingAndTrailingJunk = "SomeJunk1.22.333.444SomeJunk";
|
|
13
|
+
const oidAsPartOfUrl = "https://org-address.org/v1/org/1.22.333.444";
|
|
13
14
|
const oidWithLeadingZeros = "1.02.003.0004";
|
|
14
15
|
const emptyString = "";
|
|
15
16
|
const onlyDots = "...";
|
|
@@ -51,4 +52,17 @@ describe("normalizeOid", () => {
|
|
|
51
52
|
expect((0, normalize_oid_1.normalizeOid)(rootBoundaryTwo)).toBe(rootBoundaryTwo);
|
|
52
53
|
});
|
|
53
54
|
});
|
|
55
|
+
describe("parseOid", () => {
|
|
56
|
+
it("should return the same oid if it is already valid", () => {
|
|
57
|
+
expect((0, normalize_oid_1.parseOid)(validOid)).toBe(validOid);
|
|
58
|
+
expect((0, normalize_oid_1.parseOid)(shorterValidOid)).toBe(shorterValidOid);
|
|
59
|
+
expect((0, normalize_oid_1.parseOid)(longerValidOid)).toBe(longerValidOid);
|
|
60
|
+
});
|
|
61
|
+
it("should return the oid from a url", () => {
|
|
62
|
+
expect((0, normalize_oid_1.parseOid)(oidAsPartOfUrl)).toBe(validOid);
|
|
63
|
+
});
|
|
64
|
+
it("should return the oid without leading and trailing junk", () => {
|
|
65
|
+
expect((0, normalize_oid_1.parseOid)(oidWithLeadingAndTrailingJunk)).toBe(validOid);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
54
68
|
//# sourceMappingURL=normalize-oid.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-oid.test.js","sourceRoot":"","sources":["../../../src/common/__tests__/normalize-oid.test.ts"],"names":[],"mappings":";;AAAA,
|
|
1
|
+
{"version":3,"file":"normalize-oid.test.js","sourceRoot":"","sources":["../../../src/common/__tests__/normalize-oid.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
export declare function normalizeOid(input: string): string;
|
|
2
|
+
/**
|
|
3
|
+
* Parses an OID from a string, handling various formats and extracting the valid OID portion
|
|
4
|
+
* @param input - String that may contain an OID
|
|
5
|
+
* @returns The parsed and normalized OID string
|
|
6
|
+
* @throws Error if no valid OID can be found in the input
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseOid(input: string): string;
|
|
2
9
|
//# sourceMappingURL=normalize-oid.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-oid.d.ts","sourceRoot":"","sources":["../../src/common/normalize-oid.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYlD"}
|
|
1
|
+
{"version":3,"file":"normalize-oid.d.ts","sourceRoot":"","sources":["../../src/common/normalize-oid.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYlD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAwC9C"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.normalizeOid = void 0;
|
|
3
|
+
exports.parseOid = exports.normalizeOid = void 0;
|
|
4
4
|
const OID_REGEX = /(?:[^.\d]*)((([0-9]*)(?:\.*))*)*(?:[^.\d]*)/;
|
|
5
5
|
function normalizeOid(input) {
|
|
6
6
|
const match = input.match(OID_REGEX);
|
|
@@ -15,6 +15,65 @@ function normalizeOid(input) {
|
|
|
15
15
|
throw new Error("OID is not valid");
|
|
16
16
|
}
|
|
17
17
|
exports.normalizeOid = normalizeOid;
|
|
18
|
+
/**
|
|
19
|
+
* Parses an OID from a string, handling various formats and extracting the valid OID portion
|
|
20
|
+
* @param input - String that may contain an OID
|
|
21
|
+
* @returns The parsed and normalized OID string
|
|
22
|
+
* @throws Error if no valid OID can be found in the input
|
|
23
|
+
*/
|
|
24
|
+
function parseOid(input) {
|
|
25
|
+
if (!input || typeof input !== "string") {
|
|
26
|
+
throw new Error("Input must be a non-empty string");
|
|
27
|
+
}
|
|
28
|
+
// Enhanced regex to find OID patterns in various contexts
|
|
29
|
+
// Matches: 1.2.3.4, urn:oid:1.2.3.4, /path/1.2.3.4, ?oid=1.2.3.4, etc.
|
|
30
|
+
const oidPatterns = [
|
|
31
|
+
/urn:oid:([0-9]+(?:\.[0-9]+)*)/i,
|
|
32
|
+
/[?&]oid=([0-9]+(?:\.[0-9]+)*)/i,
|
|
33
|
+
/[?&]id=([0-9]+(?:\.[0-9]+)*)/i,
|
|
34
|
+
/[\s]([0-9]+(?:\.[0-9]+)*)[\s]/,
|
|
35
|
+
/^([0-9]+(?:\.[0-9]+)*)$/,
|
|
36
|
+
/([0-9]+(?:\.[0-9]+)*)/g,
|
|
37
|
+
];
|
|
38
|
+
// Try each pattern to find a valid OID
|
|
39
|
+
for (const pattern of oidPatterns) {
|
|
40
|
+
const matches = input.match(pattern);
|
|
41
|
+
if (matches) {
|
|
42
|
+
// For patterns with capture groups, use the first capture group
|
|
43
|
+
const oidCandidate = matches[1] || matches[0];
|
|
44
|
+
if (isValidOid(oidCandidate)) {
|
|
45
|
+
return oidCandidate;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// If no pattern matched, try to extract any sequence of numbers and dots
|
|
50
|
+
const allMatches = input.match(/([0-9]+(?:\.[0-9]+)*)/g);
|
|
51
|
+
if (allMatches) {
|
|
52
|
+
for (const match of allMatches) {
|
|
53
|
+
if (isValidOid(match)) {
|
|
54
|
+
return match;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
throw new Error("No valid OID found in input string");
|
|
59
|
+
}
|
|
60
|
+
exports.parseOid = parseOid;
|
|
61
|
+
/**
|
|
62
|
+
* Validates if a string is a valid OID
|
|
63
|
+
* @param oid - The OID string to validate
|
|
64
|
+
* @returns True if the OID is valid, false otherwise
|
|
65
|
+
*/
|
|
66
|
+
function isValidOid(oid) {
|
|
67
|
+
if (!oid || typeof oid !== "string") {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
// Check for consecutive dots
|
|
71
|
+
if (oid.includes("..")) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
// Check if it starts with valid root code (0, 1, or 2)
|
|
75
|
+
return startsWithRootCode(oid);
|
|
76
|
+
}
|
|
18
77
|
function startsWithRootCode(oid) {
|
|
19
78
|
if (oid.includes(".")) {
|
|
20
79
|
const root = oid.split(".")[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-oid.js","sourceRoot":"","sources":["../../src/common/normalize-oid.ts"],"names":[],"mappings":";;;AAAA,MAAM,SAAS,GAAG,6CAA6C,CAAC;AAEhE,SAAgB,YAAY,CAAC,KAAa;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACrC,sEAAsE;IACtE,2GAA2G;IAC3G,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE;QACrB,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,YAAY,CAAC,EAAE;YACpE,OAAO,YAAY,CAAC;SACrB;KACF;IAED,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;AACtC,CAAC;AAZD,oCAYC;AAED,SAAS,kBAAkB,CAAC,GAAW;IACrC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;QACrB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,IAAI,EAAE;YACR,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO,kBAAkB,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;SAC7C;KACF;SAAM;QACL,OAAO,kBAAkB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;KAC1C;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAChC,CAAC"}
|
|
1
|
+
{"version":3,"file":"normalize-oid.js","sourceRoot":"","sources":["../../src/common/normalize-oid.ts"],"names":[],"mappings":";;;AAAA,MAAM,SAAS,GAAG,6CAA6C,CAAC;AAEhE,SAAgB,YAAY,CAAC,KAAa;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACrC,sEAAsE;IACtE,2GAA2G;IAC3G,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE;QACrB,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,YAAY,CAAC,EAAE;YACpE,OAAO,YAAY,CAAC;SACrB;KACF;IAED,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;AACtC,CAAC;AAZD,oCAYC;AAED;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,KAAa;IACpC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QACvC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;KACrD;IAED,0DAA0D;IAC1D,uEAAuE;IACvE,MAAM,WAAW,GAAG;QAClB,gCAAgC;QAChC,gCAAgC;QAChC,+BAA+B;QAC/B,+BAA+B;QAC/B,yBAAyB;QACzB,wBAAwB;KACzB,CAAC;IAEF,uCAAuC;IACvC,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE;QACjC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,OAAO,EAAE;YACX,gEAAgE;YAChE,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;YAE9C,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE;gBAC5B,OAAO,YAAY,CAAC;aACrB;SACF;KACF;IAED,yEAAyE;IACzE,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACzD,IAAI,UAAU,EAAE;QACd,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE;YAC9B,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE;gBACrB,OAAO,KAAK,CAAC;aACd;SACF;KACF;IAED,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;AACxD,CAAC;AAxCD,4BAwCC;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;QACnC,OAAO,KAAK,CAAC;KACd;IAED,6BAA6B;IAC7B,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;QACtB,OAAO,KAAK,CAAC;KACd;IAED,uDAAuD;IACvD,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAW;IACrC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;QACrB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,IAAI,EAAE;YACR,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO,kBAAkB,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;SAC7C;KACF;SAAM;QACL,OAAO,kBAAkB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;KAC1C;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAChC,CAAC"}
|
package/dist/common/numbers.d.ts
CHANGED
|
@@ -3,6 +3,19 @@ export declare function getFloatValue(value: string | number): number;
|
|
|
3
3
|
* Truncate the number to 2 decimal places
|
|
4
4
|
*/
|
|
5
5
|
export declare function formatNumber(num: number): number;
|
|
6
|
+
/**
|
|
7
|
+
* Format a number to a human readable string, with optional decimal places and thousand separator.
|
|
8
|
+
*/
|
|
9
|
+
export declare function abbreviateNumber(num: number): string;
|
|
10
|
+
/**
|
|
11
|
+
* Format a number to a string, with optional decimal places and thousand separator.
|
|
12
|
+
*
|
|
13
|
+
* @param num the number to format
|
|
14
|
+
* @param digits number of decimal places, only used if `thousandSeparator` is true
|
|
15
|
+
* @param thousandSeparator if true (default), use Intl.NumberFormat to format the number; otherwise,
|
|
16
|
+
* return the number without formatting.
|
|
17
|
+
*/
|
|
18
|
+
export declare function numberToString(num: number, digits?: number, thousandSeparator?: boolean): string;
|
|
6
19
|
export declare function randomInt(maxDigits?: number): number;
|
|
7
20
|
export declare function randomIntBetween(min: number, max: number): number;
|
|
8
21
|
//# sourceMappingURL=numbers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numbers.d.ts","sourceRoot":"","sources":["../../src/common/numbers.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,SAAS,CAAC,SAAS,SAAI,GAAG,MAAM,CAE/C;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAQjE"}
|
|
1
|
+
{"version":3,"file":"numbers.d.ts","sourceRoot":"","sources":["../../src/common/numbers.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWpD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAI,EAAE,iBAAiB,UAAO,GAAG,MAAM,CAWxF;AAED,wBAAgB,SAAS,CAAC,SAAS,SAAI,GAAG,MAAM,CAE/C;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAQjE"}
|
package/dist/common/numbers.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.randomIntBetween = exports.randomInt = exports.formatNumber = exports.getFloatValue = void 0;
|
|
3
|
+
exports.randomIntBetween = exports.randomInt = exports.numberToString = exports.abbreviateNumber = exports.formatNumber = exports.getFloatValue = void 0;
|
|
4
4
|
function getFloatValue(value) {
|
|
5
5
|
return typeof value === "string" ? parseFloat(value) : value;
|
|
6
6
|
}
|
|
@@ -12,6 +12,45 @@ function formatNumber(num) {
|
|
|
12
12
|
return Math.floor(num * 100) / 100;
|
|
13
13
|
}
|
|
14
14
|
exports.formatNumber = formatNumber;
|
|
15
|
+
/**
|
|
16
|
+
* Format a number to a human readable string, with optional decimal places and thousand separator.
|
|
17
|
+
*/
|
|
18
|
+
function abbreviateNumber(num) {
|
|
19
|
+
if (num < 1000) {
|
|
20
|
+
return numberToString(num, 1);
|
|
21
|
+
}
|
|
22
|
+
if (num < 1000000) {
|
|
23
|
+
return `${numberToString(num / 1000, 1)}K`;
|
|
24
|
+
}
|
|
25
|
+
if (num < 1000000000) {
|
|
26
|
+
return `${numberToString(num / 1000000, 1)}M`;
|
|
27
|
+
}
|
|
28
|
+
return `${numberToString(num / 1000000000, 1)}G`;
|
|
29
|
+
}
|
|
30
|
+
exports.abbreviateNumber = abbreviateNumber;
|
|
31
|
+
/**
|
|
32
|
+
* Format a number to a string, with optional decimal places and thousand separator.
|
|
33
|
+
*
|
|
34
|
+
* @param num the number to format
|
|
35
|
+
* @param digits number of decimal places, only used if `thousandSeparator` is true
|
|
36
|
+
* @param thousandSeparator if true (default), use Intl.NumberFormat to format the number; otherwise,
|
|
37
|
+
* return the number without formatting.
|
|
38
|
+
*/
|
|
39
|
+
function numberToString(num, digits = 2, thousandSeparator = true) {
|
|
40
|
+
const asString = num.toFixed(digits);
|
|
41
|
+
if (!thousandSeparator)
|
|
42
|
+
return asString;
|
|
43
|
+
const parts = asString.split(".");
|
|
44
|
+
const integerPart = parts[0] ?? 0;
|
|
45
|
+
const decimalPart = parts[1];
|
|
46
|
+
const integerPartWithSeparator = integerPart
|
|
47
|
+
? Intl.NumberFormat("en-US").format(Number(integerPart))
|
|
48
|
+
: integerPart;
|
|
49
|
+
if (decimalPart == undefined)
|
|
50
|
+
return integerPartWithSeparator.toString();
|
|
51
|
+
return `${integerPartWithSeparator}.${decimalPart}`;
|
|
52
|
+
}
|
|
53
|
+
exports.numberToString = numberToString;
|
|
15
54
|
function randomInt(maxDigits = 2) {
|
|
16
55
|
return Math.floor(Math.random() * Math.pow(10, maxDigits));
|
|
17
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numbers.js","sourceRoot":"","sources":["../../src/common/numbers.ts"],"names":[],"mappings":";;;AAAA,SAAgB,aAAa,CAAC,KAAsB;IAClD,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC/D,CAAC;AAFD,sCAEC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,GAAW;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AACrC,CAAC;AAFD,oCAEC;AAED,SAAgB,SAAS,CAAC,SAAS,GAAG,CAAC;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;AAC7D,CAAC;AAFD,8BAEC;AAED,SAAgB,gBAAgB,CAAC,GAAW,EAAE,GAAW;IACvD,IAAI,GAAG,GAAG,GAAG,EAAE;QACb,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;KAC9C;IACD,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;KAChD;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;AAC3D,CAAC;AARD,4CAQC"}
|
|
1
|
+
{"version":3,"file":"numbers.js","sourceRoot":"","sources":["../../src/common/numbers.ts"],"names":[],"mappings":";;;AAAA,SAAgB,aAAa,CAAC,KAAsB;IAClD,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC/D,CAAC;AAFD,sCAEC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,GAAW;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AACrC,CAAC;AAFD,oCAEC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,GAAW;IAC1C,IAAI,GAAG,GAAG,IAAK,EAAE;QACf,OAAO,cAAc,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;KAC/B;IACD,IAAI,GAAG,GAAG,OAAS,EAAE;QACnB,OAAO,GAAG,cAAc,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC;KAC5C;IACD,IAAI,GAAG,GAAG,UAAa,EAAE;QACvB,OAAO,GAAG,cAAc,CAAC,GAAG,GAAG,OAAS,EAAE,CAAC,CAAC,GAAG,CAAC;KACjD;IACD,OAAO,GAAG,cAAc,CAAC,GAAG,GAAG,UAAa,EAAE,CAAC,CAAC,GAAG,CAAC;AACtD,CAAC;AAXD,4CAWC;AAED;;;;;;;GAOG;AACH,SAAgB,cAAc,CAAC,GAAW,EAAE,MAAM,GAAG,CAAC,EAAE,iBAAiB,GAAG,IAAI;IAC9E,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,iBAAiB;QAAE,OAAO,QAAQ,CAAC;IACxC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,wBAAwB,GAAG,WAAW;QAC1C,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACxD,CAAC,CAAC,WAAW,CAAC;IAChB,IAAI,WAAW,IAAI,SAAS;QAAE,OAAO,wBAAwB,CAAC,QAAQ,EAAE,CAAC;IACzE,OAAO,GAAG,wBAAwB,IAAI,WAAW,EAAE,CAAC;AACtD,CAAC;AAXD,wCAWC;AAED,SAAgB,SAAS,CAAC,SAAS,GAAG,CAAC;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;AAC7D,CAAC;AAFD,8BAEC;AAED,SAAgB,gBAAgB,CAAC,GAAW,EAAE,GAAW;IACvD,IAAI,GAAG,GAAG,GAAG,EAAE;QACb,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;KAC9C;IACD,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;KAChD;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;AAC3D,CAAC;AARD,4CAQC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-utils.test.d.ts","sourceRoot":"","sources":["../../../src/domain/__tests__/cursor-utils.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const faker_1 = require("@faker-js/faker");
|
|
4
|
+
const cursor_utils_1 = require("../cursor-utils");
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
jest.restoreAllMocks();
|
|
7
|
+
});
|
|
8
|
+
describe("cursor-utils", () => {
|
|
9
|
+
describe("encodeCursor", () => {
|
|
10
|
+
it("returns encoded string when given empty object", () => {
|
|
11
|
+
const cursor = {};
|
|
12
|
+
const encoded = (0, cursor_utils_1.encodeCursor)(cursor);
|
|
13
|
+
expect(encoded).toBe("e30="); // base64 for '{}'
|
|
14
|
+
});
|
|
15
|
+
it("encodes simple cursor object", () => {
|
|
16
|
+
const cursor = { id: "123" };
|
|
17
|
+
const encoded = (0, cursor_utils_1.encodeCursor)(cursor);
|
|
18
|
+
const decoded = JSON.parse(Buffer.from(encoded, "base64").toString("utf8"));
|
|
19
|
+
expect(decoded).toEqual(cursor);
|
|
20
|
+
});
|
|
21
|
+
it("encodes complex cursor with multiple fields and types", () => {
|
|
22
|
+
const cursor = {
|
|
23
|
+
name: "john doe",
|
|
24
|
+
createdAt: "2023-12-01T10:00:00Z",
|
|
25
|
+
priority: 5,
|
|
26
|
+
isActive: true,
|
|
27
|
+
id: "uuid-123",
|
|
28
|
+
};
|
|
29
|
+
const encoded = (0, cursor_utils_1.encodeCursor)(cursor);
|
|
30
|
+
const decoded = JSON.parse(Buffer.from(encoded, "base64").toString("utf8"));
|
|
31
|
+
expect(decoded).toEqual(cursor);
|
|
32
|
+
});
|
|
33
|
+
it("handles special characters in cursor values", () => {
|
|
34
|
+
const cursor = {
|
|
35
|
+
name: "João da Silva & Co.",
|
|
36
|
+
notes: "Test with 🦄 emojis and\nnewlines",
|
|
37
|
+
};
|
|
38
|
+
const encoded = (0, cursor_utils_1.encodeCursor)(cursor);
|
|
39
|
+
const decoded = JSON.parse(Buffer.from(encoded, "base64").toString("utf8"));
|
|
40
|
+
expect(decoded).toEqual(cursor);
|
|
41
|
+
});
|
|
42
|
+
it("handles null and undefined values", () => {
|
|
43
|
+
const cursor = {
|
|
44
|
+
name: null,
|
|
45
|
+
description: undefined,
|
|
46
|
+
id: "123",
|
|
47
|
+
};
|
|
48
|
+
const encoded = (0, cursor_utils_1.encodeCursor)(cursor);
|
|
49
|
+
const decoded = JSON.parse(Buffer.from(encoded, "base64").toString("utf8"));
|
|
50
|
+
expect(decoded).toEqual({ name: null, id: "123" }); // undefined gets removed by JSON
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
describe("decodeCursor", () => {
|
|
54
|
+
it("decodes empty object cursor", () => {
|
|
55
|
+
const encoded = "e30="; // base64 for '{}'
|
|
56
|
+
const decoded = (0, cursor_utils_1.decodeCursor)(encoded);
|
|
57
|
+
expect(decoded).toEqual({});
|
|
58
|
+
});
|
|
59
|
+
it("decodes simple cursor", () => {
|
|
60
|
+
const original = { id: "123" };
|
|
61
|
+
const encoded = (0, cursor_utils_1.encodeCursor)(original);
|
|
62
|
+
const decoded = (0, cursor_utils_1.decodeCursor)(encoded);
|
|
63
|
+
expect(decoded).toEqual(original);
|
|
64
|
+
});
|
|
65
|
+
it("decodes complex cursor with multiple types", () => {
|
|
66
|
+
const original = {
|
|
67
|
+
name: "test user",
|
|
68
|
+
timestamp: "2023-12-01T10:00:00Z",
|
|
69
|
+
count: 42,
|
|
70
|
+
isEnabled: false,
|
|
71
|
+
};
|
|
72
|
+
const encoded = (0, cursor_utils_1.encodeCursor)(original);
|
|
73
|
+
const decoded = (0, cursor_utils_1.decodeCursor)(encoded);
|
|
74
|
+
expect(decoded).toEqual(original);
|
|
75
|
+
});
|
|
76
|
+
it("throws error for invalid base64", () => {
|
|
77
|
+
const invalidBase64 = "not-valid-base64!!!";
|
|
78
|
+
expect(() => (0, cursor_utils_1.decodeCursor)(invalidBase64)).toThrow();
|
|
79
|
+
});
|
|
80
|
+
it("throws error for valid base64 but invalid JSON", () => {
|
|
81
|
+
const validBase64 = Buffer.from("invalid json", "utf8").toString("base64");
|
|
82
|
+
expect(() => (0, cursor_utils_1.decodeCursor)(validBase64)).toThrow();
|
|
83
|
+
});
|
|
84
|
+
it("throws error for empty string", () => {
|
|
85
|
+
expect(() => (0, cursor_utils_1.decodeCursor)("")).toThrow();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
describe("encode and decode together", () => {
|
|
89
|
+
it("roundtrip preserves empty object", () => {
|
|
90
|
+
const original = {};
|
|
91
|
+
const roundtrip = (0, cursor_utils_1.decodeCursor)((0, cursor_utils_1.encodeCursor)(original));
|
|
92
|
+
expect(roundtrip).toEqual(original);
|
|
93
|
+
});
|
|
94
|
+
it("roundtrip preserves simple object", () => {
|
|
95
|
+
const original = { id: faker_1.faker.string.uuid() };
|
|
96
|
+
const roundtrip = (0, cursor_utils_1.decodeCursor)((0, cursor_utils_1.encodeCursor)(original));
|
|
97
|
+
expect(roundtrip).toEqual(original);
|
|
98
|
+
});
|
|
99
|
+
it("roundtrip preserves complex object", () => {
|
|
100
|
+
const original = {
|
|
101
|
+
id: faker_1.faker.string.uuid(),
|
|
102
|
+
name: faker_1.faker.person.fullName(),
|
|
103
|
+
email: faker_1.faker.internet.email(),
|
|
104
|
+
age: faker_1.faker.number.int({ min: 18, max: 100 }),
|
|
105
|
+
createdAt: faker_1.faker.date.recent().toISOString(),
|
|
106
|
+
isActive: faker_1.faker.datatype.boolean(),
|
|
107
|
+
};
|
|
108
|
+
const roundtrip = (0, cursor_utils_1.decodeCursor)((0, cursor_utils_1.encodeCursor)(original));
|
|
109
|
+
expect(roundtrip).toEqual(original);
|
|
110
|
+
});
|
|
111
|
+
it("roundtrip handles special characters", () => {
|
|
112
|
+
const original = {
|
|
113
|
+
unicode: "🦄🌟⭐",
|
|
114
|
+
multiline: "line1\nline2\r\nline3",
|
|
115
|
+
quotes: 'single "double" quotes',
|
|
116
|
+
special: "& < > ' \"",
|
|
117
|
+
};
|
|
118
|
+
const roundtrip = (0, cursor_utils_1.decodeCursor)((0, cursor_utils_1.encodeCursor)(original));
|
|
119
|
+
expect(roundtrip).toEqual(original);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
describe("createCompositeCursor", () => {
|
|
123
|
+
const mockSortFields = [
|
|
124
|
+
{ col: "name", order: "asc" },
|
|
125
|
+
{ col: "createdAt", order: "desc" },
|
|
126
|
+
{ col: "id", order: "asc" },
|
|
127
|
+
];
|
|
128
|
+
it("creates cursor with all sort fields from item", () => {
|
|
129
|
+
const item = {
|
|
130
|
+
id: faker_1.faker.string.uuid(),
|
|
131
|
+
name: faker_1.faker.person.fullName(),
|
|
132
|
+
createdAt: faker_1.faker.date.recent().toISOString(),
|
|
133
|
+
email: faker_1.faker.internet.email(),
|
|
134
|
+
age: faker_1.faker.number.int(),
|
|
135
|
+
};
|
|
136
|
+
const cursor = (0, cursor_utils_1.createCompositeCursor)(item, mockSortFields);
|
|
137
|
+
expect(cursor).toEqual({
|
|
138
|
+
name: item.name,
|
|
139
|
+
createdAt: item.createdAt,
|
|
140
|
+
id: item.id,
|
|
141
|
+
});
|
|
142
|
+
expect(cursor).not.toHaveProperty("email");
|
|
143
|
+
expect(cursor).not.toHaveProperty("age");
|
|
144
|
+
});
|
|
145
|
+
it("creates cursor with subset of fields when item missing some sort fields", () => {
|
|
146
|
+
const item = {
|
|
147
|
+
id: faker_1.faker.string.uuid(),
|
|
148
|
+
name: faker_1.faker.person.fullName(),
|
|
149
|
+
// missing createdAt
|
|
150
|
+
email: faker_1.faker.internet.email(),
|
|
151
|
+
};
|
|
152
|
+
const cursor = (0, cursor_utils_1.createCompositeCursor)(item, mockSortFields);
|
|
153
|
+
expect(cursor).toEqual({
|
|
154
|
+
name: item.name,
|
|
155
|
+
createdAt: undefined,
|
|
156
|
+
id: item.id,
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
it("creates empty cursor for empty sort fields", () => {
|
|
160
|
+
const item = {
|
|
161
|
+
id: faker_1.faker.string.uuid(),
|
|
162
|
+
name: faker_1.faker.person.fullName(),
|
|
163
|
+
};
|
|
164
|
+
const cursor = (0, cursor_utils_1.createCompositeCursor)(item, []);
|
|
165
|
+
expect(cursor).toEqual({});
|
|
166
|
+
});
|
|
167
|
+
it("handles null and undefined values in item", () => {
|
|
168
|
+
const item = {
|
|
169
|
+
id: faker_1.faker.string.uuid(),
|
|
170
|
+
name: null,
|
|
171
|
+
createdAt: undefined,
|
|
172
|
+
status: "active",
|
|
173
|
+
};
|
|
174
|
+
const cursor = (0, cursor_utils_1.createCompositeCursor)(item, mockSortFields);
|
|
175
|
+
expect(cursor).toEqual({
|
|
176
|
+
name: null,
|
|
177
|
+
createdAt: undefined,
|
|
178
|
+
id: item.id,
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
it("works with single sort field", () => {
|
|
182
|
+
const item = {
|
|
183
|
+
id: faker_1.faker.string.uuid(),
|
|
184
|
+
name: faker_1.faker.person.fullName(),
|
|
185
|
+
};
|
|
186
|
+
const singleSortField = [{ col: "name", order: "asc" }];
|
|
187
|
+
const cursor = (0, cursor_utils_1.createCompositeCursor)(item, singleSortField);
|
|
188
|
+
expect(cursor).toEqual({
|
|
189
|
+
name: item.name,
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
it("preserves different data types in cursor", () => {
|
|
193
|
+
const item = {
|
|
194
|
+
id: faker_1.faker.string.uuid(),
|
|
195
|
+
count: faker_1.faker.number.int(),
|
|
196
|
+
price: faker_1.faker.number.float(),
|
|
197
|
+
isActive: faker_1.faker.datatype.boolean(),
|
|
198
|
+
createdAt: faker_1.faker.date.recent(),
|
|
199
|
+
};
|
|
200
|
+
const sortFields = [
|
|
201
|
+
{ col: "count", order: "desc" },
|
|
202
|
+
{ col: "price", order: "asc" },
|
|
203
|
+
{ col: "isActive", order: "desc" },
|
|
204
|
+
{ col: "createdAt", order: "asc" },
|
|
205
|
+
];
|
|
206
|
+
const cursor = (0, cursor_utils_1.createCompositeCursor)(item, sortFields);
|
|
207
|
+
expect(cursor).toEqual({
|
|
208
|
+
count: item.count,
|
|
209
|
+
price: item.price,
|
|
210
|
+
isActive: item.isActive,
|
|
211
|
+
createdAt: item.createdAt,
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
//# sourceMappingURL=cursor-utils.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-utils.test.js","sourceRoot":"","sources":["../../../src/domain/__tests__/cursor-utils.test.ts"],"names":[],"mappings":";;AAAA,2CAAwC;AACxC,kDAAoF;AAGpF,UAAU,CAAC,GAAG,EAAE;IACd,IAAI,CAAC,eAAe,EAAE,CAAC;AACzB,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,MAAM,GAAG,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,IAAA,2BAAY,EAAC,MAAM,CAAC,CAAC;YACrC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,MAAM,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,IAAA,2BAAY,EAAC,MAAM,CAAC,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5E,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;YAC/D,MAAM,MAAM,GAAG;gBACb,IAAI,EAAE,UAAU;gBAChB,SAAS,EAAE,sBAAsB;gBACjC,QAAQ,EAAE,CAAC;gBACX,QAAQ,EAAE,IAAI;gBACd,EAAE,EAAE,UAAU;aACf,CAAC;YACF,MAAM,OAAO,GAAG,IAAA,2BAAY,EAAC,MAAM,CAAC,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5E,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,MAAM,GAAG;gBACb,IAAI,EAAE,qBAAqB;gBAC3B,KAAK,EAAE,mCAAmC;aAC3C,CAAC;YACF,MAAM,OAAO,GAAG,IAAA,2BAAY,EAAC,MAAM,CAAC,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5E,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,MAAM,GAAG;gBACb,IAAI,EAAE,IAAI;gBACV,WAAW,EAAE,SAAS;gBACtB,EAAE,EAAE,KAAK;aACV,CAAC;YACF,MAAM,OAAO,GAAG,IAAA,2BAAY,EAAC,MAAM,CAAC,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5E,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,iCAAiC;QACvF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,kBAAkB;YAC1C,MAAM,OAAO,GAAG,IAAA,2BAAY,EAAC,OAAO,CAAC,CAAC;YACtC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;YAC/B,MAAM,QAAQ,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,IAAA,2BAAY,EAAC,QAAQ,CAAC,CAAC;YACvC,MAAM,OAAO,GAAG,IAAA,2BAAY,EAAC,OAAO,CAAC,CAAC;YACtC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,WAAW;gBACjB,SAAS,EAAE,sBAAsB;gBACjC,KAAK,EAAE,EAAE;gBACT,SAAS,EAAE,KAAK;aACjB,CAAC;YACF,MAAM,OAAO,GAAG,IAAA,2BAAY,EAAC,QAAQ,CAAC,CAAC;YACvC,MAAM,OAAO,GAAG,IAAA,2BAAY,EAAC,OAAO,CAAC,CAAC;YACtC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,aAAa,GAAG,qBAAqB,CAAC;YAC5C,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,2BAAY,EAAC,aAAa,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC3E,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,2BAAY,EAAC,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,2BAAY,EAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;QAC1C,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,QAAQ,GAAG,EAAE,CAAC;YACpB,MAAM,SAAS,GAAG,IAAA,2BAAY,EAAC,IAAA,2BAAY,EAAC,QAAQ,CAAC,CAAC,CAAC;YACvD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,QAAQ,GAAG,EAAE,EAAE,EAAE,aAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YAC7C,MAAM,SAAS,GAAG,IAAA,2BAAY,EAAC,IAAA,2BAAY,EAAC,QAAQ,CAAC,CAAC,CAAC;YACvD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,QAAQ,GAAG;gBACf,EAAE,EAAE,aAAK,CAAC,MAAM,CAAC,IAAI,EAAE;gBACvB,IAAI,EAAE,aAAK,CAAC,MAAM,CAAC,QAAQ,EAAE;gBAC7B,KAAK,EAAE,aAAK,CAAC,QAAQ,CAAC,KAAK,EAAE;gBAC7B,GAAG,EAAE,aAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;gBAC5C,SAAS,EAAE,aAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE;gBAC5C,QAAQ,EAAE,aAAK,CAAC,QAAQ,CAAC,OAAO,EAAE;aACnC,CAAC;YACF,MAAM,SAAS,GAAG,IAAA,2BAAY,EAAC,IAAA,2BAAY,EAAC,QAAQ,CAAC,CAAC,CAAC;YACvD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,QAAQ,GAAG;gBACf,OAAO,EAAE,OAAO;gBAChB,SAAS,EAAE,uBAAuB;gBAClC,MAAM,EAAE,wBAAwB;gBAChC,OAAO,EAAE,YAAY;aACtB,CAAC;YACF,MAAM,SAAS,GAAG,IAAA,2BAAY,EAAC,IAAA,2BAAY,EAAC,QAAQ,CAAC,CAAC,CAAC;YACvD,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,MAAM,cAAc,GAAe;YACjC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE;YAC7B,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE;YACnC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;SAC5B,CAAC;QAEF,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,IAAI,GAAG;gBACX,EAAE,EAAE,aAAK,CAAC,MAAM,CAAC,IAAI,EAAE;gBACvB,IAAI,EAAE,aAAK,CAAC,MAAM,CAAC,QAAQ,EAAE;gBAC7B,SAAS,EAAE,aAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE;gBAC5C,KAAK,EAAE,aAAK,CAAC,QAAQ,CAAC,KAAK,EAAE;gBAC7B,GAAG,EAAE,aAAK,CAAC,MAAM,CAAC,GAAG,EAAE;aACxB,CAAC;YAEF,MAAM,MAAM,GAAG,IAAA,oCAAqB,EAAC,IAAI,EAAE,cAAc,CAAC,CAAC;YAE3D,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,EAAE,EAAE,IAAI,CAAC,EAAE;aACZ,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;YACjF,MAAM,IAAI,GAAG;gBACX,EAAE,EAAE,aAAK,CAAC,MAAM,CAAC,IAAI,EAAE;gBACvB,IAAI,EAAE,aAAK,CAAC,MAAM,CAAC,QAAQ,EAAE;gBAC7B,oBAAoB;gBACpB,KAAK,EAAE,aAAK,CAAC,QAAQ,CAAC,KAAK,EAAE;aAC9B,CAAC;YAEF,MAAM,MAAM,GAAG,IAAA,oCAAqB,EAAC,IAAI,EAAE,cAAc,CAAC,CAAC;YAE3D,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,SAAS,EAAE,SAAS;gBACpB,EAAE,EAAE,IAAI,CAAC,EAAE;aACZ,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,IAAI,GAAG;gBACX,EAAE,EAAE,aAAK,CAAC,MAAM,CAAC,IAAI,EAAE;gBACvB,IAAI,EAAE,aAAK,CAAC,MAAM,CAAC,QAAQ,EAAE;aAC9B,CAAC;YAEF,MAAM,MAAM,GAAG,IAAA,oCAAqB,EAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,IAAI,GAAG;gBACX,EAAE,EAAE,aAAK,CAAC,MAAM,CAAC,IAAI,EAAE;gBACvB,IAAI,EAAE,IAAI;gBACV,SAAS,EAAE,SAAS;gBACpB,MAAM,EAAE,QAAQ;aACjB,CAAC;YAEF,MAAM,MAAM,GAAG,IAAA,oCAAqB,EAAC,IAAI,EAAE,cAAc,CAAC,CAAC;YAE3D,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,IAAI,EAAE,IAAI;gBACV,SAAS,EAAE,SAAS;gBACpB,EAAE,EAAE,IAAI,CAAC,EAAE;aACZ,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,IAAI,GAAG;gBACX,EAAE,EAAE,aAAK,CAAC,MAAM,CAAC,IAAI,EAAE;gBACvB,IAAI,EAAE,aAAK,CAAC,MAAM,CAAC,QAAQ,EAAE;aAC9B,CAAC;YACF,MAAM,eAAe,GAAe,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YAEpE,MAAM,MAAM,GAAG,IAAA,oCAAqB,EAAC,IAAI,EAAE,eAAe,CAAC,CAAC;YAE5D,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,IAAI,GAAG;gBACX,EAAE,EAAE,aAAK,CAAC,MAAM,CAAC,IAAI,EAAE;gBACvB,KAAK,EAAE,aAAK,CAAC,MAAM,CAAC,GAAG,EAAE;gBACzB,KAAK,EAAE,aAAK,CAAC,MAAM,CAAC,KAAK,EAAE;gBAC3B,QAAQ,EAAE,aAAK,CAAC,QAAQ,CAAC,OAAO,EAAE;gBAClC,SAAS,EAAE,aAAK,CAAC,IAAI,CAAC,MAAM,EAAE;aAC/B,CAAC;YACF,MAAM,UAAU,GAAe;gBAC7B,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE;gBAC/B,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE;gBAC9B,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE;gBAClC,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE;aACnC,CAAC;YAEF,MAAM,MAAM,GAAG,IAAA,oCAAqB,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YAEvD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination-schema.test.d.ts","sourceRoot":"","sources":["../../../src/domain/__tests__/pagination-schema.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const faker_1 = require("@faker-js/faker");
|
|
4
|
+
const cursor_utils_1 = require("../cursor-utils");
|
|
5
|
+
const pagination_v2_1 = require("../pagination-v2");
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
jest.restoreAllMocks();
|
|
8
|
+
});
|
|
9
|
+
describe("pagination schema", () => {
|
|
10
|
+
const schema = (0, pagination_v2_1.createQueryMetaSchemaV2)();
|
|
11
|
+
describe("sort parameter validation", () => {
|
|
12
|
+
it("accepts valid sort string with multiple fields", () => {
|
|
13
|
+
const query = {
|
|
14
|
+
sort: "createdAt=desc,name=asc,id=asc",
|
|
15
|
+
count: 25,
|
|
16
|
+
};
|
|
17
|
+
const result = schema.parse(query);
|
|
18
|
+
expect(result.sort).toEqual([
|
|
19
|
+
{ col: "createdAt", order: "desc" },
|
|
20
|
+
{ col: "name", order: "asc" },
|
|
21
|
+
{ col: "id", order: "asc" },
|
|
22
|
+
]);
|
|
23
|
+
});
|
|
24
|
+
it("validates sort parameter formats", () => {
|
|
25
|
+
// Invalid sort order
|
|
26
|
+
expect(() => schema.parse({ sort: "name=invalid", count: 10 })).toThrow("Invalid sort order: invalid. Must be 'asc' or 'desc'");
|
|
27
|
+
// Missing column
|
|
28
|
+
expect(() => schema.parse({ sort: "=asc", count: 10 })).toThrow("Invalid sort format: =asc. Expected: column=order");
|
|
29
|
+
// Missing order
|
|
30
|
+
expect(() => schema.parse({ sort: "name=", count: 10 })).toThrow("Invalid sort format: name=. Expected: column=order");
|
|
31
|
+
// Wrong separator
|
|
32
|
+
expect(() => schema.parse({ sort: "name:asc", count: 10 })).toThrow("Invalid sort format: name:asc. Expected: column=order");
|
|
33
|
+
});
|
|
34
|
+
it("auto-adds id sort only to final sort, not originalSort", () => {
|
|
35
|
+
const query = {
|
|
36
|
+
sort: "name=asc,priority=desc",
|
|
37
|
+
count: 25,
|
|
38
|
+
};
|
|
39
|
+
const result = schema.parse(query);
|
|
40
|
+
// originalSort should contain exactly what user provided (no auto-added ID)
|
|
41
|
+
expect(result.originalSort).toEqual([
|
|
42
|
+
{ col: "name", order: "asc" },
|
|
43
|
+
{ col: "priority", order: "desc" },
|
|
44
|
+
]);
|
|
45
|
+
// sort should contain auto-added ID sort
|
|
46
|
+
expect(result.sort).toEqual([
|
|
47
|
+
{ col: "name", order: "asc" },
|
|
48
|
+
{ col: "priority", order: "desc" },
|
|
49
|
+
{ col: "id", order: "desc" },
|
|
50
|
+
]);
|
|
51
|
+
});
|
|
52
|
+
it("preserves user-provided id sort in both originalSort and sort", () => {
|
|
53
|
+
const query = {
|
|
54
|
+
sort: "name=asc,id=asc",
|
|
55
|
+
count: 25,
|
|
56
|
+
};
|
|
57
|
+
const result = schema.parse(query);
|
|
58
|
+
// Both should contain the user-provided ID sort
|
|
59
|
+
expect(result.originalSort).toEqual([
|
|
60
|
+
{ col: "name", order: "asc" },
|
|
61
|
+
{ col: "id", order: "asc" },
|
|
62
|
+
]);
|
|
63
|
+
expect(result.sort).toEqual([
|
|
64
|
+
{ col: "name", order: "asc" },
|
|
65
|
+
{ col: "id", order: "asc" },
|
|
66
|
+
]);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe("cursor parameter validation and transformation", () => {
|
|
70
|
+
it("transforms complex cursor with multiple string values", () => {
|
|
71
|
+
const cursorData = {
|
|
72
|
+
name: faker_1.faker.person.fullName(),
|
|
73
|
+
priority: faker_1.faker.number.int().toString(),
|
|
74
|
+
timestamp: faker_1.faker.date.recent().toISOString(),
|
|
75
|
+
category: "active",
|
|
76
|
+
id: faker_1.faker.string.uuid(),
|
|
77
|
+
};
|
|
78
|
+
const encodedCursor = (0, cursor_utils_1.encodeCursor)(cursorData);
|
|
79
|
+
const query = {
|
|
80
|
+
fromItem: encodedCursor,
|
|
81
|
+
sort: "name=asc,priority=desc,timestamp=desc,category=asc,id=desc",
|
|
82
|
+
count: 10,
|
|
83
|
+
};
|
|
84
|
+
const result = schema.parse(query);
|
|
85
|
+
expect(result.fromItem).toEqual(cursorData);
|
|
86
|
+
expect(result.sort).toEqual([
|
|
87
|
+
{ col: "name", order: "asc" },
|
|
88
|
+
{ col: "priority", order: "desc" },
|
|
89
|
+
{ col: "timestamp", order: "desc" },
|
|
90
|
+
{ col: "category", order: "asc" },
|
|
91
|
+
{ col: "id", order: "desc" },
|
|
92
|
+
]);
|
|
93
|
+
});
|
|
94
|
+
it("rejects invalid base64 cursor", () => {
|
|
95
|
+
const query = {
|
|
96
|
+
fromItem: "invalid-base64!!!",
|
|
97
|
+
count: 10,
|
|
98
|
+
};
|
|
99
|
+
expect(() => schema.parse(query)).toThrow("Invalid cursor: unable to decode cursor");
|
|
100
|
+
});
|
|
101
|
+
it("rejects valid base64 but invalid JSON cursor", () => {
|
|
102
|
+
const invalidJson = Buffer.from("not valid json", "utf8").toString("base64");
|
|
103
|
+
const query = {
|
|
104
|
+
fromItem: invalidJson,
|
|
105
|
+
count: 10,
|
|
106
|
+
};
|
|
107
|
+
expect(() => schema.parse(query)).toThrow();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
describe("complete query validation", () => {
|
|
111
|
+
it("validates complete query with sort and fromItem", () => {
|
|
112
|
+
const cursorData = {
|
|
113
|
+
name: "john",
|
|
114
|
+
createdAt: "2023-12-01T10:00:00Z",
|
|
115
|
+
id: faker_1.faker.string.uuid(),
|
|
116
|
+
};
|
|
117
|
+
const encodedCursor = (0, cursor_utils_1.encodeCursor)(cursorData);
|
|
118
|
+
const query = {
|
|
119
|
+
sort: "name=asc,createdAt=desc,id=asc",
|
|
120
|
+
fromItem: encodedCursor,
|
|
121
|
+
count: 25,
|
|
122
|
+
};
|
|
123
|
+
const result = schema.parse(query);
|
|
124
|
+
expect(result).toEqual({
|
|
125
|
+
sort: [
|
|
126
|
+
{ col: "name", order: "asc" },
|
|
127
|
+
{ col: "createdAt", order: "desc" },
|
|
128
|
+
{ col: "id", order: "asc" },
|
|
129
|
+
],
|
|
130
|
+
originalSort: [
|
|
131
|
+
{ col: "name", order: "asc" },
|
|
132
|
+
{ col: "createdAt", order: "desc" },
|
|
133
|
+
{ col: "id", order: "asc" },
|
|
134
|
+
],
|
|
135
|
+
fromItem: cursorData,
|
|
136
|
+
count: 25,
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
it("validates complete query with sort and toItem", () => {
|
|
140
|
+
const cursorData = { priority: "5", name: "test", id: faker_1.faker.string.uuid() };
|
|
141
|
+
const encodedCursor = (0, cursor_utils_1.encodeCursor)(cursorData);
|
|
142
|
+
const query = {
|
|
143
|
+
sort: "priority=desc,name=asc,id=asc",
|
|
144
|
+
toItem: encodedCursor,
|
|
145
|
+
count: 50,
|
|
146
|
+
};
|
|
147
|
+
const result = schema.parse(query);
|
|
148
|
+
expect(result).toEqual({
|
|
149
|
+
sort: [
|
|
150
|
+
{ col: "priority", order: "asc" },
|
|
151
|
+
{ col: "name", order: "desc" },
|
|
152
|
+
{ col: "id", order: "desc" },
|
|
153
|
+
],
|
|
154
|
+
originalSort: [
|
|
155
|
+
{ col: "priority", order: "desc" },
|
|
156
|
+
{ col: "name", order: "asc" },
|
|
157
|
+
{ col: "id", order: "asc" },
|
|
158
|
+
],
|
|
159
|
+
toItem: cursorData,
|
|
160
|
+
count: 50,
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
//# sourceMappingURL=pagination-schema.test.js.map
|