retold-data-service 2.0.43 → 2.1.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/.github/workflows/publish-image.yml +66 -0
- package/BUILDING-AND-PUBLISHING.md +140 -0
- package/Dockerfile +21 -0
- package/package.json +25 -14
- package/source/services/data-cloner/DataCloner-Command-Connection.js +41 -1
- package/source/services/data-cloner/pict-app/Pict-Application-DataCloner.js +50 -16
- package/source/services/data-cloner/pict-app/providers/Pict-Provider-DataCloner.js +185 -96
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Connection.js +181 -383
- package/source/services/data-cloner/pict-app/views/PictView-DataCloner-Export.js +34 -57
- package/source/services/data-cloner/web/data-cloner.js +1116 -530
- package/source/services/data-cloner/web/data-cloner.js.map +1 -1
- package/source/services/data-cloner/web/data-cloner.min.js +1 -1
- package/source/services/data-cloner/web/data-cloner.min.js.map +1 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Publish a container image to GitHub Container Registry on every
|
|
2
|
+
# version tag push (e.g. `v1.2.3`). Generated by `quack docker-init`.
|
|
3
|
+
#
|
|
4
|
+
# Image lands at:
|
|
5
|
+
# ghcr.io/stevenvelozo/retold-data-service:<version>
|
|
6
|
+
# ghcr.io/stevenvelozo/retold-data-service:latest (only on stable tags)
|
|
7
|
+
|
|
8
|
+
name: Publish container image
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
push:
|
|
12
|
+
tags:
|
|
13
|
+
- 'v*.*.*'
|
|
14
|
+
workflow_dispatch:
|
|
15
|
+
inputs:
|
|
16
|
+
tag:
|
|
17
|
+
description: 'Tag to apply (e.g. dev or 1.2.3-test). `latest` is reserved for stable tag pushes.'
|
|
18
|
+
required: true
|
|
19
|
+
default: 'dev'
|
|
20
|
+
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
packages: write
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
build-and-push:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
steps:
|
|
29
|
+
- name: Checkout
|
|
30
|
+
uses: actions/checkout@v4
|
|
31
|
+
|
|
32
|
+
- name: Set up QEMU (multi-arch support)
|
|
33
|
+
uses: docker/setup-qemu-action@v3
|
|
34
|
+
|
|
35
|
+
- name: Set up Docker Buildx
|
|
36
|
+
uses: docker/setup-buildx-action@v3
|
|
37
|
+
|
|
38
|
+
- name: Log in to GHCR
|
|
39
|
+
uses: docker/login-action@v3
|
|
40
|
+
with:
|
|
41
|
+
registry: ghcr.io
|
|
42
|
+
username: ${{ github.actor }}
|
|
43
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
44
|
+
|
|
45
|
+
- name: Compute image tags
|
|
46
|
+
id: meta
|
|
47
|
+
uses: docker/metadata-action@v5
|
|
48
|
+
with:
|
|
49
|
+
images: ghcr.io/${{ github.repository_owner }}/retold-data-service
|
|
50
|
+
tags: |
|
|
51
|
+
type=semver,pattern={{version}}
|
|
52
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
53
|
+
type=semver,pattern={{major}}
|
|
54
|
+
type=raw,value=${{ github.event.inputs.tag }},enable=${{ github.event_name == 'workflow_dispatch' }}
|
|
55
|
+
|
|
56
|
+
- name: Build and push
|
|
57
|
+
uses: docker/build-push-action@v5
|
|
58
|
+
with:
|
|
59
|
+
context: .
|
|
60
|
+
file: ./Dockerfile
|
|
61
|
+
platforms: linux/amd64,linux/arm64
|
|
62
|
+
push: true
|
|
63
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
64
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
65
|
+
cache-from: type=gha
|
|
66
|
+
cache-to: type=gha,mode=max
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Building and Publishing
|
|
2
|
+
|
|
3
|
+
How to ship `retold-data-service` to npm and to GitHub Container Registry
|
|
4
|
+
(GHCR). Generated by `quack docker-init`; the structure matches the
|
|
5
|
+
shared template across all dockerized retold tools.
|
|
6
|
+
|
|
7
|
+
`retold-data-service` is a **long-running service**. Restart policy in compose / k8s should be `unless-stopped` (or equivalent). The Dockerfile should declare a HEALTHCHECK against the service's health endpoint.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## TL;DR
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# npm-only release (the default — most common case)
|
|
15
|
+
npm run release:patch
|
|
16
|
+
|
|
17
|
+
# npm release that ALSO rebuilds the GHCR image
|
|
18
|
+
npm run release:patch:image
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The default release is npm-only. Docker images are deliberate, opt-in
|
|
22
|
+
artifacts because each multi-arch build burns several minutes of CI
|
|
23
|
+
time. Use `:image` (or set `BUILD_DOCKER=1`) when runtime code,
|
|
24
|
+
dependencies, env-var contract, or the Dockerfile changed.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Prerequisites (one-time setup)
|
|
29
|
+
|
|
30
|
+
- **npm login** — `npm whoami` should print your username.
|
|
31
|
+
- **Git remote configured** — `git remote get-url origin` should print
|
|
32
|
+
`git@github.com:stevenvelozo/retold-data-service.git` (or the
|
|
33
|
+
HTTPS equivalent).
|
|
34
|
+
- **Push access to the repo** — required so `postversion` /
|
|
35
|
+
`postpublish` hooks can push commits and tags.
|
|
36
|
+
- **Docker** (only if you want to test the image locally before tag).
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Ecosystem convention: lockfiles are gitignored
|
|
41
|
+
|
|
42
|
+
`package-lock.json` is in this repo's `.gitignore` (Quackage convention
|
|
43
|
+
shared across the retold ecosystem). The Dockerfile must use `npm install`,
|
|
44
|
+
not `npm ci` — `npm ci` requires the lockfile to be in the build context
|
|
45
|
+
and CI runners only check out what's in git. If you see EUSAGE errors in
|
|
46
|
+
GHCR build logs, change `RUN npm ci` to `RUN npm install` in the
|
|
47
|
+
Dockerfile.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Releasing
|
|
52
|
+
|
|
53
|
+
| Command | npm registry | GHCR image rebuild |
|
|
54
|
+
|--------------------------------------|--------------|--------------------|
|
|
55
|
+
| `npm run release:patch` | yes | no |
|
|
56
|
+
| `npm run release:patch:image` | yes | yes |
|
|
57
|
+
| `npm run release:minor` | yes | no |
|
|
58
|
+
| `npm run release:minor:image` | yes | yes |
|
|
59
|
+
| `npm run release:major` | yes | no |
|
|
60
|
+
| `npm run release:major:image` | yes | yes |
|
|
61
|
+
|
|
62
|
+
The non-`:image` variants are the default because most patch releases
|
|
63
|
+
don't change runtime behavior. The `:image` variants tell the pipeline
|
|
64
|
+
"this release does change runtime — build me a new image."
|
|
65
|
+
|
|
66
|
+
### Direct CLI (also works)
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm publish # npm only
|
|
70
|
+
npm run publish:docker # npm + docker (sets BUILD_DOCKER=1)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### From `retold-manager` TUI
|
|
74
|
+
|
|
75
|
+
- `[!]` Publish — npm only
|
|
76
|
+
- `[D]` Publish with docker image — npm + GHCR build
|
|
77
|
+
|
|
78
|
+
### Promoting a previous npm release to docker later
|
|
79
|
+
|
|
80
|
+
If you released `v<x>` to npm only, then later decide you do want a
|
|
81
|
+
docker image:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
git push origin v<x> # pushes the local tag → GHCR fires
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The local tag is still sitting there from the original `npm version`
|
|
88
|
+
step. Pushing it triggers the workflow without touching npm.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## The chain
|
|
93
|
+
|
|
94
|
+
The lifecycle hooks all live in `package.json` and delegate to
|
|
95
|
+
`npx quack release …`. Default path (`BUILD_DOCKER` unset):
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
npm publish
|
|
99
|
+
→ prepublishOnly: npm test ← test gate
|
|
100
|
+
→ publish to npm
|
|
101
|
+
→ postpublish: BUILD_DOCKER unset → no-op ← image NOT triggered
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Docker-included path (`BUILD_DOCKER=1`):
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
BUILD_DOCKER=1 npm publish (or: npm run publish:docker)
|
|
108
|
+
→ prepublishOnly: npm test
|
|
109
|
+
→ publish to npm
|
|
110
|
+
→ postpublish: BUILD_DOCKER=1 → tag + push ← image trigger
|
|
111
|
+
→ .github/workflows/publish-image.yml fires
|
|
112
|
+
→ docker buildx build linux/amd64,linux/arm64
|
|
113
|
+
→ docker push ghcr.io/stevenvelozo/retold-data-service:<version>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Verifying a release
|
|
119
|
+
|
|
120
|
+
1. **npm**: `npm view retold-data-service version`
|
|
121
|
+
2. **Workflow**: `https://github.com/stevenvelozo/retold-data-service/actions`
|
|
122
|
+
3. **Image**: `docker pull ghcr.io/stevenvelozo/retold-data-service:latest`
|
|
123
|
+
|
|
124
|
+
If the first `docker pull` returns `denied`, the package is private by
|
|
125
|
+
default — flip visibility to public via Package Settings → Danger Zone
|
|
126
|
+
on the package page.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Image consumption
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
docker pull ghcr.io/stevenvelozo/retold-data-service:latest
|
|
134
|
+
docker run --rm ghcr.io/stevenvelozo/retold-data-service:latest
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Configuration via env vars: see this module's README for the supported
|
|
138
|
+
`<MODULE>_*` variables. Any secret-bearing var also accepts `<NAME>_FILE`
|
|
139
|
+
pointing at a file whose contents become the value (mysql/postgres
|
|
140
|
+
convention; works with docker secrets and k8s Secrets).
|
package/Dockerfile
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
FROM node:20-bookworm AS base
|
|
2
|
+
MAINTAINER steven velozo <steven@velozo.com>
|
|
3
|
+
|
|
4
|
+
RUN apt-get update && apt-get -y --force-yes install curl vim nano less \
|
|
5
|
+
tmux uuid-runtime
|
|
6
|
+
|
|
7
|
+
ADD package.json /service_root/package.json
|
|
8
|
+
RUN cd /service_root && npm install --omit=dev
|
|
9
|
+
|
|
10
|
+
ADD source /service_root/source
|
|
11
|
+
ADD bin /service_root/bin
|
|
12
|
+
|
|
13
|
+
WORKDIR /service_root
|
|
14
|
+
|
|
15
|
+
RUN rm -rf package-lock.json .git test
|
|
16
|
+
|
|
17
|
+
FROM base AS production
|
|
18
|
+
|
|
19
|
+
RUN date -u +"%Y-%m-%dT%H:%M:%SZ" > ./build.date
|
|
20
|
+
|
|
21
|
+
CMD ["node", "bin/retold-data-service-clone.js"]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "retold-data-service",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "Serve up a whole model!",
|
|
5
5
|
"main": "source/Retold-Data-Service.js",
|
|
6
6
|
"bin": {
|
|
@@ -22,7 +22,16 @@
|
|
|
22
22
|
"docker-service-shell": "docker exec -it retold-data-service /bin/bash",
|
|
23
23
|
"test:integration": "node test/run-integration-tests.js",
|
|
24
24
|
"test:integration:no-browser": "node test/run-integration-tests.js --skip-puppeteer",
|
|
25
|
-
"test:all": "npx quack test && node test/run-integration-tests.js --skip-puppeteer"
|
|
25
|
+
"test:all": "npx quack test && node test/run-integration-tests.js --skip-puppeteer",
|
|
26
|
+
"postversion": "npx quack release postversion",
|
|
27
|
+
"postpublish": "npx quack release postpublish",
|
|
28
|
+
"publish:docker": "npx quack release publish --image",
|
|
29
|
+
"release:patch": "npx quack release patch",
|
|
30
|
+
"release:minor": "npx quack release minor",
|
|
31
|
+
"release:major": "npx quack release major",
|
|
32
|
+
"release:patch:image": "npx quack release patch --image",
|
|
33
|
+
"release:minor:image": "npx quack release minor --image",
|
|
34
|
+
"release:major:image": "npx quack release major --image"
|
|
26
35
|
},
|
|
27
36
|
"mocha": {
|
|
28
37
|
"spec": "test/RetoldDataService_tests.js",
|
|
@@ -59,27 +68,29 @@
|
|
|
59
68
|
},
|
|
60
69
|
"homepage": "https://github.com/stevenvelozo/retold-data-service",
|
|
61
70
|
"devDependencies": {
|
|
62
|
-
"meadow-connection-sqlite": "^1.0.
|
|
71
|
+
"meadow-connection-sqlite": "^1.0.19",
|
|
63
72
|
"pict-docuserve": "^0.1.5",
|
|
64
73
|
"puppeteer": "^24.40.0",
|
|
65
|
-
"quackage": "^1.
|
|
74
|
+
"quackage": "^1.2.0",
|
|
66
75
|
"stricture": "^4.0.2",
|
|
67
76
|
"supertest": "^7.2.2"
|
|
68
77
|
},
|
|
69
78
|
"dependencies": {
|
|
70
|
-
"bibliograph": "^0.1.
|
|
71
|
-
"fable": "^3.1.
|
|
79
|
+
"bibliograph": "^0.1.6",
|
|
80
|
+
"fable": "^3.1.71",
|
|
72
81
|
"fable-serviceproviderbase": "^3.0.19",
|
|
73
|
-
"meadow": "^2.0.
|
|
74
|
-
"meadow-connection-
|
|
75
|
-
"
|
|
76
|
-
"meadow-
|
|
77
|
-
"meadow-
|
|
78
|
-
"
|
|
82
|
+
"meadow": "^2.0.37",
|
|
83
|
+
"meadow-connection-manager": "^1.1.0",
|
|
84
|
+
"pict-section-connection-form": "^0.0.1",
|
|
85
|
+
"meadow-connection-mysql": "^1.0.18",
|
|
86
|
+
"meadow-endpoints": "^4.0.17",
|
|
87
|
+
"meadow-integration": "^1.0.38",
|
|
88
|
+
"meadow-migrationmanager": "^0.0.14",
|
|
89
|
+
"orator": "^6.1.1",
|
|
79
90
|
"orator-http-proxy": "^1.0.5",
|
|
80
91
|
"orator-serviceserver-restify": "^2.0.10",
|
|
81
|
-
"orator-static-server": "^2.
|
|
82
|
-
"pict": "^1.0.
|
|
92
|
+
"orator-static-server": "^2.1.3",
|
|
93
|
+
"pict": "^1.0.365",
|
|
83
94
|
"pict-section-histogram": "^1.0.0",
|
|
84
95
|
"pict-sessionmanager": "^1.0.2",
|
|
85
96
|
"stricture": "^4.0.2"
|
|
@@ -2,17 +2,57 @@
|
|
|
2
2
|
* DataCloner Connection Management Routes
|
|
3
3
|
*
|
|
4
4
|
* Registers /clone/connection/* endpoints for managing the local database
|
|
5
|
-
* connection (status, configure, test).
|
|
5
|
+
* connection (status, configure, test, schemas).
|
|
6
6
|
*
|
|
7
7
|
* @param {Object} pDataClonerService - The RetoldDataServiceDataCloner instance
|
|
8
8
|
* @param {Object} pOratorServiceServer - The Orator ServiceServer instance
|
|
9
9
|
*/
|
|
10
|
+
const libMeadowConnectionManager = require('meadow-connection-manager');
|
|
11
|
+
|
|
10
12
|
module.exports = (pDataClonerService, pOratorServiceServer) =>
|
|
11
13
|
{
|
|
12
14
|
let tmpFable = pDataClonerService.fable;
|
|
13
15
|
let tmpCloneState = pDataClonerService.cloneState;
|
|
14
16
|
let tmpPrefix = pDataClonerService.routePrefix;
|
|
15
17
|
|
|
18
|
+
// MCM is the canonical aggregator for connection-form schemas; the
|
|
19
|
+
// DataCloner browser UI fetches /clone/connection/schemas and renders
|
|
20
|
+
// its provider form straight off the result, instead of carrying
|
|
21
|
+
// per-provider HTML in the bundle. Cached on the service so we don't
|
|
22
|
+
// re-walk the filesystem on every poll.
|
|
23
|
+
let tmpSchemaMCM = null;
|
|
24
|
+
let tmpCachedSchemas = null;
|
|
25
|
+
let tmpGetSchemas = () =>
|
|
26
|
+
{
|
|
27
|
+
if (tmpCachedSchemas) { return tmpCachedSchemas; }
|
|
28
|
+
if (!tmpSchemaMCM)
|
|
29
|
+
{
|
|
30
|
+
tmpSchemaMCM = new libMeadowConnectionManager(tmpFable, {}, 'datacloner-mcm-formschemas');
|
|
31
|
+
}
|
|
32
|
+
// Defensive: an older MCM (< 1.1.0) won't have the aggregator
|
|
33
|
+
// method. Surface an empty array rather than throwing so the
|
|
34
|
+
// UI can fall back to a "schemas unavailable" message.
|
|
35
|
+
if (typeof(tmpSchemaMCM.getAllProviderFormSchemas) !== 'function')
|
|
36
|
+
{
|
|
37
|
+
tmpFable.log.warn('DataCloner: meadow-connection-manager is older than 1.1.0; connection form schemas are not available. Run npm update meadow-connection-manager.');
|
|
38
|
+
tmpCachedSchemas = [];
|
|
39
|
+
return tmpCachedSchemas;
|
|
40
|
+
}
|
|
41
|
+
tmpCachedSchemas = tmpSchemaMCM.getAllProviderFormSchemas();
|
|
42
|
+
return tmpCachedSchemas;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// GET /clone/connection/schemas
|
|
46
|
+
// Returns the form schemas for every provider whose module is
|
|
47
|
+
// installed in the host environment. Drives the connection
|
|
48
|
+
// section's UI (provider picker + per-provider field block).
|
|
49
|
+
pOratorServiceServer.get(`${tmpPrefix}/connection/schemas`,
|
|
50
|
+
(pRequest, pResponse, fNext) =>
|
|
51
|
+
{
|
|
52
|
+
pResponse.send(200, { Schemas: tmpGetSchemas() });
|
|
53
|
+
return fNext();
|
|
54
|
+
});
|
|
55
|
+
|
|
16
56
|
// GET /clone/connection/status
|
|
17
57
|
pOratorServiceServer.get(`${tmpPrefix}/connection/status`,
|
|
18
58
|
(pRequest, pResponse, fNext) =>
|
|
@@ -11,6 +11,7 @@ const libViewSync = require('./views/PictView-DataCloner-Sync.js');
|
|
|
11
11
|
const libViewExport = require('./views/PictView-DataCloner-Export.js');
|
|
12
12
|
const libViewViewData = require('./views/PictView-DataCloner-ViewData.js');
|
|
13
13
|
const libViewHistogram = require('pict-section-histogram');
|
|
14
|
+
const libViewConnectionForm = require('pict-section-connection-form');
|
|
14
15
|
|
|
15
16
|
class DataClonerApplication extends libPictApplication
|
|
16
17
|
{
|
|
@@ -45,11 +46,35 @@ class DataClonerApplication extends libPictApplication
|
|
|
45
46
|
BarColor: '#4a90d9',
|
|
46
47
|
Bins: []
|
|
47
48
|
}, libViewHistogram);
|
|
49
|
+
|
|
50
|
+
// Shared schema-driven connection form. Renders into the slot
|
|
51
|
+
// the DataCloner-Connection accordion shell exposes; the
|
|
52
|
+
// provider's bootstrapConnectionSchemas() pumps the schemas in
|
|
53
|
+
// once the host's /clone/connection/schemas endpoint responds.
|
|
54
|
+
this.pict.addView('PictSection-ConnectionForm',
|
|
55
|
+
Object.assign({}, libViewConnectionForm.default_configuration,
|
|
56
|
+
{
|
|
57
|
+
ContainerSelector: '#DataCloner-Connection-FormSlot',
|
|
58
|
+
DefaultDestinationAddress: '#DataCloner-Connection-FormSlot',
|
|
59
|
+
SchemasAddress: 'AppData.DataCloner.Connection.Schemas',
|
|
60
|
+
ActiveAddress: 'AppData.DataCloner.Connection.ActiveProvider',
|
|
61
|
+
FieldIDPrefix: 'datacloner-conn'
|
|
62
|
+
}), libViewConnectionForm);
|
|
48
63
|
}
|
|
49
64
|
|
|
50
65
|
onAfterInitializeAsync(fCallback)
|
|
51
66
|
{
|
|
52
|
-
// Centralized state (replaces global variables)
|
|
67
|
+
// Centralized state (replaces global variables).
|
|
68
|
+
//
|
|
69
|
+
// PersistFields covers the static, non-connection inputs only.
|
|
70
|
+
// Connection-section fields (provider picker + per-provider
|
|
71
|
+
// inputs) are schema-driven now: their DOM ids and
|
|
72
|
+
// localStorage keys are derived at runtime from the host's
|
|
73
|
+
// /clone/connection/schemas response and persistence is hooked
|
|
74
|
+
// up by Pict-Provider-DataCloner#bootstrapConnectionSchemas
|
|
75
|
+
// after the schema-driven Connection view re-renders. See
|
|
76
|
+
// PictView-DataCloner-Connection.js for the field-id
|
|
77
|
+
// convention.
|
|
53
78
|
this.pict.AppData.DataCloner =
|
|
54
79
|
{
|
|
55
80
|
FetchedTables: [],
|
|
@@ -67,30 +92,32 @@ class DataClonerApplication extends libPictApplication
|
|
|
67
92
|
'serverURL', 'authMethod', 'authURI', 'checkURI',
|
|
68
93
|
'cookieName', 'cookieValueAddr', 'cookieValueTemplate', 'loginMarker',
|
|
69
94
|
'userName', 'password', 'schemaURL', 'pageSize', 'dateTimePrecisionMS',
|
|
70
|
-
'connProvider', 'sqliteFilePath',
|
|
71
|
-
'mysqlServer', 'mysqlPort', 'mysqlUser', 'mysqlPassword', 'mysqlDatabase', 'mysqlConnectionLimit',
|
|
72
|
-
'mssqlServer', 'mssqlPort', 'mssqlUser', 'mssqlPassword', 'mssqlDatabase', 'mssqlConnectionLimit',
|
|
73
|
-
'mssqlRequestTimeoutSec', 'mssqlConnectionTimeoutSec',
|
|
74
|
-
'mssqlConnectMaxAttempts', 'mssqlDDLMaxAttempts',
|
|
75
|
-
'mssqlRetryInitialDelaySec', 'mssqlRetryMaxDelaySec',
|
|
76
|
-
'postgresqlHost', 'postgresqlPort', 'postgresqlUser', 'postgresqlPassword', 'postgresqlDatabase', 'postgresqlConnectionLimit',
|
|
77
|
-
'solrHost', 'solrPort', 'solrCore', 'solrPath',
|
|
78
|
-
'mongodbHost', 'mongodbPort', 'mongodbUser', 'mongodbPassword', 'mongodbDatabase', 'mongodbConnectionLimit',
|
|
79
|
-
'rocksdbFolder',
|
|
80
|
-
'bibliographFolder',
|
|
81
95
|
'syncMaxRecords'
|
|
82
|
-
]
|
|
96
|
+
],
|
|
97
|
+
// Connection state — populated by bootstrapConnectionSchemas().
|
|
98
|
+
// Initialized empty here so the Connection view's first
|
|
99
|
+
// onBeforeRender finds a valid (if empty) shape.
|
|
100
|
+
Connection:
|
|
101
|
+
{
|
|
102
|
+
Schemas: [],
|
|
103
|
+
ActiveProvider: '',
|
|
104
|
+
ProviderOptions: [],
|
|
105
|
+
ProviderForms: [],
|
|
106
|
+
NoSchemasSlot: [{}],
|
|
107
|
+
PreviewText: 'Loading providers…'
|
|
108
|
+
}
|
|
83
109
|
};
|
|
84
110
|
|
|
85
111
|
// Make pict available for inline onclick handlers
|
|
86
112
|
window.pict = this.pict;
|
|
87
113
|
|
|
88
|
-
// Render layout (which chains child view renders via onAfterRender)
|
|
114
|
+
// Render layout (which chains child view renders via onAfterRender).
|
|
115
|
+
// The Connection view renders an empty shell here — the schemas
|
|
116
|
+
// arrive asynchronously and trigger a re-render once they land.
|
|
89
117
|
this.pict.views['DataCloner-Layout'].render();
|
|
90
118
|
|
|
91
|
-
// Post-render initialization
|
|
119
|
+
// Post-render initialization for the static (non-connection) UI.
|
|
92
120
|
this.pict.providers.DataCloner.initPersistence();
|
|
93
|
-
this.pict.views['DataCloner-Connection'].onProviderChange();
|
|
94
121
|
this.pict.providers.DataCloner.restoreDeployedTables();
|
|
95
122
|
this.pict.providers.DataCloner.startLiveStatusPolling();
|
|
96
123
|
this.pict.providers.DataCloner.initAccordionPreviews();
|
|
@@ -98,6 +125,13 @@ class DataClonerApplication extends libPictApplication
|
|
|
98
125
|
this.pict.views['DataCloner-Layout'].collapseAllSections();
|
|
99
126
|
this.pict.providers.DataCloner.initAutoProcess();
|
|
100
127
|
|
|
128
|
+
// Async: fetch the host's connection-form schemas and re-render
|
|
129
|
+
// the Connection section. bootstrapConnectionSchemas restores
|
|
130
|
+
// localStorage values + hooks save listeners once the new DOM
|
|
131
|
+
// is in place, then invokes onProviderChange() to surface the
|
|
132
|
+
// active provider's form.
|
|
133
|
+
this.pict.providers.DataCloner.bootstrapConnectionSchemas(function () { /* fire-and-forget */ });
|
|
134
|
+
|
|
101
135
|
return fCallback();
|
|
102
136
|
}
|
|
103
137
|
}
|