@harperfast/harper-pro 5.0.0-alpha.9 → 5.0.0-beta.2
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/core/.dockerignore +9 -0
- package/core/.git-blame-ignore-revs +2 -0
- package/core/.github/workflows/create-release.yaml +4 -4
- package/core/.github/workflows/integration-tests.yml +12 -10
- package/core/.github/workflows/notify-release-published.yaml +1 -1
- package/core/.github/workflows/publish-docker.yaml +2 -2
- package/core/.github/workflows/publish-npm.yaml +4 -4
- package/core/CONTRIBUTING.md +1 -1
- package/core/Dockerfile +62 -0
- package/core/build-tools/build-studio.sh +12 -0
- package/core/build-tools/build.sh +22 -0
- package/core/build-tools/download-prebuilds.js +13 -0
- package/core/components/Logger.ts +14 -0
- package/core/components/Scope.ts +35 -11
- package/core/components/componentLoader.ts +27 -10
- package/core/components/operations.js +10 -2
- package/core/config/configUtils.js +1 -1
- package/core/dataLayer/CreateTableObject.js +2 -2
- package/core/dataLayer/schema.js +7 -5
- package/core/dataLayer/schemaDescribe.js +1 -1
- package/core/index.d.ts +11 -6
- package/core/index.js +2 -0
- package/core/integrationTests/README.md +24 -0
- package/core/integrationTests/apiTests/tests/10_otherRoleTests.mjs +6 -6
- package/core/integrationTests/apiTests/tests/12_configuration.mjs +1 -1
- package/core/integrationTests/apiTests/tests/14_tokenAuth.mjs +2 -2
- package/core/integrationTests/apiTests/tests/16_terminologyUpdates.mjs +4 -4
- package/core/integrationTests/apiTests/tests/1_environmentSetup.mjs +1 -1
- package/core/integrationTests/apiTests/tests/2_dataLoad.mjs +4 -4
- package/core/integrationTests/apiTests/tests/3_sqlTests.mjs +3 -3
- package/core/integrationTests/apiTests/tests/4_noSqlTests.mjs +12 -12
- package/core/integrationTests/apiTests/tests/5_noSqlRoleTesting.mjs +8 -8
- package/core/integrationTests/apiTests/tests/7_jobsAndJobRoleTesting.mjs +10 -12
- package/core/integrationTests/apiTests/tests/8_deleteTests.mjs +8 -8
- package/core/integrationTests/apiTests/tests/9_transactions.mjs +2 -2
- package/core/integrationTests/apiTests/utils/search.mjs +1 -1
- package/core/integrationTests/apiTests/utils/table.mjs +1 -1
- package/core/integrationTests/server/operation-user-rbac.test.ts +1 -1
- package/core/integrationTests/server/operations-server.test.ts +1 -1
- package/core/integrationTests/server/storage-reclamation.test.ts +1 -1
- package/core/integrationTests/utils/README.md +1 -15
- package/core/integrationTests/utils/harperLifecycle.ts +33 -21
- package/core/package.json +23 -5
- package/core/resources/ResourceInterface.ts +1 -1
- package/core/resources/Table.ts +26 -11
- package/core/resources/analytics/read.ts +33 -26
- package/core/resources/analytics/write.ts +3 -7
- package/core/resources/databases.ts +29 -18
- package/core/resources/search.ts +10 -5
- package/core/security/auth.ts +1 -1
- package/core/security/jsLoader.ts +302 -83
- package/core/security/keys.js +11 -12
- package/core/security/user.ts +3 -3
- package/core/server/REST.ts +18 -2
- package/core/server/Server.ts +2 -1
- package/core/server/fastifyRoutes.ts +1 -0
- package/core/server/http.ts +13 -9
- package/core/server/loadRootComponents.js +1 -0
- package/core/server/operationsServer.ts +2 -1
- package/core/server/threads/manageThreads.js +49 -35
- package/core/static/defaultConfig.yaml +3 -0
- package/core/unitTests/apiTests/RESTProperties-test.mjs +2 -2
- package/core/unitTests/apiTests/basicREST-test.mjs +2 -2
- package/core/unitTests/components/Scope.test.js +54 -16
- package/core/unitTests/components/fixtures/testJSWithDeps/child-dir/circular.js +4 -0
- package/core/unitTests/components/fixtures/testJSWithDeps/child-dir/in-child-dir.js +4 -0
- package/core/unitTests/components/fixtures/testJSWithDeps/child-dir/typestrip.ts +2 -0
- package/core/unitTests/components/fixtures/testJSWithDeps/resources.js +43 -0
- package/core/unitTests/components/fixtures/testJSWithDeps/test-child-process.js +18 -0
- package/core/unitTests/components/globalIsolation.test.js +87 -1
- package/core/unitTests/config/configUtils.test.js +1 -260
- package/core/unitTests/resources/query.test.js +16 -1
- package/core/unitTests/resources/vectorIndex.test.js +1 -1
- package/core/unitTests/server/fastifyRoutes/operations.test.js +1 -1
- package/core/unitTests/testUtils.js +0 -17
- package/core/utility/hdbTerms.ts +3 -0
- package/core/utility/installation.ts +2 -5
- package/core/utility/lmdb/commonUtility.js +21 -10
- package/dist/core/{resources/ResourceInterfaceV2.js → components/Logger.js} +1 -1
- package/dist/core/components/Logger.js.map +1 -0
- package/dist/core/components/Scope.js +18 -10
- package/dist/core/components/Scope.js.map +1 -1
- package/dist/core/components/componentLoader.js +17 -10
- package/dist/core/components/componentLoader.js.map +1 -1
- package/dist/core/components/operations.js +2 -2
- package/dist/core/components/operations.js.map +1 -1
- package/dist/core/config/configUtils.js +1 -1
- package/dist/core/config/configUtils.js.map +1 -1
- package/dist/core/dataLayer/CreateTableObject.js +2 -2
- package/dist/core/dataLayer/CreateTableObject.js.map +1 -1
- package/dist/core/dataLayer/schema.js +6 -5
- package/dist/core/dataLayer/schema.js.map +1 -1
- package/dist/core/dataLayer/schemaDescribe.js +1 -1
- package/dist/core/dataLayer/schemaDescribe.js.map +1 -1
- package/dist/core/index.js +2 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/resources/Table.js +12 -4
- package/dist/core/resources/Table.js.map +1 -1
- package/dist/core/resources/analytics/read.js +32 -22
- package/dist/core/resources/analytics/read.js.map +1 -1
- package/dist/core/resources/analytics/write.js +3 -6
- package/dist/core/resources/analytics/write.js.map +1 -1
- package/dist/core/resources/databases.js +22 -19
- package/dist/core/resources/databases.js.map +1 -1
- package/dist/core/resources/search.js +11 -5
- package/dist/core/resources/search.js.map +1 -1
- package/dist/core/security/auth.js +1 -1
- package/dist/core/security/auth.js.map +1 -1
- package/dist/core/security/jsLoader.js +265 -73
- package/dist/core/security/jsLoader.js.map +1 -1
- package/dist/core/security/keys.js +11 -12
- package/dist/core/security/keys.js.map +1 -1
- package/dist/core/security/user.js +3 -3
- package/dist/core/security/user.js.map +1 -1
- package/dist/core/server/REST.js +16 -2
- package/dist/core/server/REST.js.map +1 -1
- package/dist/core/server/Server.js.map +1 -1
- package/dist/core/server/fastifyRoutes.js +2 -0
- package/dist/core/server/fastifyRoutes.js.map +1 -1
- package/dist/core/server/http.js +12 -6
- package/dist/core/server/http.js.map +1 -1
- package/dist/core/server/loadRootComponents.js +1 -0
- package/dist/core/server/loadRootComponents.js.map +1 -1
- package/dist/core/server/operationsServer.js +3 -1
- package/dist/core/server/operationsServer.js.map +1 -1
- package/dist/core/server/threads/manageThreads.js +50 -35
- package/dist/core/server/threads/manageThreads.js.map +1 -1
- package/dist/core/utility/hdbTerms.js +3 -0
- package/dist/core/utility/hdbTerms.js.map +1 -1
- package/dist/core/utility/installation.js.map +1 -1
- package/dist/core/utility/lmdb/commonUtility.js +20 -13
- package/dist/core/utility/lmdb/commonUtility.js.map +1 -1
- package/dist/licensing/usageLicensing.js.map +1 -1
- package/dist/replication/knownNodes.js +5 -37
- package/dist/replication/knownNodes.js.map +1 -1
- package/dist/replication/nodeIdMapping.js +2 -35
- package/dist/replication/nodeIdMapping.js.map +1 -1
- package/dist/replication/replicationConnection.js +15 -6
- package/dist/replication/replicationConnection.js.map +1 -1
- package/dist/replication/replicator.js +3 -2
- package/dist/replication/replicator.js.map +1 -1
- package/dist/replication/setNode.js +1 -1
- package/dist/replication/setNode.js.map +1 -1
- package/dist/security/certificate.js.map +1 -1
- package/licensing/usageLicensing.ts +3 -2
- package/npm-shrinkwrap.json +303 -282
- package/package.json +4 -3
- package/replication/knownNodes.ts +3 -2
- package/replication/nodeIdMapping.ts +1 -1
- package/replication/replicationConnection.ts +33 -8
- package/replication/replicator.ts +7 -2
- package/replication/setNode.ts +1 -1
- package/security/certificate.ts +2 -1
- package/studio/web/assets/{index-v3wIpSYx.js → index-CWN9Wp5V.js} +2 -2
- package/studio/web/assets/{index-v3wIpSYx.js.map → index-CWN9Wp5V.js.map} +1 -1
- package/studio/web/assets/{index-ChCctErQ.js → index-CzghSAn2.js} +2 -2
- package/studio/web/assets/{index-ChCctErQ.js.map → index-CzghSAn2.js.map} +1 -1
- package/studio/web/assets/{index-Qu8D43wo.js → index-DMDhGP7N.js} +5 -5
- package/studio/web/assets/{index-Qu8D43wo.js.map → index-DMDhGP7N.js.map} +1 -1
- package/studio/web/assets/{index.lazy-tVSPM7bX.js → index.lazy-C-yDTGUy.js} +2 -2
- package/studio/web/assets/{index.lazy-tVSPM7bX.js.map → index.lazy-C-yDTGUy.js.map} +1 -1
- package/studio/web/assets/{profiler-C9as4sv-.js → profiler-0fZAOscv.js} +2 -2
- package/studio/web/assets/{profiler-C9as4sv-.js.map → profiler-0fZAOscv.js.map} +1 -1
- package/studio/web/assets/{react-redux-RRIhZnM6.js → react-redux-BIxqK8O6.js} +2 -2
- package/studio/web/assets/{react-redux-RRIhZnM6.js.map → react-redux-BIxqK8O6.js.map} +1 -1
- package/studio/web/assets/{startRecording-DYa4zCXV.js → startRecording-Ca3Gf2MY.js} +2 -2
- package/studio/web/assets/{startRecording-DYa4zCXV.js.map → startRecording-Ca3Gf2MY.js.map} +1 -1
- package/studio/web/index.html +1 -1
- package/core/resources/ResourceInterfaceV2.ts +0 -53
- package/core/resources/ResourceV2.ts +0 -67
- package/core/resources/analytics/profile.ts +0 -109
- package/core/unitTests/apiTests/analytics-test.mjs +0 -38
- package/core/v1.d.ts +0 -47
- package/core/v1.js +0 -38
- package/core/v2.d.ts +0 -47
- package/core/v2.js +0 -38
- package/dist/core/resources/ResourceInterfaceV2.js.map +0 -1
- package/dist/core/resources/ResourceV2.js +0 -27
- package/dist/core/resources/ResourceV2.js.map +0 -1
- package/dist/core/resources/analytics/profile.js +0 -144
- package/dist/core/resources/analytics/profile.js.map +0 -1
|
@@ -46,7 +46,7 @@ jobs:
|
|
|
46
46
|
uses: slackapi/slack-github-action@v2
|
|
47
47
|
with:
|
|
48
48
|
method: chat.postMessage
|
|
49
|
-
token: ${{ secrets.
|
|
49
|
+
token: ${{ secrets.SLACK_BOT_TOKEN }}
|
|
50
50
|
payload: |
|
|
51
51
|
{
|
|
52
52
|
"channel": "#development-ci",
|
|
@@ -91,7 +91,7 @@ jobs:
|
|
|
91
91
|
with:
|
|
92
92
|
name: ${{ steps.tag-version.outputs.tagVersion }}
|
|
93
93
|
tag_name: ${{ steps.tag-version.outputs.tagVersion }}
|
|
94
|
-
files:
|
|
94
|
+
files: harper-*.tgz
|
|
95
95
|
fail_on_unmatched_files: true
|
|
96
96
|
generate_release_notes: true
|
|
97
97
|
prerelease: ${{ steps.version-components.outputs.prerelease != '' }}
|
|
@@ -106,7 +106,7 @@ jobs:
|
|
|
106
106
|
- uses: slackapi/slack-github-action@v2
|
|
107
107
|
with:
|
|
108
108
|
method: chat.postMessage
|
|
109
|
-
token: ${{ secrets.
|
|
109
|
+
token: ${{ secrets.SLACK_BOT_TOKEN }}
|
|
110
110
|
payload: |
|
|
111
111
|
{
|
|
112
112
|
"channel": "#development-ci",
|
|
@@ -147,7 +147,7 @@ jobs:
|
|
|
147
147
|
- uses: slackapi/slack-github-action@v2
|
|
148
148
|
with:
|
|
149
149
|
method: chat.postMessage
|
|
150
|
-
token: ${{ secrets.
|
|
150
|
+
token: ${{ secrets.SLACK_BOT_TOKEN }}
|
|
151
151
|
payload: |
|
|
152
152
|
{
|
|
153
153
|
"channel": "#development-ci",
|
|
@@ -64,7 +64,7 @@ jobs:
|
|
|
64
64
|
run: npm run build || true # we currently have type errors so just ignore that
|
|
65
65
|
|
|
66
66
|
- name: Upload build artifacts
|
|
67
|
-
uses: actions/upload-artifact@
|
|
67
|
+
uses: actions/upload-artifact@v7
|
|
68
68
|
with:
|
|
69
69
|
name: harper-build-artifacts-node-${{ matrix.node-version }}
|
|
70
70
|
path: |
|
|
@@ -95,7 +95,7 @@ jobs:
|
|
|
95
95
|
package-manager-cache: false
|
|
96
96
|
|
|
97
97
|
- name: Download build artifacts
|
|
98
|
-
uses: actions/download-artifact@
|
|
98
|
+
uses: actions/download-artifact@v8
|
|
99
99
|
with:
|
|
100
100
|
name: harper-build-artifacts-node-${{ matrix.node-version }}
|
|
101
101
|
|
|
@@ -112,9 +112,10 @@ jobs:
|
|
|
112
112
|
THREADS_DEBUG: false
|
|
113
113
|
NODE_HOSTNAME: 'localhost'
|
|
114
114
|
run: |
|
|
115
|
-
|
|
115
|
+
mkdir -p /tmp/hdb/log
|
|
116
|
+
node ./dist/bin/harper.js install > /tmp/hdb/log/install-stdout.log 2> /tmp/hdb/log/install-stderr.log
|
|
116
117
|
sleep 10
|
|
117
|
-
node ./dist/bin/harper.js start
|
|
118
|
+
node ./dist/bin/harper.js start > /tmp/hdb/log/start-stdout.log 2> /tmp/hdb/log/start-stderr.log &
|
|
118
119
|
sleep 10
|
|
119
120
|
|
|
120
121
|
- name: Run API Tests
|
|
@@ -125,12 +126,13 @@ jobs:
|
|
|
125
126
|
run: npm run test:integration:api-tests
|
|
126
127
|
|
|
127
128
|
- name: Upload Harper logs
|
|
128
|
-
if:
|
|
129
|
-
uses: actions/upload-artifact@
|
|
129
|
+
if: failure()
|
|
130
|
+
uses: actions/upload-artifact@v7
|
|
130
131
|
with:
|
|
131
132
|
name: harper-integration-api-test-logs-node-${{ matrix.node-version }}
|
|
132
|
-
path: /tmp/hdb/log/
|
|
133
|
-
retention-days:
|
|
133
|
+
path: /tmp/hdb/log/
|
|
134
|
+
retention-days: 3
|
|
135
|
+
if-no-files-found: ignore
|
|
134
136
|
|
|
135
137
|
run-integration-tests:
|
|
136
138
|
name: Integration Tests ${{matrix.shard}}/4 (Node.js v${{ matrix.node-version }})
|
|
@@ -155,7 +157,7 @@ jobs:
|
|
|
155
157
|
package-manager-cache: false
|
|
156
158
|
|
|
157
159
|
- name: Download build artifacts
|
|
158
|
-
uses: actions/download-artifact@
|
|
160
|
+
uses: actions/download-artifact@v8
|
|
159
161
|
with:
|
|
160
162
|
name: harper-build-artifacts-node-${{ matrix.node-version }}
|
|
161
163
|
|
|
@@ -167,7 +169,7 @@ jobs:
|
|
|
167
169
|
|
|
168
170
|
- name: Upload Harper server logs
|
|
169
171
|
if: failure()
|
|
170
|
-
uses: actions/upload-artifact@
|
|
172
|
+
uses: actions/upload-artifact@v7
|
|
171
173
|
with:
|
|
172
174
|
name: harper-server-logs-node-${{ matrix.node-version }}-shard-${{ matrix.shard }}
|
|
173
175
|
path: /tmp/harper-integration-test-logs/
|
|
@@ -99,7 +99,7 @@ jobs:
|
|
|
99
99
|
uses: slackapi/slack-github-action@v2
|
|
100
100
|
with:
|
|
101
101
|
method: chat.postMessage
|
|
102
|
-
token: ${{ secrets.
|
|
102
|
+
token: ${{ secrets.SLACK_BOT_TOKEN }}
|
|
103
103
|
payload: |
|
|
104
104
|
{
|
|
105
105
|
"channel": "#development-ci",
|
|
@@ -140,7 +140,7 @@ jobs:
|
|
|
140
140
|
- uses: slackapi/slack-github-action@v2
|
|
141
141
|
with:
|
|
142
142
|
method: chat.postMessage
|
|
143
|
-
token: ${{ secrets.
|
|
143
|
+
token: ${{ secrets.SLACK_BOT_TOKEN }}
|
|
144
144
|
payload: |
|
|
145
145
|
{
|
|
146
146
|
"channel": "#development-ci",
|
|
@@ -38,7 +38,7 @@ jobs:
|
|
|
38
38
|
fi
|
|
39
39
|
- name: Publish package to NPM registry
|
|
40
40
|
env:
|
|
41
|
-
NODE_AUTH_TOKEN: ${{ secrets.
|
|
41
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
42
42
|
run: npm publish --access=public --tag=${{ steps.package-tag.outputs.packageTag }} harper-*.tgz
|
|
43
43
|
|
|
44
44
|
publish-harperfast-npm-package:
|
|
@@ -78,7 +78,7 @@ jobs:
|
|
|
78
78
|
fi
|
|
79
79
|
- name: Publish package to NPM registry
|
|
80
80
|
env:
|
|
81
|
-
NODE_AUTH_TOKEN: ${{ secrets.
|
|
81
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
82
82
|
run: npm publish --access=public --tag=${{ steps.package-tag.outputs.packageTag }} harperfast-harper-*.tgz
|
|
83
83
|
|
|
84
84
|
send-slack-message-on-success:
|
|
@@ -92,7 +92,7 @@ jobs:
|
|
|
92
92
|
uses: slackapi/slack-github-action@v2
|
|
93
93
|
with:
|
|
94
94
|
method: chat.postMessage
|
|
95
|
-
token: ${{ secrets.
|
|
95
|
+
token: ${{ secrets.SLACK_BOT_TOKEN }}
|
|
96
96
|
payload: |
|
|
97
97
|
{
|
|
98
98
|
"channel": "#development-ci",
|
|
@@ -139,7 +139,7 @@ jobs:
|
|
|
139
139
|
- uses: slackapi/slack-github-action@v2
|
|
140
140
|
with:
|
|
141
141
|
method: chat.postMessage
|
|
142
|
-
token: ${{ secrets.
|
|
142
|
+
token: ${{ secrets.SLACK_BOT_TOKEN }}
|
|
143
143
|
payload: |
|
|
144
144
|
{
|
|
145
145
|
"channel": "#development-ci",
|
package/core/CONTRIBUTING.md
CHANGED
package/core/Dockerfile
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
ARG NODE_BUILD_VERSION=24
|
|
2
|
+
ARG NODE_VERSION=24
|
|
3
|
+
|
|
4
|
+
FROM docker.io/node:${NODE_BUILD_VERSION} AS build
|
|
5
|
+
|
|
6
|
+
WORKDIR /usr/src/harper
|
|
7
|
+
|
|
8
|
+
COPY . .
|
|
9
|
+
|
|
10
|
+
RUN env NO_USE_GIT=true npm run package
|
|
11
|
+
|
|
12
|
+
FROM docker.io/node:${NODE_VERSION} AS run
|
|
13
|
+
|
|
14
|
+
# Change node user to harper
|
|
15
|
+
RUN <<-EOF
|
|
16
|
+
mkdir -p /home/harperdb
|
|
17
|
+
usermod -d /home/harperdb -l harperdb node
|
|
18
|
+
groupmod -n harperdb node
|
|
19
|
+
rm -rf /home/node
|
|
20
|
+
chown -R harperdb:harperdb /home/harperdb
|
|
21
|
+
EOF
|
|
22
|
+
|
|
23
|
+
WORKDIR /home/harperdb
|
|
24
|
+
|
|
25
|
+
USER harperdb
|
|
26
|
+
|
|
27
|
+
# Install pnpm
|
|
28
|
+
RUN wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.bashrc" SHELL="$(which bash)" bash -
|
|
29
|
+
|
|
30
|
+
COPY --from=build /usr/src/harper/harper-*.tgz .
|
|
31
|
+
|
|
32
|
+
# Configure NPM
|
|
33
|
+
ENV NPM_CONFIG_PREFIX=/home/harperdb/.npm-global
|
|
34
|
+
ENV PATH=/home/harperdb/.npm-global/bin:$PATH
|
|
35
|
+
|
|
36
|
+
VOLUME /home/harperdb/harper
|
|
37
|
+
|
|
38
|
+
# Install Harper globally
|
|
39
|
+
RUN <<-EOF
|
|
40
|
+
npm install --global harper-*.tgz
|
|
41
|
+
rm harper-*.tgz
|
|
42
|
+
mkdir -p /home/harperdb/harper
|
|
43
|
+
chown harperdb:harperdb /home/harperdb/harper
|
|
44
|
+
EOF
|
|
45
|
+
|
|
46
|
+
# Harper config parameters
|
|
47
|
+
ENV HDB_ADMIN_USERNAME=admin
|
|
48
|
+
ENV ROOTPATH=/home/harperdb/harper
|
|
49
|
+
ENV TC_AGREEMENT=yes
|
|
50
|
+
ENV NETWORK_OPERATIONSAPI_PORT=9925
|
|
51
|
+
ENV LOGGING_STDSTREAMS=true
|
|
52
|
+
ENV NODE_HOSTNAME=localhost
|
|
53
|
+
ENV DEFAULTS_MODE=prod
|
|
54
|
+
|
|
55
|
+
EXPOSE 9925
|
|
56
|
+
EXPOSE 9926
|
|
57
|
+
EXPOSE 9932
|
|
58
|
+
EXPOSE 9933
|
|
59
|
+
|
|
60
|
+
ENTRYPOINT ["harper"]
|
|
61
|
+
|
|
62
|
+
CMD ["run"]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
rm -Rf studio-src studio
|
|
4
|
+
mkdir studio-src
|
|
5
|
+
cd studio-src
|
|
6
|
+
git clone --branch prod --single-branch --depth 1 https://github.com/HarperFast/studio.git .
|
|
7
|
+
npm install -g pnpm
|
|
8
|
+
pnpm install
|
|
9
|
+
VITE_STUDIO_VERSION="v$(jq -r '.version' ../package.json)" pnpm run build:local
|
|
10
|
+
cd ..
|
|
11
|
+
mkdir studio
|
|
12
|
+
mv ./studio-src/web ./studio/web
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
echo -e "\n📦 Installing core deps"
|
|
6
|
+
npm install
|
|
7
|
+
|
|
8
|
+
echo -e "\n📦 Building project"
|
|
9
|
+
npm run build || true
|
|
10
|
+
|
|
11
|
+
echo -e "\n📦 Creating shrinkwrap"
|
|
12
|
+
npm shrinkwrap
|
|
13
|
+
|
|
14
|
+
./build-tools/build-studio.sh
|
|
15
|
+
|
|
16
|
+
echo -e "\n📦 Building package"
|
|
17
|
+
npm pack
|
|
18
|
+
|
|
19
|
+
version=$(npm pkg get version | tr -d \")
|
|
20
|
+
packageFile="harper-${version}.tgz"
|
|
21
|
+
echo -e "\n📦 Built Harper Pro ${version} in ${packageFile}"
|
|
22
|
+
echo "📦 Run 'npm publish ${packageFile}' to release"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const util = require('util');
|
|
2
|
+
const exec = util.promisify(require('child_process').exec);
|
|
3
|
+
|
|
4
|
+
(async function () {
|
|
5
|
+
// need prebuildify-ci for the downloads to run
|
|
6
|
+
let output = await exec('npm install -g prebuildify-ci');
|
|
7
|
+
console.error(output.stderr);
|
|
8
|
+
console.log(output.stdout);
|
|
9
|
+
// download lmdb (and msgpackr-extract) binaries
|
|
10
|
+
output = await exec('download-lmdb-prebuilds');
|
|
11
|
+
console.error(output.stderr);
|
|
12
|
+
console.log(output.stdout);
|
|
13
|
+
})();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface Logger {
|
|
2
|
+
logLevel: string;
|
|
3
|
+
|
|
4
|
+
notify?: (...args: any[]) => void;
|
|
5
|
+
fatal?: (...args: any[]) => void;
|
|
6
|
+
error?: (...args: any[]) => void;
|
|
7
|
+
warn?: (...args: any[]) => void;
|
|
8
|
+
info?: (...args: any[]) => void;
|
|
9
|
+
debug?: (...args: any[]) => void;
|
|
10
|
+
trace?: (...args: any[]) => void;
|
|
11
|
+
|
|
12
|
+
withTag: (tag: string) => Logger;
|
|
13
|
+
loggerWithTag: (tag: string) => Logger;
|
|
14
|
+
}
|
package/core/components/Scope.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Logger } from '../utility/logging/logger.ts';
|
|
2
2
|
import { loggerWithTag } from '../utility/logging/harper_logger.js';
|
|
3
3
|
import { EventEmitter, once } from 'node:events';
|
|
4
|
+
import { databaseEventsEmitter } from '../resources/databases.ts';
|
|
4
5
|
import { server, type Server } from '../server/Server.ts';
|
|
5
6
|
import { EntryHandler, type EntryHandlerEventMap, type onEntryEventHandler } from './EntryHandler.ts';
|
|
6
7
|
import { OptionsWatcher, OptionsWatcherEventMap } from './OptionsWatcher.ts';
|
|
@@ -17,17 +18,26 @@ export class MissingDefaultFilesOptionError extends Error {
|
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
|
|
21
|
+
export type ScopeEventsMap = {
|
|
22
|
+
all: [...args: unknown[]];
|
|
23
|
+
close: [];
|
|
24
|
+
error: [error: unknown];
|
|
25
|
+
ready: [];
|
|
26
|
+
[record: string]: [...args: unknown[]];
|
|
27
|
+
};
|
|
28
|
+
|
|
20
29
|
/**
|
|
21
30
|
* This class is what is passed to the `handleApplication` function of an extension.
|
|
22
31
|
*
|
|
23
|
-
* It is imperative that the instance is "ready" before
|
|
32
|
+
* It is imperative that the instance is "ready" before it's passed to the `handleApplication` function
|
|
24
33
|
* so that the developer can immediately start using `scope.options`, etc.
|
|
25
34
|
*
|
|
26
35
|
*/
|
|
27
|
-
export class Scope extends EventEmitter {
|
|
36
|
+
export class Scope extends EventEmitter<ScopeEventsMap> {
|
|
28
37
|
#configFilePath: string;
|
|
29
38
|
#directory: string;
|
|
30
|
-
#
|
|
39
|
+
#appName: string;
|
|
40
|
+
#pluginName: string;
|
|
31
41
|
#entryHandler?: EntryHandler;
|
|
32
42
|
#entryHandlers: EntryHandler[];
|
|
33
43
|
#logger: Logger;
|
|
@@ -38,14 +48,24 @@ export class Scope extends EventEmitter {
|
|
|
38
48
|
resources?: Resources;
|
|
39
49
|
server?: Server;
|
|
40
50
|
ready: Promise<any[]>;
|
|
41
|
-
|
|
51
|
+
databaseEvents: typeof databaseEventsEmitter;
|
|
52
|
+
|
|
53
|
+
constructor(
|
|
54
|
+
appName: string,
|
|
55
|
+
pluginName: string,
|
|
56
|
+
directory: string,
|
|
57
|
+
configFilePath: string,
|
|
58
|
+
applicationScope: ApplicationScope
|
|
59
|
+
) {
|
|
42
60
|
super();
|
|
43
61
|
|
|
44
|
-
this.#
|
|
62
|
+
this.#appName = appName;
|
|
63
|
+
this.#pluginName = pluginName;
|
|
45
64
|
this.#directory = directory;
|
|
46
65
|
this.#configFilePath = configFilePath;
|
|
47
|
-
this.#logger = loggerWithTag(this.#
|
|
66
|
+
this.#logger = logger || loggerWithTag(this.#appName);
|
|
48
67
|
|
|
68
|
+
this.databaseEvents = databaseEventsEmitter;
|
|
49
69
|
this.applicationScope = applicationScope;
|
|
50
70
|
this.resources = applicationScope?.resources ?? resources;
|
|
51
71
|
this.server = applicationScope?.server ?? server;
|
|
@@ -56,7 +76,7 @@ export class Scope extends EventEmitter {
|
|
|
56
76
|
this.ready = once(this, 'ready');
|
|
57
77
|
|
|
58
78
|
// Create the options instance for the scope immediately
|
|
59
|
-
this.options = new OptionsWatcher(
|
|
79
|
+
this.options = new OptionsWatcher(pluginName, configFilePath, this.#logger)
|
|
60
80
|
.on('error', this.#handleError.bind(this))
|
|
61
81
|
.on('change', this.#optionsWatcherChangeListener.bind(this)())
|
|
62
82
|
.on('ready', this.#handleOptionsWatcherReady.bind(this));
|
|
@@ -66,8 +86,12 @@ export class Scope extends EventEmitter {
|
|
|
66
86
|
return this.#logger;
|
|
67
87
|
}
|
|
68
88
|
|
|
69
|
-
get
|
|
70
|
-
return this.#
|
|
89
|
+
get appName(): string {
|
|
90
|
+
return this.#appName;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get pluginName(): string {
|
|
94
|
+
return this.#pluginName;
|
|
71
95
|
}
|
|
72
96
|
|
|
73
97
|
get directory(): string {
|
|
@@ -107,7 +131,7 @@ export class Scope extends EventEmitter {
|
|
|
107
131
|
}
|
|
108
132
|
|
|
109
133
|
#createEntryHandler(config: FilesOption | FileAndURLPathConfig): EntryHandler {
|
|
110
|
-
const entryHandler = new EntryHandler(this.#
|
|
134
|
+
const entryHandler = new EntryHandler(this.#pluginName, this.#directory, config, this.#logger)
|
|
111
135
|
.on('error', this.#handleError.bind(this))
|
|
112
136
|
.on('add', this.#defaultEntryHandlerListener('add'))
|
|
113
137
|
.on('change', this.#defaultEntryHandlerListener('change'))
|
|
@@ -279,7 +303,7 @@ export class Scope extends EventEmitter {
|
|
|
279
303
|
}
|
|
280
304
|
|
|
281
305
|
requestRestart() {
|
|
282
|
-
this.#logger.debug?.(`Restart requested from ${this
|
|
306
|
+
this.#logger.debug?.(`Restart requested from ${this.#pluginName} scope for ${this.#appName}`);
|
|
283
307
|
requestRestart();
|
|
284
308
|
}
|
|
285
309
|
|
|
@@ -60,12 +60,20 @@ export function loadComponentDirectories(loadedPluginModules?: Map<any, any>, lo
|
|
|
60
60
|
if (!appEntry.isDirectory() && !appEntry.isSymbolicLink()) continue;
|
|
61
61
|
const appName = appEntry.name;
|
|
62
62
|
const appFolder = join(CF_ROUTES_DIR, appName);
|
|
63
|
-
cfsLoaded.push(
|
|
63
|
+
cfsLoaded.push(
|
|
64
|
+
loadComponent(appFolder, resources, HDB_ROOT_DIR_NAME, { isRoot: false, autoReload: false, appName })
|
|
65
|
+
);
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
const hdbAppFolder = process.env.RUN_HDB_APP;
|
|
67
69
|
if (hdbAppFolder) {
|
|
68
|
-
cfsLoaded.push(
|
|
70
|
+
cfsLoaded.push(
|
|
71
|
+
loadComponent(hdbAppFolder, resources, hdbAppFolder, {
|
|
72
|
+
isRoot: false,
|
|
73
|
+
autoReload: Boolean(process.env.DEV_MODE),
|
|
74
|
+
appName: hdbAppFolder,
|
|
75
|
+
})
|
|
76
|
+
);
|
|
69
77
|
}
|
|
70
78
|
return Promise.all(cfsLoaded).then(() => {
|
|
71
79
|
watchesSetup = true;
|
|
@@ -176,7 +184,7 @@ function sequentiallyHandleApplication(scope: Scope, plugin: PluginModule) {
|
|
|
176
184
|
// Timeout priority is user config, plugin default, finally 30 seconds
|
|
177
185
|
const timeout = scope.options.get(['timeout']) || plugin.defaultTimeout || 30_000; // default 30 second timeout
|
|
178
186
|
if (typeof timeout !== 'number') {
|
|
179
|
-
throw new Error(`Invalid timeout value for ${scope.
|
|
187
|
+
throw new Error(`Invalid timeout value for ${scope.pluginName}. Expected a number, received: ${typeof timeout}`);
|
|
180
188
|
}
|
|
181
189
|
let whenResolved, timer;
|
|
182
190
|
const callback = () => {
|
|
@@ -184,13 +192,13 @@ function sequentiallyHandleApplication(scope: Scope, plugin: PluginModule) {
|
|
|
184
192
|
whenResolved(sequentiallyHandleApplication(scope, plugin));
|
|
185
193
|
};
|
|
186
194
|
const store = Status.primaryStore;
|
|
187
|
-
const lockAcquired = store.tryLock(scope.
|
|
195
|
+
const lockAcquired = store.tryLock(scope.pluginName, callback);
|
|
188
196
|
|
|
189
197
|
if (!lockAcquired) {
|
|
190
198
|
return new Promise((resolve, reject) => {
|
|
191
199
|
whenResolved = resolve;
|
|
192
200
|
timer = setTimeout(() => {
|
|
193
|
-
reject(new Error(`Timeout waiting for lock on ${scope.
|
|
201
|
+
reject(new Error(`Timeout waiting for lock on ${scope.pluginName}`));
|
|
194
202
|
}, timeout + 5_000); // extra time for lock acquisition
|
|
195
203
|
});
|
|
196
204
|
}
|
|
@@ -206,13 +214,18 @@ function sequentiallyHandleApplication(scope: Scope, plugin: PluginModule) {
|
|
|
206
214
|
new Promise(
|
|
207
215
|
(_, reject) =>
|
|
208
216
|
(loadTimeout = setTimeout(
|
|
209
|
-
() =>
|
|
217
|
+
() =>
|
|
218
|
+
reject(
|
|
219
|
+
new Error(
|
|
220
|
+
`handleApplication timed out after ${timeout}ms for ${scope.pluginName} on behalf of ${scope.appName}`
|
|
221
|
+
)
|
|
222
|
+
),
|
|
210
223
|
timeout
|
|
211
224
|
))
|
|
212
225
|
),
|
|
213
226
|
]);
|
|
214
227
|
} finally {
|
|
215
|
-
Status.primaryStore.unlock(scope.
|
|
228
|
+
Status.primaryStore.unlock(scope.pluginName);
|
|
216
229
|
clearTimeout(loadTimeout);
|
|
217
230
|
}
|
|
218
231
|
});
|
|
@@ -222,8 +235,8 @@ export interface LoadComponentOptions {
|
|
|
222
235
|
isRoot?: boolean;
|
|
223
236
|
applicationScope?: ApplicationScope;
|
|
224
237
|
autoReload?: boolean;
|
|
225
|
-
applicationContainment?: ApplicationContainment;
|
|
226
238
|
providedLoadedComponents?: Map<any, any>;
|
|
239
|
+
appName?: string;
|
|
227
240
|
}
|
|
228
241
|
|
|
229
242
|
/**
|
|
@@ -249,6 +262,7 @@ export async function loadComponent(
|
|
|
249
262
|
applicationScope = new ApplicationScope(basename(componentDirectory), resources, server),
|
|
250
263
|
isRoot,
|
|
251
264
|
autoReload,
|
|
265
|
+
appName,
|
|
252
266
|
} = options;
|
|
253
267
|
applicationScope.verifyPath ??= componentDirectory;
|
|
254
268
|
if (providedLoadedComponents) loadedComponents = providedLoadedComponents;
|
|
@@ -321,7 +335,10 @@ export async function loadComponent(
|
|
|
321
335
|
subApplicationScope.verifyPath = componentPath;
|
|
322
336
|
if (!process.env.HARPER_SAFE_MODE) {
|
|
323
337
|
extensionModule = await loadComponent(componentPath, resources, origin, {
|
|
338
|
+
isRoot: false,
|
|
324
339
|
applicationScope: subApplicationScope,
|
|
340
|
+
autoReload: false,
|
|
341
|
+
appName: appName || componentName,
|
|
325
342
|
});
|
|
326
343
|
componentFunctionality[componentName] = true;
|
|
327
344
|
}
|
|
@@ -373,7 +390,7 @@ export async function loadComponent(
|
|
|
373
390
|
|
|
374
391
|
// New Plugin API (`handleApplication`)
|
|
375
392
|
if (resources.isWorker && extensionModule.handleApplication) {
|
|
376
|
-
const scope = new Scope(componentName, componentDirectory, configPath, applicationScope);
|
|
393
|
+
const scope = new Scope(appName || 'harper', componentName, componentDirectory, configPath, applicationScope);
|
|
377
394
|
|
|
378
395
|
await sequentiallyHandleApplication(scope, extensionModule);
|
|
379
396
|
|
|
@@ -477,7 +494,7 @@ export async function loadComponent(
|
|
|
477
494
|
return loadComponentDirectories(); // return the promise
|
|
478
495
|
});
|
|
479
496
|
}
|
|
480
|
-
if (config.extensionModule || config.pluginModule) {
|
|
497
|
+
if ((config.extensionModule || config.pluginModule) && (!isMainThread || config.runOnMainThread)) {
|
|
481
498
|
const extensionModule = await scopedImport(
|
|
482
499
|
join(componentDirectory, config.extensionModule || config.pluginModule),
|
|
483
500
|
applicationScope
|
|
@@ -408,7 +408,15 @@ async function deployComponent(req) {
|
|
|
408
408
|
const componentLoader = require('./componentLoader.ts');
|
|
409
409
|
let lastError;
|
|
410
410
|
componentLoader.setErrorReporter((error) => (lastError = error));
|
|
411
|
-
await componentLoader.loadComponent(
|
|
411
|
+
await componentLoader.loadComponent(
|
|
412
|
+
application.dirPath,
|
|
413
|
+
pseudoResources,
|
|
414
|
+
undefined,
|
|
415
|
+
false,
|
|
416
|
+
undefined,
|
|
417
|
+
false,
|
|
418
|
+
req.project
|
|
419
|
+
);
|
|
412
420
|
|
|
413
421
|
if (lastError) throw lastError;
|
|
414
422
|
}
|
|
@@ -473,7 +481,7 @@ async function getComponents() {
|
|
|
473
481
|
const list = await fs.readdir(dir, { withFileTypes: true });
|
|
474
482
|
for (let item of list) {
|
|
475
483
|
const itemName = item.name;
|
|
476
|
-
if (itemName
|
|
484
|
+
if (itemName === 'node_modules') continue;
|
|
477
485
|
const itemPath = path.join(dir, itemName);
|
|
478
486
|
if (item.isDirectory() || item.isSymbolicLink()) {
|
|
479
487
|
let res = {
|
|
@@ -140,7 +140,7 @@ function createConfigFile(args, skipFsValidation = false) {
|
|
|
140
140
|
if (configDoc.errors?.length > 0) {
|
|
141
141
|
throw handleHDBError(
|
|
142
142
|
new Error(),
|
|
143
|
-
`Error parsing
|
|
143
|
+
`Error parsing ${configFilePath} ${configDoc.errors}`,
|
|
144
144
|
HTTP_STATUS_CODES.BAD_REQUEST,
|
|
145
145
|
undefined,
|
|
146
146
|
undefined,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
class CreateTableObject {
|
|
4
|
-
constructor(schema, table,
|
|
4
|
+
constructor(schema, table, primary_key) {
|
|
5
5
|
this.schema = schema;
|
|
6
6
|
this.table = table;
|
|
7
|
-
this.
|
|
7
|
+
this.primary_key = primary_key;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
package/core/dataLayer/schema.js
CHANGED
|
@@ -13,7 +13,7 @@ const harperBridge = require('./harperBridge/harperBridge.js');
|
|
|
13
13
|
const { handleHDBError, hdbErrors, ClientError } = require('../utility/errors/hdbError.js');
|
|
14
14
|
const { HDB_ERROR_MSGS, HTTP_STATUS_CODES } = hdbErrors;
|
|
15
15
|
const { SchemaEventMsg } = require('../server/threads/itc.js');
|
|
16
|
-
const { getDatabases } = require('../resources/databases.ts');
|
|
16
|
+
const { getDatabases, dropTableMeta } = require('../resources/databases.ts');
|
|
17
17
|
const { transformReq } = require('../utility/common_utils.js');
|
|
18
18
|
const { server } = require('../server/Server.ts');
|
|
19
19
|
const { cleanupOrphans } = require('../resources/blob.ts');
|
|
@@ -96,7 +96,7 @@ async function createSchemaStructure(schemaCreateObject) {
|
|
|
96
96
|
|
|
97
97
|
async function createTable(createTableObject) {
|
|
98
98
|
transformReq(createTableObject);
|
|
99
|
-
createTableObject.
|
|
99
|
+
createTableObject.primary_key = createTableObject.primary_key ?? createTableObject.hash_attribute;
|
|
100
100
|
return await createTableStructure(createTableObject);
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -108,7 +108,7 @@ async function createTableStructure(createTableObject) {
|
|
|
108
108
|
schema: DB_NAME_CONSTRAINTS,
|
|
109
109
|
table: TABLE_NAME_CONSTRAINTS,
|
|
110
110
|
residence: Joi.array().items(Joi.string().min(1)).optional(),
|
|
111
|
-
|
|
111
|
+
primary_key: PRIMARY_KEY_CONSTRAINTS,
|
|
112
112
|
})
|
|
113
113
|
);
|
|
114
114
|
if (validation) throw new ClientError(validation.message);
|
|
@@ -132,7 +132,7 @@ async function createTableStructure(createTableObject) {
|
|
|
132
132
|
name: createTableObject.table,
|
|
133
133
|
schema: createTableObject.schema,
|
|
134
134
|
id: uuidV4(),
|
|
135
|
-
|
|
135
|
+
primary_key: createTableObject.primary_key,
|
|
136
136
|
};
|
|
137
137
|
|
|
138
138
|
if (createTableObject.residence) {
|
|
@@ -219,6 +219,8 @@ async function dropTable(dropTableObject) {
|
|
|
219
219
|
|
|
220
220
|
await harperBridge.dropTable(dropTableObject);
|
|
221
221
|
|
|
222
|
+
await dropTableMeta({ table: dropTableObject.table, database: dropTableObject.schema });
|
|
223
|
+
|
|
222
224
|
let response = await server.replication.replicateOperation(dropTableObject);
|
|
223
225
|
response.message = `successfully deleted table '${dropTableObject.schema}.${dropTableObject.table}'`;
|
|
224
226
|
return response;
|
|
@@ -260,7 +262,7 @@ async function dropAttribute(dropAttributeObject) {
|
|
|
260
262
|
|
|
261
263
|
if (
|
|
262
264
|
dropAttributeObject.attribute ===
|
|
263
|
-
global.hdb_schema[dropAttributeObject.schema][dropAttributeObject.table].
|
|
265
|
+
global.hdb_schema[dropAttributeObject.schema][dropAttributeObject.table].primary_key
|
|
264
266
|
) {
|
|
265
267
|
throw handleHDBError(
|
|
266
268
|
new Error(),
|
|
@@ -192,7 +192,7 @@ async function descTable(describeTableObject, attrPerms) {
|
|
|
192
192
|
let tableResult = {
|
|
193
193
|
schema,
|
|
194
194
|
name: tableObj.tableName,
|
|
195
|
-
|
|
195
|
+
primary_key: tableObj.attributes.find((attribute) => attribute.isPrimaryKey || attribute.isPrimaryKey)?.name,
|
|
196
196
|
audit: tableObj.audit,
|
|
197
197
|
schema_defined: tableObj.schemaDefined,
|
|
198
198
|
attributes,
|