alepha 0.20.2 → 0.20.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +0 -1
  2. package/assets/swagger-ui/swagger-ui-bundle.js +1 -1
  3. package/assets/swagger-ui/swagger-ui.css +1 -1
  4. package/dist/api/audits/index.browser.js +49 -0
  5. package/dist/api/audits/index.browser.js.map +1 -1
  6. package/dist/api/audits/index.d.ts.map +1 -1
  7. package/dist/api/audits/index.js +49 -0
  8. package/dist/api/audits/index.js.map +1 -1
  9. package/dist/api/files/index.d.ts.map +1 -1
  10. package/dist/api/files/index.js.map +1 -1
  11. package/dist/api/jobs/index.d.ts +16 -75
  12. package/dist/api/jobs/index.d.ts.map +1 -1
  13. package/dist/api/jobs/index.js.map +1 -1
  14. package/dist/api/keys/index.js.map +1 -1
  15. package/dist/api/notifications/index.d.ts +1 -10
  16. package/dist/api/notifications/index.d.ts.map +1 -1
  17. package/dist/api/organizations/index.d.ts.map +1 -1
  18. package/dist/api/parameters/index.browser.js +37 -0
  19. package/dist/api/parameters/index.browser.js.map +1 -1
  20. package/dist/api/parameters/index.d.ts +4 -65
  21. package/dist/api/parameters/index.d.ts.map +1 -1
  22. package/dist/api/parameters/index.js +37 -0
  23. package/dist/api/parameters/index.js.map +1 -1
  24. package/dist/api/payments/index.d.ts.map +1 -1
  25. package/dist/api/payments/index.js.map +1 -1
  26. package/dist/api/users/index.d.ts +207 -5184
  27. package/dist/api/users/index.d.ts.map +1 -1
  28. package/dist/api/users/index.js +2 -4
  29. package/dist/api/users/index.js.map +1 -1
  30. package/dist/api/verifications/index.d.ts.map +1 -1
  31. package/dist/api/verifications/index.js +2 -1
  32. package/dist/api/verifications/index.js.map +1 -1
  33. package/dist/bucket/index.js +5 -1
  34. package/dist/bucket/index.js.map +1 -1
  35. package/dist/bucket/index.workerd.js +5 -1
  36. package/dist/bucket/index.workerd.js.map +1 -1
  37. package/dist/cache/core/index.js.map +1 -1
  38. package/dist/cache/core/index.workerd.js.map +1 -1
  39. package/dist/captcha/index.js.map +1 -1
  40. package/dist/cli/core/index.d.ts +217 -11647
  41. package/dist/cli/core/index.d.ts.map +1 -1
  42. package/dist/cli/core/index.js +706 -42
  43. package/dist/cli/core/index.js.map +1 -1
  44. package/dist/cli/devtools/index.js +7 -1
  45. package/dist/cli/devtools/index.js.map +1 -1
  46. package/dist/cli/platform/index.d.ts +41 -64
  47. package/dist/cli/platform/index.d.ts.map +1 -1
  48. package/dist/cli/platform/index.js +47 -0
  49. package/dist/cli/platform/index.js.map +1 -1
  50. package/dist/cli/vendor/index.js +15 -0
  51. package/dist/cli/vendor/index.js.map +1 -1
  52. package/dist/command/index.js +1 -1
  53. package/dist/command/index.js.map +1 -1
  54. package/dist/core/index.browser.js.map +1 -1
  55. package/dist/core/index.d.ts +2 -8
  56. package/dist/core/index.d.ts.map +1 -1
  57. package/dist/core/index.js.map +1 -1
  58. package/dist/core/index.native.js.map +1 -1
  59. package/dist/core/index.workerd.js.map +1 -1
  60. package/dist/crypto/index.js.map +1 -1
  61. package/dist/datetime/index.js.map +1 -1
  62. package/dist/email/core/index.js.map +1 -1
  63. package/dist/email/smtp/index.js +2 -10522
  64. package/dist/email/smtp/index.js.map +1 -1
  65. package/dist/fake/index.d.ts +4 -8085
  66. package/dist/fake/index.d.ts.map +1 -1
  67. package/dist/fake/index.js +3 -33554
  68. package/dist/fake/index.js.map +1 -1
  69. package/dist/lock/core/index.js.map +1 -1
  70. package/dist/lock/redis/index.js.map +1 -1
  71. package/dist/logger/index.js +32 -1
  72. package/dist/logger/index.js.map +1 -1
  73. package/dist/mcp/index.js +5 -1
  74. package/dist/mcp/index.js.map +1 -1
  75. package/dist/orm/core/index.browser.js +1 -361
  76. package/dist/orm/core/index.browser.js.map +1 -1
  77. package/dist/orm/core/index.bun.js +14 -406
  78. package/dist/orm/core/index.bun.js.map +1 -1
  79. package/dist/orm/core/index.d.ts +96 -5117
  80. package/dist/orm/core/index.d.ts.map +1 -1
  81. package/dist/orm/core/index.js +23 -419
  82. package/dist/orm/core/index.js.map +1 -1
  83. package/dist/orm/postgres/index.bun.js +17 -20
  84. package/dist/orm/postgres/index.bun.js.map +1 -1
  85. package/dist/orm/postgres/index.d.ts +2 -613
  86. package/dist/orm/postgres/index.d.ts.map +1 -1
  87. package/dist/orm/postgres/index.js +17 -20
  88. package/dist/orm/postgres/index.js.map +1 -1
  89. package/dist/react/core/index.js.map +1 -1
  90. package/dist/react/i18n/index.js.map +1 -1
  91. package/dist/react/intro/index.js +22 -17
  92. package/dist/react/intro/index.js.map +1 -1
  93. package/dist/react/router/index.browser.js +78 -2
  94. package/dist/react/router/index.browser.js.map +1 -1
  95. package/dist/react/router/index.d.ts +22 -1
  96. package/dist/react/router/index.d.ts.map +1 -1
  97. package/dist/react/router/index.js +102 -4
  98. package/dist/react/router/index.js.map +1 -1
  99. package/dist/react/testing/index.d.ts +1 -411
  100. package/dist/react/testing/index.d.ts.map +1 -1
  101. package/dist/react/testing/index.js +13 -12293
  102. package/dist/react/testing/index.js.map +1 -1
  103. package/dist/react/ui/index.js +3 -0
  104. package/dist/react/ui/index.js.map +1 -1
  105. package/dist/react/websocket/index.js.map +1 -1
  106. package/dist/redis/index.js.map +1 -1
  107. package/dist/scheduler/index.d.ts +1 -83
  108. package/dist/scheduler/index.d.ts.map +1 -1
  109. package/dist/scheduler/index.js +2 -391
  110. package/dist/scheduler/index.js.map +1 -1
  111. package/dist/scheduler/index.workerd.js +2 -391
  112. package/dist/scheduler/index.workerd.js.map +1 -1
  113. package/dist/security/index.browser.js.map +1 -1
  114. package/dist/security/index.d.ts +2 -325
  115. package/dist/security/index.d.ts.map +1 -1
  116. package/dist/security/index.js +3 -1362
  117. package/dist/security/index.js.map +1 -1
  118. package/dist/server/auth/index.d.ts +1 -1054
  119. package/dist/server/auth/index.d.ts.map +1 -1
  120. package/dist/server/auth/index.js +16 -1224
  121. package/dist/server/auth/index.js.map +1 -1
  122. package/dist/server/cookies/index.js.map +1 -1
  123. package/dist/server/core/index.browser.js.map +1 -1
  124. package/dist/server/core/index.d.ts +1 -4
  125. package/dist/server/core/index.d.ts.map +1 -1
  126. package/dist/server/core/index.js +19 -4
  127. package/dist/server/core/index.js.map +1 -1
  128. package/dist/server/links/index.browser.js.map +1 -1
  129. package/dist/server/links/index.js.map +1 -1
  130. package/dist/server/metrics/index.d.ts +1 -514
  131. package/dist/server/metrics/index.d.ts.map +1 -1
  132. package/dist/server/metrics/index.js +4 -4356
  133. package/dist/server/metrics/index.js.map +1 -1
  134. package/dist/server/rate-limit/index.js.map +1 -1
  135. package/dist/server/static/index.js.map +1 -1
  136. package/dist/server/swagger/index.js +1 -1
  137. package/dist/server/swagger/index.js.map +1 -1
  138. package/dist/sms/index.js.map +1 -1
  139. package/dist/system/index.browser.js.map +1 -1
  140. package/dist/system/index.js.map +1 -1
  141. package/dist/system/index.workerd.js.map +1 -1
  142. package/dist/topic/core/index.js.map +1 -1
  143. package/dist/websocket/index.browser.js +21 -0
  144. package/dist/websocket/index.browser.js.map +1 -1
  145. package/dist/websocket/index.js +21 -0
  146. package/dist/websocket/index.js.map +1 -1
  147. package/package.json +18 -15
  148. package/src/api/files/__tests__/FileController.spec.ts +1 -1
  149. package/src/api/jobs/__tests__/$job.spec.ts +5 -1
  150. package/src/api/users/schemas/userQuerySchema.ts +0 -1
  151. package/src/api/users/services/UserService.ts +1 -5
  152. package/src/api/verifications/__tests__/CodeVerification.spec.ts +14 -0
  153. package/src/api/verifications/__tests__/LinkVerification.spec.ts +14 -0
  154. package/src/api/verifications/services/VerificationService.ts +1 -0
  155. package/src/cli/core/__tests__/init.spec.ts +208 -0
  156. package/src/cli/core/commands/init.ts +12 -0
  157. package/src/cli/core/services/PackageManagerUtils.ts +23 -6
  158. package/src/cli/core/services/ProjectScaffolder.ts +298 -20
  159. package/src/cli/core/tasks/BuildDockerTask.ts +9 -10
  160. package/src/cli/core/tasks/BuildServerTask.ts +8 -0
  161. package/src/cli/core/templates/apiIndexTs.ts +23 -1
  162. package/src/cli/core/templates/componentsJsonTs.ts +39 -0
  163. package/src/cli/core/templates/mainCss.ts +1 -0
  164. package/src/cli/core/templates/saasAdminLayoutTsx.ts +77 -0
  165. package/src/cli/core/templates/saasAdminPagesTsx.ts +26 -0
  166. package/src/cli/core/templates/saasAuthLayoutTsx.ts +20 -0
  167. package/src/cli/core/templates/saasAuthPagesTsx.ts +62 -0
  168. package/src/cli/core/templates/saasRealmProviderTs.ts +46 -0
  169. package/src/cli/core/templates/webAppRouterTs.ts +104 -1
  170. package/src/cli/core/templates/webIndexTs.ts +23 -1
  171. package/src/cli/platform/__tests__/SecretsCommand.spec.ts +2 -0
  172. package/src/command/providers/CliProvider.ts +1 -1
  173. package/src/core/interfaces/Service.ts +3 -1
  174. package/src/core/providers/TypeProvider.ts +1 -1
  175. package/src/logger/services/Logger.ts +1 -1
  176. package/src/mcp/__tests__/$resource.spec.ts +1 -1
  177. package/src/mcp/__tests__/$tool.spec.ts +1 -1
  178. package/src/mcp/__tests__/McpServerProvider.spec.ts +1 -1
  179. package/src/orm/__tests__/$repository-tests.ts +1 -0
  180. package/src/orm/__tests__/orm-next-tests.ts +2 -67
  181. package/src/orm/__tests__/orm-next.spec.ts +0 -21
  182. package/src/orm/core/index.shared.ts +0 -2
  183. package/src/orm/core/index.ts +1 -2
  184. package/src/orm/core/primitives/$repository.ts +3 -6
  185. package/src/orm/core/providers/drivers/DatabaseProvider.ts +0 -5
  186. package/src/orm/core/providers/drivers/NodeSqliteProvider.ts +11 -13
  187. package/src/orm/core/services/ModelBuilder.ts +1 -13
  188. package/src/orm/core/services/Repository.ts +1 -42
  189. package/src/orm/core/services/SqliteModelBuilder.ts +2 -33
  190. package/src/orm/postgres/services/PostgresModelBuilder.ts +10 -45
  191. package/src/react/intro/components/GettingStartedAuthSlide.tsx +11 -4
  192. package/src/react/router/__tests__/ReactBrowserProvider.browser.spec.ts +213 -2
  193. package/src/react/router/providers/ReactBrowserProvider.ts +73 -0
  194. package/src/react/router/providers/ReactBrowserRouterProvider.ts +1 -1
  195. package/src/react/router/providers/ReactPreloadProvider.ts +1 -1
  196. package/src/react/router/providers/ReactServerProvider.ts +1 -0
  197. package/src/scheduler/providers/CronProvider.ts +1 -1
  198. package/src/security/primitives/$basicAuth.ts +1 -1
  199. package/src/server/auth/providers/ServerAuthProvider.ts +5 -1
  200. package/src/server/core/interfaces/ServerRequest.ts +1 -0
  201. package/src/server/core/providers/ServerProvider.ts +1 -1
  202. package/src/server/core/providers/ServerRouterProvider.ts +2 -2
  203. package/src/server/core/services/HttpClient.ts +1 -1
  204. package/src/server/swagger/providers/ServerSwaggerProvider.ts +1 -1
  205. package/dist/react/testing/chunk-DBEY4PJZ.js +0 -16
  206. package/src/orm/core/__tests__/parseQueryString.spec.ts +0 -196
  207. package/src/orm/core/helpers/parseQueryString.ts +0 -502
  208. package/src/orm/core/primitives/$view.ts +0 -88
@@ -39,7 +39,7 @@ export function $basicAuth(options: BasicAuthOptions): Middleware {
39
39
 
40
40
  const authHeader = request.headers.authorization;
41
41
 
42
- if (!authHeader || !authHeader.startsWith("Basic ")) {
42
+ if (!authHeader?.startsWith("Basic ")) {
43
43
  sendAuthRequired(request);
44
44
  throw new HttpError({
45
45
  status: 401,
@@ -114,7 +114,7 @@ export class ServerAuthProvider {
114
114
  // [feature] support for auth providers with fallback
115
115
  if (!request.headers.authorization) {
116
116
  for (const provider of this.identities) {
117
- if ("fallback" in provider.options && !!provider.options.fallback) {
117
+ if ("fallback" in provider.options && provider.options.fallback) {
118
118
  const token = await provider.options.fallback();
119
119
  if (token) {
120
120
  request.headers.authorization = `Bearer ${token}`;
@@ -336,10 +336,12 @@ export class ServerAuthProvider {
336
336
  parameters.scope = scope;
337
337
  }
338
338
 
339
+ // biome-ignore lint/complexity/useOptionalChain: oidc is `false | OidcOptions`; optional chaining doesn't narrow `false`
339
340
  if (oidc && oidc.responseMode) {
340
341
  parameters.response_mode = oidc.responseMode;
341
342
  }
342
343
 
344
+ // biome-ignore lint/complexity/useOptionalChain: oidc is `false | OidcOptions`; optional chaining doesn't narrow `false`
343
345
  if (oidc && oidc.authorizationParameters) {
344
346
  Object.assign(parameters, oidc.authorizationParameters);
345
347
  }
@@ -381,10 +383,12 @@ export class ServerAuthProvider {
381
383
  parameters.scope = scope;
382
384
  }
383
385
 
386
+ // biome-ignore lint/complexity/useOptionalChain: oidc is `false | OidcOptions`; optional chaining doesn't narrow `false`
384
387
  if (oidc && oidc.responseMode) {
385
388
  parameters.response_mode = oidc.responseMode;
386
389
  }
387
390
 
391
+ // biome-ignore lint/complexity/useOptionalChain: oidc is `false | OidcOptions`; optional chaining doesn't narrow `false`
388
392
  if (oidc && oidc.authorizationParameters) {
389
393
  Object.assign(parameters, oidc.authorizationParameters);
390
394
  }
@@ -212,6 +212,7 @@ export type ResponseKind = "json" | "text" | "void" | "file" | "any";
212
212
 
213
213
  export type ResponseBodyType =
214
214
  // not: object is not allowed, you want object ? add schema !
215
+ // biome-ignore lint/suspicious/noConfusingVoidType: handlers may return void (no return statement)
215
216
  string | Buffer | StreamLike | undefined | null | void;
216
217
 
217
218
  export type ServerHandler<
@@ -411,7 +411,7 @@ export class ServerProvider {
411
411
 
412
412
  url = url?.split("?")[0];
413
413
 
414
- if (!!params?.["*"] && `/${params?.["*"]}` === url) {
414
+ if (params?.["*"] && `/${params?.["*"]}` === url) {
415
415
  return true;
416
416
  }
417
417
  }
@@ -319,7 +319,7 @@ export class ServerRouterProvider extends RouterProvider<ServerRouteMatcher> {
319
319
  }
320
320
 
321
321
  if (reply.body == null || responseKind === "void") {
322
- delete headers["content-type"];
322
+ delete (headers as Record<string, unknown>)["content-type"];
323
323
  reply.body = undefined;
324
324
  return;
325
325
  }
@@ -416,7 +416,7 @@ export class ServerRouterProvider extends RouterProvider<ServerRouteMatcher> {
416
416
  if (
417
417
  "status" in error &&
418
418
  typeof error.status === "number" &&
419
- !!errorNameByStatus[error.status]
419
+ errorNameByStatus[error.status]
420
420
  ) {
421
421
  const status = error.status;
422
422
  reply.status = status;
@@ -213,7 +213,7 @@ export class HttpClient {
213
213
 
214
214
  if (hasHeader || isMultipart(action)) {
215
215
  if (typeof init.headers === "object" && "content-type" in init.headers) {
216
- delete init.headers["content-type"]; // fetch() will fill this for us
216
+ delete (init.headers as Record<string, unknown>)["content-type"]; // fetch() will fill this for us
217
217
  }
218
218
 
219
219
  const formData = new FormData();
@@ -260,7 +260,7 @@ export class ServerSwaggerProvider {
260
260
  ? value.description
261
261
  : undefined;
262
262
  const ref = schema(value);
263
- delete ref.description;
263
+ ref.description = undefined;
264
264
  const param: any = {
265
265
  name: key,
266
266
  in: "path",
@@ -1,16 +0,0 @@
1
- import { createRequire } from "node:module";
2
- //#region \0rolldown/runtime.js
3
- var __defProp = Object.defineProperty;
4
- var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
5
- var __exportAll = (all, no_symbols) => {
6
- let target = {};
7
- for (var name in all) __defProp(target, name, {
8
- get: all[name],
9
- enumerable: true
10
- });
11
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
12
- return target;
13
- };
14
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
15
- //#endregion
16
- export { __exportAll as n, __require as r, __commonJSMin as t };
@@ -1,196 +0,0 @@
1
- import { describe, test } from "vitest";
2
- import { buildQueryString, parseQueryString } from "../index.ts";
3
-
4
- describe("parseQueryString with wildcard patterns", () => {
5
- test("should parse wildcard patterns with = operator", ({ expect }) => {
6
- // Test startsWith pattern
7
- const result1 = parseQueryString("name=John*");
8
- expect(result1).toEqual({ name: { startsWith: "John" } });
9
-
10
- // Test endsWith pattern
11
- const result2 = parseQueryString("name=*Smith");
12
- expect(result2).toEqual({ name: { endsWith: "Smith" } });
13
-
14
- // Test contains pattern
15
- const result3 = parseQueryString("name=*oh*");
16
- expect(result3).toEqual({ name: { contains: "oh" } });
17
-
18
- // Test literal asterisk in the middle (not at beginning or end)
19
- const result4 = parseQueryString("name=Jo*hn");
20
- expect(result4).toEqual({ name: { eq: "Jo*hn" } });
21
-
22
- // Test literal equals (no wildcards)
23
- const result5 = parseQueryString("name=John");
24
- expect(result5).toEqual({ name: { eq: "John" } });
25
- });
26
-
27
- test("should handle wildcard patterns in complex queries", ({ expect }) => {
28
- // Multiple conditions with wildcards
29
- const result1 = parseQueryString("name=*John&email=*@example.com");
30
- expect(result1).toEqual({
31
- and: [
32
- { name: { endsWith: "John" } },
33
- { email: { endsWith: "@example.com" } },
34
- ],
35
- });
36
-
37
- // OR conditions with wildcards
38
- const result2 = parseQueryString("name=John*|name=*Smith");
39
- expect(result2).toEqual({
40
- or: [{ name: { startsWith: "John" } }, { name: { endsWith: "Smith" } }],
41
- });
42
-
43
- // Nested conditions with wildcards
44
- const result3 = parseQueryString("(name=*John*|email=admin*)&age>18");
45
- expect(result3).toEqual({
46
- and: [
47
- {
48
- or: [
49
- { name: { contains: "John" } },
50
- { email: { startsWith: "admin" } },
51
- ],
52
- },
53
- { age: { gt: 18 } },
54
- ],
55
- });
56
- });
57
-
58
- test("should handle wildcard patterns in quoted strings", ({ expect }) => {
59
- // Quoted string with wildcards should be treated as wildcards
60
- const result1 = parseQueryString('name="*John*"');
61
- expect(result1).toEqual({ name: { contains: "John" } });
62
-
63
- // Quoted string with asterisk in middle
64
- const result2 = parseQueryString('name="Jo*hn"');
65
- expect(result2).toEqual({ name: { eq: "Jo*hn" } });
66
-
67
- // Single quotes
68
- const result3 = parseQueryString("name='*Smith'");
69
- expect(result3).toEqual({ name: { endsWith: "Smith" } });
70
- });
71
-
72
- test("should handle wildcard patterns with special characters", ({
73
- expect,
74
- }) => {
75
- // Wildcard with spaces
76
- const result1 = parseQueryString("name=*John Smith*");
77
- expect(result1).toEqual({ name: { contains: "John Smith" } });
78
-
79
- // Wildcard with special characters
80
- const result2 = parseQueryString("email=*@example.com");
81
- expect(result2).toEqual({ email: { endsWith: "@example.com" } });
82
-
83
- // Wildcard with numbers
84
- const result3 = parseQueryString("code=ABC*123");
85
- expect(result3).toEqual({ code: { eq: "ABC*123" } }); // Asterisk in middle is literal
86
- });
87
-
88
- test("should handle wildcard patterns in arrays", ({ expect }) => {
89
- // Array values don't support wildcards (treated as literal)
90
- const result = parseQueryString("status=[active*,*pending,*idle*]");
91
- expect(result).toEqual({
92
- status: { inArray: ["active*", "*pending", "*idle*"] },
93
- });
94
- });
95
-
96
- test("should handle wildcard patterns with != operator", ({ expect }) => {
97
- // != operator doesn't support wildcards, treats as literal
98
- const result1 = parseQueryString("name!=*John");
99
- expect(result1).toEqual({ name: { ne: "*John" } });
100
-
101
- const result2 = parseQueryString("name!=John*");
102
- expect(result2).toEqual({ name: { ne: "John*" } });
103
- });
104
-
105
- test("should handle empty wildcard patterns", ({ expect }) => {
106
- // Just asterisks - a single asterisk at the end means "starts with nothing" = everything
107
- const result1 = parseQueryString("name=*");
108
- expect(result1).toEqual({ name: { contains: "" } }); // Since * alone has both start and end asterisk
109
-
110
- const result2 = parseQueryString("name=**");
111
- expect(result2).toEqual({ name: { contains: "" } });
112
-
113
- const result3 = parseQueryString("name=***");
114
- expect(result3).toEqual({ name: { contains: "*" } });
115
- });
116
-
117
- test("should handle JSONB nested queries with wildcards", ({ expect }) => {
118
- const result = parseQueryString("profile.city=*Paris*&profile.name=John*");
119
- expect(result).toEqual({
120
- and: [
121
- { profile: { city: { contains: "Paris" } } },
122
- { profile: { name: { startsWith: "John" } } },
123
- ],
124
- });
125
- });
126
-
127
- test("should not apply wildcards to non-string operators", ({ expect }) => {
128
- // Numeric comparison operators don't use wildcards
129
- const result1 = parseQueryString("age>18");
130
- expect(result1).toEqual({ age: { gt: 18 } });
131
-
132
- // NULL checks don't use wildcards
133
- const result2 = parseQueryString("name=null");
134
- expect(result2).toEqual({ name: { isNull: true } });
135
-
136
- const result3 = parseQueryString("name!=null");
137
- expect(result3).toEqual({ name: { isNotNull: true } });
138
- });
139
- });
140
-
141
- describe("buildQueryString with wildcard patterns", () => {
142
- test("should build query strings from wildcard conditions", ({ expect }) => {
143
- // startsWith
144
- const query1 = buildQueryString({ name: { startsWith: "John" } });
145
- expect(query1).toBe("name=John*");
146
-
147
- // endsWith
148
- const query2 = buildQueryString({ name: { endsWith: "Smith" } });
149
- expect(query2).toBe("name=*Smith");
150
-
151
- // contains
152
- const query3 = buildQueryString({ name: { contains: "oh" } });
153
- expect(query3).toBe("name=*oh*");
154
- });
155
-
156
- test("should build complex query strings with wildcards", ({ expect }) => {
157
- const query = buildQueryString({
158
- and: [
159
- { name: { startsWith: "John" } },
160
- { email: { endsWith: "@example.com" } },
161
- { bio: { contains: "developer" } },
162
- ],
163
- });
164
- expect(query).toBe("name=John*&email=*@example.com&bio=*developer*");
165
- });
166
-
167
- test("should handle OR conditions with wildcards", ({ expect }) => {
168
- const query = buildQueryString({
169
- or: [
170
- { name: { startsWith: "Admin" } },
171
- { role: { contains: "manager" } },
172
- ],
173
- });
174
- expect(query).toBe("(name=Admin*|role=*manager*)");
175
- });
176
-
177
- test("round-trip conversion should preserve wildcard semantics", ({
178
- expect,
179
- }) => {
180
- const testCases = [
181
- "name=John*",
182
- "name=*Smith",
183
- "name=*John*",
184
- "email=admin*&role=*manager*",
185
- "(name=*John*|name=*Jane*)&active=true",
186
- "profile.city=*Paris*",
187
- ];
188
-
189
- for (const original of testCases) {
190
- const parsed = parseQueryString(original);
191
- const rebuilt = buildQueryString(parsed);
192
- const reparsed = parseQueryString(rebuilt);
193
- expect(reparsed).toEqual(parsed);
194
- }
195
- });
196
- });