@muze-nl/simplystore 0.3.0 → 0.3.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/package.json +2 -2
- package/src/server.mjs +4 -1
- package/www/assets/css/page.css +34 -0
- package/www/help/index.html +94 -0
- package/www/index.html +71 -20
- package/.dockerignore +0 -8
- package/.github/workflows/docker-build.yml +0 -45
- package/Dockerfile +0 -60
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@muze-nl/simplystore",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"main": "src/server.mjs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"homepage": "https://github.com/simplyedit/simplystore#readme",
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@muze-nl/jsontag": "^0.8.4",
|
|
19
|
-
"array-where-select": "^0.3.
|
|
19
|
+
"array-where-select": "^0.3.1",
|
|
20
20
|
"codemirror": "^6.0.1",
|
|
21
21
|
"express": "^4.18.1",
|
|
22
22
|
"json-pointer": "^0.6.2",
|
package/src/server.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import pointer from 'json-pointer'
|
|
|
4
4
|
import JSONTag from '@muze-nl/jsontag'
|
|
5
5
|
import {JSONPath} from 'jsonpath-plus'
|
|
6
6
|
import {VM} from 'vm2'
|
|
7
|
-
import {_,from} from 'array-where-select'
|
|
7
|
+
import {_,from,not,anyOf,allOf} from 'array-where-select'
|
|
8
8
|
import { fileURLToPath } from 'url'
|
|
9
9
|
import path from 'path'
|
|
10
10
|
|
|
@@ -195,6 +195,9 @@ async function main(options) {
|
|
|
195
195
|
meta: meta,
|
|
196
196
|
_: _,
|
|
197
197
|
from: from,
|
|
198
|
+
not: not,
|
|
199
|
+
anyOf: anyOf,
|
|
200
|
+
allOf: allOf,
|
|
198
201
|
console: connectConsole(res),
|
|
199
202
|
JSONTag: JSONTag,
|
|
200
203
|
request: {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--ds-primary: var(--ds-simplystore);
|
|
3
|
+
--ds-primary-contrast: var(--ds-simplystore-contrast);
|
|
4
|
+
--ds-primary-gradient: var(--ds-simplystore-gradient);
|
|
5
|
+
--ds-primary-gradient-bump: var(--ds-simplystore-gradient-bump);
|
|
6
|
+
}
|
|
7
|
+
html, body {
|
|
8
|
+
height: 100%;
|
|
9
|
+
margin: 0;
|
|
10
|
+
background: var(--ds-black);
|
|
11
|
+
color: var(--ds-white);
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
}
|
|
14
|
+
body {
|
|
15
|
+
display: flow-root;
|
|
16
|
+
overflow: auto;
|
|
17
|
+
}
|
|
18
|
+
a:hover, a:active {
|
|
19
|
+
text-decoration: underline;
|
|
20
|
+
color: var(--ds-simplystore-light);
|
|
21
|
+
}
|
|
22
|
+
a:link {
|
|
23
|
+
text-decoration: none;
|
|
24
|
+
color: var(--ds-simplystore);
|
|
25
|
+
}
|
|
26
|
+
a:visited {
|
|
27
|
+
text-decoration: none;
|
|
28
|
+
color: var(--ds-simplystore-dark);
|
|
29
|
+
}
|
|
30
|
+
pre {
|
|
31
|
+
background-color: var(--ds-grey-80);
|
|
32
|
+
border-radius: 8px;
|
|
33
|
+
padding: 8px;
|
|
34
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<link rel="stylesheet" href="/assets/css/style.css">
|
|
3
|
+
<link rel="stylesheet" href="/assets/css/page.css">
|
|
4
|
+
<section class="ds-space">
|
|
5
|
+
<h1>Help</h1>
|
|
6
|
+
<nav>
|
|
7
|
+
<ul>
|
|
8
|
+
<li><a href="#intro">Introduction</a></li>
|
|
9
|
+
<li><a href="#queries">Queries</a></li>
|
|
10
|
+
<li><a href="#jsontag">JSONTag</a></li>
|
|
11
|
+
<li><a href="#fixtures">Fixtures</a></li>
|
|
12
|
+
<li><a href="#about">About</a></li>
|
|
13
|
+
</ul>
|
|
14
|
+
</nav>
|
|
15
|
+
<h2 id="introduction">Introduction</h2>
|
|
16
|
+
<p>
|
|
17
|
+
SimplyStore is a datastore that allows you to query data with javascript. The data is stored and retrieved as JSONTag, an enhanced version of JSON that has support for metadata (type, attributes) and links.
|
|
18
|
+
</p><p>
|
|
19
|
+
SimplyStore has a single dataspace, named <code>data</code>. You can enter a query on the left and press <Control+Enter> to execute it. If you haven't written a query, the right data pane shows an overview of the available data in the dataspace.
|
|
20
|
+
</p>
|
|
21
|
+
<h2 id="queries">Queries</h2>
|
|
22
|
+
<p>SimplyStore queries are just javascript, so this works:</p>
|
|
23
|
+
<pre class="javascript">data.filter(p => p.name=='John')</pre>
|
|
24
|
+
<p>SimplyStore uses the <a href="//npmjs.com/package/array-where-select" target="_blank">array-where-select library</a> to allow for shorter, more expressive queries, e.g:</p>
|
|
25
|
+
<pre class="javascript">from(data)
|
|
26
|
+
.where({
|
|
27
|
+
name: 'John'
|
|
28
|
+
})
|
|
29
|
+
.select({
|
|
30
|
+
name: _,
|
|
31
|
+
dob: _
|
|
32
|
+
})</pre>
|
|
33
|
+
<p>The <code>_</code> is a placeholder that selects the property value corresponding with the property name on the left.</p>
|
|
34
|
+
<p>This query results in output like this:</p>
|
|
35
|
+
<pre class="JSONTag">[
|
|
36
|
+
{
|
|
37
|
+
"name":"John",
|
|
38
|
+
"dob":<date>"1972-09-20"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name":"Jane",
|
|
42
|
+
"dob":<date>"1986-01-01"
|
|
43
|
+
}
|
|
44
|
+
]</pre>
|
|
45
|
+
<p>See the array-where-select library to learn more about this.</p>
|
|
46
|
+
<h2 id="jsontag">JSONTag</h2>
|
|
47
|
+
<p>JSONtag is backwards compatible with JSON. It adds two important things: links and tags.</p>
|
|
48
|
+
<p>JSON cannot represent data structures with internal references. JSONTag adds a <code><link></code> tag to represent these, like this:</p>
|
|
49
|
+
<pre class="JSONTag">{
|
|
50
|
+
"name": "John",
|
|
51
|
+
"friends": [
|
|
52
|
+
<link>"/persons/1/"
|
|
53
|
+
]
|
|
54
|
+
}</pre>
|
|
55
|
+
<p>Here you also see the first tag pop up. Tags in JSONTag are similar to HTML opening tags. There are no closing tags. Each tag starts with a tagName, which denotes the basic type of the JSON value to the right.</p>
|
|
56
|
+
<p>Available types (tag names) are:</p>
|
|
57
|
+
<h3>JSON</h3>
|
|
58
|
+
<ul>
|
|
59
|
+
<li>boolean</li>
|
|
60
|
+
<li>number</li>
|
|
61
|
+
<li>string</li>
|
|
62
|
+
<li>array</li>
|
|
63
|
+
<li>object</li>
|
|
64
|
+
</ul>
|
|
65
|
+
<h3>Scalars</h3>
|
|
66
|
+
<ul>
|
|
67
|
+
<li>text</li>
|
|
68
|
+
<li>blob</li>
|
|
69
|
+
<li>int (uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64)</li>
|
|
70
|
+
<li>float (float32, float64)</li>
|
|
71
|
+
</ul>
|
|
72
|
+
<h3>Semantic types</h3>
|
|
73
|
+
<ul>
|
|
74
|
+
<li>color</li>
|
|
75
|
+
<li>date</li>
|
|
76
|
+
<li>decimal</li>
|
|
77
|
+
<li>email</li>
|
|
78
|
+
<li>hash</li>
|
|
79
|
+
<li>interval</li>
|
|
80
|
+
<li>link</li>
|
|
81
|
+
<li>money</li>
|
|
82
|
+
<li>phone</li>
|
|
83
|
+
<li>range</li>
|
|
84
|
+
<li>time</li>
|
|
85
|
+
<li>timestamp</li>
|
|
86
|
+
<li>url</li>
|
|
87
|
+
<li>uuid</li>
|
|
88
|
+
</ul>
|
|
89
|
+
<p>Read <a href="//npmjs.com/package/@muze-nl/jsontag" target="_blank">more about JSONTag here</a>.
|
|
90
|
+
<h3 id="fixtures">Fixtures</h3>
|
|
91
|
+
<p>The SimplyStore UI allows you to save and restore queries. These are saved in your browser on your local machine. Because queries are just javascript, you can add your own helper functions. To prevent having to add these to all your seperate queries, the UI has a special 'Fixtures' query. The contents of this query are always prepended to whatever query you send.</p>
|
|
92
|
+
<h3 id="about">About</h3>
|
|
93
|
+
<p>SimplyStore is made by <a href="//muze.nl/" target="_blank">muze.nl</a> and is part of the <a href="//simplyedit.io/" target="_blank">SimplyEdit</a> product range. SimplyStore's source code is open source (MIT) and can be found on <a href="//github.com/SimplyEdit/SimplyStore" target="_blank">//github.com/SimplyEdit/SimplyStore</a></p>
|
|
94
|
+
</section>
|
package/www/index.html
CHANGED
|
@@ -8,33 +8,62 @@
|
|
|
8
8
|
--ds-primary-gradient: var(--ds-simplystore-gradient);
|
|
9
9
|
--ds-primary-gradient-bump: var(--ds-simplystore-gradient-bump);
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
body {
|
|
12
|
+
position: fixed;
|
|
13
|
+
width: 100%;
|
|
14
|
+
display: grid;
|
|
15
|
+
grid-template:
|
|
16
|
+
"header header" 65px
|
|
17
|
+
"code data" auto / 1fr 1fr;
|
|
18
|
+
height: 100%;
|
|
19
|
+
column-gap: 5px;
|
|
20
|
+
}
|
|
21
|
+
header {
|
|
22
|
+
grid-area: header;
|
|
17
23
|
}
|
|
18
24
|
form.Query {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
grid-area: code;
|
|
26
|
+
overflow: auto;
|
|
27
|
+
}
|
|
28
|
+
.dataBrowser {
|
|
29
|
+
position: relative;
|
|
30
|
+
grid-area: data;
|
|
31
|
+
overflow: auto;
|
|
24
32
|
}
|
|
25
33
|
.CodeMirror {
|
|
26
34
|
height: 100% !important;
|
|
27
35
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
|
|
37
|
+
.ds-visible {
|
|
38
|
+
display: block;
|
|
31
39
|
}
|
|
32
|
-
|
|
33
|
-
position:
|
|
40
|
+
.help {
|
|
41
|
+
position: absolute;
|
|
42
|
+
top: 0;
|
|
43
|
+
left: 0;
|
|
34
44
|
width: 100%;
|
|
45
|
+
height: 100%;
|
|
46
|
+
background: var(--ds-black);
|
|
47
|
+
color: var(--ds-white);
|
|
48
|
+
margin:0;
|
|
49
|
+
padding:0;
|
|
50
|
+
overflow: hidden;
|
|
35
51
|
}
|
|
36
|
-
.
|
|
37
|
-
|
|
52
|
+
iframe.full {
|
|
53
|
+
border: 0;
|
|
54
|
+
height: calc(100% + 1px);
|
|
55
|
+
width: calc(100% + 1px);
|
|
56
|
+
border: 0;
|
|
57
|
+
}
|
|
58
|
+
.ds-close {
|
|
59
|
+
position: absolute;
|
|
60
|
+
z-index: 1000;
|
|
61
|
+
top: 0;
|
|
62
|
+
right: 0;
|
|
63
|
+
}
|
|
64
|
+
dialog {
|
|
65
|
+
border: 0;
|
|
66
|
+
margin: 0;
|
|
38
67
|
}
|
|
39
68
|
</style>
|
|
40
69
|
<body class="ds-nightmode">
|
|
@@ -81,13 +110,13 @@
|
|
|
81
110
|
Fixtures
|
|
82
111
|
</button>
|
|
83
112
|
<span class="ds-push-right"></span>
|
|
84
|
-
<button class="ds-button ds-button-icon">
|
|
113
|
+
<button data-simply-command="download" class="ds-button ds-button-icon">
|
|
85
114
|
<svg class="ds-icon ds-icon-feather">
|
|
86
115
|
<use xlink:href="/assets/feather-sprite.svg#download">
|
|
87
116
|
</use></svg>
|
|
88
117
|
Download
|
|
89
118
|
</button>
|
|
90
|
-
<button class="ds-button ds-button-icon">
|
|
119
|
+
<button data-simply-command="help" class="ds-button ds-button-icon">
|
|
91
120
|
<svg class="ds-icon ds-icon-feather">
|
|
92
121
|
<use xlink:href="/assets/feather-sprite.svg#help-circle">
|
|
93
122
|
</use></svg>
|
|
@@ -102,6 +131,14 @@
|
|
|
102
131
|
|
|
103
132
|
<div class="dataBrowser">
|
|
104
133
|
<textarea id="databrowser" class="CodeMirror" data-simply-field="data"></textarea>
|
|
134
|
+
<dialog class="help">
|
|
135
|
+
<button data-simply-command="close" class="ds-button ds-button-naked ds-close" data-simply-value="button[data-simply-command=help]">
|
|
136
|
+
<svg class="ds-icon ds-icon-feather">
|
|
137
|
+
<use xlink:href="/assets/feather-sprite.svg#x">
|
|
138
|
+
</use></svg>
|
|
139
|
+
</button>
|
|
140
|
+
<iframe class="full" src="/help/"></iframe>
|
|
141
|
+
<dialog>
|
|
105
142
|
</div>
|
|
106
143
|
|
|
107
144
|
<script src="/codemirror/lib/codemirror.js"></script>
|
|
@@ -175,6 +212,20 @@
|
|
|
175
212
|
let fixtures = await this.app.actions.loadFixtures()
|
|
176
213
|
codeEditor.setValue(fixtures)
|
|
177
214
|
codeEditor.focus()
|
|
215
|
+
},
|
|
216
|
+
'help': async function(el) {
|
|
217
|
+
let help = document.querySelector('.help');
|
|
218
|
+
if (help.open) {
|
|
219
|
+
help.removeAttribute('open')
|
|
220
|
+
el.classList.remove('ds-selected')
|
|
221
|
+
} else {
|
|
222
|
+
help.setAttribute('open','open')
|
|
223
|
+
el.classList.add('ds-selected')
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
'close': async function(el, value) {
|
|
227
|
+
el.closest('dialog').removeAttribute('open')
|
|
228
|
+
document.querySelector(value).classList.remove('ds-selected')
|
|
178
229
|
}
|
|
179
230
|
},
|
|
180
231
|
actions: {
|
package/.dockerignore
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Build Docker Image
|
|
3
|
-
|
|
4
|
-
on:
|
|
5
|
-
push:
|
|
6
|
-
branches:
|
|
7
|
-
- master
|
|
8
|
-
- main
|
|
9
|
-
pull_request:
|
|
10
|
-
branches: [ main, master ]
|
|
11
|
-
# Allow manually triggering the workflow.
|
|
12
|
-
workflow_dispatch:
|
|
13
|
-
|
|
14
|
-
# Cancels all previous workflow runs for the same branch that have not yet completed.
|
|
15
|
-
concurrency:
|
|
16
|
-
# The concurrency group contains the workflow name and the branch name.
|
|
17
|
-
group: ${{ github.workflow }}-${{ github.ref }}
|
|
18
|
-
cancel-in-progress: true
|
|
19
|
-
|
|
20
|
-
jobs:
|
|
21
|
-
build-docker:
|
|
22
|
-
runs-on: ubuntu-latest
|
|
23
|
-
steps:
|
|
24
|
-
- name: Create docker tag (from git reference)
|
|
25
|
-
# A tag name may only contain lower- and uppercase letters, digits, underscores, periods and dashes.
|
|
26
|
-
run: |
|
|
27
|
-
echo "TAG=$(echo -n "${{ github.ref_name }}" \
|
|
28
|
-
| tr --complement --squeeze-repeats '[:alnum:]._-' '_')" \
|
|
29
|
-
>> "${GITHUB_ENV}"
|
|
30
|
-
|
|
31
|
-
- uses: actions/checkout@v3
|
|
32
|
-
|
|
33
|
-
- name: Login to GitHub Container Registry
|
|
34
|
-
uses: docker/login-action@v2
|
|
35
|
-
with:
|
|
36
|
-
registry: ghcr.io
|
|
37
|
-
username: ${{ github.actor }}
|
|
38
|
-
password: ${{ secrets.GITHUB_TOKEN }}
|
|
39
|
-
|
|
40
|
-
- name: Build Docker Image
|
|
41
|
-
run: |
|
|
42
|
-
docker build \
|
|
43
|
-
--tag "ghcr.io/poef/jsontag-rest-server:${{ env.TAG }}" \
|
|
44
|
-
.
|
|
45
|
-
docker push "ghcr.io/poef/jsontag-rest-server:${{ env.TAG }}"
|
package/Dockerfile
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# ==============================================================================
|
|
2
|
-
# Dependencies
|
|
3
|
-
# ------------------------------------------------------------------------------
|
|
4
|
-
FROM node:18-alpine3.17 as builder
|
|
5
|
-
|
|
6
|
-
WORKDIR /usr/src/app
|
|
7
|
-
COPY package.json ./
|
|
8
|
-
|
|
9
|
-
# @TODO: Once development is stable, `npm ci --only=production` should be used instead of `npm install`
|
|
10
|
-
RUN npm install --omit=dev
|
|
11
|
-
# ==============================================================================
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# ==============================================================================
|
|
15
|
-
# Application
|
|
16
|
-
# ------------------------------------------------------------------------------
|
|
17
|
-
FROM alpine:3.17
|
|
18
|
-
|
|
19
|
-
ENV NODE_ENV=production
|
|
20
|
-
|
|
21
|
-
RUN addgroup -g 1000 node \
|
|
22
|
-
&& adduser -u 1000 -G node -s /bin/sh -D node \
|
|
23
|
-
&& apk add --no-cache nodejs=~18.14
|
|
24
|
-
|
|
25
|
-
COPY --chown=node:node . /app
|
|
26
|
-
COPY --chown=node:node --from=builder /usr/src/app/node_modules /app/node_modules
|
|
27
|
-
|
|
28
|
-
WORKDIR /app
|
|
29
|
-
|
|
30
|
-
CMD [ "node", "/app/src/main.mjs" ]
|
|
31
|
-
# ==============================================================================
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# ==============================================================================
|
|
35
|
-
# Metadata
|
|
36
|
-
# ------------------------------------------------------------------------------
|
|
37
|
-
# @TODO: Once development is stable, the following should also be added
|
|
38
|
-
# org.label-schema.build-date=${BUILD_DATE} \ # Usually $(date --iso-8601=seconds)
|
|
39
|
-
# org.label-schema.vcs-ref=${BUILD_REF} \ # Usually $(git describe --tags --always)
|
|
40
|
-
# org.label-schema.version=${VERSION} \ # Usually $(git describe --tags --abbrev=0)
|
|
41
|
-
# org.opencontainers.image.created="${BUILD_DATE}" \
|
|
42
|
-
# org.opencontainers.image.version="${VERSION}"
|
|
43
|
-
LABEL maintainer="Auke van Slooten <auke@muze.nl>" \
|
|
44
|
-
org.label-schema.description="JSONTag REST Server" \
|
|
45
|
-
org.label-schema.docker.cmd='docker run --expose 3000 --interactive --name=jsontag-rest-server --rm --tty --volume "\$PWD/my-data.json:/app/data.jsontag" jsontag-rest-server' \
|
|
46
|
-
org.label-schema.schema-version="1.0" \
|
|
47
|
-
org.label-schema.name="jsontag-rest-server" \
|
|
48
|
-
org.label-schema.url="https://github.com/poef/jsontag-rest-server" \
|
|
49
|
-
org.label-schema.usage="https://github.com/poef/jsontag-rest-server" \
|
|
50
|
-
org.label-schema.vcs-url="https://github.com/poef/jsontag-rest-server" \
|
|
51
|
-
org.label-schema.vendor="Auke van Slooten" \
|
|
52
|
-
org.opencontainers.image.authors="Auke van Slooten <auke@muze.nl>" \
|
|
53
|
-
org.opencontainers.image.description="JSONTag REST Server" \
|
|
54
|
-
org.opencontainers.image.documentation="https://github.com/poef/jsontag-rest-server" \
|
|
55
|
-
org.opencontainers.image.licenses="MIT" \
|
|
56
|
-
org.opencontainers.image.source="https://github.com/poef/jsontag-rest-server" \
|
|
57
|
-
org.opencontainers.image.title="jsontag-rest-server" \
|
|
58
|
-
org.opencontainers.image.url="https://github.com/poef/jsontag-rest-server" \
|
|
59
|
-
org.opencontainers.image.vendor="Auke van Slooten"
|
|
60
|
-
# ==============================================================================
|