@noy-db/create 0.5.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.
- package/LICENSE +21 -0
- package/README.md +283 -0
- package/dist/bin/create.d.ts +1 -0
- package/dist/bin/create.js +724 -0
- package/dist/bin/create.js.map +1 -0
- package/dist/bin/noy-db.d.ts +1 -0
- package/dist/bin/noy-db.js +548 -0
- package/dist/bin/noy-db.js.map +1 -0
- package/dist/index.d.ts +665 -0
- package/dist/index.js +902 -0
- package/dist/index.js.map +1 -0
- package/package.json +70 -0
- package/templates/nuxt-default/README.md +38 -0
- package/templates/nuxt-default/_gitignore +32 -0
- package/templates/nuxt-default/app/app.vue +37 -0
- package/templates/nuxt-default/app/pages/index.vue +21 -0
- package/templates/nuxt-default/app/pages/invoices.vue +62 -0
- package/templates/nuxt-default/app/stores/invoices.ts +23 -0
- package/templates/nuxt-default/nuxt.config.ts +30 -0
- package/templates/nuxt-default/package.json +28 -0
- package/templates/nuxt-default/tsconfig.json +3 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 vLannaAi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# @noy-db/create
|
|
2
|
+
|
|
3
|
+
Wizard + CLI tool for [noy-db](https://github.com/vLannaAi/noy-db) — scaffold a fresh Nuxt 4 + Pinia encrypted store, augment an existing Nuxt project, or run operational commands (add user, rotate keys, backup) from the command line.
|
|
4
|
+
|
|
5
|
+
Two bins ship in this package:
|
|
6
|
+
|
|
7
|
+
- **`create`** — invoked by `npm create @noy-db`. Fresh-project wizard OR in-place augmenter for an existing Nuxt 4 project, depending on where you run it.
|
|
8
|
+
- **`noy-db`** — ongoing CLI tool. Invoked via `pnpm exec noy-db <cmd>` or `npx noy-db <cmd>` from inside a project. Five subcommands: `add`, `add user`, `verify`, `rotate`, `backup`.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## `create @noy-db` — the wizard
|
|
13
|
+
|
|
14
|
+
The wizard auto-detects whether your current directory is an existing Nuxt 4 project:
|
|
15
|
+
|
|
16
|
+
- If `nuxt.config.{ts,js,mjs}` **and** a `package.json` listing `nuxt` are both present, the wizard enters **augment mode** (patches the existing config in-place)
|
|
17
|
+
- Otherwise it enters **fresh mode** (creates a new subdirectory with a full Nuxt 4 starter)
|
|
18
|
+
|
|
19
|
+
### Fresh mode — new project
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# In an empty directory
|
|
23
|
+
npm create @noy-db my-app
|
|
24
|
+
pnpm create @noy-db my-app
|
|
25
|
+
yarn create @noy-db my-app
|
|
26
|
+
bun create @noy-db my-app
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The wizard asks at most 3 questions (project name, adapter, include sample data) and writes a complete Nuxt 4 + Pinia + `@noy-db/nuxt` starter into `./my-app/`. Nothing is installed automatically — pick your package manager and run it yourself.
|
|
30
|
+
|
|
31
|
+
Skip the prompts with `--yes`:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm create @noy-db my-app --yes
|
|
35
|
+
npm create @noy-db my-app --yes --adapter file --no-sample-data
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Augment mode — existing Nuxt 4 project
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# From inside an existing Nuxt 4 project root
|
|
42
|
+
cd ~/my-existing-app
|
|
43
|
+
npm create @noy-db
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The wizard will:
|
|
47
|
+
|
|
48
|
+
1. **Detect** the existing `nuxt.config.ts` via the detection rule above
|
|
49
|
+
2. **Prompt** for the adapter (`browser` / `file` / `memory`)
|
|
50
|
+
3. **Patch** the config in-memory via [magicast](https://github.com/unjs/magicast):
|
|
51
|
+
- Add `'@noy-db/nuxt'` to the `modules` array (creating the array if missing)
|
|
52
|
+
- Add `noydb: { adapter, pinia: true, devtools: true }` (only if not already present)
|
|
53
|
+
4. **Show** a colored unified diff of the proposed changes
|
|
54
|
+
5. **Ask** for confirmation (`y/n`) — your config is only written if you confirm
|
|
55
|
+
6. **Print** the `pnpm add …` command for the packages the patched config now depends on
|
|
56
|
+
|
|
57
|
+
#### Safe behaviors
|
|
58
|
+
|
|
59
|
+
- **Idempotent**: re-running on an already-augmented project is a no-op. You'll see `Nothing to do — already configured`.
|
|
60
|
+
- **Preserves custom config**: a pre-existing `noydb:` key in your config is left untouched. The wizard only fills in what's missing.
|
|
61
|
+
- **Preserves unrelated keys, comments, and formatting**: magicast walks a real Babel AST, not a regex.
|
|
62
|
+
- **Unsupported shapes are rejected cleanly**: if your config uses an opaque export (`export default someVar`) or a non-array `modules` field, the wizard bails with a clear error message telling you to edit manually.
|
|
63
|
+
|
|
64
|
+
#### Dry run
|
|
65
|
+
|
|
66
|
+
Preview the diff without writing anything:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm create @noy-db --dry-run
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Prints the unified diff and exits. Useful in CI, code review, and "what would this do to my config?" exploration.
|
|
73
|
+
|
|
74
|
+
#### Force fresh mode inside an existing project
|
|
75
|
+
|
|
76
|
+
If you're inside a Nuxt workspace but want to create a **new** sub-project rather than augment the root, pass `--force-fresh`:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
cd ~/my-monorepo-with-nuxt
|
|
80
|
+
npm create @noy-db my-sub-app --force-fresh
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### All flags
|
|
84
|
+
|
|
85
|
+
| Flag | Effect |
|
|
86
|
+
|---|---|
|
|
87
|
+
| `<project-name>` (positional) | Target directory name (fresh mode only) |
|
|
88
|
+
| `-y`, `--yes` | Skip every prompt; use defaults |
|
|
89
|
+
| `--adapter <name>` | Pre-select adapter: `browser` (default) / `file` / `memory` |
|
|
90
|
+
| `--no-sample-data` | (fresh mode) Skip the seed invoice records |
|
|
91
|
+
| `--dry-run` | (augment mode) Show the diff without writing |
|
|
92
|
+
| `--force-fresh` | Force fresh-project mode even in an existing Nuxt dir |
|
|
93
|
+
| `--lang <code>` | UI language: `en` (default) / `th`. Auto-detected from `LC_ALL` / `LANG` when omitted |
|
|
94
|
+
| `-h`, `--help` | Show usage and exit |
|
|
95
|
+
|
|
96
|
+
#### Languages
|
|
97
|
+
|
|
98
|
+
The wizard's prompts and notes are available in **English** (default) and **Thai** (`th`). Pick a language explicitly with `--lang`:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npm create @noy-db my-app --lang th
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
When `--lang` is omitted, the wizard reads the standard POSIX locale env vars (`LC_ALL`, `LC_MESSAGES`, `LANG`, `LANGUAGE`) and auto-selects Thai when they point to a Thai locale, e.g.:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
LANG=th_TH.UTF-8 npm create @noy-db my-app
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Validation errors and stack traces stay in English regardless of language so bug reports look the same in any locale.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## `noy-db` — the CLI tool
|
|
115
|
+
|
|
116
|
+
The `noy-db` bin ships inside the same `@noy-db/create` package. Install it as a dev dependency and it's available via `pnpm exec` / `npx`:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pnpm add -D @noy-db/create
|
|
120
|
+
pnpm exec noy-db <command>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Commands at a glance
|
|
124
|
+
|
|
125
|
+
| Command | Purpose |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `noy-db add <collection>` | Scaffold a new Pinia store + Vue page for a collection |
|
|
128
|
+
| `noy-db add user <id> <role>` | Grant a new user access to a compartment |
|
|
129
|
+
| `noy-db verify` | In-memory crypto round-trip integrity check |
|
|
130
|
+
| `noy-db rotate` | Rotate DEKs for one or more collections |
|
|
131
|
+
| `noy-db backup <target>` | Dump a compartment to an encrypted file |
|
|
132
|
+
|
|
133
|
+
All commands that touch real compartments use the **file adapter** and require these flags:
|
|
134
|
+
|
|
135
|
+
- `--dir <path>` — the data directory. Defaults to `./data`.
|
|
136
|
+
- `--compartment <name>` — the compartment (tenant) name. Required.
|
|
137
|
+
- `--user <id>` — your own user id in the compartment. Required.
|
|
138
|
+
|
|
139
|
+
You'll be prompted for your passphrase at runtime. Passphrases are never echoed, never logged, never written to disk, and cleared from process memory when the command exits.
|
|
140
|
+
|
|
141
|
+
### `noy-db add <collection>`
|
|
142
|
+
|
|
143
|
+
Scaffolds two new files in your project:
|
|
144
|
+
|
|
145
|
+
- `app/stores/<name>.ts` — a `defineNoydbStore<Name>()` call with a placeholder interface
|
|
146
|
+
- `app/pages/<name>.vue` — a minimal CRUD page that lists, adds, and deletes records
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
pnpm exec noy-db add clients
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Refuses to overwrite existing files — if either target already exists, the command exits non-zero without touching anything. There's no `--force` flag; delete the old files manually if you want to regenerate.
|
|
153
|
+
|
|
154
|
+
### `noy-db add user <userId> <role> [options]`
|
|
155
|
+
|
|
156
|
+
Grants a new user access to a compartment. Two passphrase prompts: yours (caller), then the new user's (with confirmation).
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
pnpm exec noy-db add user accountant-ann operator \
|
|
160
|
+
--dir ./data \
|
|
161
|
+
--compartment demo-co \
|
|
162
|
+
--user owner-alice \
|
|
163
|
+
--collections invoices:rw,clients:ro
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Roles:
|
|
167
|
+
|
|
168
|
+
| Role | Permissions | Requires `--collections`? |
|
|
169
|
+
|---|---|:---:|
|
|
170
|
+
| `owner` | All collections, all operations | No |
|
|
171
|
+
| `admin` | All collections, all operations (except grant owner) | No |
|
|
172
|
+
| `viewer` | All collections, read-only | No |
|
|
173
|
+
| `operator` | Per-collection `rw` or `ro` explicitly | **Yes** |
|
|
174
|
+
| `client` | Per-collection `ro` explicitly | **Yes** |
|
|
175
|
+
|
|
176
|
+
For `operator` and `client`, the `--collections` flag is required. Format: `name1:rw,name2:ro,name3:rw`.
|
|
177
|
+
|
|
178
|
+
### `noy-db verify`
|
|
179
|
+
|
|
180
|
+
Runs an end-to-end crypto round-trip against an in-memory adapter. No real data is touched; the command creates a throwaway compartment, writes a record, reads it back, and verifies it decrypts correctly. Useful as a sanity check that `@noy-db/core`, `@noy-db/memory`, and your local Node version all agree on Web Crypto.
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
pnpm exec noy-db verify
|
|
184
|
+
# ✔ noy-db integrity check passed (126ms)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Exits non-zero if anything diverges.
|
|
188
|
+
|
|
189
|
+
### `noy-db rotate [options]`
|
|
190
|
+
|
|
191
|
+
Rotate the DEKs for one or more collections in a compartment. Generates fresh keys, re-encrypts every record with the new keys, and re-wraps the new keys into every user's keyring. Nobody is revoked — everyone keeps their current permissions with fresh key material.
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# Rotate every collection in the compartment
|
|
195
|
+
pnpm exec noy-db rotate --dir ./data --compartment demo-co --user owner-alice
|
|
196
|
+
|
|
197
|
+
# Rotate specific collections only
|
|
198
|
+
pnpm exec noy-db rotate --dir ./data --compartment demo-co --user owner-alice \
|
|
199
|
+
--collections invoices,clients
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Use cases:
|
|
203
|
+
|
|
204
|
+
- **Suspected key leak**: an operator lost a laptop, a developer accidentally pasted a passphrase into a Slack channel, a USB stick went missing. Rotating is cheap insurance.
|
|
205
|
+
- **Scheduled rotation**: some compliance regimes require periodic key rotation regardless of exposure. This command makes rotation scriptable from cron or a CI job.
|
|
206
|
+
|
|
207
|
+
Different from `noydb.revoke({ rotateKeys: true })` in that it doesn't kick anyone out — it's the "just rotate" path.
|
|
208
|
+
|
|
209
|
+
### `noy-db backup <target> [options]`
|
|
210
|
+
|
|
211
|
+
Dump a compartment to a local file. The dump is a **verifiable backup**: it includes the chain head and the full `_ledger` / `_ledger_deltas` snapshots, so `compartment.load()` on the receiving side will reject any tampering between dump and restore.
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
pnpm exec noy-db backup ./backups/demo-2026-04-07.json \
|
|
215
|
+
--dir ./data --compartment demo-co --user owner-alice
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Target paths:
|
|
219
|
+
|
|
220
|
+
- **Plain filesystem path** — `./backups/demo.json` or `/absolute/path.json`
|
|
221
|
+
- **`file://` URI** — `file:///absolute/path.json` or `file://./relative.json`
|
|
222
|
+
|
|
223
|
+
Parent directories are created on demand, so `./backups/2026/04/demo.json` works even if `./backups/2026/04/` doesn't exist yet.
|
|
224
|
+
|
|
225
|
+
Unsupported schemes (`s3://`, `https://`, etc.) are rejected **before** the passphrase prompt so a typo doesn't waste a passphrase entry.
|
|
226
|
+
|
|
227
|
+
### `noy-db help`
|
|
228
|
+
|
|
229
|
+
Prints the full usage message for all subcommands.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Security invariants
|
|
234
|
+
|
|
235
|
+
Every command that touches real compartments follows these rules:
|
|
236
|
+
|
|
237
|
+
1. **Passphrase via `@clack/prompts` `password()`** — never echoes to the terminal, never logged.
|
|
238
|
+
2. **Passphrase never leaves the local closure** — no file writes, no error messages, no telemetry.
|
|
239
|
+
3. **Ctrl-C at the prompt aborts before any I/O happens** — cancelling doesn't leave the system in a half-mutated state.
|
|
240
|
+
4. **`finally { db.close() }`** — KEK is cleared from process memory on exit, success or failure.
|
|
241
|
+
5. **Unsupported backup schemes are rejected before the prompt** — a typo doesn't waste a passphrase entry.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## What's in the fresh-project template
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
my-app/
|
|
249
|
+
├── nuxt.config.ts ← @noy-db/nuxt wired up with your chosen adapter
|
|
250
|
+
├── package.json ← @noy-db/* deps at ^0.5.0
|
|
251
|
+
├── tsconfig.json
|
|
252
|
+
├── README.md
|
|
253
|
+
├── .gitignore
|
|
254
|
+
└── app/
|
|
255
|
+
├── app.vue
|
|
256
|
+
├── stores/
|
|
257
|
+
│ └── invoices.ts ← defineNoydbStore<Invoice>
|
|
258
|
+
└── pages/
|
|
259
|
+
├── index.vue
|
|
260
|
+
└── invoices.vue ← CRUD page with reactive query DSL
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Everything stored is encrypted with AES-256-GCM before it touches the adapter. The adapter only ever sees ciphertext.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Deferred to a future release
|
|
268
|
+
|
|
269
|
+
These are explicit non-goals:
|
|
270
|
+
|
|
271
|
+
- **Thai i18n** of the wizard prompts ([#36](https://github.com/vLannaAi/noy-db/issues/36))
|
|
272
|
+
- **Non-Nuxt templates** — no Vite/Vue standalone, no Electron, no vanilla ([#39](https://github.com/vLannaAi/noy-db/issues/39))
|
|
273
|
+
- **`noy-db seed`** — needs a design decision about how seed scripts authenticate
|
|
274
|
+
- **S3 backup targets** — would bundle `@aws-sdk` into this package and break the zero-runtime-deps story; lives in a companion package instead
|
|
275
|
+
- **`noy-db restore <file>`** — paired with the existing `compartment.load()` + integrity check; deferred so it can be designed alongside future identity/session work
|
|
276
|
+
|
|
277
|
+
Open an issue if you need one of these sooner.
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## License
|
|
282
|
+
|
|
283
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|