@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.
@@ -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 { changesOf, writeRows } from '../app/build/data/stagedWrites'
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.0",
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.14 <1.0.0",
49
- "@antelopejs/interface-api-util": ">=0.1.2 <1.0.0",
50
- "@antelopejs/interface-core": ">=0.1.1 <1.0.0",
51
- "@antelopejs/interface-database": ">=0.1.8 <1.0.0",
52
- "@antelopejs/interface-database-decorators": ">=0.1.7 <1.0.0",
53
- "@antelopejs/interface-dms": ">=0.7.0 <1.0.0"
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.13.5 <2",
57
- "@antelopejs/dms": ">=0.9.0 <1.0.0",
58
- "@antelopejs/dms-frontend": ">=0.6.0 <0.7.0",
59
- "@antelopejs/tooling-configs": ">=0.0.7 <1.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.1.1 <1.0.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.