glasswork 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/http/route-helpers.d.ts +4 -4
  2. package/dist/http/route-helpers.d.ts.map +1 -1
  3. package/dist/http/route-helpers.js +4 -1
  4. package/dist/http/route-helpers.js.map +1 -1
  5. package/dist/index.d.ts +3 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +4 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/list-query/builder.d.ts +33 -0
  10. package/dist/list-query/builder.d.ts.map +1 -0
  11. package/dist/list-query/builder.js +104 -0
  12. package/dist/list-query/builder.js.map +1 -0
  13. package/dist/list-query/casl.d.ts +36 -0
  14. package/dist/list-query/casl.d.ts.map +1 -0
  15. package/dist/list-query/casl.js +42 -0
  16. package/dist/list-query/casl.js.map +1 -0
  17. package/dist/list-query/global-search.d.ts +20 -0
  18. package/dist/list-query/global-search.d.ts.map +1 -0
  19. package/dist/list-query/global-search.js +68 -0
  20. package/dist/list-query/global-search.js.map +1 -0
  21. package/dist/list-query/index.d.ts +6 -0
  22. package/dist/list-query/index.d.ts.map +1 -0
  23. package/dist/list-query/index.js +7 -0
  24. package/dist/list-query/index.js.map +1 -0
  25. package/dist/list-query/parser.d.ts +17 -0
  26. package/dist/list-query/parser.d.ts.map +1 -0
  27. package/dist/list-query/parser.js +162 -0
  28. package/dist/list-query/parser.js.map +1 -0
  29. package/dist/list-query/prisma-builder.d.ts +21 -0
  30. package/dist/list-query/prisma-builder.d.ts.map +1 -0
  31. package/dist/list-query/prisma-builder.js +224 -0
  32. package/dist/list-query/prisma-builder.js.map +1 -0
  33. package/dist/list-query/query-schema.d.ts +15 -0
  34. package/dist/list-query/query-schema.d.ts.map +1 -0
  35. package/dist/list-query/query-schema.js +16 -0
  36. package/dist/list-query/query-schema.js.map +1 -0
  37. package/dist/list-query/schema-helpers.d.ts +81 -0
  38. package/dist/list-query/schema-helpers.d.ts.map +1 -0
  39. package/dist/list-query/schema-helpers.js +85 -0
  40. package/dist/list-query/schema-helpers.js.map +1 -0
  41. package/dist/list-query/types.d.ts +66 -0
  42. package/dist/list-query/types.d.ts.map +1 -0
  43. package/dist/{hooks → list-query}/types.js.map +1 -1
  44. package/dist/list-query/validator.d.ts +35 -0
  45. package/dist/list-query/validator.d.ts.map +1 -0
  46. package/dist/list-query/validator.js +44 -0
  47. package/dist/list-query/validator.js.map +1 -0
  48. package/dist/openapi/defaults.d.ts.map +1 -1
  49. package/dist/openapi/defaults.js +12 -3
  50. package/dist/openapi/defaults.js.map +1 -1
  51. package/dist/openapi/hooks.d.ts.map +1 -1
  52. package/dist/openapi/hooks.js +7 -4
  53. package/dist/openapi/hooks.js.map +1 -1
  54. package/package.json +12 -1
  55. package/dist/authorization/ability-middleware.d.ts +0 -61
  56. package/dist/authorization/ability-middleware.d.ts.map +0 -1
  57. package/dist/authorization/ability-middleware.js +0 -74
  58. package/dist/authorization/ability-middleware.js.map +0 -1
  59. package/dist/authorization/index.d.ts +0 -46
  60. package/dist/authorization/index.d.ts.map +0 -1
  61. package/dist/authorization/index.js +0 -46
  62. package/dist/authorization/index.js.map +0 -1
  63. package/dist/authorization/route-helpers.d.ts +0 -106
  64. package/dist/authorization/route-helpers.d.ts.map +0 -1
  65. package/dist/authorization/route-helpers.js +0 -136
  66. package/dist/authorization/route-helpers.js.map +0 -1
  67. package/dist/authorization/service-proxy.d.ts +0 -59
  68. package/dist/authorization/service-proxy.d.ts.map +0 -1
  69. package/dist/authorization/service-proxy.js +0 -110
  70. package/dist/authorization/service-proxy.js.map +0 -1
  71. package/dist/authorization/types.d.ts +0 -58
  72. package/dist/authorization/types.d.ts.map +0 -1
  73. package/dist/authorization/types.js +0 -7
  74. package/dist/authorization/types.js.map +0 -1
  75. package/dist/hooks/authorization-hook.d.ts +0 -100
  76. package/dist/hooks/authorization-hook.d.ts.map +0 -1
  77. package/dist/hooks/authorization-hook.js +0 -93
  78. package/dist/hooks/authorization-hook.js.map +0 -1
  79. package/dist/hooks/index.d.ts +0 -54
  80. package/dist/hooks/index.d.ts.map +0 -1
  81. package/dist/hooks/index.js +0 -55
  82. package/dist/hooks/index.js.map +0 -1
  83. package/dist/hooks/service-hooks.d.ts +0 -82
  84. package/dist/hooks/service-hooks.d.ts.map +0 -1
  85. package/dist/hooks/service-hooks.js +0 -158
  86. package/dist/hooks/service-hooks.js.map +0 -1
  87. package/dist/hooks/types.d.ts +0 -151
  88. package/dist/hooks/types.d.ts.map +0 -1
  89. package/dist/utils/pagination.d.ts +0 -48
  90. package/dist/utils/pagination.d.ts.map +0 -1
  91. package/dist/utils/pagination.js +0 -42
  92. package/dist/utils/pagination.js.map +0 -1
  93. /package/dist/{hooks → list-query}/types.js +0 -0
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Parse a field path string (e.g., 'organization.name') into a FieldPath array
3
+ */
4
+ function parseFieldPath(fieldPathString) {
5
+ return fieldPathString.split('.');
6
+ }
7
+ /**
8
+ * Parse a sort string into a ParsedSort
9
+ * Format: field (ascending) or -field (descending)
10
+ * Supports nested fields: organization.name or -organization.name
11
+ */
12
+ function parseSort(sortString) {
13
+ const trimmed = sortString.trim();
14
+ if (trimmed.startsWith('-')) {
15
+ const fieldPath = parseFieldPath(trimmed.slice(1));
16
+ return {
17
+ fieldPath,
18
+ direction: 'desc',
19
+ };
20
+ }
21
+ const fieldPath = parseFieldPath(trimmed);
22
+ return {
23
+ fieldPath,
24
+ direction: 'asc',
25
+ };
26
+ }
27
+ /**
28
+ * Parse sorts string into array of ParsedSort
29
+ * Format: field1,-field2,field3
30
+ */
31
+ export function parseSorts(sortsString) {
32
+ if (!sortsString || sortsString.trim() === '') {
33
+ return [];
34
+ }
35
+ return sortsString.split(',').map((s) => parseSort(s.trim()));
36
+ }
37
+ /**
38
+ * Sieve operator patterns (longest first to avoid partial matches)
39
+ * Order matters: check longer operators before shorter ones
40
+ */
41
+ const OPERATOR_PATTERNS = [
42
+ '!_-=*',
43
+ '!_-=',
44
+ '!_=*',
45
+ '!_=',
46
+ '!@=*',
47
+ '!@=',
48
+ '_-=*',
49
+ '_-=',
50
+ '_=*',
51
+ '_=',
52
+ '@=*',
53
+ '@=',
54
+ '==*',
55
+ '!=*',
56
+ '>=',
57
+ '<=',
58
+ '==',
59
+ '!=',
60
+ '>',
61
+ '<',
62
+ ];
63
+ /**
64
+ * Find the operator in a filter string
65
+ * Returns the operator and its index
66
+ */
67
+ function findOperator(filterString) {
68
+ for (const operator of OPERATOR_PATTERNS) {
69
+ const index = filterString.indexOf(operator);
70
+ if (index > 0) {
71
+ return { operator, index };
72
+ }
73
+ }
74
+ return null;
75
+ }
76
+ /**
77
+ * Unescape a value string
78
+ * Handles: \, (comma), \| (pipe), \null (literal null string)
79
+ */
80
+ function unescapeValue(value) {
81
+ return value
82
+ .replace(/\\,/g, ',')
83
+ .replace(/\\\|/g, '|')
84
+ .replace(/\\null/g, 'null');
85
+ }
86
+ /**
87
+ * Parse a filter string into a ParsedFilter
88
+ * Format: field{operator}value
89
+ * Example: name@=value, organization.name==Acme
90
+ */
91
+ function parseFilter(filterString) {
92
+ const trimmed = filterString.trim();
93
+ const operatorMatch = findOperator(trimmed);
94
+ if (!operatorMatch) {
95
+ throw new Error(`Invalid filter format: ${trimmed}. Missing operator.`);
96
+ }
97
+ const { operator, index } = operatorMatch;
98
+ const fieldPathString = trimmed.slice(0, index).trim();
99
+ const valueString = trimmed.slice(index + operator.length).trim();
100
+ if (!fieldPathString || !valueString) {
101
+ throw new Error(`Invalid filter format: ${trimmed}. Missing field or value.`);
102
+ }
103
+ const fieldPath = parseFieldPath(fieldPathString);
104
+ const value = unescapeValue(valueString);
105
+ return {
106
+ fieldPath,
107
+ operator,
108
+ value,
109
+ };
110
+ }
111
+ /**
112
+ * Parse filters string into array of ParsedFilter
113
+ * Format: field1==value1,field2@=value2
114
+ * Handles escaped commas in values (e.g., field@=value\,with\,commas)
115
+ */
116
+ export function parseFilters(filtersString) {
117
+ if (!filtersString || filtersString.trim() === '') {
118
+ return [];
119
+ }
120
+ const filters = [];
121
+ let current = '';
122
+ let escaped = false;
123
+ for (let i = 0; i < filtersString.length; i++) {
124
+ const char = filtersString[i];
125
+ if (char === '\\' && !escaped) {
126
+ escaped = true;
127
+ current += char;
128
+ }
129
+ else if (char === ',' && !escaped) {
130
+ if (current.trim()) {
131
+ filters.push(current.trim());
132
+ }
133
+ current = '';
134
+ }
135
+ else {
136
+ current += char;
137
+ escaped = false;
138
+ }
139
+ }
140
+ if (current.trim()) {
141
+ filters.push(current.trim());
142
+ }
143
+ return filters.map((f) => parseFilter(f));
144
+ }
145
+ /**
146
+ * Parse raw query parameters into structured ParsedQueryParams
147
+ */
148
+ export function parseQueryParams(raw) {
149
+ const sorts = parseSorts(raw.sorts);
150
+ const filters = parseFilters(raw.filters);
151
+ const page = raw.page && raw.page > 0 ? raw.page : 1;
152
+ const pageSize = raw.pageSize && raw.pageSize > 0 ? Math.min(raw.pageSize, 100) : 10;
153
+ const search = raw.search?.trim() || undefined;
154
+ return {
155
+ sorts,
156
+ filters,
157
+ page,
158
+ pageSize,
159
+ search,
160
+ };
161
+ }
162
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/list-query/parser.ts"],"names":[],"mappings":"AASA;;GAEG;AACH,SAAS,cAAc,CAAC,eAAuB;IAC7C,OAAO,eAAe,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS,CAAC,UAAkB;IACnC,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;IAClC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,OAAO;YACL,SAAS;YACT,SAAS,EAAE,MAAM;SAClB,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO;QACL,SAAS;QACT,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,WAAoB;IAC7C,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC9C,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,MAAM,iBAAiB,GAA8B;IACnD,OAAO;IACP,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,KAAK;IACL,KAAK;IACL,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,GAAG;IACH,GAAG;CACK,CAAC;AAEX;;;GAGG;AACH,SAAS,YAAY,CAAC,YAAoB;IACxC,KAAK,MAAM,QAAQ,IAAI,iBAAiB,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC7B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,KAAK;SACT,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,YAAoB;IACvC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;IACpC,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,0BAA0B,OAAO,qBAAqB,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,aAAa,CAAC;IAC1C,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACvD,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAClE,IAAI,CAAC,eAAe,IAAI,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,0BAA0B,OAAO,2BAA2B,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,SAAS,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IACzC,OAAO;QACL,SAAS;QACT,QAAQ;QACR,KAAK;KACN,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,aAAsB;IACjD,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAClD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC9B,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,IAAI,IAAI,CAAC;QAClB,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACpC,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;gBACnB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YAC/B,CAAC;YACD,OAAO,GAAG,EAAE,CAAC;QACf,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,IAAI,CAAC;YAChB,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAmB;IAClD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrF,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAC/C,OAAO;QACL,KAAK;QACL,OAAO;QACP,IAAI;QACJ,QAAQ;QACR,MAAM;KACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { ParsedFilter, ParsedQueryParams, ParsedSort } from './types.js';
2
+ /**
3
+ * Build Prisma where clause from parsed filters
4
+ * Handles nested fields and merges multiple conditions on same relation
5
+ */
6
+ export declare function buildWhereClause(filters: readonly ParsedFilter[]): Record<string, unknown>;
7
+ /**
8
+ * Build Prisma orderBy clause from parsed sorts
9
+ * Handles nested fields (relations) properly
10
+ */
11
+ export declare function buildOrderBy(sorts: readonly ParsedSort[]): readonly Record<string, unknown>[];
12
+ /**
13
+ * Build Prisma query parameters from parsed query params
14
+ */
15
+ export declare function buildPrismaParams(params: ParsedQueryParams): {
16
+ where: Record<string, unknown>;
17
+ orderBy: readonly Record<string, unknown>[];
18
+ skip: number;
19
+ take: number;
20
+ };
21
+ //# sourceMappingURL=prisma-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma-builder.d.ts","sourceRoot":"","sources":["../../src/list-query/prisma-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACX,MAAM,YAAY,CAAC;AA8LpB;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAY1F;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAkC7F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG;IAC5D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAWA"}
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Build condition for equality operators
3
+ */
4
+ function buildEqualityCondition(operator, value, isCaseInsensitive) {
5
+ if (operator === '==') {
6
+ if (isCaseInsensitive && typeof value === 'string') {
7
+ return { equals: value, mode: 'insensitive' };
8
+ }
9
+ return { equals: value };
10
+ }
11
+ if (isCaseInsensitive && typeof value === 'string') {
12
+ return { not: { equals: value, mode: 'insensitive' } };
13
+ }
14
+ return { not: value };
15
+ }
16
+ /**
17
+ * Build condition for comparison operators
18
+ */
19
+ function buildComparisonCondition(operator, value) {
20
+ switch (operator) {
21
+ case '>':
22
+ return { gt: value };
23
+ case '<':
24
+ return { lt: value };
25
+ case '>=':
26
+ return { gte: value };
27
+ case '<=':
28
+ return { lte: value };
29
+ }
30
+ }
31
+ /**
32
+ * Build condition for string matching operators
33
+ */
34
+ function buildStringCondition(operator, value, isCaseInsensitive) {
35
+ if (typeof value !== 'string') {
36
+ throw new Error(`String operator ${operator} requires string value`);
37
+ }
38
+ const baseCondition = isCaseInsensitive ? { mode: 'insensitive' } : {};
39
+ switch (operator) {
40
+ case '@=':
41
+ return { contains: value, ...baseCondition };
42
+ case '_=':
43
+ return { startsWith: value, ...baseCondition };
44
+ case '_-=':
45
+ return { endsWith: value, ...baseCondition };
46
+ case '!@=':
47
+ return { not: { contains: value, ...baseCondition } };
48
+ case '!_=':
49
+ return { not: { startsWith: value, ...baseCondition } };
50
+ case '!_-=':
51
+ return { not: { endsWith: value, ...baseCondition } };
52
+ }
53
+ }
54
+ /**
55
+ * Convert a Sieve operator to Prisma where clause condition
56
+ */
57
+ function operatorToPrismaCondition(operator, value) {
58
+ const isCaseInsensitive = operator.endsWith('*');
59
+ const baseOperator = operator.replace(/\*$/, '');
60
+ if (baseOperator === '==' || baseOperator === '!=') {
61
+ return buildEqualityCondition(baseOperator, value, isCaseInsensitive);
62
+ }
63
+ if (baseOperator === '>' ||
64
+ baseOperator === '<' ||
65
+ baseOperator === '>=' ||
66
+ baseOperator === '<=') {
67
+ return buildComparisonCondition(baseOperator, value);
68
+ }
69
+ if (baseOperator === '@=' ||
70
+ baseOperator === '_=' ||
71
+ baseOperator === '_-=' ||
72
+ baseOperator === '!@=' ||
73
+ baseOperator === '!_=' ||
74
+ baseOperator === '!_-=') {
75
+ return buildStringCondition(baseOperator, value, isCaseInsensitive);
76
+ }
77
+ throw new Error(`Unsupported operator: ${operator}`);
78
+ }
79
+ /**
80
+ * Convert a value string to appropriate type for Prisma
81
+ * Attempts to parse as number or boolean, otherwise returns as string
82
+ */
83
+ function parseValue(value) {
84
+ if (value === 'true') {
85
+ return true;
86
+ }
87
+ if (value === 'false') {
88
+ return false;
89
+ }
90
+ const numValue = Number(value);
91
+ if (!Number.isNaN(numValue) && value.trim() !== '') {
92
+ return numValue;
93
+ }
94
+ return value;
95
+ }
96
+ /**
97
+ * Build a nested Prisma where condition from a field path
98
+ * For nested paths (relations), wraps in Prisma's relation filter structure { is: { ... } }
99
+ */
100
+ function buildNestedWhereCondition(fieldPath, condition) {
101
+ if (fieldPath.length === 1) {
102
+ const field = fieldPath[0];
103
+ if (!field) {
104
+ throw new Error('Field path cannot be empty');
105
+ }
106
+ return {
107
+ [field]: condition,
108
+ };
109
+ }
110
+ // For nested paths (relations), build the nested structure and wrap in { is: { ... } }
111
+ const [first, ...rest] = fieldPath;
112
+ if (!first) {
113
+ throw new Error('Field path cannot be empty');
114
+ }
115
+ // Build the deeply nested condition recursively
116
+ let nestedCondition = condition;
117
+ for (let i = rest.length - 1; i >= 0; i--) {
118
+ const field = rest[i];
119
+ if (!field) {
120
+ throw new Error('Field path cannot be empty');
121
+ }
122
+ nestedCondition = {
123
+ [field]: nestedCondition,
124
+ };
125
+ }
126
+ // Wrap in Prisma's relation filter structure
127
+ return {
128
+ [first]: {
129
+ is: nestedCondition,
130
+ },
131
+ };
132
+ }
133
+ /**
134
+ * Merge two Prisma where conditions, handling nested objects
135
+ */
136
+ function mergeWhereConditions(existing, newCondition) {
137
+ const merged = { ...existing };
138
+ for (const [key, value] of Object.entries(newCondition)) {
139
+ if (key in merged && typeof merged[key] === 'object' && typeof value === 'object') {
140
+ const existingValue = merged[key];
141
+ if (existingValue !== null && !Array.isArray(existingValue) && !Array.isArray(value)) {
142
+ merged[key] = mergeWhereConditions(existingValue, value);
143
+ }
144
+ else {
145
+ merged[key] = value;
146
+ }
147
+ }
148
+ else {
149
+ merged[key] = value;
150
+ }
151
+ }
152
+ return merged;
153
+ }
154
+ /**
155
+ * Build Prisma where clause from parsed filters
156
+ * Handles nested fields and merges multiple conditions on same relation
157
+ */
158
+ export function buildWhereClause(filters) {
159
+ if (filters.length === 0) {
160
+ return {};
161
+ }
162
+ let where = {};
163
+ for (const filter of filters) {
164
+ const parsedValue = parseValue(filter.value);
165
+ const condition = operatorToPrismaCondition(filter.operator, parsedValue);
166
+ const nestedCondition = buildNestedWhereCondition(filter.fieldPath, condition);
167
+ where = mergeWhereConditions(where, nestedCondition);
168
+ }
169
+ return where;
170
+ }
171
+ /**
172
+ * Build Prisma orderBy clause from parsed sorts
173
+ * Handles nested fields (relations) properly
174
+ */
175
+ export function buildOrderBy(sorts) {
176
+ if (sorts.length === 0) {
177
+ return [];
178
+ }
179
+ return sorts.map((sort) => {
180
+ if (sort.fieldPath.length === 1) {
181
+ const field = sort.fieldPath[0];
182
+ if (!field) {
183
+ throw new Error('Field path cannot be empty');
184
+ }
185
+ return {
186
+ [field]: sort.direction,
187
+ };
188
+ }
189
+ // For nested paths, build the structure directly (Prisma doesn't need 'is' for sorting)
190
+ const orderBy = {};
191
+ let current = orderBy;
192
+ for (let i = 0; i < sort.fieldPath.length - 1; i++) {
193
+ const field = sort.fieldPath[i];
194
+ if (!field) {
195
+ throw new Error('Field path cannot be empty');
196
+ }
197
+ const next = {};
198
+ current[field] = next;
199
+ current = next;
200
+ }
201
+ const lastField = sort.fieldPath[sort.fieldPath.length - 1];
202
+ if (!lastField) {
203
+ throw new Error('Field path cannot be empty');
204
+ }
205
+ current[lastField] = sort.direction;
206
+ return orderBy;
207
+ });
208
+ }
209
+ /**
210
+ * Build Prisma query parameters from parsed query params
211
+ */
212
+ export function buildPrismaParams(params) {
213
+ const where = buildWhereClause(params.filters);
214
+ const orderBy = buildOrderBy(params.sorts);
215
+ const skip = (params.page - 1) * params.pageSize;
216
+ const take = params.pageSize;
217
+ return {
218
+ where,
219
+ orderBy,
220
+ skip,
221
+ take,
222
+ };
223
+ }
224
+ //# sourceMappingURL=prisma-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma-builder.js","sourceRoot":"","sources":["../../src/list-query/prisma-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Valibot schema for list query parameters
3
+ * Used in route definitions for OpenAPI generation and basic validation
4
+ *
5
+ * Note: Query parameters are always strings, so we transform them to numbers
6
+ * Valibot correctly infers the output type as number after transformation
7
+ */
8
+ export declare const ListQuerySchema: import("valibot").ObjectSchema<{
9
+ readonly sorts: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
10
+ readonly filters: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
11
+ readonly page: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TransformAction<string, number>]>, undefined>;
12
+ readonly pageSize: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TransformAction<string, number>]>, undefined>;
13
+ readonly search: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
14
+ }, undefined>;
15
+ //# sourceMappingURL=query-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-schema.d.ts","sourceRoot":"","sources":["../../src/list-query/query-schema.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,eAAO,MAAM,eAAe;;;;;;aAgB1B,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { object, optional, pipe, string, transform } from 'valibot';
2
+ /**
3
+ * Valibot schema for list query parameters
4
+ * Used in route definitions for OpenAPI generation and basic validation
5
+ *
6
+ * Note: Query parameters are always strings, so we transform them to numbers
7
+ * Valibot correctly infers the output type as number after transformation
8
+ */
9
+ export const ListQuerySchema = object({
10
+ sorts: optional(string()),
11
+ filters: optional(string()),
12
+ page: optional(pipe(string(), transform((value) => Math.max(1, Math.floor(Number(value)))))),
13
+ pageSize: optional(pipe(string(), transform((value) => Math.max(1, Math.min(100, Math.floor(Number(value))))))),
14
+ search: optional(string()),
15
+ });
16
+ //# sourceMappingURL=query-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-schema.js","sourceRoot":"","sources":["../../src/list-query/query-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC;IACpC,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IAC3B,IAAI,EAAE,QAAQ,CACZ,IAAI,CACF,MAAM,EAAE,EACR,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAC7D,CACF;IACD,QAAQ,EAAE,QAAQ,CAChB,IAAI,CACF,MAAM,EAAE,EACR,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAC5E,CACF;IACD,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;CAC3B,CAAC,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { type BaseIssue, type BaseSchema } from 'valibot';
2
+ /**
3
+ * Schema for Prisma sort direction
4
+ */
5
+ export declare const sortDirectionSchema: () => import("valibot").PicklistSchema<["asc", "desc"], undefined>;
6
+ /**
7
+ * Schema for Prisma StringFilter operations
8
+ * Supports all string-based filter operations
9
+ */
10
+ export declare const stringFilterSchema: () => import("valibot").ObjectSchema<{
11
+ readonly equals: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
12
+ readonly not: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").StringSchema<undefined>, import("valibot").ObjectSchema<{
13
+ readonly equals: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
14
+ }, undefined>], undefined>, undefined>;
15
+ readonly contains: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
16
+ readonly startsWith: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
17
+ readonly endsWith: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
18
+ readonly mode: import("valibot").OptionalSchema<import("valibot").PicklistSchema<["default", "insensitive"], undefined>, undefined>;
19
+ }, undefined>;
20
+ /**
21
+ * Schema for Prisma IntFilter or FloatFilter operations
22
+ * Supports numeric comparison operations
23
+ */
24
+ export declare const numberFilterSchema: () => import("valibot").ObjectSchema<{
25
+ readonly equals: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").StringSchema<undefined>, import("valibot").LiteralSchema<true, undefined>, import("valibot").LiteralSchema<false, undefined>], undefined>, undefined>;
26
+ readonly not: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").StringSchema<undefined>, import("valibot").LiteralSchema<true, undefined>, import("valibot").LiteralSchema<false, undefined>], undefined>, undefined>;
27
+ readonly lt: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").StringSchema<undefined>, import("valibot").LiteralSchema<true, undefined>, import("valibot").LiteralSchema<false, undefined>], undefined>, undefined>;
28
+ readonly lte: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").StringSchema<undefined>, import("valibot").LiteralSchema<true, undefined>, import("valibot").LiteralSchema<false, undefined>], undefined>, undefined>;
29
+ readonly gt: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").StringSchema<undefined>, import("valibot").LiteralSchema<true, undefined>, import("valibot").LiteralSchema<false, undefined>], undefined>, undefined>;
30
+ readonly gte: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").StringSchema<undefined>, import("valibot").LiteralSchema<true, undefined>, import("valibot").LiteralSchema<false, undefined>], undefined>, undefined>;
31
+ }, undefined>;
32
+ /**
33
+ * Schema for Prisma DateTimeFilter operations
34
+ * Supports date comparison operations
35
+ */
36
+ export declare const dateFilterSchema: () => import("valibot").ObjectSchema<{
37
+ readonly equals: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
38
+ readonly not: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
39
+ readonly lt: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
40
+ readonly lte: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
41
+ readonly gt: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
42
+ readonly gte: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
43
+ }, undefined>;
44
+ /**
45
+ * Schema for Prisma BoolFilter operations
46
+ * Only supports equals and not operations
47
+ */
48
+ export declare const booleanFilterSchema: () => import("valibot").ObjectSchema<{
49
+ readonly equals: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<true, undefined>, import("valibot").LiteralSchema<false, undefined>], undefined>, undefined>;
50
+ readonly not: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<true, undefined>, import("valibot").LiteralSchema<false, undefined>], undefined>, undefined>;
51
+ }, undefined>;
52
+ /**
53
+ * Schema for Prisma EnumFilter operations
54
+ * Supports equals and not operations with specific enum values
55
+ * Pass a picklist schema with the allowed enum values
56
+ */
57
+ export declare function enumFilterSchema<TEnum extends BaseSchema<unknown, unknown, BaseIssue<unknown>>>(enumSchema: TEnum): import("valibot").ObjectSchema<{
58
+ readonly equals: import("valibot").OptionalSchema<TEnum, undefined>;
59
+ readonly not: import("valibot").OptionalSchema<TEnum, undefined>;
60
+ }, undefined>;
61
+ /**
62
+ * Schema for nested relation filters
63
+ * Allows validation of nested where conditions
64
+ */
65
+ export declare function relationFilterSchema<T extends BaseSchema<unknown, unknown, BaseIssue<unknown>>>(nestedSchema: T): import("valibot").ObjectSchema<{
66
+ readonly is: import("valibot").OptionalSchema<T, undefined>;
67
+ readonly isNot: import("valibot").OptionalSchema<T, undefined>;
68
+ }, undefined>;
69
+ /**
70
+ * Helper to create a sort schema for a model
71
+ * Pass an object with field names as keys and sortDirectionSchema() as values
72
+ */
73
+ export declare function createSortSchema(fields: Record<string, ReturnType<typeof sortDirectionSchema>>): import("valibot").ObjectSchema<{
74
+ [k: string]: import("valibot").OptionalSchema<import("valibot").PicklistSchema<["asc", "desc"], undefined>, undefined>;
75
+ }, undefined>;
76
+ /**
77
+ * Helper to create a filter schema for a model
78
+ * Pass an object with field names as keys and filter schemas as values
79
+ */
80
+ export declare function createFilterSchema<T extends Record<string, BaseSchema<unknown, unknown, BaseIssue<unknown>>>>(fields: T): import("valibot").ObjectSchema<{ [K in keyof T]: import("valibot").OptionalSchema<BaseSchema<unknown, unknown, BaseIssue<unknown>>, unknown>; }, undefined>;
81
+ //# sourceMappingURL=schema-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-helpers.d.ts","sourceRoot":"","sources":["../../src/list-query/schema-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,UAAU,EAOhB,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,eAAO,MAAM,mBAAmB,oEAAkC,CAAC;AAEnE;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;aAQ3B,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;;aAQ3B,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;;;aAQzB,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;aAI5B,CAAC;AAEL;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,SAAS,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,EAC7F,UAAU,EAAE,KAAK;;;cAMlB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,EAC7F,YAAY,EAAE,CAAC;;;cAMhB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;;cAI9F;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAC1E,MAAM,EAAE,CAAC,qCAGJ,CAAC,yHAGP"}
@@ -0,0 +1,85 @@
1
+ import { literal, object, optional, picklist, string, union, } from 'valibot';
2
+ /**
3
+ * Schema for Prisma sort direction
4
+ */
5
+ export const sortDirectionSchema = () => picklist(['asc', 'desc']);
6
+ /**
7
+ * Schema for Prisma StringFilter operations
8
+ * Supports all string-based filter operations
9
+ */
10
+ export const stringFilterSchema = () => object({
11
+ equals: optional(string()),
12
+ not: optional(union([string(), object({ equals: optional(string()) })])),
13
+ contains: optional(string()),
14
+ startsWith: optional(string()),
15
+ endsWith: optional(string()),
16
+ mode: optional(picklist(['default', 'insensitive'])),
17
+ });
18
+ /**
19
+ * Schema for Prisma IntFilter or FloatFilter operations
20
+ * Supports numeric comparison operations
21
+ */
22
+ export const numberFilterSchema = () => object({
23
+ equals: optional(union([string(), literal(true), literal(false)])),
24
+ not: optional(union([string(), literal(true), literal(false)])),
25
+ lt: optional(union([string(), literal(true), literal(false)])),
26
+ lte: optional(union([string(), literal(true), literal(false)])),
27
+ gt: optional(union([string(), literal(true), literal(false)])),
28
+ gte: optional(union([string(), literal(true), literal(false)])),
29
+ });
30
+ /**
31
+ * Schema for Prisma DateTimeFilter operations
32
+ * Supports date comparison operations
33
+ */
34
+ export const dateFilterSchema = () => object({
35
+ equals: optional(string()),
36
+ not: optional(string()),
37
+ lt: optional(string()),
38
+ lte: optional(string()),
39
+ gt: optional(string()),
40
+ gte: optional(string()),
41
+ });
42
+ /**
43
+ * Schema for Prisma BoolFilter operations
44
+ * Only supports equals and not operations
45
+ */
46
+ export const booleanFilterSchema = () => object({
47
+ equals: optional(union([literal(true), literal(false)])),
48
+ not: optional(union([literal(true), literal(false)])),
49
+ });
50
+ /**
51
+ * Schema for Prisma EnumFilter operations
52
+ * Supports equals and not operations with specific enum values
53
+ * Pass a picklist schema with the allowed enum values
54
+ */
55
+ export function enumFilterSchema(enumSchema) {
56
+ return object({
57
+ equals: optional(enumSchema),
58
+ not: optional(enumSchema),
59
+ });
60
+ }
61
+ /**
62
+ * Schema for nested relation filters
63
+ * Allows validation of nested where conditions
64
+ */
65
+ export function relationFilterSchema(nestedSchema) {
66
+ return object({
67
+ is: optional(nestedSchema),
68
+ isNot: optional(nestedSchema),
69
+ });
70
+ }
71
+ /**
72
+ * Helper to create a sort schema for a model
73
+ * Pass an object with field names as keys and sortDirectionSchema() as values
74
+ */
75
+ export function createSortSchema(fields) {
76
+ return object(Object.fromEntries(Object.entries(fields).map(([key, schema]) => [key, optional(schema)])));
77
+ }
78
+ /**
79
+ * Helper to create a filter schema for a model
80
+ * Pass an object with field names as keys and filter schemas as values
81
+ */
82
+ export function createFilterSchema(fields) {
83
+ return object(Object.fromEntries(Object.entries(fields).map(([key, schema]) => [key, optional(schema)])));
84
+ }
85
+ //# sourceMappingURL=schema-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-helpers.js","sourceRoot":"","sources":["../../src/list-query/schema-helpers.ts"],"names":[],"mappings":"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"}