boltstore 0.5.1 → 0.6.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/README.md +65 -23
- package/dist/admin/api-keys.d.ts +87 -0
- package/dist/admin/api-keys.d.ts.map +1 -0
- package/dist/admin/api-keys.js +267 -0
- package/dist/admin/api-keys.js.map +1 -0
- package/dist/admin/backup.d.ts +76 -0
- package/dist/admin/backup.d.ts.map +1 -0
- package/dist/admin/backup.js +255 -0
- package/dist/admin/backup.js.map +1 -0
- package/dist/admin/import-export/csv.d.ts +4 -0
- package/dist/admin/import-export/csv.d.ts.map +1 -0
- package/dist/admin/import-export/csv.js +123 -0
- package/dist/admin/import-export/csv.js.map +1 -0
- package/dist/admin/import-export/export.d.ts +4 -0
- package/dist/admin/import-export/export.d.ts.map +1 -0
- package/dist/admin/import-export/export.js +66 -0
- package/dist/admin/import-export/export.js.map +1 -0
- package/dist/admin/import-export/import.d.ts +4 -0
- package/dist/admin/import-export/import.d.ts.map +1 -0
- package/dist/admin/import-export/import.js +253 -0
- package/dist/admin/import-export/import.js.map +1 -0
- package/dist/admin/import-export/index.d.ts +7 -0
- package/dist/admin/import-export/index.d.ts.map +1 -0
- package/dist/admin/import-export/index.js +7 -0
- package/dist/admin/import-export/index.js.map +1 -0
- package/dist/admin/import-export/json-input.d.ts +2 -0
- package/dist/admin/import-export/json-input.d.ts.map +1 -0
- package/dist/admin/import-export/json-input.js +42 -0
- package/dist/admin/import-export/json-input.js.map +1 -0
- package/dist/admin/import-export/schema-inference.d.ts +6 -0
- package/dist/admin/import-export/schema-inference.d.ts.map +1 -0
- package/dist/admin/import-export/schema-inference.js +34 -0
- package/dist/admin/import-export/schema-inference.js.map +1 -0
- package/dist/admin/import-export/types.d.ts +40 -0
- package/dist/admin/import-export/types.d.ts.map +1 -0
- package/dist/admin/import-export/types.js +2 -0
- package/dist/admin/import-export/types.js.map +1 -0
- package/dist/admin/oauth/github.d.ts +12 -0
- package/dist/admin/oauth/github.d.ts.map +1 -0
- package/dist/admin/oauth/github.js +78 -0
- package/dist/admin/oauth/github.js.map +1 -0
- package/dist/admin/oauth/google.d.ts +12 -0
- package/dist/admin/oauth/google.d.ts.map +1 -0
- package/dist/admin/oauth/google.js +55 -0
- package/dist/admin/oauth/google.js.map +1 -0
- package/dist/admin/oauth/handler.d.ts +5 -0
- package/dist/admin/oauth/handler.d.ts.map +1 -0
- package/dist/admin/oauth/handler.js +37 -0
- package/dist/admin/oauth/handler.js.map +1 -0
- package/dist/admin/oauth/index.d.ts +5 -0
- package/dist/admin/oauth/index.d.ts.map +1 -0
- package/dist/admin/oauth/index.js +5 -0
- package/dist/admin/oauth/index.js.map +1 -0
- package/dist/admin/oauth/registry.d.ts +16 -0
- package/dist/admin/oauth/registry.d.ts.map +1 -0
- package/dist/admin/oauth/registry.js +37 -0
- package/dist/admin/oauth/registry.js.map +1 -0
- package/dist/admin/oauth/types.d.ts +14 -0
- package/dist/admin/oauth/types.d.ts.map +1 -0
- package/dist/admin/oauth/types.js +2 -0
- package/dist/admin/oauth/types.js.map +1 -0
- package/dist/admin/oauth/user.d.ts +12 -0
- package/dist/admin/oauth/user.d.ts.map +1 -0
- package/dist/admin/oauth/user.js +28 -0
- package/dist/admin/oauth/user.js.map +1 -0
- package/dist/admin/query.d.ts +54 -0
- package/dist/admin/query.d.ts.map +1 -0
- package/dist/admin/query.js +168 -0
- package/dist/admin/query.js.map +1 -0
- package/dist/admin/transaction.d.ts +46 -0
- package/dist/admin/transaction.d.ts.map +1 -0
- package/dist/admin/transaction.js +52 -0
- package/dist/admin/transaction.js.map +1 -0
- package/dist/admin/views.d.ts +64 -0
- package/dist/admin/views.d.ts.map +1 -0
- package/dist/admin/views.js +197 -0
- package/dist/admin/views.js.map +1 -0
- package/dist/audit.d.ts +36 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +92 -0
- package/dist/audit.js.map +1 -0
- package/dist/auth/jwt.d.ts +8 -0
- package/dist/auth/jwt.d.ts.map +1 -0
- package/dist/auth/jwt.js +81 -0
- package/dist/auth/jwt.js.map +1 -0
- package/dist/auth/password.d.ts +4 -0
- package/dist/auth/password.d.ts.map +1 -0
- package/dist/auth/password.js +15 -0
- package/dist/auth/password.js.map +1 -0
- package/dist/auth/tables.d.ts +5 -0
- package/dist/auth/tables.d.ts.map +1 -0
- package/dist/auth/tables.js +65 -0
- package/dist/auth/tables.js.map +1 -0
- package/dist/auth/tokens.d.ts +16 -0
- package/dist/auth/tokens.d.ts.map +1 -0
- package/dist/auth/tokens.js +126 -0
- package/dist/auth/tokens.js.map +1 -0
- package/dist/auth/types.d.ts +36 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +2 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/auth/users.d.ts +9 -0
- package/dist/auth/users.d.ts.map +1 -0
- package/dist/auth/users.js +83 -0
- package/dist/auth/users.js.map +1 -0
- package/dist/auth/validation.d.ts +5 -0
- package/dist/auth/validation.d.ts.map +1 -0
- package/dist/auth/validation.js +25 -0
- package/dist/auth/validation.js.map +1 -0
- package/dist/auth.d.ts +9 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +9 -0
- package/dist/auth.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +322 -0
- package/dist/cli.js.map +1 -0
- package/dist/collections/ddl.d.ts +25 -0
- package/dist/collections/ddl.d.ts.map +1 -0
- package/dist/collections/ddl.js +83 -0
- package/dist/collections/ddl.js.map +1 -0
- package/dist/collections/management.d.ts +57 -0
- package/dist/collections/management.d.ts.map +1 -0
- package/dist/collections/management.js +289 -0
- package/dist/collections/management.js.map +1 -0
- package/dist/collections.d.ts +3 -0
- package/dist/collections.d.ts.map +1 -0
- package/dist/collections.js +3 -0
- package/dist/collections.js.map +1 -0
- package/dist/config.d.ts +47 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +274 -0
- package/dist/config.js.map +1 -0
- package/dist/db/cast.d.ts +15 -0
- package/dist/db/cast.d.ts.map +1 -0
- package/dist/db/cast.js +16 -0
- package/dist/db/cast.js.map +1 -0
- package/dist/db/manager.d.ts +93 -0
- package/dist/db/manager.d.ts.map +1 -0
- package/dist/db/manager.js +209 -0
- package/dist/db/manager.js.map +1 -0
- package/dist/db/pool.d.ts +99 -0
- package/dist/db/pool.d.ts.map +1 -0
- package/dist/db/pool.js +232 -0
- package/dist/db/pool.js.map +1 -0
- package/dist/entry.d.ts +11 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +80 -0
- package/dist/entry.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/indexes.d.ts +61 -0
- package/dist/indexes.d.ts.map +1 -0
- package/dist/indexes.js +174 -0
- package/dist/indexes.js.map +1 -0
- package/dist/logger.d.ts +40 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +147 -0
- package/dist/logger.js.map +1 -0
- package/dist/middleware/auth.d.ts +43 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +87 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/cors.d.ts +28 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/cors.js +71 -0
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/proxy.d.ts +10 -0
- package/dist/middleware/proxy.d.ts.map +1 -0
- package/dist/middleware/proxy.js +31 -0
- package/dist/middleware/proxy.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +64 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +130 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/migrations.d.ts +56 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +133 -0
- package/dist/migrations.js.map +1 -0
- package/dist/query/builder.d.ts +6 -0
- package/dist/query/builder.d.ts.map +1 -0
- package/dist/query/builder.js +97 -0
- package/dist/query/builder.js.map +1 -0
- package/dist/query/executor.d.ts +3 -0
- package/dist/query/executor.d.ts.map +1 -0
- package/dist/query/executor.js +64 -0
- package/dist/query/executor.js.map +1 -0
- package/dist/query/filter-builder.d.ts +8 -0
- package/dist/query/filter-builder.d.ts.map +1 -0
- package/dist/query/filter-builder.js +128 -0
- package/dist/query/filter-builder.js.map +1 -0
- package/dist/query/search.d.ts +4 -0
- package/dist/query/search.d.ts.map +1 -0
- package/dist/query/search.js +28 -0
- package/dist/query/search.js.map +1 -0
- package/dist/query/types.d.ts +45 -0
- package/dist/query/types.d.ts.map +1 -0
- package/dist/query/types.js +2 -0
- package/dist/query/types.js.map +1 -0
- package/dist/query.d.ts +6 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +6 -0
- package/dist/query.js.map +1 -0
- package/dist/records/batch.d.ts +13 -0
- package/dist/records/batch.d.ts.map +1 -0
- package/dist/records/batch.js +113 -0
- package/dist/records/batch.js.map +1 -0
- package/dist/records/count.d.ts +5 -0
- package/dist/records/count.d.ts.map +1 -0
- package/dist/records/count.js +34 -0
- package/dist/records/count.js.map +1 -0
- package/dist/records/crud.d.ts +8 -0
- package/dist/records/crud.d.ts.map +1 -0
- package/dist/records/crud.js +121 -0
- package/dist/records/crud.js.map +1 -0
- package/dist/records/distinct.d.ts +5 -0
- package/dist/records/distinct.d.ts.map +1 -0
- package/dist/records/distinct.js +22 -0
- package/dist/records/distinct.js.map +1 -0
- package/dist/records/helpers.d.ts +4 -0
- package/dist/records/helpers.d.ts.map +1 -0
- package/dist/records/helpers.js +9 -0
- package/dist/records/helpers.js.map +1 -0
- package/dist/records/list.d.ts +44 -0
- package/dist/records/list.d.ts.map +1 -0
- package/dist/records/list.js +133 -0
- package/dist/records/list.js.map +1 -0
- package/dist/records/schema-cache.d.ts +8 -0
- package/dist/records/schema-cache.d.ts.map +1 -0
- package/dist/records/schema-cache.js +64 -0
- package/dist/records/schema-cache.js.map +1 -0
- package/dist/records.d.ts +8 -0
- package/dist/records.d.ts.map +1 -0
- package/dist/records.js +8 -0
- package/dist/records.js.map +1 -0
- package/dist/relations.d.ts +50 -0
- package/dist/relations.d.ts.map +1 -0
- package/dist/relations.js +179 -0
- package/dist/relations.js.map +1 -0
- package/dist/rls.d.ts +63 -0
- package/dist/rls.d.ts.map +1 -0
- package/dist/rls.js +146 -0
- package/dist/rls.js.map +1 -0
- package/dist/router.d.ts +53 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +104 -0
- package/dist/router.js.map +1 -0
- package/dist/routes/admin-query.d.ts +5 -0
- package/dist/routes/admin-query.d.ts.map +1 -0
- package/dist/routes/admin-query.js +57 -0
- package/dist/routes/admin-query.js.map +1 -0
- package/dist/routes/api-keys.d.ts +12 -0
- package/dist/routes/api-keys.d.ts.map +1 -0
- package/dist/routes/api-keys.js +114 -0
- package/dist/routes/api-keys.js.map +1 -0
- package/dist/routes/auth.d.ts +10 -0
- package/dist/routes/auth.d.ts.map +1 -0
- package/dist/routes/auth.js +116 -0
- package/dist/routes/auth.js.map +1 -0
- package/dist/routes/backup.d.ts +5 -0
- package/dist/routes/backup.d.ts.map +1 -0
- package/dist/routes/backup.js +88 -0
- package/dist/routes/backup.js.map +1 -0
- package/dist/routes/collections.d.ts +5 -0
- package/dist/routes/collections.d.ts.map +1 -0
- package/dist/routes/collections.js +110 -0
- package/dist/routes/collections.js.map +1 -0
- package/dist/routes/databases.d.ts +5 -0
- package/dist/routes/databases.d.ts.map +1 -0
- package/dist/routes/databases.js +90 -0
- package/dist/routes/databases.js.map +1 -0
- package/dist/routes/health.d.ts +9 -0
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +34 -0
- package/dist/routes/health.js.map +1 -0
- package/dist/routes/import-export.d.ts +8 -0
- package/dist/routes/import-export.d.ts.map +1 -0
- package/dist/routes/import-export.js +173 -0
- package/dist/routes/import-export.js.map +1 -0
- package/dist/routes/indexes.d.ts +5 -0
- package/dist/routes/indexes.d.ts.map +1 -0
- package/dist/routes/indexes.js +94 -0
- package/dist/routes/indexes.js.map +1 -0
- package/dist/routes/migrations.d.ts +5 -0
- package/dist/routes/migrations.d.ts.map +1 -0
- package/dist/routes/migrations.js +87 -0
- package/dist/routes/migrations.js.map +1 -0
- package/dist/routes/oauth.d.ts +5 -0
- package/dist/routes/oauth.d.ts.map +1 -0
- package/dist/routes/oauth.js +35 -0
- package/dist/routes/oauth.js.map +1 -0
- package/dist/routes/query.d.ts +5 -0
- package/dist/routes/query.d.ts.map +1 -0
- package/dist/routes/query.js +36 -0
- package/dist/routes/query.js.map +1 -0
- package/dist/routes/records.d.ts +5 -0
- package/dist/routes/records.d.ts.map +1 -0
- package/dist/routes/records.js +181 -0
- package/dist/routes/records.js.map +1 -0
- package/dist/routes/transactions.d.ts +5 -0
- package/dist/routes/transactions.d.ts.map +1 -0
- package/dist/routes/transactions.js +43 -0
- package/dist/routes/transactions.js.map +1 -0
- package/dist/routes/views.d.ts +5 -0
- package/dist/routes/views.d.ts.map +1 -0
- package/dist/routes/views.js +123 -0
- package/dist/routes/views.js.map +1 -0
- package/dist/server.d.ts +80 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +271 -0
- package/dist/server.js.map +1 -0
- package/package.json +20 -40
- package/bin/cli.ts +0 -185
- package/src/admin/assets.ts +0 -134
- package/src/admin/serve.ts +0 -447
- package/src/admin-ui/App.vue +0 -71
- package/src/admin-ui/api/client.ts +0 -179
- package/src/admin-ui/components/Icon.vue +0 -85
- package/src/admin-ui/components/Sidebar.vue +0 -275
- package/src/admin-ui/components/StatCard.vue +0 -40
- package/src/admin-ui/dist/assets/ApiKeys.css +0 -1
- package/src/admin-ui/dist/assets/ApiKeys.js +0 -1
- package/src/admin-ui/dist/assets/AppDashboard.css +0 -1
- package/src/admin-ui/dist/assets/AppDashboard.js +0 -1
- package/src/admin-ui/dist/assets/Backups.js +0 -1
- package/src/admin-ui/dist/assets/Dashboard.css +0 -1
- package/src/admin-ui/dist/assets/Dashboard.js +0 -3
- package/src/admin-ui/dist/assets/DataBrowser.css +0 -1
- package/src/admin-ui/dist/assets/DataBrowser.js +0 -1
- package/src/admin-ui/dist/assets/Docs.css +0 -1
- package/src/admin-ui/dist/assets/Docs.js +0 -1
- package/src/admin-ui/dist/assets/FileBrowser.css +0 -1
- package/src/admin-ui/dist/assets/FileBrowser.js +0 -1
- package/src/admin-ui/dist/assets/HookEditor.css +0 -1
- package/src/admin-ui/dist/assets/HookEditor.js +0 -2
- package/src/admin-ui/dist/assets/LogViewer.css +0 -1
- package/src/admin-ui/dist/assets/LogViewer.js +0 -1
- package/src/admin-ui/dist/assets/Login.css +0 -1
- package/src/admin-ui/dist/assets/Login.js +0 -1
- package/src/admin-ui/dist/assets/SchemaBuilder.css +0 -1
- package/src/admin-ui/dist/assets/SchemaBuilder.js +0 -1
- package/src/admin-ui/dist/assets/Settings.js +0 -1
- package/src/admin-ui/dist/assets/Setup.css +0 -1
- package/src/admin-ui/dist/assets/Setup.js +0 -1
- package/src/admin-ui/dist/assets/StatCard.css +0 -1
- package/src/admin-ui/dist/assets/StatCard.js +0 -1
- package/src/admin-ui/dist/assets/main.css +0 -1
- package/src/admin-ui/dist/assets/main.js +0 -30
- package/src/admin-ui/dist/index.html +0 -49
- package/src/admin-ui/index.html +0 -48
- package/src/admin-ui/main.ts +0 -25
- package/src/admin-ui/pages/ApiKeys.vue +0 -198
- package/src/admin-ui/pages/AppDashboard.vue +0 -274
- package/src/admin-ui/pages/Applications.vue +0 -123
- package/src/admin-ui/pages/Backups.vue +0 -140
- package/src/admin-ui/pages/Dashboard.vue +0 -293
- package/src/admin-ui/pages/DataBrowser.vue +0 -310
- package/src/admin-ui/pages/Docs.vue +0 -40
- package/src/admin-ui/pages/FileBrowser.vue +0 -587
- package/src/admin-ui/pages/HookEditor.vue +0 -258
- package/src/admin-ui/pages/LogViewer.vue +0 -109
- package/src/admin-ui/pages/Login.vue +0 -229
- package/src/admin-ui/pages/SchemaBuilder.vue +0 -501
- package/src/admin-ui/pages/Settings.vue +0 -251
- package/src/admin-ui/pages/Setup.vue +0 -275
- package/src/admin-ui/router.ts +0 -169
- package/src/admin-ui/stores/application.ts +0 -68
- package/src/admin-ui/stores/auth.ts +0 -109
- package/src/admin-ui/style.css +0 -530
- package/src/admin-ui/tsconfig.json +0 -21
- package/src/admin-ui/version.ts +0 -3
- package/src/admin-ui/vite.config.ts +0 -35
- package/src/api/admin-config.ts +0 -596
- package/src/api/admin.ts +0 -8
- package/src/api/aggregate.ts +0 -104
- package/src/api/applications.ts +0 -148
- package/src/api/auth.ts +0 -690
- package/src/api/backups.ts +0 -173
- package/src/api/batch.ts +0 -135
- package/src/api/collections.ts +0 -354
- package/src/api/files.ts +0 -801
- package/src/api/health.ts +0 -48
- package/src/api/helpers.ts +0 -86
- package/src/api/middleware/auth.ts +0 -202
- package/src/api/middleware/cors.ts +0 -37
- package/src/api/middleware/logging.ts +0 -27
- package/src/api/middleware/ratelimit.ts +0 -142
- package/src/api/middleware/rls.ts +0 -37
- package/src/api/records.ts +0 -563
- package/src/api/router.ts +0 -296
- package/src/app.ts +0 -617
- package/src/auth/apikey.ts +0 -73
- package/src/auth/jwt.ts +0 -210
- package/src/auth/oauth2.ts +0 -144
- package/src/auth/password.ts +0 -68
- package/src/backup/manager.ts +0 -227
- package/src/config/yaml.ts +0 -78
- package/src/config.ts +0 -240
- package/src/db/application-migrations.ts +0 -112
- package/src/db/application-schema.ts +0 -297
- package/src/db/migrations.ts +0 -54
- package/src/db/pool.ts +0 -143
- package/src/db/system-schema.ts +0 -153
- package/src/hooks/api.ts +0 -157
- package/src/hooks/loader.ts +0 -263
- package/src/hooks/runner.ts +0 -76
- package/src/index.ts +0 -17
- package/src/logging/logger.ts +0 -131
- package/src/realtime/broadcast.ts +0 -132
- package/src/realtime/subscriptions.ts +0 -124
- package/src/security/rls-engine.ts +0 -183
- package/src/security/sanitizer.ts +0 -72
- package/src/storage/interface.ts +0 -48
- package/src/storage/local.ts +0 -189
- package/src/storage/mime-types.ts +0 -32
- package/src/storage/s3.ts +0 -213
- package/src/sync/changelog.ts +0 -247
- package/src/sync/engine.ts +0 -159
- package/src/sync/lamport.ts +0 -48
- package/src/sync/protocol.ts +0 -234
- package/src/version.ts +0 -2
package/src/config/yaml.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
// ── YAML Config Parser ──
|
|
2
|
-
// Minimal YAML parser for boltstore.yaml — no external dependency.
|
|
3
|
-
// Handles simple key-value pairs and nested objects.
|
|
4
|
-
|
|
5
|
-
import { readFileSync } from "node:fs";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Try to read and parse a YAML config file.
|
|
9
|
-
* Returns null if the file doesn't exist or can't be parsed.
|
|
10
|
-
*/
|
|
11
|
-
export function tryParseYaml(path: string): Record<string, unknown> | null {
|
|
12
|
-
try {
|
|
13
|
-
const content = readFileSync(path, "utf-8");
|
|
14
|
-
return parseSimpleYaml(content);
|
|
15
|
-
} catch {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Parse a simple YAML string into a nested object.
|
|
22
|
-
* Supports comments (#), string/number/boolean values, and indented sections.
|
|
23
|
-
*/
|
|
24
|
-
function parseSimpleYaml(content: string): Record<string, unknown> {
|
|
25
|
-
const result: Record<string, unknown> = {};
|
|
26
|
-
const lines = content.split("\n");
|
|
27
|
-
let currentSection: Record<string, unknown> = result;
|
|
28
|
-
const sectionStack: Array<{ obj: Record<string, unknown>; indent: number }> = [];
|
|
29
|
-
|
|
30
|
-
for (const line of lines) {
|
|
31
|
-
const trimmed = line.trimEnd();
|
|
32
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
33
|
-
|
|
34
|
-
const indent = line.length - line.trimStart().length;
|
|
35
|
-
const colonIdx = trimmed.indexOf(":");
|
|
36
|
-
|
|
37
|
-
// Section header (key: without value on same line)
|
|
38
|
-
if (colonIdx > 0 && colonIdx === trimmed.length - 1) {
|
|
39
|
-
const key = trimmed.slice(0, -1).trim();
|
|
40
|
-
while (sectionStack.length > 0 && sectionStack[sectionStack.length - 1]!.indent >= indent) {
|
|
41
|
-
sectionStack.pop();
|
|
42
|
-
}
|
|
43
|
-
currentSection = sectionStack.length > 0 ? sectionStack[sectionStack.length - 1]!.obj : result;
|
|
44
|
-
const newSection: Record<string, unknown> = {};
|
|
45
|
-
currentSection[key] = newSection;
|
|
46
|
-
sectionStack.push({ obj: newSection, indent });
|
|
47
|
-
currentSection = newSection;
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (colonIdx > 0) {
|
|
52
|
-
const key = trimmed.slice(0, colonIdx).trim();
|
|
53
|
-
let value: string = trimmed.slice(colonIdx + 1).trim();
|
|
54
|
-
|
|
55
|
-
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
56
|
-
(value.startsWith("'") && value.endsWith("'"))) {
|
|
57
|
-
value = value.slice(1, -1);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
while (sectionStack.length > 0 && sectionStack[sectionStack.length - 1]!.indent >= indent) {
|
|
61
|
-
sectionStack.pop();
|
|
62
|
-
}
|
|
63
|
-
currentSection = sectionStack.length > 0 ? sectionStack[sectionStack.length - 1]!.obj : result;
|
|
64
|
-
|
|
65
|
-
currentSection[key] = parseYamlValue(value);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return result;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function parseYamlValue(value: string): unknown {
|
|
73
|
-
if (value === "true") return true;
|
|
74
|
-
if (value === "false") return false;
|
|
75
|
-
if (/^-?\d+$/.test(value)) return parseInt(value, 10);
|
|
76
|
-
if (/^-?\d+\.\d+$/.test(value)) return parseFloat(value);
|
|
77
|
-
return value;
|
|
78
|
-
}
|
package/src/config.ts
DELETED
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
// ── Configuration ──
|
|
2
|
-
// Loads from boltstore.yaml, env vars, and CLI flags.
|
|
3
|
-
|
|
4
|
-
import { parseArgs } from "node:util";
|
|
5
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
6
|
-
import { join } from "node:path";
|
|
7
|
-
import type { StorageConfig } from "@boltstore/utils/storage-types";
|
|
8
|
-
import type { OAuth2Provider } from "@boltstore/utils/auth-types";
|
|
9
|
-
import { ServerDefaults } from "@boltstore/utils/constants";
|
|
10
|
-
|
|
11
|
-
export interface BoltstoreConfig {
|
|
12
|
-
/** Server hostname */
|
|
13
|
-
host: string;
|
|
14
|
-
/** Server port */
|
|
15
|
-
port: number;
|
|
16
|
-
/** Path to the data directory */
|
|
17
|
-
dataDir: string;
|
|
18
|
-
/** JWT secret for signing tokens */
|
|
19
|
-
jwtSecret: string;
|
|
20
|
-
/** Storage configuration */
|
|
21
|
-
storage: StorageConfig;
|
|
22
|
-
/** OAuth2 providers */
|
|
23
|
-
oauth2?: Partial<Record<OAuth2Provider, OAuth2ProviderConfig>>;
|
|
24
|
-
/** SMTP configuration */
|
|
25
|
-
smtp?: SmtpConfig;
|
|
26
|
-
/** Logging */
|
|
27
|
-
logLevel: "debug" | "info" | "warn" | "error";
|
|
28
|
-
/** Rate limiting */
|
|
29
|
-
rateLimit?: RateLimitConfig;
|
|
30
|
-
/** Backup schedule */
|
|
31
|
-
backup?: BackupConfig;
|
|
32
|
-
/** Admin UI enabled */
|
|
33
|
-
admin: boolean;
|
|
34
|
-
/** WebSocket configuration */
|
|
35
|
-
websocket?: WebsocketConfig;
|
|
36
|
-
/** CORS */
|
|
37
|
-
cors?: CorsConfig;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface OAuth2ProviderConfig {
|
|
41
|
-
clientId: string;
|
|
42
|
-
clientSecret: string;
|
|
43
|
-
redirectUri: string;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export interface SmtpConfig {
|
|
47
|
-
host: string;
|
|
48
|
-
port: number;
|
|
49
|
-
username?: string;
|
|
50
|
-
password?: string;
|
|
51
|
-
from: string;
|
|
52
|
-
fromName?: string;
|
|
53
|
-
tls?: boolean;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export interface RateLimitConfig {
|
|
57
|
-
enabled: boolean;
|
|
58
|
-
window: number;
|
|
59
|
-
max: number;
|
|
60
|
-
/** Rate limit per API key (separate from IP) */
|
|
61
|
-
perApiKey?: number;
|
|
62
|
-
/** List of trusted proxy IPs. When the direct connection IP is in this list, X-Forwarded-For is trusted. */
|
|
63
|
-
trustedProxies?: string[];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export interface BackupConfig {
|
|
67
|
-
/** Interval in hours for per-application SQLite snapshots */
|
|
68
|
-
snapshotIntervalHours: number;
|
|
69
|
-
/** Interval in days for full-instance backups */
|
|
70
|
-
fullBackupIntervalDays: number;
|
|
71
|
-
/** Upload backups to S3 */
|
|
72
|
-
uploadToS3: boolean;
|
|
73
|
-
/** Keep N most recent snapshots */
|
|
74
|
-
retentionCount: number;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export interface WebsocketConfig {
|
|
78
|
-
idleTimeout: number;
|
|
79
|
-
maxPayloadLength: number;
|
|
80
|
-
perMessageDeflate: boolean;
|
|
81
|
-
sendPings: boolean;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export interface CorsConfig {
|
|
85
|
-
allowedOrigins: string[];
|
|
86
|
-
allowedMethods: string[];
|
|
87
|
-
allowedHeaders: string[];
|
|
88
|
-
maxAge: number;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// ── Default Config ──
|
|
92
|
-
|
|
93
|
-
function generateJwtSecret(): string {
|
|
94
|
-
const bytes = crypto.getRandomValues(new Uint8Array(32));
|
|
95
|
-
let hex = "";
|
|
96
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
97
|
-
hex += bytes[i]!.toString(16).padStart(2, "0");
|
|
98
|
-
}
|
|
99
|
-
return hex;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function loadOrGenerateJwtSecret(dataDir: string): string {
|
|
103
|
-
const secretPath = join(dataDir, ".jwt-secret");
|
|
104
|
-
if (existsSync(secretPath)) {
|
|
105
|
-
return readFileSync(secretPath, "utf-8").trim();
|
|
106
|
-
}
|
|
107
|
-
const secret = generateJwtSecret();
|
|
108
|
-
mkdirSync(dataDir, { recursive: true });
|
|
109
|
-
writeFileSync(secretPath, secret, "utf-8");
|
|
110
|
-
return secret;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const DEFAULT_CONFIG: BoltstoreConfig = {
|
|
114
|
-
host: ServerDefaults.DEFAULT_HOST,
|
|
115
|
-
port: ServerDefaults.DEFAULT_PORT,
|
|
116
|
-
dataDir: "data",
|
|
117
|
-
jwtSecret: generateJwtSecret(),
|
|
118
|
-
storage: {
|
|
119
|
-
provider: "local",
|
|
120
|
-
localBasePath: "data/application",
|
|
121
|
-
},
|
|
122
|
-
logLevel: "info",
|
|
123
|
-
admin: true,
|
|
124
|
-
websocket: {
|
|
125
|
-
idleTimeout: ServerDefaults.WS_IDLE_TIMEOUT,
|
|
126
|
-
maxPayloadLength: 16 * 1024 * 1024,
|
|
127
|
-
perMessageDeflate: true,
|
|
128
|
-
sendPings: true,
|
|
129
|
-
},
|
|
130
|
-
rateLimit: {
|
|
131
|
-
enabled: true,
|
|
132
|
-
window: ServerDefaults.RATE_LIMIT_WINDOW,
|
|
133
|
-
max: ServerDefaults.RATE_LIMIT_MAX,
|
|
134
|
-
},
|
|
135
|
-
backup: {
|
|
136
|
-
snapshotIntervalHours: ServerDefaults.BACKUP_INTERVAL_HOURS,
|
|
137
|
-
fullBackupIntervalDays: ServerDefaults.FULL_BACKUP_INTERVAL_DAYS,
|
|
138
|
-
uploadToS3: false,
|
|
139
|
-
retentionCount: 48,
|
|
140
|
-
},
|
|
141
|
-
cors: {
|
|
142
|
-
allowedOrigins: ["*"],
|
|
143
|
-
allowedMethods: ["GET", "POST", "PATCH", "DELETE", "OPTIONS"],
|
|
144
|
-
allowedHeaders: ["Authorization", "Content-Type"],
|
|
145
|
-
maxAge: 86400,
|
|
146
|
-
},
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
// ── Config Loading ──
|
|
150
|
-
|
|
151
|
-
import { tryParseYaml } from "./config/yaml";
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Load configuration from YAML file, environment variables, and CLI flags.
|
|
155
|
-
* Precedence: CLI flags > env vars > YAML file > defaults
|
|
156
|
-
*
|
|
157
|
-
* JWT secret can be provided via the `BOLTSTORE_JWT_SECRET` environment variable.
|
|
158
|
-
* If not provided, a secret is persisted to `{dataDir}/.jwt-secret` across restarts.
|
|
159
|
-
*/
|
|
160
|
-
export function loadConfig(args?: string[]): BoltstoreConfig {
|
|
161
|
-
// 1. Start with defaults
|
|
162
|
-
const config = deepClone(DEFAULT_CONFIG);
|
|
163
|
-
|
|
164
|
-
// 2. Load YAML file
|
|
165
|
-
const yamlPath = process.env.BOLTSTORE_CONFIG ?? "boltstore.yaml";
|
|
166
|
-
const yamlConfig = tryParseYaml(yamlPath);
|
|
167
|
-
if (yamlConfig) {
|
|
168
|
-
mergeConfig(config, yamlConfig);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// 3. Apply environment variables
|
|
172
|
-
applyEnvOverrides(config);
|
|
173
|
-
|
|
174
|
-
// 4. Apply CLI flags
|
|
175
|
-
if (args) {
|
|
176
|
-
applyCliOverrides(config, args);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// 5. Persist or load JWT secret
|
|
180
|
-
if (!process.env.BOLTSTORE_JWT_SECRET) {
|
|
181
|
-
config.jwtSecret = loadOrGenerateJwtSecret(config.dataDir);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return config;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
function deepClone<T>(obj: T): T {
|
|
188
|
-
return JSON.parse(JSON.stringify(obj));
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
function mergeConfig(target: Record<string, unknown>, source: Record<string, unknown>): void {
|
|
192
|
-
for (const [key, value] of Object.entries(source)) {
|
|
193
|
-
if (value && typeof value === "object" && !Array.isArray(value) &&
|
|
194
|
-
target[key] && typeof target[key] === "object" && !Array.isArray(target[key])) {
|
|
195
|
-
mergeConfig(target[key] as Record<string, unknown>, value as Record<string, unknown>);
|
|
196
|
-
} else {
|
|
197
|
-
target[key] = value;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function applyEnvOverrides(config: Record<string, unknown>, prefix = "BOLTSTORE_"): void {
|
|
203
|
-
for (const [key, value] of Object.entries(process.env)) {
|
|
204
|
-
if (!key.startsWith(prefix) || !value) continue;
|
|
205
|
-
|
|
206
|
-
const configKey = key.slice(prefix.length).toLowerCase();
|
|
207
|
-
const parts = configKey.split("_");
|
|
208
|
-
|
|
209
|
-
let current = config;
|
|
210
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
211
|
-
const part = parts[i]!;
|
|
212
|
-
if (!current[part] || typeof current[part] !== "object") {
|
|
213
|
-
current[part] = {};
|
|
214
|
-
}
|
|
215
|
-
current = current[part] as Record<string, unknown>;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const lastPart = parts[parts.length - 1]!;
|
|
219
|
-
current[lastPart] = parseYamlValue(value);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
function applyCliOverrides(config: BoltstoreConfig, args: string[]): void {
|
|
224
|
-
const { values } = parseArgs({
|
|
225
|
-
args,
|
|
226
|
-
options: {
|
|
227
|
-
port: { type: "string" },
|
|
228
|
-
host: { type: "string" },
|
|
229
|
-
dataDir: { type: "string" },
|
|
230
|
-
config: { type: "string" },
|
|
231
|
-
logLevel: { type: "string" },
|
|
232
|
-
},
|
|
233
|
-
strict: false,
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
if (values.port) config.port = parseInt(values.port, 10);
|
|
237
|
-
if (values.host) config.host = values.host;
|
|
238
|
-
if (values.dataDir) config.dataDir = values.dataDir;
|
|
239
|
-
if (values.logLevel) config.logLevel = values.logLevel as BoltstoreConfig["logLevel"];
|
|
240
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
// ── Application Database Migrations ──
|
|
2
|
-
// Applied to every application database when it is first accessed.
|
|
3
|
-
// Ensures existing application DBs get new tables as the schema evolves.
|
|
4
|
-
|
|
5
|
-
import { defineMigration } from "./migrations";
|
|
6
|
-
|
|
7
|
-
export const applicationMigrations = [
|
|
8
|
-
defineMigration("001_create_collections_meta", `
|
|
9
|
-
CREATE TABLE IF NOT EXISTS _collections (
|
|
10
|
-
name TEXT PRIMARY KEY,
|
|
11
|
-
schema_json TEXT NOT NULL,
|
|
12
|
-
created TEXT NOT NULL DEFAULT (datetime('now')),
|
|
13
|
-
updated TEXT NOT NULL DEFAULT (datetime('now'))
|
|
14
|
-
);
|
|
15
|
-
`),
|
|
16
|
-
|
|
17
|
-
defineMigration("002_create_changes_log", `
|
|
18
|
-
CREATE TABLE IF NOT EXISTS _changes (
|
|
19
|
-
id TEXT PRIMARY KEY,
|
|
20
|
-
row_id TEXT NOT NULL,
|
|
21
|
-
collection TEXT NOT NULL,
|
|
22
|
-
field TEXT,
|
|
23
|
-
old_value TEXT,
|
|
24
|
-
new_value TEXT,
|
|
25
|
-
clock INTEGER NOT NULL,
|
|
26
|
-
client_id TEXT NOT NULL,
|
|
27
|
-
operation TEXT NOT NULL CHECK(operation IN ('insert', 'update', 'delete')),
|
|
28
|
-
timestamp TEXT NOT NULL DEFAULT (datetime('now'))
|
|
29
|
-
);
|
|
30
|
-
CREATE INDEX IF NOT EXISTS idx_changes_clock ON _changes(clock);
|
|
31
|
-
CREATE INDEX IF NOT EXISTS idx_changes_row ON _changes(row_id, collection);
|
|
32
|
-
CREATE INDEX IF NOT EXISTS idx_changes_collection_clock ON _changes(collection, clock);
|
|
33
|
-
`),
|
|
34
|
-
|
|
35
|
-
defineMigration("003_create_users", `
|
|
36
|
-
CREATE TABLE IF NOT EXISTS _users (
|
|
37
|
-
id TEXT PRIMARY KEY,
|
|
38
|
-
email TEXT NOT NULL UNIQUE,
|
|
39
|
-
password_hash TEXT NOT NULL,
|
|
40
|
-
name TEXT,
|
|
41
|
-
role TEXT NOT NULL DEFAULT 'user',
|
|
42
|
-
avatar TEXT,
|
|
43
|
-
email_verified INTEGER NOT NULL DEFAULT 0,
|
|
44
|
-
created TEXT NOT NULL DEFAULT (datetime('now')),
|
|
45
|
-
updated TEXT NOT NULL DEFAULT (datetime('now'))
|
|
46
|
-
);
|
|
47
|
-
CREATE INDEX IF NOT EXISTS idx_users_email ON _users(email);
|
|
48
|
-
`),
|
|
49
|
-
|
|
50
|
-
defineMigration("004_create_user_refresh_tokens", `
|
|
51
|
-
CREATE TABLE IF NOT EXISTS _user_refresh_tokens (
|
|
52
|
-
id TEXT PRIMARY KEY,
|
|
53
|
-
user_id TEXT NOT NULL,
|
|
54
|
-
token_hash TEXT NOT NULL,
|
|
55
|
-
family TEXT NOT NULL,
|
|
56
|
-
rotation_count INTEGER NOT NULL DEFAULT 0,
|
|
57
|
-
expires_at TEXT NOT NULL,
|
|
58
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
59
|
-
FOREIGN KEY (user_id) REFERENCES _users(id) ON DELETE CASCADE
|
|
60
|
-
);
|
|
61
|
-
CREATE INDEX IF NOT EXISTS idx_user_refresh_hash ON _user_refresh_tokens(token_hash);
|
|
62
|
-
CREATE INDEX IF NOT EXISTS idx_user_refresh_user ON _user_refresh_tokens(user_id);
|
|
63
|
-
`),
|
|
64
|
-
|
|
65
|
-
defineMigration("005_create_user_email_verifications", `
|
|
66
|
-
CREATE TABLE IF NOT EXISTS _user_email_verifications (
|
|
67
|
-
id TEXT PRIMARY KEY,
|
|
68
|
-
user_id TEXT NOT NULL,
|
|
69
|
-
token TEXT NOT NULL,
|
|
70
|
-
expires_at TEXT NOT NULL,
|
|
71
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
72
|
-
FOREIGN KEY (user_id) REFERENCES _users(id) ON DELETE CASCADE
|
|
73
|
-
);
|
|
74
|
-
CREATE INDEX IF NOT EXISTS idx_user_email_verif_token ON _user_email_verifications(token);
|
|
75
|
-
`),
|
|
76
|
-
|
|
77
|
-
defineMigration("006_create_user_password_resets", `
|
|
78
|
-
CREATE TABLE IF NOT EXISTS _user_password_resets (
|
|
79
|
-
id TEXT PRIMARY KEY,
|
|
80
|
-
user_id TEXT NOT NULL,
|
|
81
|
-
token TEXT NOT NULL,
|
|
82
|
-
expires_at TEXT NOT NULL,
|
|
83
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
84
|
-
used INTEGER NOT NULL DEFAULT 0,
|
|
85
|
-
FOREIGN KEY (user_id) REFERENCES _users(id) ON DELETE CASCADE
|
|
86
|
-
);
|
|
87
|
-
CREATE INDEX IF NOT EXISTS idx_user_password_reset_token ON _user_password_resets(token);
|
|
88
|
-
`),
|
|
89
|
-
|
|
90
|
-
defineMigration("007_create_folders_and_files", `
|
|
91
|
-
CREATE TABLE IF NOT EXISTS _folders (
|
|
92
|
-
path TEXT PRIMARY KEY,
|
|
93
|
-
visibility TEXT NOT NULL DEFAULT 'private',
|
|
94
|
-
max_size INTEGER,
|
|
95
|
-
mime_types TEXT,
|
|
96
|
-
created TEXT NOT NULL DEFAULT (datetime('now')),
|
|
97
|
-
updated TEXT NOT NULL DEFAULT (datetime('now'))
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
CREATE TABLE IF NOT EXISTS _files (
|
|
101
|
-
key TEXT PRIMARY KEY,
|
|
102
|
-
filename TEXT NOT NULL,
|
|
103
|
-
size INTEGER NOT NULL,
|
|
104
|
-
mime_type TEXT,
|
|
105
|
-
folder TEXT,
|
|
106
|
-
visibility TEXT NOT NULL DEFAULT 'inherit',
|
|
107
|
-
uploaded_by TEXT,
|
|
108
|
-
uploaded_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
109
|
-
);
|
|
110
|
-
CREATE INDEX IF NOT EXISTS idx_files_folder ON _files(folder);
|
|
111
|
-
`),
|
|
112
|
-
];
|