pgkiln 0.46.0 → 0.48.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/db/migrations/108_sql_history.sql +25 -0
- package/db/migrations/109_builder_pins.sql +19 -0
- package/db/migrations/110_sql_charts.sql +23 -0
- package/db/migrations/111_sql_diagram.sql +24 -0
- package/db/migrations/113_rest_objects.sql +49 -0
- package/docs/apex-feature-parity.md +28 -2
- package/docs/guide/03-builder.md +178 -21
- package/docs/guide/08-security.md +19 -1
- package/docs/guide/10-tutorial.md +1 -1
- package/docs/guide/12-development.md +46 -2
- package/docs/guide/13-rest-api.md +74 -9
- package/docs/guide/16-files.md +2 -2
- package/package.json +1 -1
- package/public/builder.css +22 -0
- package/public/data-modeler.css +56 -0
- package/public/data-modeler.js +367 -0
- package/public/palette.js +133 -0
- package/public/worksheet.css +293 -0
- package/public/worksheet.js +669 -0
- package/src/app.ts +4 -0
- package/src/builder/ai-builder.ts +3 -3
- package/src/builder/autorest.ts +362 -0
- package/src/builder/data-modeler.ts +382 -0
- package/src/builder/db-users.ts +472 -0
- package/src/builder/launchpad.ts +140 -0
- package/src/builder/object-actions.ts +167 -0
- package/src/builder/object-browser.ts +47 -26
- package/src/builder/querybuilder.ts +1 -1
- package/src/builder/sampledata.ts +2 -2
- package/src/builder/scripts.ts +3 -3
- package/src/builder/sql-charts.ts +203 -0
- package/src/builder/sql-tools.ts +49 -0
- package/src/builder/sql.ts +28 -81
- package/src/builder/table-editor.ts +219 -0
- package/src/builder/ui.ts +21 -15
- package/src/builder/unload.ts +8 -4
- package/src/builder/worksheet.ts +592 -0
- package/src/builder/workspaces.ts +5 -3
- package/src/cli/replace.ts +3 -1
- package/src/datamodel.ts +324 -0
- package/src/dbroles.ts +215 -0
- package/src/runtime/autorest.ts +336 -0
- package/src/runtime/rest.ts +4 -4
- package/src/session.ts +2 -0
- package/src/sqlformat.ts +208 -0
- package/src/sqlplan.ts +133 -0
- package/src/sqlscript.ts +6 -2
- package/src/sqlworksheet.ts +278 -0
- package/src/tabledef.ts +226 -0
- package/src/unload.ts +14 -3
|
@@ -66,7 +66,13 @@ src/
|
|
|
66
66
|
sampledata-words.ts built-in name, city, company and word lists of Sample Data
|
|
67
67
|
unload.ts Unload Data: unloadStatement() (one SELECT), openUnload() (cursor, batches, CSV/JSON/XLSX/XML encoders on Postgres text values)
|
|
68
68
|
xml.ts safe XML reader (no DTDs or entities, limits) and xmlTable(): rows from a repeating element (unit tested)
|
|
69
|
-
sqlscript.ts SQL scripts: splitScript() (statements, line numbers, psql commands), runScript() (stop/continue, transaction, savepoints)
|
|
69
|
+
sqlscript.ts SQL scripts: splitScript() (statements, line numbers and offsets, psql commands), runScript() (stop/continue, transaction, savepoints)
|
|
70
|
+
sqlworksheet.ts (sprint 91) the worksheet's runs: pickStatements() (at the cursor, a selection, all), runStatements() (a log per
|
|
71
|
+
statement, psql command tags, notices, error line and column), explainStatement() (EXPLAIN / rolled-back ANALYZE)
|
|
72
|
+
datamodel.ts (sprint 98) Data Modeler diagrams: readModel() (catalog), boxSize(), fkPath() (crow's feet), autoLayout(), diagramSvg()
|
|
73
|
+
tabledef.ts (sprint 95) a table as a definition: readTable(), checkTable(), tableSql() (CREATE, or ALTER from the catalog's version)
|
|
74
|
+
sqlformat.ts (sprint 93) formatSql(): the worksheet's Format (clauses per line, keyword case; strings and comments kept)
|
|
75
|
+
sqlplan.ts (sprint 92) EXPLAIN (FORMAT JSON) as a tree: parsePlan() (self time, slowest step, misestimates), planText()
|
|
70
76
|
quicksql.ts Quick SQL: shorthand parser and PostgreSQL DDL generator (unit tested)
|
|
71
77
|
xlsx.ts Excel writer for report downloads and Unload Data (typed cells, streamed through fflate's Zip)
|
|
72
78
|
automations.ts cron parser, next run in a time zone, scheduler (also meta.task_expire_tick, 094), running automations (the actions run
|
|
@@ -81,6 +87,9 @@ src/
|
|
|
81
87
|
mvt.ts Mapbox Vector Tile encoding for map layers served as tiles
|
|
82
88
|
yamltext.ts the text style of the directory export: a strict YAML subset, written and read
|
|
83
89
|
webclient.ts outgoing HTTP to web services: allow-list, address checks at connect time (SSRF), redirects, limits
|
|
90
|
+
dbroles.ts (sprint 99, DA-13) Database Users' SQL: roleSql (CREATE/ALTER ROLE, memberships, search path, schema
|
|
91
|
+
and default privileges: only what differs from the catalog), dropSql, checkRole/checkPassword,
|
|
92
|
+
scramVerifier (SCRAM-SHA-256, SASLprep) and the password slot (maskSql for review and log, withVerifier to run)
|
|
84
93
|
secrets.ts secrets at rest (web credentials): AES-256-GCM with PGKILN_SECRET_KEY
|
|
85
94
|
websources.ts web credentials (OAuth2 client credentials/password/refresh token grants, token cache, stored refresh
|
|
86
95
|
tokens) and REST data sources: requests, JSON paths, typed rows, response cache, write-back operations
|
|
@@ -144,6 +153,9 @@ src/
|
|
|
144
153
|
spatial.ts spatial filtering on the server: map area and distance parsing, PostGIS detection and SQL (ST_Intersects, ST_DWithin), lat/lng fallback (bounding box, haversine)
|
|
145
154
|
pwa.ts Progressive Web App: manifest, service worker route, icons (PNG encoder), offline page
|
|
146
155
|
rest.ts REST modules: handler checks, matching, bearer tokens, execution (collections stream from a cursor), OpenAPI
|
|
156
|
+
autorest.ts (sprint 100, migration 113) AutoREST: /a/:alias/autorest/<object>/ for the tables and views SQL Workshop →
|
|
157
|
+
RESTful Services published (meta.rest_object): caller() of rest.ts, SET ROLE to the app role, owner/BYPASSRLS
|
|
158
|
+
check, columns from the catalog (column grants), filters/q/order/paging, POST/PUT/DELETE by primary key, OpenAPI
|
|
147
159
|
rest-sources.ts REST data sources in apps: regions and LOVs as SQL over "rest", the invoke_api process (items; the call is websources.ts invoke()),
|
|
148
160
|
write-back of forms (fetch, form_dml) and grids (grid_dml) through the source's operations
|
|
149
161
|
tree.ts tree region
|
|
@@ -215,12 +227,28 @@ src/
|
|
|
215
227
|
(sprint 86) GET /builder/apps/:app/pages/:no, /builder/pages/:id redirects browsers there (designerUrl in ui.ts)
|
|
216
228
|
errors.ts (sprint 86) the builder's HTML 404 and 500 pages for browsers (wantsHtml, a not-found handler and an onSend hook)
|
|
217
229
|
arrange.ts page designer layout changes: move, column span, create from the gallery, undo / redo
|
|
218
|
-
sql.ts SQL Workshop: the home and
|
|
230
|
+
sql.ts SQL Workshop: the home and the session's schema
|
|
231
|
+
launchpad.ts (sprint 96) the SQL Workshop home's Launchpad (pins in meta.builder_pin, 109; tool groups), POST /builder/pins,
|
|
232
|
+
GET /builder/palette (the builder's search: JSON for Ctrl+K, a results page without JavaScript)
|
|
233
|
+
sql-charts.ts (sprint 97) charts of a query: chartSpec(), drawChart() (runtime/charts.ts, a PageCss in a nonce'd <style>), the
|
|
234
|
+
worksheet's Chart tab, SQL Workshop → Charts (meta.sql_chart, 110; read-only runs)
|
|
235
|
+
sql-tools.ts (sprint 96) SQL_TOOLS: every SQL Workshop tool with its group, tab and description (home, More menu, search)
|
|
236
|
+
worksheet.ts (sprint 91) the SQL Worksheet (Database Actions' SQL; /sql/commands too): navigator (pickSchema, objects with
|
|
237
|
+
columns, objectStatements), toolbar, output tabs, history (meta.sql_history, 108), plan trees, Run as an app's role, (sprint 93) Save / Rename / Download as SQL Scripts, bind and substitution values, POST /sql/worksheet/format; GET /sql/worksheet/navigator
|
|
219
238
|
object-browser.ts (sprint 75) the Object Browser: objects by type, system objects hidden, a table in tabs, column actions as SQL to review
|
|
239
|
+
table-editor.ts (sprint 95) Table Properties: GET/POST /sql/objects/table (create, edit ?o=, ?template=), fromForm(), Preview / Apply
|
|
240
|
+
(one transaction) / Open in the worksheet
|
|
241
|
+
object-actions.ts (sprint 94) an object's ⋯ menu (objectMenu) in the worksheet and the Object Browser: Quick DDL (objectDdl), Drop with
|
|
242
|
+
dependents, Add index / trigger / policy as drafts; GET /sql/objects/action, /sql/objects/panel (Open in a panel)
|
|
243
|
+
data-modeler.ts (sprint 98) SQL Workshop → Data Modeler: /sql/modeler (diagrams, meta.sql_diagram, 111), /:id (SVG), /:id/objects, /layout,
|
|
244
|
+
/rename, /delete, /svg (export), /ddl (diagramDdl), /dictionary (data dictionary, ?download=1)
|
|
220
245
|
scripts.ts SQL Workshop → SQL Scripts: editor, upload/download, run, results per statement, run history
|
|
221
246
|
quicksql.ts SQL Workshop → Quick SQL page (preview, save as script, run)
|
|
222
247
|
querybuilder.ts SQL Workshop → Query Builder: catalog, joins by foreign key or drawn, functions/group by, buildQuery() from the URL; the canvas is in builder.js
|
|
223
248
|
users.ts user directory and identity providers
|
|
249
|
+
db-users.ts (sprint 99, DA-13) Administration → Database Users (/builder/db-users, administrators only): PostgreSQL
|
|
250
|
+
roles with highlights, create/edit (review the masked SQL, then Apply in one transaction), drop with
|
|
251
|
+
reassigning; pgkiln's own roles read-only, roles of applications and workspaces not dropped
|
|
224
252
|
api.ts per-app REST API page (API role, tokens)
|
|
225
253
|
globalization.ts translations, XLIFF/CSV, text messages
|
|
226
254
|
dataload.ts SQL Workshop → Load Data (with definitions, save a mapping as one); data load definition spec (Shared Components)
|
|
@@ -248,6 +276,9 @@ src/
|
|
|
248
276
|
form-designer.ts page designer: Form Designer settings (designers' scheme; sources: key, actions, offered columns, labels, lists of values)
|
|
249
277
|
workingcopies.ts Working copies: list and create, compare with differences, merge or refresh with conflict choices, delete
|
|
250
278
|
rest.ts REST module endpoints list and curl example (Shared Components)
|
|
279
|
+
autorest.ts (sprint 100) SQL Workshop → RESTful Services (/builder/sql/rest): publish a table or view through an
|
|
280
|
+
application of the workspace (checks: schema the workshop may use, app role not the owner), its page
|
|
281
|
+
(grants per method, RLS, security_invoker, endpoints, cURL/fetch, OpenAPI link), settings, disable
|
|
251
282
|
workflows.ts workflow versions, diagram and instances (Shared Components)
|
|
252
283
|
process-jobs.ts page designer: the Jobs tab of a background chain process
|
|
253
284
|
template-spec.ts template component property form (Shared Components)
|
|
@@ -279,6 +310,10 @@ public/
|
|
|
279
310
|
app.css theme (light/dark, responsive; --font, --font-size, --radius for style variants; template option classes to-*)
|
|
280
311
|
app.js client runtime: dialogs (dialog_closed actions), popup LOVs, dynamic actions (focus, classes, messages), grids (add/duplicate rows, master-detail refresh, move/resize columns, copy/paste of cell ranges), menus, lazy regions, maps (Leaflet layers, marker clusters, heat layer, layer legend, area/distance filter) (no inline JS)
|
|
281
312
|
code-editor.js, .css builder code editor: enhances <textarea data-code>, highlighting, suggestions (no dependencies)
|
|
313
|
+
palette.js (sprint 96) the builder's search dialog (Ctrl+K), recently visited SQL Workshop pages, the Launchpad's tabs
|
|
314
|
+
data-modeler.js, .css (sprint 98) the Data Modeler: drag boxes, undo/redo, save, zoom/fit, auto layout, mini-map, SVG/PNG export, print
|
|
315
|
+
worksheet.js, .css (sprint 91) the SQL Worksheet: run keys with the cursor, output tabs, navigator swap and search, drag and drop, splitters;
|
|
316
|
+
(92) grid sort, value dialog, history filter; (93) worksheet tabs in localStorage, Files, binds dialog, format, find, case
|
|
282
317
|
builder.css builder only: IDE look (dark chrome, icon rail, panes), builder light/dark tokens
|
|
283
318
|
builder.js builder only: tabs, component tree, property filter, drag and drop on the layout
|
|
284
319
|
builder-icons.svg builder only: icons of the rail, toolbar and designer (b-*)
|
|
@@ -298,6 +333,13 @@ test/
|
|
|
298
333
|
unload.test.ts Unload Data: CSV/JSON/XLSX/XML output, read back with Load Data, read-only and one-statement checks, streaming
|
|
299
334
|
app-from-file.test.ts Create → From a file: proposed names and types, app + table + rows + pages, row errors, login, validation
|
|
300
335
|
workshop.test.ts SQL scripts, Quick SQL pages, query builder, data load definitions (Load Data, the process, export)
|
|
336
|
+
sql-charts.test.ts (sprint 97) the worksheet's Chart tab, saving a chart, the Charts dashboard, a chart's page, read-only runs
|
|
337
|
+
launchpad.test.ts (sprint 96) Launchpad groups, pins (builder pages only, at most 24), the search (JSON and page)
|
|
338
|
+
tabledef.test.ts (sprint 95) table definitions round trip: CREATE, read, ALTER, read again; mistakes
|
|
339
|
+
table-editor.test.ts (sprint 95) the Table Properties page: preview, apply, a failing apply rolls back, template, worksheet
|
|
340
|
+
object-actions.test.ts (sprint 94) object menus: Quick DDL, Drop with dependents, Add index / trigger / policy, the panel, not-found
|
|
341
|
+
data-modeler.test.ts (sprint 98) Data Modeler: "hr core" with its FK lines, saved positions, SVG, objects, DDL, dictionary, geometry
|
|
342
|
+
worksheet.test.ts (sprint 91) the SQL Worksheet: statement at the cursor, Run Script log, plans, notices, history, navigator, Run as
|
|
301
343
|
quicksql.test.ts Quick SQL parser and DDL generator
|
|
302
344
|
xml.test.ts XML reader: rows, attributes, paths, refused DTDs and entities, limits
|
|
303
345
|
printing.test.ts report PDFs
|
|
@@ -343,6 +385,8 @@ test/
|
|
|
343
385
|
helpers.ts a cookie-keeping test browser
|
|
344
386
|
e2e/responsive.test.ts browser tests at phone/tablet/desktop widths (Playwright)
|
|
345
387
|
e2e/code-editor.test.ts the code editor in a browser: highlighting, keys, suggestions, touch, screen readers
|
|
388
|
+
e2e/data-modeler.test.ts (sprint 98) the Data Modeler in a browser: drag, save, reload, undo/redo, zoom, mini-map, exports, phone
|
|
389
|
+
e2e/worksheet.test.ts (sprint 91) the SQL Worksheet in a browser: run keys, tabs, navigator, drag and drop, splitters, phone, no JavaScript
|
|
346
390
|
e2e/items.test.ts sprint 26 item types in a browser: editors, tags, stars, dates, reveal; without JavaScript
|
|
347
391
|
e2e/designer.test.ts page designer: panes per width, drag and drop, keyboard, Arrange buttons, builder theme
|
|
348
392
|
e2e/calendar.test.ts calendar drag and drop and create on click, view switching, chart drill-down
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# 13. REST APIs
|
|
2
2
|
|
|
3
|
-
pgkiln offers
|
|
3
|
+
pgkiln offers three ways to expose data securely over REST (mobile apps, integrations, scripts),
|
|
4
4
|
which can be combined:
|
|
5
5
|
|
|
6
|
-
| | [REST modules](#rest-modules-in-the-builder) | [PostgREST](#how-it-works) |
|
|
7
|
-
|
|
8
|
-
| What | Endpoints you define in the builder: a method, a path and the SQL | A separate service that turns a schema of views and functions into an API |
|
|
9
|
-
| Served by | pgkiln itself, under `/a/<alias>/rest/<module>/` | PostgREST, next to pgkiln |
|
|
10
|
-
| Runs as | the application's database role (like its pages) | a dedicated API role |
|
|
11
|
-
| Good for | a handful of tailored endpoints, field apps, integrations | broad data access with filtering, sorting and embedding |
|
|
6
|
+
| | [REST modules](#rest-modules-in-the-builder) | [AutoREST](#autorest-tables-and-views-from-the-sql-workshop) | [PostgREST](#how-it-works) |
|
|
7
|
+
|---|---|---|---|
|
|
8
|
+
| What | Endpoints you define in the builder: a method, a path and the SQL | A table or view published as it is: rows, one row, insert, update, delete | A separate service that turns a schema of views and functions into an API |
|
|
9
|
+
| Served by | pgkiln itself, under `/a/<alias>/rest/<module>/` | pgkiln itself, under `/a/<alias>/autorest/<object>/` | PostgREST, next to pgkiln |
|
|
10
|
+
| Runs as | the application's database role (like its pages) | the application's database role | a dedicated API role |
|
|
11
|
+
| Good for | a handful of tailored endpoints, field apps, integrations | quick CRUD access to a table, prototypes, simple integrations | broad data access with filtering, sorting and embedding |
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
same row level security, and
|
|
13
|
+
All three use the same tokens (App → REST API: tokens and OAuth clients), the same accounts and the
|
|
14
|
+
same row level security, and all publish an OpenAPI description.
|
|
15
15
|
|
|
16
16
|
## REST modules in the builder
|
|
17
17
|
|
|
@@ -63,6 +63,71 @@ curl -X POST http://127.0.0.1:3100/a/hr/rest/v1/leave -H "Authorization: Bearer
|
|
|
63
63
|
-H "Content-Type: application/json" -d '{"start_date": "2027-05-03", "end_date": "2027-05-04", "reason": "dentist"}'
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
## AutoREST: tables and views from the SQL Workshop
|
|
67
|
+
|
|
68
|
+
**SQL Workshop → RESTful Services** (`/builder/sql/rest`; Database Actions: a table's *REST › Enable*, ORDS
|
|
69
|
+
AutoREST), or **REST › Enable / Disable** in a table's or view's ⋯ menu (SQL Worksheet navigator, Object Browser).
|
|
70
|
+
Choose:
|
|
71
|
+
|
|
72
|
+
| Setting | Meaning |
|
|
73
|
+
|---|---|
|
|
74
|
+
| Table or view | Any table, partitioned table, view, materialized view or foreign table of a schema the SQL Workshop may use (not `meta`) |
|
|
75
|
+
| Application | An application of the current workspace with a database role. It decides how requests run (below) and gives the URL |
|
|
76
|
+
| URL name | The segment in `/a/<alias>/autorest/<name>/`: lower case letters, digits, `_` and `-`; the object's name by default |
|
|
77
|
+
| Methods | `GET` (rows and one row), `POST` (insert), `PUT` (update), `DELETE`. `PUT` and `DELETE` need a primary key; a materialized view answers `GET` only |
|
|
78
|
+
| Who may call it | **A bearer token of the application** (the default), or **public**: anyone, without a token. Public is never implied: it is a choice on the form |
|
|
79
|
+
| Roles | Optional application roles; the caller needs one of them (`meta.has_role()`), else 403 |
|
|
80
|
+
| Page size | Rows per page without `?limit=` (1–500, default 25) |
|
|
81
|
+
|
|
82
|
+
The object's page shows the checks (the role is not the owner and doesn't bypass row level security; its grants per
|
|
83
|
+
method; row level security on or off; for a view whether it is `security_invoker`; the primary key; columns the role
|
|
84
|
+
may not read), the endpoints with their URLs, cURL and `fetch` examples, and the OpenAPI link. Its settings can be
|
|
85
|
+
changed, the object disabled (404) or removed (*Disable REST*). The table itself is never changed.
|
|
86
|
+
|
|
87
|
+
**Endpoints** (`/a/hr/autorest/dept/` for `hr.dept` published through `hr`):
|
|
88
|
+
|
|
89
|
+
| Request | Answer |
|
|
90
|
+
|---|---|
|
|
91
|
+
| `GET …/dept/` | `{"items": […], "offset": 0, "limit": 25, "has_more": true}`. `?limit=` (1–500) and `?offset=` page; `?<column>=<value>` keeps rows whose column equals the value (several are combined with AND); `?q=<text>` keeps rows where a text column contains the text (case-insensitive; `%` and `_` are literal); `?order=dname,deptno.desc` sorts (default: the primary key). An unknown parameter or column is a 400 |
|
|
92
|
+
| `GET …/dept/10` | The row as an object, or 404. A composite key is comma separated: `…/pair/1,x` (URL-encode a comma inside a value) |
|
|
93
|
+
| `POST …/dept/` | A JSON object of column values → 201 with the new row and a `Location` header. Columns left out get their defaults; an unknown column is a 400 |
|
|
94
|
+
| `PUT …/dept/10` | A JSON object of the columns to change → 200 with the row, or 404 (also when row level security hides it). Columns left out keep their values |
|
|
95
|
+
| `DELETE …/dept/10` | 204, or 404 |
|
|
96
|
+
| `GET /a/hr/autorest/openapi.json` | OpenAPI 3 of the application's published objects: without a token the public ones, with a valid token all of them; column types as JSON Schema |
|
|
97
|
+
|
|
98
|
+
A method that isn't enabled answers 405 with an `Allow` header. Errors are JSON `{"error": "…"}`, as for REST modules:
|
|
99
|
+
400 for invalid input, a check or unique constraint, or a `raise exception`; 403 for a missing role or grant
|
|
100
|
+
(including column grants and a row level security `with check`).
|
|
101
|
+
|
|
102
|
+
**How a request runs.** As for [REST modules](#rest-modules-in-the-builder): the token is checked (signature, expiry,
|
|
103
|
+
the application, an active account with access or a client that isn't revoked) at every request; a browser session is
|
|
104
|
+
not accepted. The statement then runs in a transaction **as the application's database role**, with
|
|
105
|
+
`meta.app_user()` = the caller (`nobody` for a public object without a token), `meta.has_role()` reading the caller's
|
|
106
|
+
roles, and a 30-second statement timeout. So the role's grants, column grants and the table's row level security
|
|
107
|
+
apply exactly as on the application's pages. Columns the role may not select are left out of every answer and can't
|
|
108
|
+
be filtered or sorted on. AutoREST refuses, when the object is enabled and again at every request (after `SET ROLE`),
|
|
109
|
+
a role that owns the object or is a member of its owner (row level security doesn't apply to the owner), a superuser
|
|
110
|
+
and a role with `BYPASSRLS`. An application without a database role can't publish objects. Names come from the
|
|
111
|
+
catalog and are quoted; filter values, keys and bodies are query parameters, never SQL text.
|
|
112
|
+
|
|
113
|
+
The workspace preference *Enable RESTful services* turns AutoREST off with the REST modules (404), and the
|
|
114
|
+
application's availability applies too.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
TOKEN=… # App → REST API → Issue a token for king
|
|
118
|
+
curl "http://127.0.0.1:3100/a/hr/autorest/dept/?limit=2" -H "Authorization: Bearer $TOKEN"
|
|
119
|
+
# {"items":[{"deptno":10,"dname":"ACCOUNTING",…},{"deptno":20,…}],"offset":0,"limit":2,"has_more":true}
|
|
120
|
+
curl "http://127.0.0.1:3100/a/hr/autorest/dept/?limit=2" # 401: no token
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Views.** A view without `security_invoker = true` runs with its owner's rights, so the row level security of the
|
|
124
|
+
tables beneath it does not apply to the caller; the page warns about it. Views have no primary key: they publish the
|
|
125
|
+
collection (`GET`, and `POST` when PostgreSQL can insert into the view).
|
|
126
|
+
|
|
127
|
+
**Export.** The published objects are installation data, like OAuth clients: they name objects of this database and
|
|
128
|
+
are not part of an application export; an in-place import (`pgkiln import --replace`) keeps them. Tailored endpoints
|
|
129
|
+
that travel with the application are [REST modules](#rest-modules-in-the-builder).
|
|
130
|
+
|
|
66
131
|
## PostgREST
|
|
67
132
|
|
|
68
133
|
[PostgREST](https://postgrest.org) runs as a separate service **next to** pgkiln and turns
|
package/docs/guide/16-files.md
CHANGED
|
@@ -265,7 +265,7 @@ parsing, type inference and limits.)
|
|
|
265
265
|
3. The result shows the rows inserted, updated and skipped, with a link to the table in the
|
|
266
266
|
Object Browser.
|
|
267
267
|
|
|
268
|
-
Load Data runs as the builder's owner connection, like SQL
|
|
268
|
+
Load Data runs as the builder's owner connection, like the SQL Worksheet.
|
|
269
269
|
|
|
270
270
|
### SQL Workshop → Unload Data
|
|
271
271
|
|
|
@@ -352,7 +352,7 @@ Rows to develop and test with (APEX 26.1's Data Generator / "sample data for dev
|
|
|
352
352
|
Definitions are shared by the developers of the installation, like SQL scripts, and not part of
|
|
353
353
|
an application export (they describe tables, not an application).
|
|
354
354
|
|
|
355
|
-
Sample Data runs as the builder's owner connection (like SQL
|
|
355
|
+
Sample Data runs as the builder's owner connection (like the SQL Worksheet: triggers run, row level
|
|
356
356
|
security doesn't apply to the owner), on a connection of its own that is closed afterwards, with a
|
|
357
357
|
statement timeout (`SAMPLE_DATA_STATEMENT_TIMEOUT`, default `5min`) and at most
|
|
358
358
|
`SAMPLE_DATA_MAX_ROWS` rows per run (default 100,000). Table and column names come from the
|
package/package.json
CHANGED
package/public/builder.css
CHANGED
|
@@ -1032,3 +1032,25 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
|
|
|
1032
1032
|
|
|
1033
1033
|
/* (sprint 90, PD-4) a commented-out component in the tree (APEX: Comment Out): struck through and muted */
|
|
1034
1034
|
.pd-node[data-commented] .pd-label { text-decoration: line-through; color: var(--muted); }
|
|
1035
|
+
|
|
1036
|
+
/* (sprint 99, DA-13) Administration → Database Users */
|
|
1037
|
+
.dbu-stats { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0.6rem; }
|
|
1038
|
+
.dbu-stats a.stat { color: inherit; text-decoration: none; }
|
|
1039
|
+
.dbu-stats a.stat:hover, .dbu-stats a.stat:focus-visible { border-color: var(--accent); }
|
|
1040
|
+
.dbu-stats a.stat[aria-current="page"] { border-color: var(--accent); background: var(--accent-soft); }
|
|
1041
|
+
.dbu-search { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
|
|
1042
|
+
.dbu-search input { flex: 1 1 12rem; max-width: 24rem; }
|
|
1043
|
+
.dbu-members { max-height: 16rem; overflow: auto; }
|
|
1044
|
+
.dbu-schemas .te-c { text-align: center; width: 1%; white-space: nowrap; }
|
|
1045
|
+
.dbu-sql { white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
1046
|
+
.dbu-list td { white-space: normal; overflow: visible; max-width: 24rem; }
|
|
1047
|
+
.dbu-list td .tag { margin: 0.1rem 0; }
|
|
1048
|
+
.dbu-facts { display: grid; grid-template-columns: max-content 1fr; gap: 0.35rem 1rem; margin: 0; }
|
|
1049
|
+
.dbu-facts dt { color: var(--muted); }
|
|
1050
|
+
.dbu-facts dd { margin: 0; min-width: 0; }
|
|
1051
|
+
@media (max-width: 640px) {
|
|
1052
|
+
.dbu-facts { grid-template-columns: 1fr; } .dbu-facts dd { margin-bottom: 0.4rem; }
|
|
1053
|
+
.dbu-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } .dbu-stats a.stat { padding: 0.5rem 0.7rem; } .dbu-stats .stat b { font-size: 1.15rem; }
|
|
1054
|
+
}
|
|
1055
|
+
/* (sprint 100) RESTful Services: examples wrap instead of scrolling sideways */
|
|
1056
|
+
pre.wrap-pre { white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/* pgkiln builder: the SQL Workshop's Data Modeler (sprint 98, src/builder/data-modeler.ts, public/data-modeler.js).
|
|
2
|
+
The diagram is an SVG with presentation attributes (light colours: an exported file); here the builder's theme
|
|
3
|
+
overrides them. The canvas scrolls inside the page, so a wide diagram never widens the page. */
|
|
4
|
+
.dm-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 8px; }
|
|
5
|
+
.dm-name { margin: 0; font-size: 1.25rem; overflow-wrap: anywhere; }
|
|
6
|
+
.dm-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 8px; }
|
|
7
|
+
.dm-toolbar form { display: contents; }
|
|
8
|
+
.dm-toolbar .btn[disabled] { opacity: 0.5; }
|
|
9
|
+
.dm-status { min-width: 0; }
|
|
10
|
+
.dm-stage { position: relative; }
|
|
11
|
+
.dm-canvas { overflow: auto; max-width: 100%; height: 65vh; min-height: 18rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); }
|
|
12
|
+
.dm-canvas:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
13
|
+
.dm-svg { display: block; }
|
|
14
|
+
.dm-svg .dm-bg { fill: var(--bg); }
|
|
15
|
+
.dm-svg .dm-frame { fill: var(--surface); stroke: var(--border); }
|
|
16
|
+
.dm-svg .dm-view .dm-frame { fill: var(--surface-2); }
|
|
17
|
+
.dm-svg .dm-head { fill: var(--accent-soft); stroke: var(--border); }
|
|
18
|
+
.dm-svg .dm-title { fill: var(--text); }
|
|
19
|
+
.dm-svg .dm-col { fill: var(--text); }
|
|
20
|
+
.dm-svg .dm-type, .dm-svg .dm-kind, .dm-svg .dm-more { fill: var(--muted); }
|
|
21
|
+
.dm-svg .dm-key { fill: var(--gold, #b45309); }
|
|
22
|
+
.dm-svg .dm-line, .dm-svg .dm-end { stroke: var(--muted); }
|
|
23
|
+
.dm-svg .dm-opt { fill: var(--bg); stroke: var(--muted); }
|
|
24
|
+
.dm-svg .dm-fk:hover .dm-line, .dm-svg .dm-fk:hover .dm-end { stroke: var(--accent); stroke-width: 2.5; }
|
|
25
|
+
.dm-svg .dm-link:hover .dm-title, .dm-svg .dm-link:focus .dm-title { fill: var(--accent); text-decoration: underline; }
|
|
26
|
+
.dm-live .dm-box { cursor: grab; touch-action: none; }
|
|
27
|
+
.dm-live .dm-box.dm-dragging { cursor: grabbing; }
|
|
28
|
+
.dm-svg .dm-box:focus { outline: none; }
|
|
29
|
+
.dm-svg .dm-box:focus-visible .dm-frame { stroke: var(--accent); stroke-width: 2.5; }
|
|
30
|
+
.dm-svg .dm-dragging .dm-frame { stroke: var(--accent); }
|
|
31
|
+
.dm-svg text { user-select: none; }
|
|
32
|
+
.dm-minimap { position: absolute; right: 12px; bottom: 12px; width: 200px; height: 140px; border: 1px solid var(--border); border-radius: var(--radius);
|
|
33
|
+
background: var(--surface); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); cursor: pointer; touch-action: none; }
|
|
34
|
+
.dm-minimap-bg { fill: var(--surface); }
|
|
35
|
+
.dm-minimap-view { fill: var(--accent); fill-opacity: 0.15; stroke: var(--accent); stroke-width: 4; vector-effect: non-scaling-stroke; }
|
|
36
|
+
.dm-legend { margin: 6px 0 12px; }
|
|
37
|
+
.dm-search-row { display: flex; gap: 6px; flex-wrap: wrap; }
|
|
38
|
+
.dm-search-row input { flex: 1 1 12rem; min-width: 0; }
|
|
39
|
+
.dm-settings { margin-bottom: 16px; }
|
|
40
|
+
.dm-settings > summary { cursor: pointer; margin-bottom: 8px; }
|
|
41
|
+
.dm-settings form { margin-bottom: 8px; }
|
|
42
|
+
.dm-dict-actions { margin-bottom: 12px; }
|
|
43
|
+
.dm-dict-toc { columns: 3 14rem; }
|
|
44
|
+
.dm-dict-table { margin-top: 1.5rem; }
|
|
45
|
+
.dm-dict-table h2 { border-bottom: 1px solid var(--border); padding-bottom: 4px; overflow-wrap: anywhere; }
|
|
46
|
+
@media (max-width: 640px) {
|
|
47
|
+
.dm-btn-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
|
|
48
|
+
.dm-canvas { height: 55vh; }
|
|
49
|
+
.dm-minimap { width: 130px; height: 90px; }
|
|
50
|
+
}
|
|
51
|
+
@media print {
|
|
52
|
+
.sw-tabs, .dm-toolbar, .dm-legend, #dm-objects, #dm-add, .dm-settings, .dm-minimap, .dm-dict-actions, .ide-alerts { display: none !important; }
|
|
53
|
+
.dm-canvas { height: auto; overflow: visible; border: 0; }
|
|
54
|
+
.dm-svg { max-width: 100%; height: auto; }
|
|
55
|
+
.dm-dict-table { break-inside: avoid-page; }
|
|
56
|
+
}
|