covara 0.7.1 → 0.8.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 (204) hide show
  1. package/README.md +64 -16
  2. package/dist/cli/args.d.ts +14 -0
  3. package/dist/cli/args.d.ts.map +1 -0
  4. package/dist/cli/args.js +78 -0
  5. package/dist/cli/args.js.map +1 -0
  6. package/dist/cli/commands/data.d.ts +2 -0
  7. package/dist/cli/commands/data.d.ts.map +1 -0
  8. package/dist/cli/commands/data.js +31 -0
  9. package/dist/cli/commands/data.js.map +1 -0
  10. package/dist/cli/commands/db.d.ts +2 -0
  11. package/dist/cli/commands/db.d.ts.map +1 -0
  12. package/dist/cli/commands/db.js +100 -0
  13. package/dist/cli/commands/db.js.map +1 -0
  14. package/dist/cli/commands/dev.d.ts +2 -0
  15. package/dist/cli/commands/dev.d.ts.map +1 -0
  16. package/dist/cli/commands/dev.js +125 -0
  17. package/dist/cli/commands/dev.js.map +1 -0
  18. package/dist/cli/commands/env.d.ts +2 -0
  19. package/dist/cli/commands/env.d.ts.map +1 -0
  20. package/dist/cli/commands/env.js +94 -0
  21. package/dist/cli/commands/env.js.map +1 -0
  22. package/dist/cli/commands/import-export.d.ts +3 -0
  23. package/dist/cli/commands/import-export.d.ts.map +1 -0
  24. package/dist/cli/commands/import-export.js +156 -0
  25. package/dist/cli/commands/import-export.js.map +1 -0
  26. package/dist/cli/commands/migrate.d.ts +2 -0
  27. package/dist/cli/commands/migrate.d.ts.map +1 -0
  28. package/dist/cli/commands/migrate.js +12 -0
  29. package/dist/cli/commands/migrate.js.map +1 -0
  30. package/dist/cli/commands/push.d.ts +2 -0
  31. package/dist/cli/commands/push.d.ts.map +1 -0
  32. package/dist/cli/commands/push.js +45 -0
  33. package/dist/cli/commands/push.js.map +1 -0
  34. package/dist/cli/commands/run.d.ts +2 -0
  35. package/dist/cli/commands/run.d.ts.map +1 -0
  36. package/dist/cli/commands/run.js +54 -0
  37. package/dist/cli/commands/run.js.map +1 -0
  38. package/dist/cli/commands/seed.d.ts +2 -0
  39. package/dist/cli/commands/seed.d.ts.map +1 -0
  40. package/dist/cli/commands/seed.js +32 -0
  41. package/dist/cli/commands/seed.js.map +1 -0
  42. package/dist/cli/commands/studio.d.ts +2 -0
  43. package/dist/cli/commands/studio.d.ts.map +1 -0
  44. package/dist/cli/commands/studio.js +22 -0
  45. package/dist/cli/commands/studio.js.map +1 -0
  46. package/dist/cli/commands/types.d.ts +2 -0
  47. package/dist/cli/commands/types.d.ts.map +1 -0
  48. package/dist/cli/commands/types.js +28 -0
  49. package/dist/cli/commands/types.js.map +1 -0
  50. package/dist/cli/config.d.ts +28 -0
  51. package/dist/cli/config.d.ts.map +1 -0
  52. package/dist/cli/config.js +81 -0
  53. package/dist/cli/config.js.map +1 -0
  54. package/dist/cli/drizzle-bridge.d.ts +29 -0
  55. package/dist/cli/drizzle-bridge.d.ts.map +1 -0
  56. package/dist/cli/drizzle-bridge.js +85 -0
  57. package/dist/cli/drizzle-bridge.js.map +1 -0
  58. package/dist/cli/index.d.ts +2 -1
  59. package/dist/cli/index.d.ts.map +1 -1
  60. package/dist/cli/index.js +74 -20
  61. package/dist/cli/index.js.map +1 -1
  62. package/dist/cli/prompt.d.ts +2 -0
  63. package/dist/cli/prompt.d.ts.map +1 -0
  64. package/dist/cli/prompt.js +16 -0
  65. package/dist/cli/prompt.js.map +1 -0
  66. package/dist/cli/templates/package-json.js +1 -1
  67. package/dist/cli/worker.d.ts +2 -0
  68. package/dist/cli/worker.d.ts.map +1 -0
  69. package/dist/cli/worker.js +120 -0
  70. package/dist/cli/worker.js.map +1 -0
  71. package/dist/client/file-upload.d.ts +2 -1
  72. package/dist/client/file-upload.d.ts.map +1 -1
  73. package/dist/client/file-upload.js +5 -5
  74. package/dist/client/file-upload.js.map +1 -1
  75. package/dist/client/live-store.d.ts.map +1 -1
  76. package/dist/client/live-store.js +12 -6
  77. package/dist/client/live-store.js.map +1 -1
  78. package/dist/client/react-files.js +1 -1
  79. package/dist/client/react-files.js.map +1 -1
  80. package/dist/client/subscription-manager.d.ts.map +1 -1
  81. package/dist/client/subscription-manager.js +7 -0
  82. package/dist/client/subscription-manager.js.map +1 -1
  83. package/dist/htmx/client/runtime.d.ts +2 -0
  84. package/dist/htmx/client/runtime.d.ts.map +1 -0
  85. package/dist/htmx/client/runtime.js +195 -0
  86. package/dist/htmx/client/runtime.js.map +1 -0
  87. package/dist/htmx/context.d.ts +16 -0
  88. package/dist/htmx/context.d.ts.map +1 -0
  89. package/dist/htmx/context.js +52 -0
  90. package/dist/htmx/context.js.map +1 -0
  91. package/dist/htmx/forms.d.ts +3 -0
  92. package/dist/htmx/forms.d.ts.map +1 -0
  93. package/dist/htmx/forms.js +32 -0
  94. package/dist/htmx/forms.js.map +1 -0
  95. package/dist/htmx/ids.d.ts +11 -0
  96. package/dist/htmx/ids.d.ts.map +1 -0
  97. package/dist/htmx/ids.js +27 -0
  98. package/dist/htmx/ids.js.map +1 -0
  99. package/dist/htmx/index.d.ts +11 -0
  100. package/dist/htmx/index.d.ts.map +1 -0
  101. package/dist/htmx/index.js +15 -0
  102. package/dist/htmx/index.js.map +1 -0
  103. package/dist/htmx/live.d.ts +39 -0
  104. package/dist/htmx/live.d.ts.map +1 -0
  105. package/dist/htmx/live.js +37 -0
  106. package/dist/htmx/live.js.map +1 -0
  107. package/dist/htmx/page.d.ts +14 -0
  108. package/dist/htmx/page.d.ts.map +1 -0
  109. package/dist/htmx/page.js +59 -0
  110. package/dist/htmx/page.js.map +1 -0
  111. package/dist/htmx/render-util.d.ts +2 -0
  112. package/dist/htmx/render-util.d.ts.map +1 -0
  113. package/dist/htmx/render-util.js +15 -0
  114. package/dist/htmx/render-util.js.map +1 -0
  115. package/dist/htmx/server.d.ts +21 -0
  116. package/dist/htmx/server.d.ts.map +1 -0
  117. package/dist/htmx/server.js +286 -0
  118. package/dist/htmx/server.js.map +1 -0
  119. package/dist/htmx/sse-render.d.ts +10 -0
  120. package/dist/htmx/sse-render.d.ts.map +1 -0
  121. package/dist/htmx/sse-render.js +40 -0
  122. package/dist/htmx/sse-render.js.map +1 -0
  123. package/dist/htmx/template-gen.d.ts +7 -0
  124. package/dist/htmx/template-gen.d.ts.map +1 -0
  125. package/dist/htmx/template-gen.js +38 -0
  126. package/dist/htmx/template-gen.js.map +1 -0
  127. package/dist/resource/hook.d.ts.map +1 -1
  128. package/dist/resource/hook.js +101 -24
  129. package/dist/resource/hook.js.map +1 -1
  130. package/dist/resource/relations.d.ts +15 -4
  131. package/dist/resource/relations.d.ts.map +1 -1
  132. package/dist/resource/relations.js +146 -26
  133. package/dist/resource/relations.js.map +1 -1
  134. package/dist/resource/subscription.d.ts +15 -2
  135. package/dist/resource/subscription.d.ts.map +1 -1
  136. package/dist/resource/subscription.js +184 -3
  137. package/dist/resource/subscription.js.map +1 -1
  138. package/dist/resource/track-mutations.d.ts.map +1 -1
  139. package/dist/resource/track-mutations.js +11 -1
  140. package/dist/resource/track-mutations.js.map +1 -1
  141. package/dist/resource/types.d.ts +8 -0
  142. package/dist/resource/types.d.ts.map +1 -1
  143. package/dist/server/admin-bypass.d.ts +7 -0
  144. package/dist/server/admin-bypass.d.ts.map +1 -0
  145. package/dist/server/admin-bypass.js +22 -0
  146. package/dist/server/admin-bypass.js.map +1 -0
  147. package/dist/server/app.d.ts +9 -0
  148. package/dist/server/app.d.ts.map +1 -1
  149. package/dist/server/app.js +101 -1
  150. package/dist/server/app.js.map +1 -1
  151. package/dist/server/impersonation.d.ts +18 -0
  152. package/dist/server/impersonation.d.ts.map +1 -0
  153. package/dist/server/impersonation.js +53 -0
  154. package/dist/server/impersonation.js.map +1 -0
  155. package/dist/shared/escape.d.ts +3 -0
  156. package/dist/shared/escape.d.ts.map +1 -0
  157. package/dist/shared/escape.js +12 -0
  158. package/dist/shared/escape.js.map +1 -0
  159. package/dist/storage/local.d.ts +4 -0
  160. package/dist/storage/local.d.ts.map +1 -1
  161. package/dist/storage/local.js +5 -0
  162. package/dist/storage/local.js.map +1 -1
  163. package/dist/storage/resource.d.ts +5 -11
  164. package/dist/storage/resource.d.ts.map +1 -1
  165. package/dist/storage/resource.js +156 -194
  166. package/dist/storage/resource.js.map +1 -1
  167. package/dist/ui/admin-auth.d.ts +6 -0
  168. package/dist/ui/admin-auth.d.ts.map +1 -1
  169. package/dist/ui/admin-auth.js +59 -1
  170. package/dist/ui/admin-auth.js.map +1 -1
  171. package/dist/ui/data-explorer.d.ts.map +1 -1
  172. package/dist/ui/data-explorer.js +91 -4
  173. package/dist/ui/data-explorer.js.map +1 -1
  174. package/dist/ui/html/client/data-explorer-app.d.ts.map +1 -1
  175. package/dist/ui/html/client/data-explorer-app.js +20 -7
  176. package/dist/ui/html/client/data-explorer-app.js.map +1 -1
  177. package/dist/ui/html/client/runtime.d.ts.map +1 -1
  178. package/dist/ui/html/client/runtime.js +70 -2
  179. package/dist/ui/html/client/runtime.js.map +1 -1
  180. package/dist/ui/html/icons.d.ts.map +1 -1
  181. package/dist/ui/html/icons.js +2 -0
  182. package/dist/ui/html/icons.js.map +1 -1
  183. package/dist/ui/html/layout.d.ts +1 -0
  184. package/dist/ui/html/layout.d.ts.map +1 -1
  185. package/dist/ui/html/layout.js +274 -146
  186. package/dist/ui/html/layout.js.map +1 -1
  187. package/dist/ui/html/pages/filter-tester.d.ts.map +1 -1
  188. package/dist/ui/html/pages/filter-tester.js +15 -0
  189. package/dist/ui/html/pages/filter-tester.js.map +1 -1
  190. package/dist/ui/html/pages/users.d.ts.map +1 -1
  191. package/dist/ui/html/pages/users.js +8 -1
  192. package/dist/ui/html/pages/users.js.map +1 -1
  193. package/dist/ui/index.d.ts +1 -1
  194. package/dist/ui/index.d.ts.map +1 -1
  195. package/dist/ui/index.js +1 -1
  196. package/dist/ui/index.js.map +1 -1
  197. package/dist/ui/middleware.d.ts.map +1 -1
  198. package/dist/ui/middleware.js +121 -5
  199. package/dist/ui/middleware.js.map +1 -1
  200. package/dist/ui/schema-registry.d.ts +5 -0
  201. package/dist/ui/schema-registry.d.ts.map +1 -1
  202. package/dist/ui/schema-registry.js +14 -0
  203. package/dist/ui/schema-registry.js.map +1 -1
  204. package/package.json +5 -1
package/README.md CHANGED
@@ -52,7 +52,7 @@ function TodoList() {
52
52
  ### Core API
53
53
  - **Automatic REST API** - Full CRUD endpoints from your Drizzle schema
54
54
  - **Real-time Subscriptions** - SSE with changelog-based updates, sequence numbers, and seamless reconnection
55
- - **Relations & Joins** - `belongsTo`, `hasOne`, `hasMany`, `manyToMany` with efficient batch loading
55
+ - **Relations & Joins** - `belongsTo`, `hasOne`, `hasMany`, `manyToMany` with efficient batch loading, optional foreign-key **auto-discovery** (`autoRelations`), and **scope-enforced includes** (a relation never reveals rows the user couldn't read directly)
56
56
  - **RSQL Filtering** - Comprehensive query language (30+ operators) plus custom operators
57
57
  - **Cursor Pagination** - Keyset pagination with multi-field ordering
58
58
  - **Aggregations** - Group by, count, sum, avg, min, max, with `HAVING` filtering on aggregate output — available as a one-shot query or a live subscription (`useLiveAggregate`) that recomputes on every change
@@ -90,7 +90,8 @@ function TodoList() {
90
90
 
91
91
  ### File Storage
92
92
  - **Storage Adapters** - Local disk, S3, Cloudflare R2 (native binding or S3-compat), and in-memory behind one `StorageAdapter` interface
93
- - **File Resources** - `useFileResource` generates upload/download/list/delete endpoints with MIME and size validation, per-user key generation, and auth scopes
93
+ - **File Resources** - First-class resources with an upload/download layer: `app.fileResource(...)` chains like any resource and inherits the full CRUD/hooks/procedures/relations/subscriptions/scopes surface, plus MIME/size validation, per-user keys, and storage cleanup on delete
94
+ - **Zero-config local serving** - `createCovara` auto-serves a local adapter's `baseUrl` (no manual `serveStatic`); admin data explorer gets a per-row Download action
94
95
  - **Presigned URLs** - Optional direct-to-bucket uploads/downloads with configurable expiry
95
96
  - **React Hooks** - `useFileUpload` (with progress), `useFile`, `useFiles`; `getDownloadUrl()` for React Native
96
97
 
@@ -125,6 +126,13 @@ function TodoList() {
125
126
  - **Auth Strategies** - OIDC (PKCE flow, token refresh), JWT, bearer, API key, or cookie sessions — selected per client or auto-detected
126
127
  - **HMR-safe** - `getOrCreateClient` for development
127
128
 
129
+ ### Server-rendered htmx (Beta)
130
+ - **One JSX page → full app** - `app.page(path, Component)` server-renders a page whose `<Live>` regions auto-generate the htmx endpoints (list/create/update/delete/subscribe). Covara generates wiring, not UI components
131
+ - **Live by default** - each region streams server-rendered fragments over SSE (reusing the existing subscription engine); rows update in place as anyone mutates the resource
132
+ - **Optimistic & offline** - new rows insert once via the live SSE (no duplicate/phantom), deletes are optimistic, and mutations queue offline and replay on reconnect
133
+ - **No client framework** - vendored htmx core + a tiny runtime, served and injected automatically
134
+ - **Beta** - newer than the JSON API + TypeScript client; the API may still change
135
+
128
136
  ### Environment Variables
129
137
  - **Type-safe Configuration** - Define and validate env vars with Zod via `createEnv` / `envVariable`
130
138
  - **Public and Private Vars** - `PUBLIC_`-prefixed or explicitly-marked vars served to clients via `usePublicEnv` (with ETag)
@@ -132,6 +140,7 @@ function TodoList() {
132
140
 
133
141
  ### Developer Experience
134
142
  - **Project Scaffolding** - `npx covara create my-app` (Node/Workers templates, SQLite/Postgres), plus `covara generate resource|migration`
143
+ - **`covara dev` Loop** - Dev watcher: streams schema changes to the DB (additive auto-applied, destructive gated), regenerates the typed client, runs the server — no manual push. Plus `covara db` connection profiles (local/remote/Turso/Postgres), `push`/`migrate`/`studio`, and `data`/`import`/`export`/`run`/`types`
135
144
  - **Deploy-Ready Output** - Generated Dockerfile, docker-compose, complete wrangler.toml, GitHub Actions CI, `.env.example`
136
145
  - **Framework Migrations** - `covara/db` ships canonical internal-table schemas, an idempotent `autoMigrate`/`migrateInternal`, a generic seeder, and pool-sizing helpers
137
146
  - **App Factory** - `createCovara()` wires errors, auth, security headers, health, OpenAPI, admin UI
@@ -436,30 +445,69 @@ const subscription = users.subscribe(
436
445
 
437
446
  The client has no hard DOM dependencies: pass an AsyncStorage-backed `TokenStorage` for JWT auth, offline persistence picks an environment-appropriate backend, and the file hooks expose `getDownloadUrl()` for use with `Linking` instead of browser downloads.
438
447
 
448
+ ## Server-rendered htmx (Beta)
449
+
450
+ > **Beta.** This is newer than the JSON API and TypeScript client and may still change between releases. The JSON API it builds on is stable.
451
+
452
+ Prefer hypermedia over a client framework? Register a single JSX page; `<Live>` is the only special element, and Covara generates the htmx endpoints, the live SSE stream, and the optimistic/offline client runtime for you.
453
+
454
+ ```tsx
455
+ // tsconfig: { "jsx": "react-jsx", "jsxImportSource": "hono/jsx" }
456
+ import { createCovara } from "covara/server";
457
+ import { Live } from "covara/htmx";
458
+ import { todos } from "./schema";
459
+
460
+ const app = createCovara()
461
+ .resource("/todos", todos, { id: todos.id, db })
462
+ .page("/todos", () => (
463
+ <Live
464
+ resource={todos}
465
+ query={{ orderBy: "position" }}
466
+ create={(c) => (
467
+ <form {...c.create()}>
468
+ <input name="title" />
469
+ <button>Add</button>
470
+ </form>
471
+ )}
472
+ container={(rows, c) => <ul {...c.container()}>{rows}</ul>}
473
+ render={(t, c) => (
474
+ <li {...c.row(t.id)}>
475
+ {t.title}
476
+ <button {...c.delete(t.id)}>Delete</button>
477
+ </li>
478
+ )}
479
+ />
480
+ ));
481
+ ```
482
+
483
+ `GET /todos` is now a full server-rendered page. Creating a todo in one browser tab streams the new row into every other tab over SSE; updates and deletes patch rows in place. The helpers (`c.create()`, `c.row(id)`, `c.update(id)`, `c.delete(id)`, `c.container()`) emit plain htmx attributes pointing at auto-generated endpoints under `/__covara/live`. See the [htmx docs](https://kahveciderin.github.io/covara/htmx/overview) for optimistic/offline behavior, live aggregates, and scoping.
484
+
439
485
  ## File Storage
440
486
 
441
- Configure a storage backend once, then mount file resources like any other:
487
+ Configure a storage backend once, then chain a file resource like any other. Local uploads are auto-served at `baseUrl` — no `serveStatic` wiring:
442
488
 
443
489
  ```typescript
444
- import { initializeStorage, useFileResource } from "covara";
490
+ import { createCovara, initializeStorage } from "covara";
445
491
 
446
492
  initializeStorage({
447
493
  type: "local", // or "s3" | "r2" | "memory"
448
494
  local: { basePath: "./uploads", baseUrl: "/uploads" },
449
495
  });
450
496
 
451
- app.route("/api/files", useFileResource(filesTable, {
452
- db,
453
- schema: filesTable,
454
- id: filesTable.id,
455
- allowedMimeTypes: ["image/jpeg", "image/png"],
456
- maxFileSize: 5 * 1024 * 1024,
457
- auth: {
458
- read: async (user) => rsql`userId==${user?.id}`,
459
- delete: async (user) => rsql`userId==${user?.id}`,
460
- },
461
- usePresignedUrls: true, // direct-to-bucket on S3/R2
462
- }));
497
+ const app = createCovara({ cors: true })
498
+ .resource("/todos", todosTable, { id: todosTable.id, db })
499
+ .fileResource("/files", filesTable, {
500
+ db,
501
+ id: filesTable.id,
502
+ allowedMimeTypes: ["image/jpeg", "image/png"],
503
+ maxFileSize: 5 * 1024 * 1024,
504
+ auth: {
505
+ read: async (user) => rsql`userId==${user?.id}`,
506
+ delete: async (user) => rsql`userId==${user?.id}`,
507
+ },
508
+ usePresignedUrls: true, // direct-to-bucket on S3/R2
509
+ // ...plus any resource option: hooks, relations, procedures, subscriptions
510
+ });
463
511
  ```
464
512
 
465
513
  Upload from React with progress tracking:
@@ -0,0 +1,14 @@
1
+ export interface ParsedArgs {
2
+ positionals: string[];
3
+ flags: Record<string, string | boolean>;
4
+ passthrough: string[];
5
+ }
6
+ export interface ParseOptions {
7
+ booleans?: string[];
8
+ aliases?: Record<string, string>;
9
+ }
10
+ export declare const parseArgs: (argv: string[], opts?: ParseOptions) => ParsedArgs;
11
+ export declare const getString: (parsed: ParsedArgs, name: string) => string | undefined;
12
+ export declare const getBool: (parsed: ParsedArgs, name: string) => boolean;
13
+ export declare const hasFlag: (parsed: ParsedArgs, name: string) => boolean;
14
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;IACxC,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAQD,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,EAAE,OAAM,YAAiB,KAAG,UA4DnE,CAAC;AAEF,eAAO,MAAM,SAAS,GACpB,QAAQ,UAAU,EAClB,MAAM,MAAM,KACX,MAAM,GAAG,SAGX,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,QAAQ,UAAU,EAAE,MAAM,MAAM,KAAG,OAE1D,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,QAAQ,UAAU,EAAE,MAAM,MAAM,KAAG,OAE1D,CAAC"}
@@ -0,0 +1,78 @@
1
+ const splitInline = (arg) => {
2
+ const eq = arg.indexOf("=");
3
+ if (eq === -1)
4
+ return [arg, undefined];
5
+ return [arg.slice(0, eq), arg.slice(eq + 1)];
6
+ };
7
+ export const parseArgs = (argv, opts = {}) => {
8
+ const booleans = new Set(opts.booleans ?? []);
9
+ const aliases = opts.aliases ?? {};
10
+ const positionals = [];
11
+ const flags = {};
12
+ const passthrough = [];
13
+ const rest = [...argv];
14
+ while (rest.length > 0) {
15
+ const arg = rest.shift();
16
+ if (arg === "--") {
17
+ passthrough.push(...rest);
18
+ break;
19
+ }
20
+ if (arg.startsWith("--")) {
21
+ const [rawName, inline] = splitInline(arg.slice(2));
22
+ if (rawName.startsWith("no-") && inline === undefined && !booleans.has(rawName)) {
23
+ flags[rawName.slice(3)] = false;
24
+ continue;
25
+ }
26
+ const name = aliases[rawName] ?? rawName;
27
+ if (inline !== undefined) {
28
+ flags[name] = inline;
29
+ }
30
+ else if (booleans.has(rawName) || booleans.has(name)) {
31
+ flags[name] = true;
32
+ }
33
+ else {
34
+ const next = rest[0];
35
+ if (next === undefined || next.startsWith("-")) {
36
+ flags[name] = true;
37
+ }
38
+ else {
39
+ flags[name] = rest.shift();
40
+ }
41
+ }
42
+ continue;
43
+ }
44
+ if (arg.startsWith("-") && arg.length > 1) {
45
+ const [rawName, inline] = splitInline(arg.slice(1));
46
+ const name = aliases[rawName] ?? rawName;
47
+ if (inline !== undefined) {
48
+ flags[name] = inline;
49
+ }
50
+ else if (booleans.has(rawName) || booleans.has(name)) {
51
+ flags[name] = true;
52
+ }
53
+ else {
54
+ const next = rest[0];
55
+ if (next === undefined || next.startsWith("-")) {
56
+ flags[name] = true;
57
+ }
58
+ else {
59
+ flags[name] = rest.shift();
60
+ }
61
+ }
62
+ continue;
63
+ }
64
+ positionals.push(arg);
65
+ }
66
+ return { positionals, flags, passthrough };
67
+ };
68
+ export const getString = (parsed, name) => {
69
+ const v = parsed.flags[name];
70
+ return typeof v === "string" ? v : undefined;
71
+ };
72
+ export const getBool = (parsed, name) => {
73
+ return parsed.flags[name] === true;
74
+ };
75
+ export const hasFlag = (parsed, name) => {
76
+ return name in parsed.flags;
77
+ };
78
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const dataCommand: (args: string[]) => Promise<number>;
2
+ //# sourceMappingURL=data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/data.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,GAAU,MAAM,MAAM,EAAE,KAAG,OAAO,CAAC,MAAM,CAyBhE,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { resolveProfile, resolveSchemaPath } from "../config.js";
2
+ import { queryData } from "../drizzle-bridge.js";
3
+ import { parseArgs, getString } from "../args.js";
4
+ export const dataCommand = async (args) => {
5
+ const parsed = parseArgs(args);
6
+ const table = parsed.positionals[0];
7
+ if (!table) {
8
+ console.error("error: usage: covara data <table> [--limit n] [--profile name]");
9
+ return 1;
10
+ }
11
+ const cwd = process.cwd();
12
+ try {
13
+ const profile = resolveProfile(cwd, {
14
+ profile: getString(parsed, "profile"),
15
+ url: getString(parsed, "url"),
16
+ });
17
+ const schemaPath = resolveSchemaPath(cwd);
18
+ const limit = getString(parsed, "limit");
19
+ const { rows } = await queryData(cwd, profile, schemaPath, table, {
20
+ limit: limit ? parseInt(limit, 10) : undefined,
21
+ });
22
+ console.log(JSON.stringify(rows, null, 2));
23
+ console.log(`\n(${rows.length} row(s))`);
24
+ return 0;
25
+ }
26
+ catch (e) {
27
+ console.error(`error: ${e instanceof Error ? e.message : String(e)}`);
28
+ return 1;
29
+ }
30
+ };
31
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../../../src/cli/commands/data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,IAAc,EAAmB,EAAE;IACnE,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACpC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;QAChF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE;YAClC,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC;YACrC,GAAG,EAAE,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC;SAC9B,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACzC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE;YAChE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;SAC/C,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC;QACzC,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACtE,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const dbCommand: (args: string[]) => number;
2
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/db.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,KAAG,MA2F1C,CAAC"}
@@ -0,0 +1,100 @@
1
+ import { loadConfig, saveConfig, resolveProfile, dialectFromUrl, } from "../config.js";
2
+ import { parseArgs, getString } from "../args.js";
3
+ const DB_HELP = `covara db - manage database connection profiles
4
+
5
+ Usage:
6
+ covara db list
7
+ covara db current
8
+ covara db use <name>
9
+ covara db add <name> --url <url> [--token <token>] [--dialect sqlite|postgres]
10
+ covara db remove <name>
11
+ `;
12
+ export const dbCommand = (args) => {
13
+ const [sub, ...rest] = args;
14
+ const cwd = process.cwd();
15
+ if (!sub || sub === "help" || sub === "--help") {
16
+ console.log(DB_HELP);
17
+ return sub ? 0 : 1;
18
+ }
19
+ if (sub === "list") {
20
+ const config = loadConfig(cwd);
21
+ const names = Object.keys(config.profiles);
22
+ if (names.length === 0) {
23
+ console.log("No profiles configured. Add one with `covara db add <name> --url <url>`.");
24
+ return 0;
25
+ }
26
+ for (const name of names) {
27
+ const p = config.profiles[name];
28
+ const marker = name === config.active ? "* " : " ";
29
+ console.log(`${marker}${name} [${p.dialect}] ${p.url}`);
30
+ }
31
+ return 0;
32
+ }
33
+ if (sub === "current") {
34
+ try {
35
+ const p = resolveProfile(cwd);
36
+ console.log(`${p.name} [${p.dialect}] ${p.url}`);
37
+ return 0;
38
+ }
39
+ catch (e) {
40
+ console.error(`error: ${e instanceof Error ? e.message : String(e)}`);
41
+ return 1;
42
+ }
43
+ }
44
+ if (sub === "use") {
45
+ const name = rest.find((a) => !a.startsWith("-"));
46
+ if (!name) {
47
+ console.error("error: missing profile name (usage: covara db use <name>)");
48
+ return 1;
49
+ }
50
+ const config = loadConfig(cwd);
51
+ if (!config.profiles[name]) {
52
+ console.error(`error: unknown profile "${name}"`);
53
+ return 1;
54
+ }
55
+ config.active = name;
56
+ saveConfig(cwd, config);
57
+ console.log(`Active profile is now "${name}".`);
58
+ return 0;
59
+ }
60
+ if (sub === "add") {
61
+ const parsed = parseArgs(rest, { aliases: { t: "token", d: "dialect" } });
62
+ const name = parsed.positionals[0];
63
+ const url = getString(parsed, "url");
64
+ if (!name || !url) {
65
+ console.error("error: usage: covara db add <name> --url <url> [--token <token>] [--dialect sqlite|postgres]");
66
+ return 1;
67
+ }
68
+ const dialect = getString(parsed, "dialect") ?? dialectFromUrl(url);
69
+ const token = getString(parsed, "token");
70
+ const config = loadConfig(cwd);
71
+ config.profiles[name] = { dialect, url, ...(token ? { authToken: token } : {}) };
72
+ if (!config.active)
73
+ config.active = name;
74
+ saveConfig(cwd, config);
75
+ console.log(`Added profile "${name}" [${dialect}].`);
76
+ return 0;
77
+ }
78
+ if (sub === "remove" || sub === "rm") {
79
+ const name = rest.find((a) => !a.startsWith("-"));
80
+ if (!name) {
81
+ console.error("error: missing profile name (usage: covara db remove <name>)");
82
+ return 1;
83
+ }
84
+ const config = loadConfig(cwd);
85
+ if (!config.profiles[name]) {
86
+ console.error(`error: unknown profile "${name}"`);
87
+ return 1;
88
+ }
89
+ delete config.profiles[name];
90
+ if (config.active === name)
91
+ delete config.active;
92
+ saveConfig(cwd, config);
93
+ console.log(`Removed profile "${name}".`);
94
+ return 0;
95
+ }
96
+ console.error(`error: unknown db subcommand "${sub}"\n`);
97
+ console.log(DB_HELP);
98
+ return 1;
99
+ };
100
+ //# sourceMappingURL=db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/cli/commands/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const devCommand: (args: string[]) => Promise<number>;
2
+ //# sourceMappingURL=dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/dev.ts"],"names":[],"mappings":"AA4BA,eAAO,MAAM,UAAU,GAAU,MAAM,MAAM,EAAE,KAAG,OAAO,CAAC,MAAM,CAkG/D,CAAC"}
@@ -0,0 +1,125 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { spawn } from "node:child_process";
4
+ import { resolveProfile, resolveSchemaPath } from "../config.js";
5
+ import { pushSchema, findTsx } from "../drizzle-bridge.js";
6
+ import { parseArgs, getString, getBool } from "../args.js";
7
+ import { generateTypes } from "../../client/typegen.js";
8
+ const ENTRY_CANDIDATES = [
9
+ "src/main.ts",
10
+ "src/index.ts",
11
+ "src/server.ts",
12
+ "main.ts",
13
+ "index.ts",
14
+ ];
15
+ const findEntry = (cwd, explicit) => {
16
+ if (explicit) {
17
+ const p = path.resolve(cwd, explicit);
18
+ return fs.existsSync(p) ? p : null;
19
+ }
20
+ for (const candidate of ENTRY_CANDIDATES) {
21
+ const p = path.resolve(cwd, candidate);
22
+ if (fs.existsSync(p))
23
+ return p;
24
+ }
25
+ return null;
26
+ };
27
+ export const devCommand = async (args) => {
28
+ const parsed = parseArgs(args, { booleans: ["no-server"] });
29
+ const cwd = process.cwd();
30
+ let profile;
31
+ let schemaPath;
32
+ try {
33
+ profile = resolveProfile(cwd, {
34
+ profile: getString(parsed, "profile"),
35
+ url: getString(parsed, "url"),
36
+ });
37
+ schemaPath = resolveSchemaPath(cwd);
38
+ }
39
+ catch (e) {
40
+ console.error(`error: ${e instanceof Error ? e.message : String(e)}`);
41
+ return 1;
42
+ }
43
+ const serverUrl = getString(parsed, "server-url") ?? `http://localhost:${process.env.PORT ?? 3000}`;
44
+ const typesOut = getString(parsed, "types-out");
45
+ const runServer = !getBool(parsed, "no-server") && parsed.flags.server !== false;
46
+ let serverChild = null;
47
+ if (runServer) {
48
+ const entry = findEntry(cwd, parsed.positionals[0] ?? getString(parsed, "entry"));
49
+ if (!entry) {
50
+ console.error("error: could not find a server entry — pass `covara dev <entry>`");
51
+ return 1;
52
+ }
53
+ const { cmd, prefix } = findTsx(cwd);
54
+ console.log(`[covara] starting server: tsx watch ${path.relative(cwd, entry)}`);
55
+ serverChild = spawn(cmd, [...prefix, "watch", entry], { cwd, stdio: "inherit" });
56
+ }
57
+ let syncing = false;
58
+ let pending = false;
59
+ const sync = async () => {
60
+ if (syncing) {
61
+ pending = true;
62
+ return;
63
+ }
64
+ syncing = true;
65
+ try {
66
+ const result = await pushSchema(cwd, profile, schemaPath);
67
+ if (!result.applied) {
68
+ console.log("[covara] schema: destructive change detected — not auto-applied. Run `covara push --force`:");
69
+ for (const stmt of result.statementsToExecute)
70
+ console.log(` ${stmt}`);
71
+ }
72
+ else if (result.statementsToExecute.length > 0) {
73
+ console.log(`[covara] schema: applied ${result.statementsToExecute.length} change(s)`);
74
+ if (typesOut) {
75
+ try {
76
+ const generated = await generateTypes({
77
+ serverUrl,
78
+ output: "typescript",
79
+ includeClient: true,
80
+ });
81
+ fs.writeFileSync(path.resolve(cwd, typesOut), generated.code);
82
+ console.log(`[covara] types: regenerated ${typesOut}`);
83
+ }
84
+ catch {
85
+ console.log("[covara] types: server not ready yet, skipping regen");
86
+ }
87
+ }
88
+ }
89
+ }
90
+ catch (e) {
91
+ console.error(`[covara] schema error: ${e instanceof Error ? e.message : String(e)}`);
92
+ }
93
+ finally {
94
+ syncing = false;
95
+ if (pending) {
96
+ pending = false;
97
+ void sync();
98
+ }
99
+ }
100
+ };
101
+ await sync();
102
+ let timer;
103
+ try {
104
+ fs.watch(schemaPath, () => {
105
+ clearTimeout(timer);
106
+ timer = setTimeout(() => void sync(), 300);
107
+ });
108
+ }
109
+ catch {
110
+ console.error(`[covara] could not watch ${schemaPath}`);
111
+ }
112
+ console.log(`[covara] watching ${path.relative(cwd, schemaPath)} for schema changes`);
113
+ return new Promise((resolve) => {
114
+ const shutdown = () => {
115
+ if (serverChild)
116
+ serverChild.kill();
117
+ resolve(0);
118
+ };
119
+ process.on("SIGINT", shutdown);
120
+ process.on("SIGTERM", shutdown);
121
+ if (serverChild)
122
+ serverChild.on("close", () => resolve(0));
123
+ });
124
+ };
125
+ //# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../../src/cli/commands/dev.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const envCommand: (args: string[]) => number;
2
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/env.ts"],"names":[],"mappings":"AA6BA,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,EAAE,KAAG,MAoE3C,CAAC"}
@@ -0,0 +1,94 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ const envFile = (cwd) => path.join(cwd, ".env");
4
+ const readEnvFile = (cwd) => {
5
+ const p = envFile(cwd);
6
+ return fs.existsSync(p) ? fs.readFileSync(p, "utf8") : "";
7
+ };
8
+ const keyOf = (line) => {
9
+ const t = line.trim();
10
+ if (!t || t.startsWith("#"))
11
+ return null;
12
+ const i = t.indexOf("=");
13
+ return i === -1 ? null : t.slice(0, i).trim();
14
+ };
15
+ const parseEnv = (text) => {
16
+ const map = {};
17
+ for (const line of text.split("\n")) {
18
+ const t = line.trim();
19
+ if (!t || t.startsWith("#"))
20
+ continue;
21
+ const i = t.indexOf("=");
22
+ if (i === -1)
23
+ continue;
24
+ map[t.slice(0, i).trim()] = t.slice(i + 1).trim();
25
+ }
26
+ return map;
27
+ };
28
+ export const envCommand = (args) => {
29
+ const [sub, ...rest] = args;
30
+ const cwd = process.cwd();
31
+ if (sub === "list" || !sub) {
32
+ const map = parseEnv(readEnvFile(cwd));
33
+ for (const k of Object.keys(map))
34
+ console.log(`${k}=${map[k]}`);
35
+ return 0;
36
+ }
37
+ if (sub === "get") {
38
+ const key = rest[0];
39
+ if (!key) {
40
+ console.error("usage: covara env get <key>");
41
+ return 1;
42
+ }
43
+ const map = parseEnv(readEnvFile(cwd));
44
+ if (key in map) {
45
+ console.log(map[key]);
46
+ return 0;
47
+ }
48
+ return 1;
49
+ }
50
+ if (sub === "set") {
51
+ const key = rest[0];
52
+ const value = rest.slice(1).join(" ");
53
+ if (!key) {
54
+ console.error("usage: covara env set <key> <value>");
55
+ return 1;
56
+ }
57
+ const lines = readEnvFile(cwd).split("\n");
58
+ let found = false;
59
+ const updated = lines.map((line) => {
60
+ if (keyOf(line) === key) {
61
+ found = true;
62
+ return `${key}=${value}`;
63
+ }
64
+ return line;
65
+ });
66
+ if (!found) {
67
+ if (updated.length && updated[updated.length - 1] === "") {
68
+ updated.splice(updated.length - 1, 0, `${key}=${value}`);
69
+ }
70
+ else {
71
+ updated.push(`${key}=${value}`);
72
+ }
73
+ }
74
+ fs.writeFileSync(envFile(cwd), updated.join("\n"));
75
+ console.log(`Set ${key}`);
76
+ return 0;
77
+ }
78
+ if (sub === "remove" || sub === "rm") {
79
+ const key = rest[0];
80
+ if (!key) {
81
+ console.error("usage: covara env remove <key>");
82
+ return 1;
83
+ }
84
+ const lines = readEnvFile(cwd)
85
+ .split("\n")
86
+ .filter((line) => keyOf(line) !== key);
87
+ fs.writeFileSync(envFile(cwd), lines.join("\n"));
88
+ console.log(`Removed ${key}`);
89
+ return 0;
90
+ }
91
+ console.error("usage: covara env <list|get|set|remove>");
92
+ return 1;
93
+ };
94
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/cli/commands/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,OAAO,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAEhE,MAAM,WAAW,GAAG,CAAC,GAAW,EAAU,EAAE;IAC1C,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5D,CAAC,CAAC;AAEF,MAAM,KAAK,GAAG,CAAC,IAAY,EAAiB,EAAE;IAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IACtB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACzB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAChD,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,IAAY,EAA0B,EAAE;IACxD,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,CAAC;YAAE,SAAS;QACvB,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACpD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAc,EAAU,EAAE;IACnD,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;QACvC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC7C,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;QACvC,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACtB,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACrD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACjC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;gBACxB,KAAK,GAAG,IAAI,CAAC;gBACb,OAAO,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;YAC3B,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;gBACzD,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;YAC3D,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QACD,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QAC1B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;YAChD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC;aAC3B,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACzC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;QAC9B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IACzD,OAAO,CAAC,CAAC;AACX,CAAC,CAAC"}