@geekmidas/db 10.0.0-alpha.12 → 10.0.0-alpha.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/errors.cjs +72 -5
  2. package/dist/errors.cjs.map +1 -0
  3. package/dist/errors.d.cts +4 -6
  4. package/dist/errors.d.cts.map +1 -1
  5. package/dist/errors.d.mts +4 -6
  6. package/dist/errors.d.mts.map +1 -1
  7. package/dist/errors.mjs +68 -2
  8. package/dist/errors.mjs.map +1 -0
  9. package/dist/kysely/pagination.cjs +7 -9
  10. package/dist/kysely/pagination.cjs.map +1 -1
  11. package/dist/kysely/pagination.d.cts +4 -14
  12. package/dist/kysely/pagination.d.cts.map +1 -1
  13. package/dist/kysely/pagination.d.mts +4 -14
  14. package/dist/kysely/pagination.d.mts.map +1 -1
  15. package/dist/kysely/pagination.mjs +6 -9
  16. package/dist/kysely/pagination.mjs.map +1 -1
  17. package/dist/kysely.cjs +11 -2
  18. package/dist/kysely.cjs.map +1 -0
  19. package/dist/kysely.d.cts +9 -2
  20. package/dist/kysely.d.cts.map +1 -0
  21. package/dist/kysely.d.mts +9 -2
  22. package/dist/kysely.d.mts.map +1 -0
  23. package/dist/kysely.mjs +10 -2
  24. package/dist/kysely.mjs.map +1 -0
  25. package/dist/objection/pagination.cjs +6 -7
  26. package/dist/objection/pagination.cjs.map +1 -1
  27. package/dist/objection/pagination.d.cts +4 -14
  28. package/dist/objection/pagination.d.cts.map +1 -1
  29. package/dist/objection/pagination.d.mts +4 -14
  30. package/dist/objection/pagination.d.mts.map +1 -1
  31. package/dist/objection/pagination.mjs +5 -7
  32. package/dist/objection/pagination.mjs.map +1 -1
  33. package/dist/pagination.cjs +39 -4
  34. package/dist/pagination.cjs.map +1 -0
  35. package/dist/pagination.d.cts +30 -2
  36. package/dist/pagination.d.cts.map +1 -0
  37. package/dist/pagination.d.mts +30 -2
  38. package/dist/pagination.d.mts.map +1 -0
  39. package/dist/pagination.mjs +36 -2
  40. package/dist/pagination.mjs.map +1 -0
  41. package/dist/pg/roles.cjs +3 -2
  42. package/dist/pg/roles.cjs.map +1 -1
  43. package/dist/pg/roles.d.cts +6 -8
  44. package/dist/pg/roles.d.cts.map +1 -1
  45. package/dist/pg/roles.d.mts +6 -8
  46. package/dist/pg/roles.d.mts.map +1 -1
  47. package/dist/pg/roles.mjs +2 -1
  48. package/dist/pg/roles.mjs.map +1 -1
  49. package/dist/pg/url.cjs +18 -3
  50. package/dist/pg/url.cjs.map +1 -1
  51. package/dist/pg/url.d.cts +2 -4
  52. package/dist/pg/url.d.cts.map +1 -1
  53. package/dist/pg/url.d.mts +2 -4
  54. package/dist/pg/url.d.mts.map +1 -1
  55. package/dist/pg/url.mjs +17 -3
  56. package/dist/pg/url.mjs.map +1 -1
  57. package/dist/rls.cjs +5 -29
  58. package/dist/rls.cjs.map +1 -1
  59. package/dist/rls.d.cts +6 -10
  60. package/dist/rls.d.cts.map +1 -1
  61. package/dist/rls.d.mts +6 -10
  62. package/dist/rls.d.mts.map +1 -1
  63. package/dist/rls.mjs +3 -5
  64. package/dist/rls.mjs.map +1 -1
  65. package/package.json +2 -2
  66. package/dist/errors-CfFCan-X.mjs +0 -69
  67. package/dist/errors-CfFCan-X.mjs.map +0 -1
  68. package/dist/errors-Cs5jlAv-.cjs +0 -93
  69. package/dist/errors-Cs5jlAv-.cjs.map +0 -1
  70. package/dist/kysely-BAedYsvn.d.mts +0 -13
  71. package/dist/kysely-BAedYsvn.d.mts.map +0 -1
  72. package/dist/kysely-Bo_Zg-D3.mjs +0 -11
  73. package/dist/kysely-Bo_Zg-D3.mjs.map +0 -1
  74. package/dist/kysely-D3eeuId4.d.cts +0 -13
  75. package/dist/kysely-D3eeuId4.d.cts.map +0 -1
  76. package/dist/kysely-LWvS2ekY.cjs +0 -17
  77. package/dist/kysely-LWvS2ekY.cjs.map +0 -1
  78. package/dist/pagination-BAFX7C1I.d.cts +0 -32
  79. package/dist/pagination-BAFX7C1I.d.cts.map +0 -1
  80. package/dist/pagination-Bu1dqOy0.cjs +0 -55
  81. package/dist/pagination-Bu1dqOy0.cjs.map +0 -1
  82. package/dist/pagination-CQ8QHXaL.mjs +0 -37
  83. package/dist/pagination-CQ8QHXaL.mjs.map +0 -1
  84. package/dist/pagination-kv-KWS-7.d.mts +0 -32
  85. package/dist/pagination-kv-KWS-7.d.mts.map +0 -1
package/dist/errors.cjs CHANGED
@@ -1,6 +1,73 @@
1
- const require_errors = require('./errors-Cs5jlAv-.cjs');
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/errors.ts
3
+ /**
4
+ * Database URL errors and redaction — engine-neutral.
5
+ *
6
+ * Nothing here is Postgres-specific: every engine addresses itself as a URL
7
+ * carrying a password, and "must name a host" holds for all of them. The parts
8
+ * that differ — libpq's `options=-c search_path=…`, which no other engine
9
+ * accepts — live under the driver they belong to.
10
+ *
11
+ * Messages state the rule, which is constant; the offending value is a field.
12
+ * An interpolated message cannot be matched on and carries user input into
13
+ * every log line that touches it.
14
+ */
15
+ /**
16
+ * Replace the password in a connection string with `***`.
17
+ *
18
+ * A connection string is a secret, and the places it is most likely to be
19
+ * written down — a log line, an error, a crash report shipped to a third party
20
+ * — are the places nobody is reading carefully. This exists so that redacting
21
+ * is the easy thing to do at each of them.
22
+ *
23
+ * Safe on input that is not a URL: it returns a constant rather than throwing,
24
+ * because this runs on paths that must not fail. Anything unparseable is
25
+ * treated as potentially secret and withheld entirely rather than echoed.
26
+ */
27
+ function redactDatabaseUrl(url) {
28
+ try {
29
+ const parsed = new URL(url);
30
+ if (!parsed.password) return url;
31
+ parsed.password = "***";
32
+ return parsed.toString();
33
+ } catch {
34
+ return "<unparseable url>";
35
+ }
36
+ }
37
+ /**
38
+ * Base for an address that cannot become a connection string.
39
+ *
40
+ * Deliberately carries no URL field: these are thrown while *composing* one, so
41
+ * there is no URL yet — only the parts, which include the password.
42
+ */
43
+ var DatabaseAddressError = class extends Error {
44
+ constructor(message) {
45
+ super(message);
46
+ this.name = new.target.name;
47
+ }
48
+ };
49
+ /** An address with no host to connect to. */
50
+ var MissingDatabaseHost = class extends DatabaseAddressError {
51
+ constructor() {
52
+ super("A database address must name a host");
53
+ }
54
+ };
55
+ /**
56
+ * An address with no database name.
57
+ *
58
+ * Postgres silently falls back to the connecting role's name, so the app
59
+ * connects successfully to the wrong database and fails later with confusing
60
+ * "relation does not exist" errors. Rejecting it here is much cheaper.
61
+ */
62
+ var MissingDatabaseName = class extends DatabaseAddressError {
63
+ constructor() {
64
+ super("A database address must name a database");
65
+ }
66
+ };
67
+ //#endregion
68
+ exports.DatabaseAddressError = DatabaseAddressError;
69
+ exports.MissingDatabaseHost = MissingDatabaseHost;
70
+ exports.MissingDatabaseName = MissingDatabaseName;
71
+ exports.redactDatabaseUrl = redactDatabaseUrl;
2
72
 
3
- exports.DatabaseAddressError = require_errors.DatabaseAddressError;
4
- exports.MissingDatabaseHost = require_errors.MissingDatabaseHost;
5
- exports.MissingDatabaseName = require_errors.MissingDatabaseName;
6
- exports.redactDatabaseUrl = require_errors.redactDatabaseUrl;
73
+ //# sourceMappingURL=errors.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Database URL errors and redaction — engine-neutral.\n *\n * Nothing here is Postgres-specific: every engine addresses itself as a URL\n * carrying a password, and \"must name a host\" holds for all of them. The parts\n * that differ — libpq's `options=-c search_path=…`, which no other engine\n * accepts — live under the driver they belong to.\n *\n * Messages state the rule, which is constant; the offending value is a field.\n * An interpolated message cannot be matched on and carries user input into\n * every log line that touches it.\n */\n\n/**\n * Replace the password in a connection string with `***`.\n *\n * A connection string is a secret, and the places it is most likely to be\n * written down — a log line, an error, a crash report shipped to a third party\n * — are the places nobody is reading carefully. This exists so that redacting\n * is the easy thing to do at each of them.\n *\n * Safe on input that is not a URL: it returns a constant rather than throwing,\n * because this runs on paths that must not fail. Anything unparseable is\n * treated as potentially secret and withheld entirely rather than echoed.\n */\nexport function redactDatabaseUrl(url: string): string {\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\tif (!parsed.password) return url;\n\t\tparsed.password = '***';\n\t\treturn parsed.toString();\n\t} catch {\n\t\treturn '<unparseable url>';\n\t}\n}\n\n/**\n * Base for an address that cannot become a connection string.\n *\n * Deliberately carries no URL field: these are thrown while *composing* one, so\n * there is no URL yet — only the parts, which include the password.\n */\nexport abstract class DatabaseAddressError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = new.target.name;\n\t}\n}\n\n/** An address with no host to connect to. */\nexport class MissingDatabaseHost extends DatabaseAddressError {\n\tconstructor() {\n\t\tsuper('A database address must name a host');\n\t}\n}\n\n/**\n * An address with no database name.\n *\n * Postgres silently falls back to the connecting role's name, so the app\n * connects successfully to the wrong database and fails later with confusing\n * \"relation does not exist\" errors. Rejecting it here is much cheaper.\n */\nexport class MissingDatabaseName extends DatabaseAddressError {\n\tconstructor() {\n\t\tsuper('A database address must name a database');\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,kBAAkB,KAAqB;CACtD,IAAI;EACH,MAAM,SAAS,IAAI,IAAI,GAAG;EAC1B,IAAI,CAAC,OAAO,UAAU,OAAO;EAC7B,OAAO,WAAW;EAClB,OAAO,OAAO,SAAS;CACxB,QAAQ;EACP,OAAO;CACR;AACD;;;;;;;AAQA,IAAsB,uBAAtB,cAAmD,MAAM;CACxD,YAAY,SAAiB;EAC5B,MAAM,OAAO;EACb,KAAK,OAAO,WAAW;CACxB;AACD;;AAGA,IAAa,sBAAb,cAAyC,qBAAqB;CAC7D,cAAc;EACb,MAAM,qCAAqC;CAC5C;AACD;;;;;;;;AASA,IAAa,sBAAb,cAAyC,qBAAqB;CAC7D,cAAc;EACb,MAAM,yCAAyC;CAChD;AACD"}
package/dist/errors.d.cts CHANGED
@@ -23,18 +23,18 @@
23
23
  * because this runs on paths that must not fail. Anything unparseable is
24
24
  * treated as potentially secret and withheld entirely rather than echoed.
25
25
  */
26
- declare function redactDatabaseUrl(url: string): string;
26
+ export declare function redactDatabaseUrl(url: string): string;
27
27
  /**
28
28
  * Base for an address that cannot become a connection string.
29
29
  *
30
30
  * Deliberately carries no URL field: these are thrown while *composing* one, so
31
31
  * there is no URL yet — only the parts, which include the password.
32
32
  */
33
- declare abstract class DatabaseAddressError extends Error {
33
+ export declare abstract class DatabaseAddressError extends Error {
34
34
  constructor(message: string);
35
35
  }
36
36
  /** An address with no host to connect to. */
37
- declare class MissingDatabaseHost extends DatabaseAddressError {
37
+ export declare class MissingDatabaseHost extends DatabaseAddressError {
38
38
  constructor();
39
39
  }
40
40
  /**
@@ -44,10 +44,8 @@ declare class MissingDatabaseHost extends DatabaseAddressError {
44
44
  * connects successfully to the wrong database and fails later with confusing
45
45
  * "relation does not exist" errors. Rejecting it here is much cheaper.
46
46
  */
47
- declare class MissingDatabaseName extends DatabaseAddressError {
47
+ export declare class MissingDatabaseName extends DatabaseAddressError {
48
48
  constructor();
49
49
  }
50
- //# sourceMappingURL=errors.d.ts.map
51
50
  //#endregion
52
- export { DatabaseAddressError, MissingDatabaseHost, MissingDatabaseName, redactDatabaseUrl };
53
51
  //# sourceMappingURL=errors.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.cts","names":[],"sources":["../src/errors.ts"],"sourcesContent":[],"mappings":";;AAyBA;AAiBA;AAQA;AAaA;;;;;;;;;;;;;;;;;;;;iBAtCgB,iBAAA;;;;;;;uBAiBM,oBAAA,SAA6B,KAAK;;;;cAQ3C,mBAAA,SAA4B,oBAAoB;;;;;;;;;;cAahD,mBAAA,SAA4B,oBAAoB"}
1
+ {"version":3,"file":"errors.d.cts","names":[],"sources":["../src/errors.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;wBAyBgB,kBAAkB;;;;;;;8BAiBZ,6BAA6B;EACtC,YAAA;;;qBAOA,4BAA4B;EAAA;;;;;;;;;qBAa5B,4BAA4B;EAAA"}
package/dist/errors.d.mts CHANGED
@@ -23,18 +23,18 @@
23
23
  * because this runs on paths that must not fail. Anything unparseable is
24
24
  * treated as potentially secret and withheld entirely rather than echoed.
25
25
  */
26
- declare function redactDatabaseUrl(url: string): string;
26
+ export declare function redactDatabaseUrl(url: string): string;
27
27
  /**
28
28
  * Base for an address that cannot become a connection string.
29
29
  *
30
30
  * Deliberately carries no URL field: these are thrown while *composing* one, so
31
31
  * there is no URL yet — only the parts, which include the password.
32
32
  */
33
- declare abstract class DatabaseAddressError extends Error {
33
+ export declare abstract class DatabaseAddressError extends Error {
34
34
  constructor(message: string);
35
35
  }
36
36
  /** An address with no host to connect to. */
37
- declare class MissingDatabaseHost extends DatabaseAddressError {
37
+ export declare class MissingDatabaseHost extends DatabaseAddressError {
38
38
  constructor();
39
39
  }
40
40
  /**
@@ -44,10 +44,8 @@ declare class MissingDatabaseHost extends DatabaseAddressError {
44
44
  * connects successfully to the wrong database and fails later with confusing
45
45
  * "relation does not exist" errors. Rejecting it here is much cheaper.
46
46
  */
47
- declare class MissingDatabaseName extends DatabaseAddressError {
47
+ export declare class MissingDatabaseName extends DatabaseAddressError {
48
48
  constructor();
49
49
  }
50
- //# sourceMappingURL=errors.d.ts.map
51
50
  //#endregion
52
- export { DatabaseAddressError, MissingDatabaseHost, MissingDatabaseName, redactDatabaseUrl };
53
51
  //# sourceMappingURL=errors.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.mts","names":[],"sources":["../src/errors.ts"],"sourcesContent":[],"mappings":";;AAyBA;AAiBA;AAQA;AAaA;;;;;;;;;;;;;;;;;;;;iBAtCgB,iBAAA;;;;;;;uBAiBM,oBAAA,SAA6B,KAAK;;;;cAQ3C,mBAAA,SAA4B,oBAAoB;;;;;;;;;;cAahD,mBAAA,SAA4B,oBAAoB"}
1
+ {"version":3,"file":"errors.d.mts","names":[],"sources":["../src/errors.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;wBAyBgB,kBAAkB;;;;;;;8BAiBZ,6BAA6B;EACtC,YAAA;;;qBAOA,4BAA4B;EAAA;;;;;;;;;qBAa5B,4BAA4B;EAAA"}
package/dist/errors.mjs CHANGED
@@ -1,3 +1,69 @@
1
- import { DatabaseAddressError, MissingDatabaseHost, MissingDatabaseName, redactDatabaseUrl } from "./errors-CfFCan-X.mjs";
1
+ //#region src/errors.ts
2
+ /**
3
+ * Database URL errors and redaction — engine-neutral.
4
+ *
5
+ * Nothing here is Postgres-specific: every engine addresses itself as a URL
6
+ * carrying a password, and "must name a host" holds for all of them. The parts
7
+ * that differ — libpq's `options=-c search_path=…`, which no other engine
8
+ * accepts — live under the driver they belong to.
9
+ *
10
+ * Messages state the rule, which is constant; the offending value is a field.
11
+ * An interpolated message cannot be matched on and carries user input into
12
+ * every log line that touches it.
13
+ */
14
+ /**
15
+ * Replace the password in a connection string with `***`.
16
+ *
17
+ * A connection string is a secret, and the places it is most likely to be
18
+ * written down — a log line, an error, a crash report shipped to a third party
19
+ * — are the places nobody is reading carefully. This exists so that redacting
20
+ * is the easy thing to do at each of them.
21
+ *
22
+ * Safe on input that is not a URL: it returns a constant rather than throwing,
23
+ * because this runs on paths that must not fail. Anything unparseable is
24
+ * treated as potentially secret and withheld entirely rather than echoed.
25
+ */
26
+ function redactDatabaseUrl(url) {
27
+ try {
28
+ const parsed = new URL(url);
29
+ if (!parsed.password) return url;
30
+ parsed.password = "***";
31
+ return parsed.toString();
32
+ } catch {
33
+ return "<unparseable url>";
34
+ }
35
+ }
36
+ /**
37
+ * Base for an address that cannot become a connection string.
38
+ *
39
+ * Deliberately carries no URL field: these are thrown while *composing* one, so
40
+ * there is no URL yet — only the parts, which include the password.
41
+ */
42
+ var DatabaseAddressError = class extends Error {
43
+ constructor(message) {
44
+ super(message);
45
+ this.name = new.target.name;
46
+ }
47
+ };
48
+ /** An address with no host to connect to. */
49
+ var MissingDatabaseHost = class extends DatabaseAddressError {
50
+ constructor() {
51
+ super("A database address must name a host");
52
+ }
53
+ };
54
+ /**
55
+ * An address with no database name.
56
+ *
57
+ * Postgres silently falls back to the connecting role's name, so the app
58
+ * connects successfully to the wrong database and fails later with confusing
59
+ * "relation does not exist" errors. Rejecting it here is much cheaper.
60
+ */
61
+ var MissingDatabaseName = class extends DatabaseAddressError {
62
+ constructor() {
63
+ super("A database address must name a database");
64
+ }
65
+ };
66
+ //#endregion
67
+ export { DatabaseAddressError, MissingDatabaseHost, MissingDatabaseName, redactDatabaseUrl };
2
68
 
3
- export { DatabaseAddressError, MissingDatabaseHost, MissingDatabaseName, redactDatabaseUrl };
69
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Database URL errors and redaction — engine-neutral.\n *\n * Nothing here is Postgres-specific: every engine addresses itself as a URL\n * carrying a password, and \"must name a host\" holds for all of them. The parts\n * that differ — libpq's `options=-c search_path=…`, which no other engine\n * accepts — live under the driver they belong to.\n *\n * Messages state the rule, which is constant; the offending value is a field.\n * An interpolated message cannot be matched on and carries user input into\n * every log line that touches it.\n */\n\n/**\n * Replace the password in a connection string with `***`.\n *\n * A connection string is a secret, and the places it is most likely to be\n * written down — a log line, an error, a crash report shipped to a third party\n * — are the places nobody is reading carefully. This exists so that redacting\n * is the easy thing to do at each of them.\n *\n * Safe on input that is not a URL: it returns a constant rather than throwing,\n * because this runs on paths that must not fail. Anything unparseable is\n * treated as potentially secret and withheld entirely rather than echoed.\n */\nexport function redactDatabaseUrl(url: string): string {\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\tif (!parsed.password) return url;\n\t\tparsed.password = '***';\n\t\treturn parsed.toString();\n\t} catch {\n\t\treturn '<unparseable url>';\n\t}\n}\n\n/**\n * Base for an address that cannot become a connection string.\n *\n * Deliberately carries no URL field: these are thrown while *composing* one, so\n * there is no URL yet — only the parts, which include the password.\n */\nexport abstract class DatabaseAddressError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = new.target.name;\n\t}\n}\n\n/** An address with no host to connect to. */\nexport class MissingDatabaseHost extends DatabaseAddressError {\n\tconstructor() {\n\t\tsuper('A database address must name a host');\n\t}\n}\n\n/**\n * An address with no database name.\n *\n * Postgres silently falls back to the connecting role's name, so the app\n * connects successfully to the wrong database and fails later with confusing\n * \"relation does not exist\" errors. Rejecting it here is much cheaper.\n */\nexport class MissingDatabaseName extends DatabaseAddressError {\n\tconstructor() {\n\t\tsuper('A database address must name a database');\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,kBAAkB,KAAqB;CACtD,IAAI;EACH,MAAM,SAAS,IAAI,IAAI,GAAG;EAC1B,IAAI,CAAC,OAAO,UAAU,OAAO;EAC7B,OAAO,WAAW;EAClB,OAAO,OAAO,SAAS;CACxB,QAAQ;EACP,OAAO;CACR;AACD;;;;;;;AAQA,IAAsB,uBAAtB,cAAmD,MAAM;CACxD,YAAY,SAAiB;EAC5B,MAAM,OAAO;EACb,KAAK,OAAO,WAAW;CACxB;AACD;;AAGA,IAAa,sBAAb,cAAyC,qBAAqB;CAC7D,cAAc;EACb,MAAM,qCAAqC;CAC5C;AACD;;;;;;;;AASA,IAAa,sBAAb,cAAyC,qBAAqB;CAC7D,cAAc;EACb,MAAM,yCAAyC;CAChD;AACD"}
@@ -1,5 +1,5 @@
1
- const require_pagination = require('../pagination-Bu1dqOy0.cjs');
2
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_pagination = require("../pagination.cjs");
3
3
  //#region src/kysely/pagination.ts
4
4
  /**
5
5
  * Generic paginated search function that handles:
@@ -24,12 +24,11 @@ const require_pagination = require('../pagination-Bu1dqOy0.cjs');
24
24
  * });
25
25
  * ```
26
26
  */
27
- async function paginatedSearch({ query, cursor, limit = 20, mapRow, cursorField = "id", cursorDirection = require_pagination.Direction.Asc }) {
28
- const countResult = await query.clearSelect().clearOrderBy().select((eb) => eb.fn.countAll().as("count")).executeTakeFirstOrThrow();
29
- const count = countResult.count;
27
+ async function paginatedSearch({ query, cursor, limit = 20, mapRow, cursorField = "id", cursorDirection = "asc" }) {
28
+ const count = (await query.clearSelect().clearOrderBy().select((eb) => eb.fn.countAll().as("count")).executeTakeFirstOrThrow()).count;
30
29
  let paginatedQuery = query;
31
30
  if (cursor) {
32
- const operator = cursorDirection === require_pagination.Direction.Asc ? ">" : "<";
31
+ const operator = cursorDirection === "asc" ? ">" : "<";
33
32
  paginatedQuery = paginatedQuery.where(cursorField, operator, cursor);
34
33
  }
35
34
  const data = await paginatedQuery.orderBy(cursorField, cursorDirection).limit(limit + 1).execute();
@@ -38,9 +37,8 @@ async function paginatedSearch({ query, cursor, limit = 20, mapRow, cursorField
38
37
  const lastRow = rows[rows.length - 1];
39
38
  const nextCursor = hasMore && lastRow ? String(lastRow[cursorField]) : void 0;
40
39
  const mapper = mapRow ?? ((row) => row);
41
- const items = await Promise.all(rows.map(mapper));
42
40
  return {
43
- items,
41
+ items: await Promise.all(rows.map(mapper)),
44
42
  pagination: {
45
43
  total: Number(count),
46
44
  hasMore,
@@ -48,10 +46,10 @@ async function paginatedSearch({ query, cursor, limit = 20, mapRow, cursorField
48
46
  }
49
47
  };
50
48
  }
51
-
52
49
  //#endregion
53
50
  exports.Direction = require_pagination.Direction;
54
51
  exports.decodeCursor = require_pagination.decodeCursor;
55
52
  exports.encodeCursor = require_pagination.encodeCursor;
56
53
  exports.paginatedSearch = paginatedSearch;
54
+
57
55
  //# sourceMappingURL=pagination.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.cjs","names":["Direction","row: TRow"],"sources":["../../src/kysely/pagination.ts"],"sourcesContent":["import type { SelectQueryBuilder } from 'kysely';\nimport {\n\tDirection,\n\tdecodeCursor,\n\tencodeCursor,\n\ttype PaginationResult,\n} from '../pagination';\n\nexport { Direction, decodeCursor, encodeCursor, type PaginationResult };\n\n/**\n * Options for paginated search.\n */\nexport interface PaginatedSearchOptions<\n\tTRow,\n\tTMapRow extends (row: TRow) => unknown = (row: TRow) => TRow,\n> {\n\t/** The base Kysely query to paginate */\n\tquery: SelectQueryBuilder<any, any, TRow>;\n\t/** Cursor value for pagination (value of cursorField from previous page) */\n\tcursor?: string;\n\t/** Maximum number of items per page (default: 20) */\n\tlimit?: number;\n\t/** Function to transform each row to the output format (default: identity) */\n\tmapRow?: TMapRow;\n\t/** Field to use for cursor pagination (default: 'id') */\n\tcursorField?: string;\n\t/** Sort direction for cursor field (default: Direction.Asc) */\n\tcursorDirection?: Direction;\n}\n\n/**\n * Generic paginated search function that handles:\n * - Total count calculation\n * - Cursor-based pagination\n * - Fetching one extra row to determine hasMore\n * - Mapping rows to output format\n *\n * @example\n * ```typescript\n * // With mapRow\n * const result = await paginatedSearch({\n * query: db.selectFrom('users').selectAll(),\n * limit: 20,\n * mapRow: (row) => ({ id: row.id, name: row.name }),\n * });\n *\n * // Without mapRow — items are the raw row type\n * const result = await paginatedSearch({\n * query: db.selectFrom('users').selectAll(),\n * limit: 20,\n * });\n * ```\n */\nexport async function paginatedSearch<\n\tTRow extends Record<string, unknown>,\n\tTMapRow extends (row: TRow) => unknown = (row: TRow) => TRow,\n>({\n\tquery,\n\tcursor,\n\tlimit = 20,\n\tmapRow,\n\tcursorField = 'id',\n\tcursorDirection = Direction.Asc,\n}: PaginatedSearchOptions<TRow, TMapRow>): Promise<\n\tPaginationResult<Awaited<ReturnType<TMapRow>>>\n> {\n\t// Get total count (without cursor)\n\tconst countResult = await query\n\t\t.clearSelect()\n\t\t.clearOrderBy()\n\t\t.select((eb) => eb.fn.countAll().as('count'))\n\t\t.executeTakeFirstOrThrow();\n\n\tconst count = countResult.count;\n\n\t// Apply cursor if provided\n\tlet paginatedQuery = query;\n\tif (cursor) {\n\t\tconst operator = cursorDirection === Direction.Asc ? '>' : '<';\n\t\tpaginatedQuery = paginatedQuery.where(\n\t\t\tcursorField as any,\n\t\t\toperator,\n\t\t\tcursor,\n\t\t) as typeof query;\n\t}\n\n\t// Fetch one extra to determine if there are more results\n\tconst data = await paginatedQuery\n\t\t.orderBy(cursorField as any, cursorDirection)\n\t\t.limit(limit + 1)\n\t\t.execute();\n\n\tconst hasMore = data.length > limit;\n\tconst rows = hasMore ? data.slice(0, limit) : data;\n\tconst lastRow = rows[rows.length - 1];\n\tconst nextCursor =\n\t\thasMore && lastRow ? String(lastRow[cursorField]) : undefined;\n\n\tconst mapper = mapRow ?? ((row: TRow) => row);\n\tconst items = (await Promise.all(rows.map(mapper))) as Awaited<\n\t\tReturnType<TMapRow>\n\t>[];\n\n\treturn {\n\t\titems,\n\t\tpagination: {\n\t\t\ttotal: Number(count),\n\t\t\thasMore,\n\t\t\tcursor: nextCursor,\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,eAAsB,gBAGpB,EACD,OACA,QACA,QAAQ,IACR,QACA,cAAc,MACd,kBAAkBA,6BAAU,KACW,EAEtC;CAED,MAAM,cAAc,MAAM,MACxB,aAAa,CACb,cAAc,CACd,OAAO,CAAC,OAAO,GAAG,GAAG,UAAU,CAAC,GAAG,QAAQ,CAAC,CAC5C,yBAAyB;CAE3B,MAAM,QAAQ,YAAY;CAG1B,IAAI,iBAAiB;AACrB,KAAI,QAAQ;EACX,MAAM,WAAW,oBAAoBA,6BAAU,MAAM,MAAM;AAC3D,mBAAiB,eAAe,MAC/B,aACA,UACA,OACA;CACD;CAGD,MAAM,OAAO,MAAM,eACjB,QAAQ,aAAoB,gBAAgB,CAC5C,MAAM,QAAQ,EAAE,CAChB,SAAS;CAEX,MAAM,UAAU,KAAK,SAAS;CAC9B,MAAM,OAAO,UAAU,KAAK,MAAM,GAAG,MAAM,GAAG;CAC9C,MAAM,UAAU,KAAK,KAAK,SAAS;CACnC,MAAM,aACL,WAAW,UAAU,OAAO,QAAQ,aAAa;CAElD,MAAM,SAAS,WAAW,CAACC,QAAc;CACzC,MAAM,QAAS,MAAM,QAAQ,IAAI,KAAK,IAAI,OAAO,CAAC;AAIlD,QAAO;EACN;EACA,YAAY;GACX,OAAO,OAAO,MAAM;GACpB;GACA,QAAQ;EACR;CACD;AACD"}
1
+ {"version":3,"file":"pagination.cjs","names":[],"sources":["../../src/kysely/pagination.ts"],"sourcesContent":["import type { SelectQueryBuilder } from 'kysely';\nimport {\n\tDirection,\n\tdecodeCursor,\n\tencodeCursor,\n\ttype PaginationResult,\n} from '../pagination';\n\nexport { Direction, decodeCursor, encodeCursor, type PaginationResult };\n\n/**\n * Options for paginated search.\n */\nexport interface PaginatedSearchOptions<\n\tTRow,\n\tTMapRow extends (row: TRow) => unknown = (row: TRow) => TRow,\n> {\n\t/** The base Kysely query to paginate */\n\tquery: SelectQueryBuilder<any, any, TRow>;\n\t/** Cursor value for pagination (value of cursorField from previous page) */\n\tcursor?: string;\n\t/** Maximum number of items per page (default: 20) */\n\tlimit?: number;\n\t/** Function to transform each row to the output format (default: identity) */\n\tmapRow?: TMapRow;\n\t/** Field to use for cursor pagination (default: 'id') */\n\tcursorField?: string;\n\t/** Sort direction for cursor field (default: Direction.Asc) */\n\tcursorDirection?: Direction;\n}\n\n/**\n * Generic paginated search function that handles:\n * - Total count calculation\n * - Cursor-based pagination\n * - Fetching one extra row to determine hasMore\n * - Mapping rows to output format\n *\n * @example\n * ```typescript\n * // With mapRow\n * const result = await paginatedSearch({\n * query: db.selectFrom('users').selectAll(),\n * limit: 20,\n * mapRow: (row) => ({ id: row.id, name: row.name }),\n * });\n *\n * // Without mapRow — items are the raw row type\n * const result = await paginatedSearch({\n * query: db.selectFrom('users').selectAll(),\n * limit: 20,\n * });\n * ```\n */\nexport async function paginatedSearch<\n\tTRow extends Record<string, unknown>,\n\tTMapRow extends (row: TRow) => unknown = (row: TRow) => TRow,\n>({\n\tquery,\n\tcursor,\n\tlimit = 20,\n\tmapRow,\n\tcursorField = 'id',\n\tcursorDirection = Direction.Asc,\n}: PaginatedSearchOptions<TRow, TMapRow>): Promise<\n\tPaginationResult<Awaited<ReturnType<TMapRow>>>\n> {\n\t// Get total count (without cursor)\n\tconst countResult = await query\n\t\t.clearSelect()\n\t\t.clearOrderBy()\n\t\t.select((eb) => eb.fn.countAll().as('count'))\n\t\t.executeTakeFirstOrThrow();\n\n\tconst count = countResult.count;\n\n\t// Apply cursor if provided\n\tlet paginatedQuery = query;\n\tif (cursor) {\n\t\tconst operator = cursorDirection === Direction.Asc ? '>' : '<';\n\t\tpaginatedQuery = paginatedQuery.where(\n\t\t\tcursorField as any,\n\t\t\toperator,\n\t\t\tcursor,\n\t\t) as typeof query;\n\t}\n\n\t// Fetch one extra to determine if there are more results\n\tconst data = await paginatedQuery\n\t\t.orderBy(cursorField as any, cursorDirection)\n\t\t.limit(limit + 1)\n\t\t.execute();\n\n\tconst hasMore = data.length > limit;\n\tconst rows = hasMore ? data.slice(0, limit) : data;\n\tconst lastRow = rows[rows.length - 1];\n\tconst nextCursor =\n\t\thasMore && lastRow ? String(lastRow[cursorField]) : undefined;\n\n\tconst mapper = mapRow ?? ((row: TRow) => row);\n\tconst items = (await Promise.all(rows.map(mapper))) as Awaited<\n\t\tReturnType<TMapRow>\n\t>[];\n\n\treturn {\n\t\titems,\n\t\tpagination: {\n\t\t\ttotal: Number(count),\n\t\t\thasMore,\n\t\t\tcursor: nextCursor,\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,eAAsB,gBAGpB,EACD,OACA,QACA,QAAQ,IACR,QACA,cAAc,MACd,kBAAA,SAGC;CAQD,MAAM,SAAQ,MANY,MACxB,YAAY,CAAC,CACb,aAAa,CAAC,CACd,QAAQ,OAAO,GAAG,GAAG,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAC5C,wBAAwB,EAAA,CAEA;CAG1B,IAAI,iBAAiB;CACrB,IAAI,QAAQ;EACX,MAAM,WAAW,oBAAA,QAAoC,MAAM;EAC3D,iBAAiB,eAAe,MAC/B,aACA,UACA,MACD;CACD;CAGA,MAAM,OAAO,MAAM,eACjB,QAAQ,aAAoB,eAAe,CAAC,CAC5C,MAAM,QAAQ,CAAC,CAAC,CAChB,QAAQ;CAEV,MAAM,UAAU,KAAK,SAAS;CAC9B,MAAM,OAAO,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;CAC9C,MAAM,UAAU,KAAK,KAAK,SAAS;CACnC,MAAM,aACL,WAAW,UAAU,OAAO,QAAQ,YAAY,IAAI,KAAA;CAErD,MAAM,SAAS,YAAY,QAAc;CAKzC,OAAO;EACN,OAAA,MALoB,QAAQ,IAAI,KAAK,IAAI,MAAM,CAAC;EAMhD,YAAY;GACX,OAAO,OAAO,KAAK;GACnB;GACA,QAAQ;EACT;CACD;AACD"}
@@ -1,12 +1,10 @@
1
- import { Direction, PaginationResult, decodeCursor, encodeCursor } from "../pagination-BAFX7C1I.cjs";
1
+ import { Direction, PaginationResult, decodeCursor, encodeCursor } from "../pagination.cjs";
2
2
  import { SelectQueryBuilder } from "kysely";
3
-
4
3
  //#region src/kysely/pagination.d.ts
5
-
6
4
  /**
7
5
  * Options for paginated search.
8
6
  */
9
- interface PaginatedSearchOptions<TRow, TMapRow extends (row: TRow) => unknown = (row: TRow) => TRow> {
7
+ export interface PaginatedSearchOptions<TRow, TMapRow extends (row: TRow) => unknown = (row: TRow) => TRow> {
10
8
  /** The base Kysely query to paginate */
11
9
  query: SelectQueryBuilder<any, any, TRow>;
12
10
  /** Cursor value for pagination (value of cursorField from previous page) */
@@ -43,15 +41,7 @@ interface PaginatedSearchOptions<TRow, TMapRow extends (row: TRow) => unknown =
43
41
  * });
44
42
  * ```
45
43
  */
46
- declare function paginatedSearch<TRow extends Record<string, unknown>, TMapRow extends (row: TRow) => unknown = (row: TRow) => TRow>({
47
- query,
48
- cursor,
49
- limit,
50
- mapRow,
51
- cursorField,
52
- cursorDirection
53
- }: PaginatedSearchOptions<TRow, TMapRow>): Promise<PaginationResult<Awaited<ReturnType<TMapRow>>>>;
54
- //# sourceMappingURL=pagination.d.ts.map
44
+ export declare function paginatedSearch<TRow extends Record<string, unknown>, TMapRow extends (row: TRow) => unknown = (row: TRow) => TRow>({ query, cursor, limit, mapRow, cursorField, cursorDirection }: PaginatedSearchOptions<TRow, TMapRow>): Promise<PaginationResult<Awaited<ReturnType<TMapRow>>>>;
55
45
  //#endregion
56
- export { Direction, PaginatedSearchOptions, PaginationResult, decodeCursor, encodeCursor, paginatedSearch };
46
+ export { Direction, type PaginationResult, decodeCursor, encodeCursor };
57
47
  //# sourceMappingURL=pagination.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.d.cts","names":[],"sources":["../../src/kysely/pagination.ts"],"sourcesContent":[],"mappings":";;;;;;AAaA;;AAEuB,UAFN,sBAEM,CAAA,IAAA,EAAA,gBAAA,CAAA,GAAA,EAAA,IAAA,EAAA,GAAA,OAAA,GAAA,CAAA,GAAA,EAAyB,IAAzB,EAAA,GAAkC,IAAlC,CAAA,CAAA;EAAI;EAAyB,KAAK,EAGjD,kBAHiD,CAAA,GAAA,EAAA,GAAA,EAGpB,IAHoB,CAAA;EAAI;EAGpB,MAAjC,CAAA,EAAA,MAAA;EAAkB;EAMT,KAIE,CAAA,EAAA,MAAA;EAAS;EA0BN,MAAA,CAAA,EA9BZ,OA8BY;EAAe;EAAA,WACvB,CAAA,EAAA,MAAA;EAAM;EACO,eAAqB,CAAA,EA5B7B,SA4B6B;;;;;;;;;;;;;;;;AAQE;;;;;;;;;iBAV5B,6BACR,+CACS,yBAAyB,SAAS;;;;;;;GAQtD,uBAAuB,MAAM,WAAW,QAC1C,iBAAiB,QAAQ,WAAW"}
1
+ {"version":3,"file":"pagination.d.cts","names":[],"sources":["../../src/kysely/pagination.ts"],"mappings":";;;;;;iBAaiB,uBAChB,MACA,iBAAiB,KAAK,oBAAoB,KAAK,SAAS;;EAGxD,OAAO,6BAA6B;;EAEpC;;EAEA;;EAEA,SAAS;;EAET;;EAEA,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;wBA0BG,gBACrB,aAAa,yBACb,iBAAiB,KAAK,oBAAoB,KAAK,SAAS,QAExD,OACA,QACA,OACA,QACA,aACA,mBACE,uBAAuB,MAAM,WAAW,QAC1C,iBAAiB,QAAQ,WAAW"}
@@ -1,12 +1,10 @@
1
- import { Direction, PaginationResult, decodeCursor, encodeCursor } from "../pagination-kv-KWS-7.mjs";
1
+ import { Direction, PaginationResult, decodeCursor, encodeCursor } from "../pagination.mjs";
2
2
  import { SelectQueryBuilder } from "kysely";
3
-
4
3
  //#region src/kysely/pagination.d.ts
5
-
6
4
  /**
7
5
  * Options for paginated search.
8
6
  */
9
- interface PaginatedSearchOptions<TRow, TMapRow extends (row: TRow) => unknown = (row: TRow) => TRow> {
7
+ export interface PaginatedSearchOptions<TRow, TMapRow extends (row: TRow) => unknown = (row: TRow) => TRow> {
10
8
  /** The base Kysely query to paginate */
11
9
  query: SelectQueryBuilder<any, any, TRow>;
12
10
  /** Cursor value for pagination (value of cursorField from previous page) */
@@ -43,15 +41,7 @@ interface PaginatedSearchOptions<TRow, TMapRow extends (row: TRow) => unknown =
43
41
  * });
44
42
  * ```
45
43
  */
46
- declare function paginatedSearch<TRow extends Record<string, unknown>, TMapRow extends (row: TRow) => unknown = (row: TRow) => TRow>({
47
- query,
48
- cursor,
49
- limit,
50
- mapRow,
51
- cursorField,
52
- cursorDirection
53
- }: PaginatedSearchOptions<TRow, TMapRow>): Promise<PaginationResult<Awaited<ReturnType<TMapRow>>>>;
54
- //# sourceMappingURL=pagination.d.ts.map
44
+ export declare function paginatedSearch<TRow extends Record<string, unknown>, TMapRow extends (row: TRow) => unknown = (row: TRow) => TRow>({ query, cursor, limit, mapRow, cursorField, cursorDirection }: PaginatedSearchOptions<TRow, TMapRow>): Promise<PaginationResult<Awaited<ReturnType<TMapRow>>>>;
55
45
  //#endregion
56
- export { Direction, PaginatedSearchOptions, PaginationResult, decodeCursor, encodeCursor, paginatedSearch };
46
+ export { Direction, type PaginationResult, decodeCursor, encodeCursor };
57
47
  //# sourceMappingURL=pagination.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.d.mts","names":[],"sources":["../../src/kysely/pagination.ts"],"sourcesContent":[],"mappings":";;;;;;AAaA;;AAEuB,UAFN,sBAEM,CAAA,IAAA,EAAA,gBAAA,CAAA,GAAA,EAAA,IAAA,EAAA,GAAA,OAAA,GAAA,CAAA,GAAA,EAAyB,IAAzB,EAAA,GAAkC,IAAlC,CAAA,CAAA;EAAI;EAAyB,KAAK,EAGjD,kBAHiD,CAAA,GAAA,EAAA,GAAA,EAGpB,IAHoB,CAAA;EAAI;EAGpB,MAAjC,CAAA,EAAA,MAAA;EAAkB;EAMT,KAIE,CAAA,EAAA,MAAA;EAAS;EA0BN,MAAA,CAAA,EA9BZ,OA8BY;EAAe;EAAA,WACvB,CAAA,EAAA,MAAA;EAAM;EACO,eAAqB,CAAA,EA5B7B,SA4B6B;;;;;;;;;;;;;;;;AAQE;;;;;;;;;iBAV5B,6BACR,+CACS,yBAAyB,SAAS;;;;;;;GAQtD,uBAAuB,MAAM,WAAW,QAC1C,iBAAiB,QAAQ,WAAW"}
1
+ {"version":3,"file":"pagination.d.mts","names":[],"sources":["../../src/kysely/pagination.ts"],"mappings":";;;;;;iBAaiB,uBAChB,MACA,iBAAiB,KAAK,oBAAoB,KAAK,SAAS;;EAGxD,OAAO,6BAA6B;;EAEpC;;EAEA;;EAEA,SAAS;;EAET;;EAEA,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;wBA0BG,gBACrB,aAAa,yBACb,iBAAiB,KAAK,oBAAoB,KAAK,SAAS,QAExD,OACA,QACA,OACA,QACA,aACA,mBACE,uBAAuB,MAAM,WAAW,QAC1C,iBAAiB,QAAQ,WAAW"}
@@ -1,5 +1,4 @@
1
- import { Direction, decodeCursor, encodeCursor } from "../pagination-CQ8QHXaL.mjs";
2
-
1
+ import { Direction, decodeCursor, encodeCursor } from "../pagination.mjs";
3
2
  //#region src/kysely/pagination.ts
4
3
  /**
5
4
  * Generic paginated search function that handles:
@@ -24,12 +23,11 @@ import { Direction, decodeCursor, encodeCursor } from "../pagination-CQ8QHXaL.mj
24
23
  * });
25
24
  * ```
26
25
  */
27
- async function paginatedSearch({ query, cursor, limit = 20, mapRow, cursorField = "id", cursorDirection = Direction.Asc }) {
28
- const countResult = await query.clearSelect().clearOrderBy().select((eb) => eb.fn.countAll().as("count")).executeTakeFirstOrThrow();
29
- const count = countResult.count;
26
+ async function paginatedSearch({ query, cursor, limit = 20, mapRow, cursorField = "id", cursorDirection = "asc" }) {
27
+ const count = (await query.clearSelect().clearOrderBy().select((eb) => eb.fn.countAll().as("count")).executeTakeFirstOrThrow()).count;
30
28
  let paginatedQuery = query;
31
29
  if (cursor) {
32
- const operator = cursorDirection === Direction.Asc ? ">" : "<";
30
+ const operator = cursorDirection === "asc" ? ">" : "<";
33
31
  paginatedQuery = paginatedQuery.where(cursorField, operator, cursor);
34
32
  }
35
33
  const data = await paginatedQuery.orderBy(cursorField, cursorDirection).limit(limit + 1).execute();
@@ -38,9 +36,8 @@ async function paginatedSearch({ query, cursor, limit = 20, mapRow, cursorField
38
36
  const lastRow = rows[rows.length - 1];
39
37
  const nextCursor = hasMore && lastRow ? String(lastRow[cursorField]) : void 0;
40
38
  const mapper = mapRow ?? ((row) => row);
41
- const items = await Promise.all(rows.map(mapper));
42
39
  return {
43
- items,
40
+ items: await Promise.all(rows.map(mapper)),
44
41
  pagination: {
45
42
  total: Number(count),
46
43
  hasMore,
@@ -48,7 +45,7 @@ async function paginatedSearch({ query, cursor, limit = 20, mapRow, cursorField
48
45
  }
49
46
  };
50
47
  }
51
-
52
48
  //#endregion
53
49
  export { Direction, decodeCursor, encodeCursor, paginatedSearch };
50
+
54
51
  //# sourceMappingURL=pagination.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.mjs","names":["row: TRow"],"sources":["../../src/kysely/pagination.ts"],"sourcesContent":["import type { SelectQueryBuilder } from 'kysely';\nimport {\n\tDirection,\n\tdecodeCursor,\n\tencodeCursor,\n\ttype PaginationResult,\n} from '../pagination';\n\nexport { Direction, decodeCursor, encodeCursor, type PaginationResult };\n\n/**\n * Options for paginated search.\n */\nexport interface PaginatedSearchOptions<\n\tTRow,\n\tTMapRow extends (row: TRow) => unknown = (row: TRow) => TRow,\n> {\n\t/** The base Kysely query to paginate */\n\tquery: SelectQueryBuilder<any, any, TRow>;\n\t/** Cursor value for pagination (value of cursorField from previous page) */\n\tcursor?: string;\n\t/** Maximum number of items per page (default: 20) */\n\tlimit?: number;\n\t/** Function to transform each row to the output format (default: identity) */\n\tmapRow?: TMapRow;\n\t/** Field to use for cursor pagination (default: 'id') */\n\tcursorField?: string;\n\t/** Sort direction for cursor field (default: Direction.Asc) */\n\tcursorDirection?: Direction;\n}\n\n/**\n * Generic paginated search function that handles:\n * - Total count calculation\n * - Cursor-based pagination\n * - Fetching one extra row to determine hasMore\n * - Mapping rows to output format\n *\n * @example\n * ```typescript\n * // With mapRow\n * const result = await paginatedSearch({\n * query: db.selectFrom('users').selectAll(),\n * limit: 20,\n * mapRow: (row) => ({ id: row.id, name: row.name }),\n * });\n *\n * // Without mapRow — items are the raw row type\n * const result = await paginatedSearch({\n * query: db.selectFrom('users').selectAll(),\n * limit: 20,\n * });\n * ```\n */\nexport async function paginatedSearch<\n\tTRow extends Record<string, unknown>,\n\tTMapRow extends (row: TRow) => unknown = (row: TRow) => TRow,\n>({\n\tquery,\n\tcursor,\n\tlimit = 20,\n\tmapRow,\n\tcursorField = 'id',\n\tcursorDirection = Direction.Asc,\n}: PaginatedSearchOptions<TRow, TMapRow>): Promise<\n\tPaginationResult<Awaited<ReturnType<TMapRow>>>\n> {\n\t// Get total count (without cursor)\n\tconst countResult = await query\n\t\t.clearSelect()\n\t\t.clearOrderBy()\n\t\t.select((eb) => eb.fn.countAll().as('count'))\n\t\t.executeTakeFirstOrThrow();\n\n\tconst count = countResult.count;\n\n\t// Apply cursor if provided\n\tlet paginatedQuery = query;\n\tif (cursor) {\n\t\tconst operator = cursorDirection === Direction.Asc ? '>' : '<';\n\t\tpaginatedQuery = paginatedQuery.where(\n\t\t\tcursorField as any,\n\t\t\toperator,\n\t\t\tcursor,\n\t\t) as typeof query;\n\t}\n\n\t// Fetch one extra to determine if there are more results\n\tconst data = await paginatedQuery\n\t\t.orderBy(cursorField as any, cursorDirection)\n\t\t.limit(limit + 1)\n\t\t.execute();\n\n\tconst hasMore = data.length > limit;\n\tconst rows = hasMore ? data.slice(0, limit) : data;\n\tconst lastRow = rows[rows.length - 1];\n\tconst nextCursor =\n\t\thasMore && lastRow ? String(lastRow[cursorField]) : undefined;\n\n\tconst mapper = mapRow ?? ((row: TRow) => row);\n\tconst items = (await Promise.all(rows.map(mapper))) as Awaited<\n\t\tReturnType<TMapRow>\n\t>[];\n\n\treturn {\n\t\titems,\n\t\tpagination: {\n\t\t\ttotal: Number(count),\n\t\t\thasMore,\n\t\t\tcursor: nextCursor,\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,eAAsB,gBAGpB,EACD,OACA,QACA,QAAQ,IACR,QACA,cAAc,MACd,kBAAkB,UAAU,KACW,EAEtC;CAED,MAAM,cAAc,MAAM,MACxB,aAAa,CACb,cAAc,CACd,OAAO,CAAC,OAAO,GAAG,GAAG,UAAU,CAAC,GAAG,QAAQ,CAAC,CAC5C,yBAAyB;CAE3B,MAAM,QAAQ,YAAY;CAG1B,IAAI,iBAAiB;AACrB,KAAI,QAAQ;EACX,MAAM,WAAW,oBAAoB,UAAU,MAAM,MAAM;AAC3D,mBAAiB,eAAe,MAC/B,aACA,UACA,OACA;CACD;CAGD,MAAM,OAAO,MAAM,eACjB,QAAQ,aAAoB,gBAAgB,CAC5C,MAAM,QAAQ,EAAE,CAChB,SAAS;CAEX,MAAM,UAAU,KAAK,SAAS;CAC9B,MAAM,OAAO,UAAU,KAAK,MAAM,GAAG,MAAM,GAAG;CAC9C,MAAM,UAAU,KAAK,KAAK,SAAS;CACnC,MAAM,aACL,WAAW,UAAU,OAAO,QAAQ,aAAa;CAElD,MAAM,SAAS,WAAW,CAACA,QAAc;CACzC,MAAM,QAAS,MAAM,QAAQ,IAAI,KAAK,IAAI,OAAO,CAAC;AAIlD,QAAO;EACN;EACA,YAAY;GACX,OAAO,OAAO,MAAM;GACpB;GACA,QAAQ;EACR;CACD;AACD"}
1
+ {"version":3,"file":"pagination.mjs","names":[],"sources":["../../src/kysely/pagination.ts"],"sourcesContent":["import type { SelectQueryBuilder } from 'kysely';\nimport {\n\tDirection,\n\tdecodeCursor,\n\tencodeCursor,\n\ttype PaginationResult,\n} from '../pagination';\n\nexport { Direction, decodeCursor, encodeCursor, type PaginationResult };\n\n/**\n * Options for paginated search.\n */\nexport interface PaginatedSearchOptions<\n\tTRow,\n\tTMapRow extends (row: TRow) => unknown = (row: TRow) => TRow,\n> {\n\t/** The base Kysely query to paginate */\n\tquery: SelectQueryBuilder<any, any, TRow>;\n\t/** Cursor value for pagination (value of cursorField from previous page) */\n\tcursor?: string;\n\t/** Maximum number of items per page (default: 20) */\n\tlimit?: number;\n\t/** Function to transform each row to the output format (default: identity) */\n\tmapRow?: TMapRow;\n\t/** Field to use for cursor pagination (default: 'id') */\n\tcursorField?: string;\n\t/** Sort direction for cursor field (default: Direction.Asc) */\n\tcursorDirection?: Direction;\n}\n\n/**\n * Generic paginated search function that handles:\n * - Total count calculation\n * - Cursor-based pagination\n * - Fetching one extra row to determine hasMore\n * - Mapping rows to output format\n *\n * @example\n * ```typescript\n * // With mapRow\n * const result = await paginatedSearch({\n * query: db.selectFrom('users').selectAll(),\n * limit: 20,\n * mapRow: (row) => ({ id: row.id, name: row.name }),\n * });\n *\n * // Without mapRow — items are the raw row type\n * const result = await paginatedSearch({\n * query: db.selectFrom('users').selectAll(),\n * limit: 20,\n * });\n * ```\n */\nexport async function paginatedSearch<\n\tTRow extends Record<string, unknown>,\n\tTMapRow extends (row: TRow) => unknown = (row: TRow) => TRow,\n>({\n\tquery,\n\tcursor,\n\tlimit = 20,\n\tmapRow,\n\tcursorField = 'id',\n\tcursorDirection = Direction.Asc,\n}: PaginatedSearchOptions<TRow, TMapRow>): Promise<\n\tPaginationResult<Awaited<ReturnType<TMapRow>>>\n> {\n\t// Get total count (without cursor)\n\tconst countResult = await query\n\t\t.clearSelect()\n\t\t.clearOrderBy()\n\t\t.select((eb) => eb.fn.countAll().as('count'))\n\t\t.executeTakeFirstOrThrow();\n\n\tconst count = countResult.count;\n\n\t// Apply cursor if provided\n\tlet paginatedQuery = query;\n\tif (cursor) {\n\t\tconst operator = cursorDirection === Direction.Asc ? '>' : '<';\n\t\tpaginatedQuery = paginatedQuery.where(\n\t\t\tcursorField as any,\n\t\t\toperator,\n\t\t\tcursor,\n\t\t) as typeof query;\n\t}\n\n\t// Fetch one extra to determine if there are more results\n\tconst data = await paginatedQuery\n\t\t.orderBy(cursorField as any, cursorDirection)\n\t\t.limit(limit + 1)\n\t\t.execute();\n\n\tconst hasMore = data.length > limit;\n\tconst rows = hasMore ? data.slice(0, limit) : data;\n\tconst lastRow = rows[rows.length - 1];\n\tconst nextCursor =\n\t\thasMore && lastRow ? String(lastRow[cursorField]) : undefined;\n\n\tconst mapper = mapRow ?? ((row: TRow) => row);\n\tconst items = (await Promise.all(rows.map(mapper))) as Awaited<\n\t\tReturnType<TMapRow>\n\t>[];\n\n\treturn {\n\t\titems,\n\t\tpagination: {\n\t\t\ttotal: Number(count),\n\t\t\thasMore,\n\t\t\tcursor: nextCursor,\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,eAAsB,gBAGpB,EACD,OACA,QACA,QAAQ,IACR,QACA,cAAc,MACd,kBAAA,SAGC;CAQD,MAAM,SAAQ,MANY,MACxB,YAAY,CAAC,CACb,aAAa,CAAC,CACd,QAAQ,OAAO,GAAG,GAAG,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAC5C,wBAAwB,EAAA,CAEA;CAG1B,IAAI,iBAAiB;CACrB,IAAI,QAAQ;EACX,MAAM,WAAW,oBAAA,QAAoC,MAAM;EAC3D,iBAAiB,eAAe,MAC/B,aACA,UACA,MACD;CACD;CAGA,MAAM,OAAO,MAAM,eACjB,QAAQ,aAAoB,eAAe,CAAC,CAC5C,MAAM,QAAQ,CAAC,CAAC,CAChB,QAAQ;CAEV,MAAM,UAAU,KAAK,SAAS;CAC9B,MAAM,OAAO,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;CAC9C,MAAM,UAAU,KAAK,KAAK,SAAS;CACnC,MAAM,aACL,WAAW,UAAU,OAAO,QAAQ,YAAY,IAAI,KAAA;CAErD,MAAM,SAAS,YAAY,QAAc;CAKzC,OAAO;EACN,OAAA,MALoB,QAAQ,IAAI,KAAK,IAAI,MAAM,CAAC;EAMhD,YAAY;GACX,OAAO,OAAO,KAAK;GACnB;GACA,QAAQ;EACT;CACD;AACD"}
package/dist/kysely.cjs CHANGED
@@ -1,3 +1,12 @@
1
- const require_kysely = require('./kysely-LWvS2ekY.cjs');
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/kysely.ts
3
+ function withTransaction(db, cb, settings) {
4
+ if (db.isTransaction) return cb(db);
5
+ const builder = db.transaction();
6
+ if (settings?.isolationLevel) return builder.setIsolationLevel(settings.isolationLevel).execute(cb);
7
+ return builder.execute(cb);
8
+ }
9
+ //#endregion
10
+ exports.withTransaction = withTransaction;
2
11
 
3
- exports.withTransaction = require_kysely.withTransaction;
12
+ //# sourceMappingURL=kysely.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely.cjs","names":[],"sources":["../src/kysely.ts"],"sourcesContent":["import type {\n\tControlledTransaction,\n\tIsolationLevel,\n\tKysely,\n\tTransaction,\n} from 'kysely';\n\nexport interface TransactionSettings {\n\tisolationLevel?: IsolationLevel;\n}\n\nexport function withTransaction<DB, T>(\n\tdb: DatabaseConnection<DB>,\n\tcb: (trx: Transaction<DB>) => Promise<T>,\n\tsettings?: TransactionSettings,\n): Promise<T> {\n\tif (db.isTransaction) {\n\t\treturn cb(db as Transaction<DB>);\n\t}\n\n\tconst builder = db.transaction();\n\n\tif (settings?.isolationLevel) {\n\t\treturn builder.setIsolationLevel(settings.isolationLevel).execute(cb);\n\t}\n\n\treturn builder.execute(cb);\n}\n\nexport type DatabaseConnection<T> =\n\t| ControlledTransaction<T>\n\t| Kysely<T>\n\t| Transaction<T>;\n"],"mappings":";;AAWA,SAAgB,gBACf,IACA,IACA,UACa;CACb,IAAI,GAAG,eACN,OAAO,GAAG,EAAqB;CAGhC,MAAM,UAAU,GAAG,YAAY;CAE/B,IAAI,UAAU,gBACb,OAAO,QAAQ,kBAAkB,SAAS,cAAc,CAAC,CAAC,QAAQ,EAAE;CAGrE,OAAO,QAAQ,QAAQ,EAAE;AAC1B"}
package/dist/kysely.d.cts CHANGED
@@ -1,2 +1,9 @@
1
- import { DatabaseConnection, TransactionSettings, withTransaction } from "./kysely-D3eeuId4.cjs";
2
- export { DatabaseConnection, TransactionSettings, withTransaction };
1
+ import { ControlledTransaction, IsolationLevel, Kysely, Transaction } from "kysely";
2
+ //#region src/kysely.d.ts
3
+ export interface TransactionSettings {
4
+ isolationLevel?: IsolationLevel;
5
+ }
6
+ export declare function withTransaction<DB, T>(db: DatabaseConnection<DB>, cb: (trx: Transaction<DB>) => Promise<T>, settings?: TransactionSettings): Promise<T>;
7
+ export type DatabaseConnection<T> = ControlledTransaction<T> | Kysely<T> | Transaction<T>;
8
+ //#endregion
9
+ //# sourceMappingURL=kysely.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely.d.cts","names":[],"sources":["../src/kysely.ts"],"mappings":";;iBAOiB;EAChB,iBAAiB;;wBAGF,gBAAgB,IAAI,GACnC,IAAI,mBAAmB,KACvB,KAAK,KAAK,YAAY,QAAQ,QAAQ,IACtC,WAAW,sBACT,QAAQ;YAcC,mBAAmB,KAC5B,sBAAsB,KACtB,OAAO,KACP,YAAY"}
package/dist/kysely.d.mts CHANGED
@@ -1,2 +1,9 @@
1
- import { DatabaseConnection, TransactionSettings, withTransaction } from "./kysely-BAedYsvn.mjs";
2
- export { DatabaseConnection, TransactionSettings, withTransaction };
1
+ import { ControlledTransaction, IsolationLevel, Kysely, Transaction } from "kysely";
2
+ //#region src/kysely.d.ts
3
+ export interface TransactionSettings {
4
+ isolationLevel?: IsolationLevel;
5
+ }
6
+ export declare function withTransaction<DB, T>(db: DatabaseConnection<DB>, cb: (trx: Transaction<DB>) => Promise<T>, settings?: TransactionSettings): Promise<T>;
7
+ export type DatabaseConnection<T> = ControlledTransaction<T> | Kysely<T> | Transaction<T>;
8
+ //#endregion
9
+ //# sourceMappingURL=kysely.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely.d.mts","names":[],"sources":["../src/kysely.ts"],"mappings":";;iBAOiB;EAChB,iBAAiB;;wBAGF,gBAAgB,IAAI,GACnC,IAAI,mBAAmB,KACvB,KAAK,KAAK,YAAY,QAAQ,QAAQ,IACtC,WAAW,sBACT,QAAQ;YAcC,mBAAmB,KAC5B,sBAAsB,KACtB,OAAO,KACP,YAAY"}
package/dist/kysely.mjs CHANGED
@@ -1,3 +1,11 @@
1
- import { withTransaction } from "./kysely-Bo_Zg-D3.mjs";
1
+ //#region src/kysely.ts
2
+ function withTransaction(db, cb, settings) {
3
+ if (db.isTransaction) return cb(db);
4
+ const builder = db.transaction();
5
+ if (settings?.isolationLevel) return builder.setIsolationLevel(settings.isolationLevel).execute(cb);
6
+ return builder.execute(cb);
7
+ }
8
+ //#endregion
9
+ export { withTransaction };
2
10
 
3
- export { withTransaction };
11
+ //# sourceMappingURL=kysely.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kysely.mjs","names":[],"sources":["../src/kysely.ts"],"sourcesContent":["import type {\n\tControlledTransaction,\n\tIsolationLevel,\n\tKysely,\n\tTransaction,\n} from 'kysely';\n\nexport interface TransactionSettings {\n\tisolationLevel?: IsolationLevel;\n}\n\nexport function withTransaction<DB, T>(\n\tdb: DatabaseConnection<DB>,\n\tcb: (trx: Transaction<DB>) => Promise<T>,\n\tsettings?: TransactionSettings,\n): Promise<T> {\n\tif (db.isTransaction) {\n\t\treturn cb(db as Transaction<DB>);\n\t}\n\n\tconst builder = db.transaction();\n\n\tif (settings?.isolationLevel) {\n\t\treturn builder.setIsolationLevel(settings.isolationLevel).execute(cb);\n\t}\n\n\treturn builder.execute(cb);\n}\n\nexport type DatabaseConnection<T> =\n\t| ControlledTransaction<T>\n\t| Kysely<T>\n\t| Transaction<T>;\n"],"mappings":";AAWA,SAAgB,gBACf,IACA,IACA,UACa;CACb,IAAI,GAAG,eACN,OAAO,GAAG,EAAqB;CAGhC,MAAM,UAAU,GAAG,YAAY;CAE/B,IAAI,UAAU,gBACb,OAAO,QAAQ,kBAAkB,SAAS,cAAc,CAAC,CAAC,QAAQ,EAAE;CAGrE,OAAO,QAAQ,QAAQ,EAAE;AAC1B"}
@@ -1,5 +1,5 @@
1
- const require_pagination = require('../pagination-Bu1dqOy0.cjs');
2
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_pagination = require("../pagination.cjs");
3
3
  //#region src/objection/pagination.ts
4
4
  /**
5
5
  * Cursor-based paginated search for Objection.js models.
@@ -18,11 +18,11 @@ const require_pagination = require('../pagination-Bu1dqOy0.cjs');
18
18
  * });
19
19
  * ```
20
20
  */
21
- async function paginatedSearch({ query, cursor, limit = 20, mapRow, cursorField = "id", cursorDirection = require_pagination.Direction.Asc }) {
21
+ async function paginatedSearch({ query, cursor, limit = 20, mapRow, cursorField = "id", cursorDirection = "asc" }) {
22
22
  const total = await query.resultSize();
23
23
  let paginatedQuery = query.clone();
24
24
  if (cursor) {
25
- const operator = cursorDirection === require_pagination.Direction.Asc ? ">" : "<";
25
+ const operator = cursorDirection === "asc" ? ">" : "<";
26
26
  paginatedQuery = paginatedQuery.where(cursorField, operator, cursor);
27
27
  }
28
28
  const data = await paginatedQuery.orderBy(cursorField, cursorDirection).limit(limit + 1);
@@ -31,9 +31,8 @@ async function paginatedSearch({ query, cursor, limit = 20, mapRow, cursorField
31
31
  const lastRow = rows[rows.length - 1];
32
32
  const nextCursor = hasMore && lastRow ? String(lastRow[cursorField]) : void 0;
33
33
  const mapper = mapRow ?? ((row) => row);
34
- const items = await Promise.all(rows.map(mapper));
35
34
  return {
36
- items,
35
+ items: await Promise.all(rows.map(mapper)),
37
36
  pagination: {
38
37
  total,
39
38
  hasMore,
@@ -41,10 +40,10 @@ async function paginatedSearch({ query, cursor, limit = 20, mapRow, cursorField
41
40
  }
42
41
  };
43
42
  }
44
-
45
43
  //#endregion
46
44
  exports.Direction = require_pagination.Direction;
47
45
  exports.decodeCursor = require_pagination.decodeCursor;
48
46
  exports.encodeCursor = require_pagination.encodeCursor;
49
47
  exports.paginatedSearch = paginatedSearch;
48
+
50
49
  //# sourceMappingURL=pagination.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.cjs","names":["Direction","row: TModel"],"sources":["../../src/objection/pagination.ts"],"sourcesContent":["import type { Model, QueryBuilder } from 'objection';\nimport {\n\tDirection,\n\tdecodeCursor,\n\tencodeCursor,\n\ttype PaginationResult,\n} from '../pagination';\n\nexport { Direction, decodeCursor, encodeCursor, type PaginationResult };\n\n/**\n * Options for paginated search with Objection.js models.\n */\nexport interface ObjectionPaginatedSearchOptions<\n\tTModel extends Model,\n\tTMapRow extends (row: TModel) => unknown = (row: TModel) => TModel,\n> {\n\t/** The Objection QueryBuilder to paginate (e.g. User.query(trx).where(...)) */\n\tquery: QueryBuilder<TModel>;\n\t/** Cursor value for pagination (value of cursorField from previous page) */\n\tcursor?: string;\n\t/** Maximum number of items per page (default: 20) */\n\tlimit?: number;\n\t/** Function to transform each row to the output format (default: identity) */\n\tmapRow?: TMapRow;\n\t/** Field to use for cursor pagination (default: 'id') */\n\tcursorField?: string;\n\t/** Sort direction for cursor field (default: Direction.Asc) */\n\tcursorDirection?: Direction;\n}\n\n/**\n * Cursor-based paginated search for Objection.js models.\n *\n * Accepts a pre-built QueryBuilder so callers can apply filters,\n * eager loading, and scopes before pagination is layered on top.\n *\n * @example\n * ```typescript\n * const result = await paginatedSearch({\n * query: User.query(trx).where('orgId', orgId).withGraphFetched('roles'),\n * cursor: previousCursor,\n * limit: 20,\n * cursorField: 'createdAt',\n * cursorDirection: Direction.Desc,\n * });\n * ```\n */\nexport async function paginatedSearch<\n\tTModel extends Model,\n\tTMapRow extends (row: TModel) => unknown = (row: TModel) => TModel,\n>({\n\tquery,\n\tcursor,\n\tlimit = 20,\n\tmapRow,\n\tcursorField = 'id',\n\tcursorDirection = Direction.Asc,\n}: ObjectionPaginatedSearchOptions<TModel, TMapRow>): Promise<\n\tPaginationResult<Awaited<ReturnType<TMapRow>>>\n> {\n\t// Get total count (without cursor filtering)\n\tconst total = await query.resultSize();\n\n\t// Apply cursor if provided\n\tlet paginatedQuery = query.clone();\n\tif (cursor) {\n\t\tconst operator = cursorDirection === Direction.Asc ? '>' : '<';\n\t\tpaginatedQuery = paginatedQuery.where(cursorField, operator, cursor);\n\t}\n\n\t// Fetch one extra to determine if there are more results\n\tconst data = await paginatedQuery\n\t\t.orderBy(cursorField, cursorDirection)\n\t\t.limit(limit + 1);\n\n\tconst hasMore = data.length > limit;\n\tconst rows = hasMore ? data.slice(0, limit) : data;\n\tconst lastRow = rows[rows.length - 1];\n\tconst nextCursor =\n\t\thasMore && lastRow\n\t\t\t? String((lastRow as Record<string, unknown>)[cursorField])\n\t\t\t: undefined;\n\n\tconst mapper = mapRow ?? ((row: TModel) => row);\n\tconst items = (await Promise.all(rows.map(mapper))) as Awaited<\n\t\tReturnType<TMapRow>\n\t>[];\n\n\treturn {\n\t\titems,\n\t\tpagination: {\n\t\t\ttotal,\n\t\t\thasMore,\n\t\t\tcursor: nextCursor,\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgDA,eAAsB,gBAGpB,EACD,OACA,QACA,QAAQ,IACR,QACA,cAAc,MACd,kBAAkBA,6BAAU,KACsB,EAEjD;CAED,MAAM,QAAQ,MAAM,MAAM,YAAY;CAGtC,IAAI,iBAAiB,MAAM,OAAO;AAClC,KAAI,QAAQ;EACX,MAAM,WAAW,oBAAoBA,6BAAU,MAAM,MAAM;AAC3D,mBAAiB,eAAe,MAAM,aAAa,UAAU,OAAO;CACpE;CAGD,MAAM,OAAO,MAAM,eACjB,QAAQ,aAAa,gBAAgB,CACrC,MAAM,QAAQ,EAAE;CAElB,MAAM,UAAU,KAAK,SAAS;CAC9B,MAAM,OAAO,UAAU,KAAK,MAAM,GAAG,MAAM,GAAG;CAC9C,MAAM,UAAU,KAAK,KAAK,SAAS;CACnC,MAAM,aACL,WAAW,UACR,OAAQ,QAAoC,aAAa;CAG7D,MAAM,SAAS,WAAW,CAACC,QAAgB;CAC3C,MAAM,QAAS,MAAM,QAAQ,IAAI,KAAK,IAAI,OAAO,CAAC;AAIlD,QAAO;EACN;EACA,YAAY;GACX;GACA;GACA,QAAQ;EACR;CACD;AACD"}
1
+ {"version":3,"file":"pagination.cjs","names":[],"sources":["../../src/objection/pagination.ts"],"sourcesContent":["import type { Model, QueryBuilder } from 'objection';\nimport {\n\tDirection,\n\tdecodeCursor,\n\tencodeCursor,\n\ttype PaginationResult,\n} from '../pagination';\n\nexport { Direction, decodeCursor, encodeCursor, type PaginationResult };\n\n/**\n * Options for paginated search with Objection.js models.\n */\nexport interface ObjectionPaginatedSearchOptions<\n\tTModel extends Model,\n\tTMapRow extends (row: TModel) => unknown = (row: TModel) => TModel,\n> {\n\t/** The Objection QueryBuilder to paginate (e.g. User.query(trx).where(...)) */\n\tquery: QueryBuilder<TModel>;\n\t/** Cursor value for pagination (value of cursorField from previous page) */\n\tcursor?: string;\n\t/** Maximum number of items per page (default: 20) */\n\tlimit?: number;\n\t/** Function to transform each row to the output format (default: identity) */\n\tmapRow?: TMapRow;\n\t/** Field to use for cursor pagination (default: 'id') */\n\tcursorField?: string;\n\t/** Sort direction for cursor field (default: Direction.Asc) */\n\tcursorDirection?: Direction;\n}\n\n/**\n * Cursor-based paginated search for Objection.js models.\n *\n * Accepts a pre-built QueryBuilder so callers can apply filters,\n * eager loading, and scopes before pagination is layered on top.\n *\n * @example\n * ```typescript\n * const result = await paginatedSearch({\n * query: User.query(trx).where('orgId', orgId).withGraphFetched('roles'),\n * cursor: previousCursor,\n * limit: 20,\n * cursorField: 'createdAt',\n * cursorDirection: Direction.Desc,\n * });\n * ```\n */\nexport async function paginatedSearch<\n\tTModel extends Model,\n\tTMapRow extends (row: TModel) => unknown = (row: TModel) => TModel,\n>({\n\tquery,\n\tcursor,\n\tlimit = 20,\n\tmapRow,\n\tcursorField = 'id',\n\tcursorDirection = Direction.Asc,\n}: ObjectionPaginatedSearchOptions<TModel, TMapRow>): Promise<\n\tPaginationResult<Awaited<ReturnType<TMapRow>>>\n> {\n\t// Get total count (without cursor filtering)\n\tconst total = await query.resultSize();\n\n\t// Apply cursor if provided\n\tlet paginatedQuery = query.clone();\n\tif (cursor) {\n\t\tconst operator = cursorDirection === Direction.Asc ? '>' : '<';\n\t\tpaginatedQuery = paginatedQuery.where(cursorField, operator, cursor);\n\t}\n\n\t// Fetch one extra to determine if there are more results\n\tconst data = await paginatedQuery\n\t\t.orderBy(cursorField, cursorDirection)\n\t\t.limit(limit + 1);\n\n\tconst hasMore = data.length > limit;\n\tconst rows = hasMore ? data.slice(0, limit) : data;\n\tconst lastRow = rows[rows.length - 1];\n\tconst nextCursor =\n\t\thasMore && lastRow\n\t\t\t? String((lastRow as Record<string, unknown>)[cursorField])\n\t\t\t: undefined;\n\n\tconst mapper = mapRow ?? ((row: TModel) => row);\n\tconst items = (await Promise.all(rows.map(mapper))) as Awaited<\n\t\tReturnType<TMapRow>\n\t>[];\n\n\treturn {\n\t\titems,\n\t\tpagination: {\n\t\t\ttotal,\n\t\t\thasMore,\n\t\t\tcursor: nextCursor,\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgDA,eAAsB,gBAGpB,EACD,OACA,QACA,QAAQ,IACR,QACA,cAAc,MACd,kBAAA,SAGC;CAED,MAAM,QAAQ,MAAM,MAAM,WAAW;CAGrC,IAAI,iBAAiB,MAAM,MAAM;CACjC,IAAI,QAAQ;EACX,MAAM,WAAW,oBAAA,QAAoC,MAAM;EAC3D,iBAAiB,eAAe,MAAM,aAAa,UAAU,MAAM;CACpE;CAGA,MAAM,OAAO,MAAM,eACjB,QAAQ,aAAa,eAAe,CAAC,CACrC,MAAM,QAAQ,CAAC;CAEjB,MAAM,UAAU,KAAK,SAAS;CAC9B,MAAM,OAAO,UAAU,KAAK,MAAM,GAAG,KAAK,IAAI;CAC9C,MAAM,UAAU,KAAK,KAAK,SAAS;CACnC,MAAM,aACL,WAAW,UACR,OAAQ,QAAoC,YAAY,IACxD,KAAA;CAEJ,MAAM,SAAS,YAAY,QAAgB;CAK3C,OAAO;EACN,OAAA,MALoB,QAAQ,IAAI,KAAK,IAAI,MAAM,CAAC;EAMhD,YAAY;GACX;GACA;GACA,QAAQ;EACT;CACD;AACD"}