covara 0.7.1 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -16
- package/dist/cli/args.d.ts +14 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +78 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/commands/data.d.ts +2 -0
- package/dist/cli/commands/data.d.ts.map +1 -0
- package/dist/cli/commands/data.js +31 -0
- package/dist/cli/commands/data.js.map +1 -0
- package/dist/cli/commands/db.d.ts +2 -0
- package/dist/cli/commands/db.d.ts.map +1 -0
- package/dist/cli/commands/db.js +100 -0
- package/dist/cli/commands/db.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +2 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +125 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/env.d.ts +2 -0
- package/dist/cli/commands/env.d.ts.map +1 -0
- package/dist/cli/commands/env.js +94 -0
- package/dist/cli/commands/env.js.map +1 -0
- package/dist/cli/commands/import-export.d.ts +3 -0
- package/dist/cli/commands/import-export.d.ts.map +1 -0
- package/dist/cli/commands/import-export.js +156 -0
- package/dist/cli/commands/import-export.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +2 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +12 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/commands/push.d.ts +2 -0
- package/dist/cli/commands/push.d.ts.map +1 -0
- package/dist/cli/commands/push.js +45 -0
- package/dist/cli/commands/push.js.map +1 -0
- package/dist/cli/commands/run.d.ts +2 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +54 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/seed.d.ts +2 -0
- package/dist/cli/commands/seed.d.ts.map +1 -0
- package/dist/cli/commands/seed.js +32 -0
- package/dist/cli/commands/seed.js.map +1 -0
- package/dist/cli/commands/studio.d.ts +2 -0
- package/dist/cli/commands/studio.d.ts.map +1 -0
- package/dist/cli/commands/studio.js +22 -0
- package/dist/cli/commands/studio.js.map +1 -0
- package/dist/cli/commands/types.d.ts +2 -0
- package/dist/cli/commands/types.d.ts.map +1 -0
- package/dist/cli/commands/types.js +28 -0
- package/dist/cli/commands/types.js.map +1 -0
- package/dist/cli/config.d.ts +28 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +81 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/drizzle-bridge.d.ts +29 -0
- package/dist/cli/drizzle-bridge.d.ts.map +1 -0
- package/dist/cli/drizzle-bridge.js +85 -0
- package/dist/cli/drizzle-bridge.js.map +1 -0
- package/dist/cli/index.d.ts +2 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +74 -20
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/prompt.d.ts +2 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +16 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/templates/package-json.js +1 -1
- package/dist/cli/worker.d.ts +2 -0
- package/dist/cli/worker.d.ts.map +1 -0
- package/dist/cli/worker.js +120 -0
- package/dist/cli/worker.js.map +1 -0
- package/dist/client/file-upload.d.ts +2 -1
- package/dist/client/file-upload.d.ts.map +1 -1
- package/dist/client/file-upload.js +5 -5
- package/dist/client/file-upload.js.map +1 -1
- package/dist/client/live-store.d.ts.map +1 -1
- package/dist/client/live-store.js +12 -6
- package/dist/client/live-store.js.map +1 -1
- package/dist/client/react-files.js +1 -1
- package/dist/client/react-files.js.map +1 -1
- package/dist/client/subscription-manager.d.ts.map +1 -1
- package/dist/client/subscription-manager.js +7 -0
- package/dist/client/subscription-manager.js.map +1 -1
- package/dist/htmx/client/runtime.d.ts +2 -0
- package/dist/htmx/client/runtime.d.ts.map +1 -0
- package/dist/htmx/client/runtime.js +195 -0
- package/dist/htmx/client/runtime.js.map +1 -0
- package/dist/htmx/context.d.ts +16 -0
- package/dist/htmx/context.d.ts.map +1 -0
- package/dist/htmx/context.js +52 -0
- package/dist/htmx/context.js.map +1 -0
- package/dist/htmx/forms.d.ts +3 -0
- package/dist/htmx/forms.d.ts.map +1 -0
- package/dist/htmx/forms.js +32 -0
- package/dist/htmx/forms.js.map +1 -0
- package/dist/htmx/ids.d.ts +11 -0
- package/dist/htmx/ids.d.ts.map +1 -0
- package/dist/htmx/ids.js +27 -0
- package/dist/htmx/ids.js.map +1 -0
- package/dist/htmx/index.d.ts +11 -0
- package/dist/htmx/index.d.ts.map +1 -0
- package/dist/htmx/index.js +15 -0
- package/dist/htmx/index.js.map +1 -0
- package/dist/htmx/live.d.ts +39 -0
- package/dist/htmx/live.d.ts.map +1 -0
- package/dist/htmx/live.js +37 -0
- package/dist/htmx/live.js.map +1 -0
- package/dist/htmx/page.d.ts +14 -0
- package/dist/htmx/page.d.ts.map +1 -0
- package/dist/htmx/page.js +59 -0
- package/dist/htmx/page.js.map +1 -0
- package/dist/htmx/render-util.d.ts +2 -0
- package/dist/htmx/render-util.d.ts.map +1 -0
- package/dist/htmx/render-util.js +15 -0
- package/dist/htmx/render-util.js.map +1 -0
- package/dist/htmx/server.d.ts +21 -0
- package/dist/htmx/server.d.ts.map +1 -0
- package/dist/htmx/server.js +286 -0
- package/dist/htmx/server.js.map +1 -0
- package/dist/htmx/sse-render.d.ts +10 -0
- package/dist/htmx/sse-render.d.ts.map +1 -0
- package/dist/htmx/sse-render.js +40 -0
- package/dist/htmx/sse-render.js.map +1 -0
- package/dist/htmx/template-gen.d.ts +7 -0
- package/dist/htmx/template-gen.d.ts.map +1 -0
- package/dist/htmx/template-gen.js +38 -0
- package/dist/htmx/template-gen.js.map +1 -0
- package/dist/resource/hook.d.ts.map +1 -1
- package/dist/resource/hook.js +158 -48
- package/dist/resource/hook.js.map +1 -1
- package/dist/resource/mutate.d.ts.map +1 -1
- package/dist/resource/mutate.js +11 -7
- package/dist/resource/mutate.js.map +1 -1
- package/dist/resource/relations.d.ts +15 -4
- package/dist/resource/relations.d.ts.map +1 -1
- package/dist/resource/relations.js +146 -26
- package/dist/resource/relations.js.map +1 -1
- package/dist/resource/subscription.d.ts +15 -2
- package/dist/resource/subscription.d.ts.map +1 -1
- package/dist/resource/subscription.js +184 -3
- package/dist/resource/subscription.js.map +1 -1
- package/dist/resource/track-mutations.d.ts.map +1 -1
- package/dist/resource/track-mutations.js +11 -1
- package/dist/resource/track-mutations.js.map +1 -1
- package/dist/resource/transaction.d.ts +24 -0
- package/dist/resource/transaction.d.ts.map +1 -0
- package/dist/resource/transaction.js +47 -0
- package/dist/resource/transaction.js.map +1 -0
- package/dist/resource/types.d.ts +9 -0
- package/dist/resource/types.d.ts.map +1 -1
- package/dist/server/admin-bypass.d.ts +7 -0
- package/dist/server/admin-bypass.d.ts.map +1 -0
- package/dist/server/admin-bypass.js +22 -0
- package/dist/server/admin-bypass.js.map +1 -0
- package/dist/server/app.d.ts +9 -0
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/app.js +101 -1
- package/dist/server/app.js.map +1 -1
- package/dist/server/impersonation.d.ts +18 -0
- package/dist/server/impersonation.d.ts.map +1 -0
- package/dist/server/impersonation.js +53 -0
- package/dist/server/impersonation.js.map +1 -0
- package/dist/shared/escape.d.ts +3 -0
- package/dist/shared/escape.d.ts.map +1 -0
- package/dist/shared/escape.js +12 -0
- package/dist/shared/escape.js.map +1 -0
- package/dist/storage/local.d.ts +4 -0
- package/dist/storage/local.d.ts.map +1 -1
- package/dist/storage/local.js +5 -0
- package/dist/storage/local.js.map +1 -1
- package/dist/storage/resource.d.ts +5 -11
- package/dist/storage/resource.d.ts.map +1 -1
- package/dist/storage/resource.js +156 -194
- package/dist/storage/resource.js.map +1 -1
- package/dist/ui/admin-auth.d.ts +6 -0
- package/dist/ui/admin-auth.d.ts.map +1 -1
- package/dist/ui/admin-auth.js +59 -1
- package/dist/ui/admin-auth.js.map +1 -1
- package/dist/ui/data-explorer.d.ts.map +1 -1
- package/dist/ui/data-explorer.js +91 -4
- package/dist/ui/data-explorer.js.map +1 -1
- package/dist/ui/html/client/data-explorer-app.d.ts.map +1 -1
- package/dist/ui/html/client/data-explorer-app.js +20 -7
- package/dist/ui/html/client/data-explorer-app.js.map +1 -1
- package/dist/ui/html/client/runtime.d.ts.map +1 -1
- package/dist/ui/html/client/runtime.js +70 -2
- package/dist/ui/html/client/runtime.js.map +1 -1
- package/dist/ui/html/icons.d.ts.map +1 -1
- package/dist/ui/html/icons.js +2 -0
- package/dist/ui/html/icons.js.map +1 -1
- package/dist/ui/html/layout.d.ts +1 -0
- package/dist/ui/html/layout.d.ts.map +1 -1
- package/dist/ui/html/layout.js +274 -146
- package/dist/ui/html/layout.js.map +1 -1
- package/dist/ui/html/pages/filter-tester.d.ts.map +1 -1
- package/dist/ui/html/pages/filter-tester.js +15 -0
- package/dist/ui/html/pages/filter-tester.js.map +1 -1
- package/dist/ui/html/pages/users.d.ts.map +1 -1
- package/dist/ui/html/pages/users.js +8 -1
- package/dist/ui/html/pages/users.js.map +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/middleware.d.ts.map +1 -1
- package/dist/ui/middleware.js +121 -5
- package/dist/ui/middleware.js.map +1 -1
- package/dist/ui/schema-registry.d.ts +5 -0
- package/dist/ui/schema-registry.d.ts.map +1 -1
- package/dist/ui/schema-registry.js +14 -0
- package/dist/ui/schema-registry.js.map +1 -1
- 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** -
|
|
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
|
|
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 {
|
|
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
|
|
452
|
-
db
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
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"}
|
package/dist/cli/args.js
ADDED
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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":"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"}
|