@antelopejs/dms-database 0.2.0 → 0.2.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 +73 -49
- package/dist/db/models/diagram_layouts.model.d.ts +1 -0
- package/dist/db/models/diagram_notes.model.d.ts +1 -0
- package/dist/db/models/query_history.model.d.ts +1 -0
- package/dist/db/models/saved_queries.model.d.ts +1 -0
- package/dist/routes/data.d.ts +1 -3
- package/dist/routes/data.js +6 -1
- package/dist/routes/data.js.map +1 -1
- package/frontend-vue/app/build/data/stagedWrites.ts +46 -6
- package/frontend-vue/app/build/data/useStagedSave.ts +42 -12
- package/frontend-vue/app/components/DataGrid.vue +30 -2
- package/frontend-vue/package.json +3 -3
- package/frontend-vue/pnpm-lock.yaml +532 -243
- package/frontend-vue/tests/dataBrowser.test.ts +59 -1
- package/package.json +31 -14
- package/skills/dms-database/SKILL.md +35 -0
|
@@ -7,7 +7,12 @@ import {
|
|
|
7
7
|
tabInstanceOf,
|
|
8
8
|
} from '../app/build/composables/useDataBrowserTabs'
|
|
9
9
|
import { cellLabel, draftText, parseDraft } from '../app/build/data/cellValues'
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
changesOf,
|
|
12
|
+
mayMoveRows,
|
|
13
|
+
withWrittenRow,
|
|
14
|
+
writeRows,
|
|
15
|
+
} from '../app/build/data/stagedWrites'
|
|
11
16
|
import {
|
|
12
17
|
instanceFromUrl,
|
|
13
18
|
instanceToUrl,
|
|
@@ -148,6 +153,24 @@ describe('staged writes', () => {
|
|
|
148
153
|
expect(settled).toEqual(['a'])
|
|
149
154
|
})
|
|
150
155
|
|
|
156
|
+
it('hands each row written its answer, and a row gone none', async () => {
|
|
157
|
+
const settled: [string, unknown][] = []
|
|
158
|
+
await writeRows(
|
|
159
|
+
rows,
|
|
160
|
+
async (id, body) => {
|
|
161
|
+
if (id === 'b')
|
|
162
|
+
throw Object.assign(new Error('gone'), { statusCode: 404 })
|
|
163
|
+
return { _id: id, ...body, stored: true }
|
|
164
|
+
},
|
|
165
|
+
(id, answer) => settled.push([id, answer]),
|
|
166
|
+
)
|
|
167
|
+
expect(settled).toEqual([
|
|
168
|
+
['a', { _id: 'a', name: 'A', stored: true }],
|
|
169
|
+
['b', undefined],
|
|
170
|
+
['c', { _id: 'c', name: 'C', stored: true }],
|
|
171
|
+
])
|
|
172
|
+
})
|
|
173
|
+
|
|
151
174
|
it('picks the changes of the rows written', () => {
|
|
152
175
|
const changes = [
|
|
153
176
|
{ rowId: 'a', field: 'x' },
|
|
@@ -161,6 +184,41 @@ describe('staged writes', () => {
|
|
|
161
184
|
})
|
|
162
185
|
})
|
|
163
186
|
|
|
187
|
+
describe('rows written in place', () => {
|
|
188
|
+
const idOf = (row: Record<string, unknown>) =>
|
|
189
|
+
row._id === undefined ? null : String(row._id)
|
|
190
|
+
const page = [
|
|
191
|
+
{ _id: 1, name: 'Ada', _instance: 'eu' },
|
|
192
|
+
{ _id: 2, name: 'Bob', _instance: 'eu' },
|
|
193
|
+
]
|
|
194
|
+
|
|
195
|
+
it('shows the row the server answered in place of the one read', () => {
|
|
196
|
+
expect(
|
|
197
|
+
withWrittenRow(page, { _id: 2, name: 'Bea', updated: true }, idOf),
|
|
198
|
+
).toEqual([
|
|
199
|
+
{ _id: 1, name: 'Ada', _instance: 'eu' },
|
|
200
|
+
{ _id: 2, name: 'Bea', updated: true, _instance: 'eu' },
|
|
201
|
+
])
|
|
202
|
+
expect(withWrittenRow(page, { _id: 3, name: 'Cy' }, idOf)).toEqual(page)
|
|
203
|
+
expect(withWrittenRow(page, { name: 'no id' }, idOf)).toBe(page)
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
it('reads the page again only when a write may move rows in or out of it', () => {
|
|
207
|
+
const plain = { sortKey: null, search: '', filtered: [] }
|
|
208
|
+
expect(mayMoveRows(['name'], plain)).toBe(false)
|
|
209
|
+
expect(mayMoveRows(['name'], { ...plain, sortKey: 'total' })).toBe(false)
|
|
210
|
+
expect(mayMoveRows(['name'], { ...plain, sortKey: 'name' })).toBe(true)
|
|
211
|
+
expect(mayMoveRows(['name'], { ...plain, filtered: ['status'] })).toBe(
|
|
212
|
+
false,
|
|
213
|
+
)
|
|
214
|
+
expect(
|
|
215
|
+
mayMoveRows(['name', 'status'], { ...plain, filtered: ['status'] }),
|
|
216
|
+
).toBe(true)
|
|
217
|
+
expect(mayMoveRows(['name'], { ...plain, search: 'ad' })).toBe(true)
|
|
218
|
+
expect(mayMoveRows([], plain)).toBe(false)
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
|
|
164
222
|
describe('instance URL parameter', () => {
|
|
165
223
|
it('reads none as the default instance, all as every instance', () => {
|
|
166
224
|
expect(instanceFromUrl(undefined)).toEqual({ kind: 'default' })
|
package/package.json
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antelopejs/dms-database",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Database console for the AntelopeJS DMS: schemas, relation diagrams, a data browser and an AQL query console.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"admin",
|
|
7
|
+
"antelopejs",
|
|
8
|
+
"aql",
|
|
9
|
+
"database",
|
|
10
|
+
"dms",
|
|
11
|
+
"dms-module"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://dms.antelopejs.com/docs/modules/database",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/AntelopeJS/dms-database/issues"
|
|
16
|
+
},
|
|
4
17
|
"license": "Apache-2.0",
|
|
5
18
|
"repository": {
|
|
6
19
|
"type": "git",
|
|
@@ -10,7 +23,8 @@
|
|
|
10
23
|
"dist",
|
|
11
24
|
"!dist/test",
|
|
12
25
|
"!dist/.tsbuildinfo",
|
|
13
|
-
"frontend-vue"
|
|
26
|
+
"frontend-vue",
|
|
27
|
+
"skills"
|
|
14
28
|
],
|
|
15
29
|
"main": "dist/index.js",
|
|
16
30
|
"types": "dist/index.d.ts",
|
|
@@ -45,18 +59,18 @@
|
|
|
45
59
|
"test:frontend": "ajs dms verify-source --layer node_modules/@antelopejs/dms/frontend-vue --module frontend-vue"
|
|
46
60
|
},
|
|
47
61
|
"dependencies": {
|
|
48
|
-
"@antelopejs/interface-api": ">=0.0.
|
|
49
|
-
"@antelopejs/interface-api-util": ">=0.1.
|
|
50
|
-
"@antelopejs/interface-core": ">=0.
|
|
51
|
-
"@antelopejs/interface-database": ">=0.1.
|
|
52
|
-
"@antelopejs/interface-database-decorators": ">=0.1.
|
|
53
|
-
"@antelopejs/interface-dms": ">=0.7.
|
|
62
|
+
"@antelopejs/interface-api": ">=0.0.15 <1.0.0",
|
|
63
|
+
"@antelopejs/interface-api-util": ">=0.1.3 <1.0.0",
|
|
64
|
+
"@antelopejs/interface-core": ">=0.2.4 <1.0.0",
|
|
65
|
+
"@antelopejs/interface-database": ">=0.1.10 <1.0.0",
|
|
66
|
+
"@antelopejs/interface-database-decorators": ">=0.1.9 <1.0.0",
|
|
67
|
+
"@antelopejs/interface-dms": ">=0.7.2 <1.0.0"
|
|
54
68
|
},
|
|
55
69
|
"devDependencies": {
|
|
56
|
-
"@antelopejs/core": ">=1.
|
|
57
|
-
"@antelopejs/dms": ">=0.9.
|
|
58
|
-
"@antelopejs/dms-frontend": ">=0.6.
|
|
59
|
-
"@antelopejs/tooling-configs": ">=0.0.
|
|
70
|
+
"@antelopejs/core": ">=1.16.0 <2",
|
|
71
|
+
"@antelopejs/dms": ">=0.9.3 <1.0.0",
|
|
72
|
+
"@antelopejs/dms-frontend": ">=0.6.3 <0.7.0",
|
|
73
|
+
"@antelopejs/tooling-configs": ">=0.0.9 <1.0.0",
|
|
60
74
|
"@types/chai": "^5.2.3",
|
|
61
75
|
"@types/mocha": "^10.0.10",
|
|
62
76
|
"@types/node": "^24.0.0",
|
|
@@ -74,12 +88,15 @@
|
|
|
74
88
|
"typescript": "^6.0.3"
|
|
75
89
|
},
|
|
76
90
|
"optionalDependencies": {
|
|
77
|
-
"@antelopejs/interface-dms-automation": ">=0.
|
|
91
|
+
"@antelopejs/interface-dms-automation": ">=0.2.1 <1.0.0"
|
|
78
92
|
},
|
|
79
93
|
"packageManager": "pnpm@10.2.0",
|
|
80
94
|
"antelopeJs": {
|
|
81
95
|
"baseUrl": "dist",
|
|
82
96
|
"implements": [],
|
|
83
|
-
"test": "src/test/harness.ts"
|
|
97
|
+
"test": "src/test/harness.ts",
|
|
98
|
+
"skills": [
|
|
99
|
+
"./skills"
|
|
100
|
+
]
|
|
84
101
|
}
|
|
85
102
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dms-database
|
|
3
|
+
description: Uses the @antelopejs/dms-database console of the AntelopeJS DMS (owner-only pages under /modules/database to inspect schemas, draw diagrams, browse and edit rows, and run AQL). Use when installing or configuring dms-database (driverLabel, schemaLabels), deep-linking to its pages, wiring its "database.table-watch" automation trigger, or explaining why a table is missing from it.
|
|
4
|
+
icon: i-lucide-database
|
|
5
|
+
category: data
|
|
6
|
+
tags: [database, schemas, aql, data-browser, automation]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# dms-database
|
|
10
|
+
|
|
11
|
+
A read-mostly database console for the platform owner. It has no API for other modules: it introspects every schema registered through `@antelopejs/interface-database-decorators`, so a table appears once its module calls `RegisterSchema(<id>)` and declares `@RegisterTable(<table>, <id>)`. User docs: https://dms.antelopejs.com/docs/modules/database (source: `docs/` of this package).
|
|
12
|
+
|
|
13
|
+
## When to reach for it
|
|
14
|
+
|
|
15
|
+
- A user wants to look at, fix or query raw rows: point them to the console instead of writing a throwaway admin page.
|
|
16
|
+
- A procedure must react to row changes: use the `database.table-watch` trigger (`schema`, `table`, optional `eventTypes`), loaded only with `@antelopejs/dms-automation`.
|
|
17
|
+
- Never build a business screen on it: saved edits bypass every module's logic. Build a DMS page for that.
|
|
18
|
+
|
|
19
|
+
## Config (`antelope.config.ts`, all optional)
|
|
20
|
+
|
|
21
|
+
- Version 0.2+ needs `@antelopejs/dms` 0.9 (`interface-dms` 0.7) and `@antelopejs/dms-frontend` 0.6; 0.1 is the DMS 0.8 line.
|
|
22
|
+
|
|
23
|
+
- `driverLabel: "MongoDB 8.0"`: the database name on the Overview (the interface cannot discover it).
|
|
24
|
+
- `schemaLabels: { "<schemaId or glob*>": { label, color?: Tone } }`: badges; built-in patterns cover `app*`, `core*`, `global*`, `staging*`, `review*`, `prod*`.
|
|
25
|
+
|
|
26
|
+
## Deep links
|
|
27
|
+
|
|
28
|
+
`/modules/database/schemas?record=<schema>::<table>`, `/modules/database/{diagram,data,query}?schema=<schema>&table=<table>`, plus `instance=<name>` or `instance=all`.
|
|
29
|
+
|
|
30
|
+
## Gotchas
|
|
31
|
+
|
|
32
|
+
- Owner-only: pages and `/api/database/*` routes answer the platform owner alone.
|
|
33
|
+
- The data browser is read-only on **All instances**; a saved edit can be undone for 10 seconds only.
|
|
34
|
+
- Write queries in the console always run a dry run and need the table name typed to confirm.
|
|
35
|
+
- `table-watch` needs a change feed: MongoDB must run as a replica set.
|