@nzz/q-cli 1.10.3 → 2.0.0-beta.10
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/README.md +22 -313
- package/dist/createCustomCodeItem.js +70 -0
- package/dist/enums.js +6 -0
- package/dist/index.js +80 -0
- package/dist/interfaces.js +1 -0
- package/dist/newCustomCode.js +107 -0
- package/dist/updateItem.js +140 -0
- package/dist/utils.js +88 -0
- package/package.json +29 -36
- package/.nvmrc +0 -1
- package/.travis.yml +0 -17
- package/.vscode/launch.json +0 -36
- package/.vscode/settings.json +0 -5
- package/LICENSE +0 -21
- package/bin/commands/bootstrap.js +0 -68
- package/bin/commands/qItem/configStore.js +0 -144
- package/bin/commands/qItem/copyItem/copyItem.js +0 -103
- package/bin/commands/qItem/copyItem/copySchema.json +0 -37
- package/bin/commands/qItem/createCustomCodeItem/createCustomCodeItem.js +0 -81
- package/bin/commands/qItem/createCustomCodeItem/schema.json +0 -41
- package/bin/commands/qItem/helpers.js +0 -102
- package/bin/commands/qItem/itemService.js +0 -310
- package/bin/commands/qItem/resourcesService.js +0 -148
- package/bin/commands/qItem/schemaService.js +0 -65
- package/bin/commands/qItem/updateItem/updateItem.js +0 -64
- package/bin/commands/server.js +0 -80
- package/bin/q.js +0 -213
- package/dev-server/config/default.js +0 -51
- package/dev-server/public/favicon.ico +0 -0
- package/dev-server/public/style.css +0 -64
- package/dev-server/routes/dev-view.js +0 -52
- package/dev-server/routes/file.js +0 -10
- package/dev-server/routes/rendering-info.js +0 -130
- package/dev-server/routes/routes.js +0 -6
- package/dev-server/routes/tool-default.js +0 -108
- package/dev-server/server-plugins.js +0 -1
- package/dev-server/server.js +0 -18
- package/dev-server/views/index.html +0 -184
- package/skeletons/custom-code-skeleton/.nvmrc +0 -1
- package/skeletons/custom-code-skeleton/.vscode/settings.json +0 -5
- package/skeletons/custom-code-skeleton/README.md +0 -26
- package/skeletons/custom-code-skeleton/index.d.ts +0 -3
- package/skeletons/custom-code-skeleton/package-lock.json +0 -7355
- package/skeletons/custom-code-skeleton/package.json +0 -46
- package/skeletons/custom-code-skeleton/q.config.json +0 -60
- package/skeletons/custom-code-skeleton/rollup.config.js +0 -185
- package/skeletons/custom-code-skeleton/src/App.scss +0 -5
- package/skeletons/custom-code-skeleton/src/App.svelte +0 -7
- package/skeletons/custom-code-skeleton/src/enums.ts +0 -0
- package/skeletons/custom-code-skeleton/src/interfaces.ts +0 -0
- package/skeletons/custom-code-skeleton/src/main-prod.ts +0 -4
- package/skeletons/custom-code-skeleton/src/main.scss +0 -1
- package/skeletons/custom-code-skeleton/src/main.ts +0 -18
- package/skeletons/custom-code-skeleton/tsconfig.json +0 -16
- package/skeletons/et-utils-package-skeleton/.nvmrc +0 -1
- package/skeletons/et-utils-package-skeleton/README.md +0 -12
- package/skeletons/et-utils-package-skeleton/jest.config.ts +0 -17
- package/skeletons/et-utils-package-skeleton/package-lock.json +0 -3969
- package/skeletons/et-utils-package-skeleton/package.json +0 -40
- package/skeletons/et-utils-package-skeleton/scripts/package-fixup.sh +0 -13
- package/skeletons/et-utils-package-skeleton/src/Service.ts +0 -8
- package/skeletons/et-utils-package-skeleton/src/index.ts +0 -4
- package/skeletons/et-utils-package-skeleton/test/Service.spec.ts +0 -10
- package/skeletons/et-utils-package-skeleton/test/tsconfig.json +0 -8
- package/skeletons/et-utils-package-skeleton/tsconfig-base.json +0 -10
- package/skeletons/et-utils-package-skeleton/tsconfig-cjs.json +0 -8
- package/skeletons/et-utils-package-skeleton/tsconfig.json +0 -8
- package/skeletons/server-skeleton/.nvmrc +0 -1
- package/skeletons/server-skeleton/Dockerfile +0 -19
- package/skeletons/server-skeleton/auth/routes.js +0 -85
- package/skeletons/server-skeleton/auth/strategyOptions.js +0 -28
- package/skeletons/server-skeleton/config/base.js +0 -45
- package/skeletons/server-skeleton/config/db.js +0 -6
- package/skeletons/server-skeleton/config/editor.js +0 -105
- package/skeletons/server-skeleton/config/rendering-info.js +0 -70
- package/skeletons/server-skeleton/config/screenshot.js +0 -80
- package/skeletons/server-skeleton/config/targets.js +0 -31
- package/skeletons/server-skeleton/config/tools.js +0 -65
- package/skeletons/server-skeleton/files/favicon.png +0 -0
- package/skeletons/server-skeleton/files/system.js +0 -3612
- package/skeletons/server-skeleton/index.js +0 -106
- package/skeletons/server-skeleton/package-lock.json +0 -1825
- package/skeletons/server-skeleton/package.json +0 -29
- package/skeletons/tool-skeleton/.dockerignore +0 -1
- package/skeletons/tool-skeleton/.nvmrc +0 -1
- package/skeletons/tool-skeleton/.travis.yml +0 -26
- package/skeletons/tool-skeleton/.vscode/settings.json +0 -5
- package/skeletons/tool-skeleton/Dockerfile +0 -19
- package/skeletons/tool-skeleton/LICENSE +0 -20
- package/skeletons/tool-skeleton/README.md +0 -104
- package/skeletons/tool-skeleton/index.js +0 -32
- package/skeletons/tool-skeleton/package-lock.json +0 -10108
- package/skeletons/tool-skeleton/package.json +0 -45
- package/skeletons/tool-skeleton/resources/display-options-schema.json +0 -11
- package/skeletons/tool-skeleton/resources/fixtures/data/basic.json +0 -4
- package/skeletons/tool-skeleton/resources/locales/de/translation.json +0 -1
- package/skeletons/tool-skeleton/resources/locales/en/translation.json +0 -1
- package/skeletons/tool-skeleton/resources/locales/fr/translation.json +0 -1
- package/skeletons/tool-skeleton/resources/schema.json +0 -16
- package/skeletons/tool-skeleton/rollup.config.js +0 -75
- package/skeletons/tool-skeleton/routes/fixtures/data.js +0 -15
- package/skeletons/tool-skeleton/routes/health.js +0 -10
- package/skeletons/tool-skeleton/routes/locales.js +0 -21
- package/skeletons/tool-skeleton/routes/rendering-info/web.js +0 -97
- package/skeletons/tool-skeleton/routes/routes.js +0 -8
- package/skeletons/tool-skeleton/routes/schema.js +0 -19
- package/skeletons/tool-skeleton/routes/script.js +0 -17
- package/skeletons/tool-skeleton/routes/stylesheet.js +0 -17
- package/skeletons/tool-skeleton/sass.config.js +0 -66
- package/skeletons/tool-skeleton/scripts_src/default.js +0 -3
- package/skeletons/tool-skeleton/styles_src/_variables.scss +0 -1
- package/skeletons/tool-skeleton/styles_src/main.scss +0 -2
- package/skeletons/tool-skeleton/test/e2e-tests.js +0 -162
- package/skeletons/tool-skeleton/views/dynamic/YourTool.scss +0 -5
- package/skeletons/tool-skeleton/views/dynamic/YourTool.svelte +0 -19
- package/skeletons/tool-skeleton/views/static/App.scss +0 -5
- package/skeletons/tool-skeleton/views/static/App.svelte +0 -21
- package/skeletons/tool-skeleton/views/static/components/Footer.svelte +0 -31
- package/skeletons/tool-skeleton/views/static/components/Header.svelte +0 -7
- package/skeletons/toolv2-skeleton/.husky/pre-commit +0 -6
- package/skeletons/toolv2-skeleton/.nvmrc +0 -1
- package/skeletons/toolv2-skeleton/.prettierrc.cjs +0 -15
- package/skeletons/toolv2-skeleton/.travis.yml +0 -30
- package/skeletons/toolv2-skeleton/.vscode/settings.json +0 -6
- package/skeletons/toolv2-skeleton/Dockerfile +0 -19
- package/skeletons/toolv2-skeleton/LICENSE +0 -21
- package/skeletons/toolv2-skeleton/README.md +0 -99
- package/skeletons/toolv2-skeleton/dev.js +0 -7
- package/skeletons/toolv2-skeleton/index.js +0 -39
- package/skeletons/toolv2-skeleton/jest.config.ts +0 -39
- package/skeletons/toolv2-skeleton/nodemon.json +0 -4
- package/skeletons/toolv2-skeleton/package-lock.json +0 -21382
- package/skeletons/toolv2-skeleton/package.json +0 -80
- package/skeletons/toolv2-skeleton/resources/display-options-schema.json +0 -11
- package/skeletons/toolv2-skeleton/resources/locales/de/translation.json +0 -8
- package/skeletons/toolv2-skeleton/resources/locales/en/translation.json +0 -10
- package/skeletons/toolv2-skeleton/resources/locales/fr/translation.json +0 -10
- package/skeletons/toolv2-skeleton/resources/schema.json +0 -66
- package/skeletons/toolv2-skeleton/rollup.config.js +0 -48
- package/skeletons/toolv2-skeleton/scripts/postinstall.sh +0 -5
- package/skeletons/toolv2-skeleton/src/.eslintrc.cjs +0 -52
- package/skeletons/toolv2-skeleton/src/components/Main.spec.ts +0 -15
- package/skeletons/toolv2-skeleton/src/components/Main.svelte +0 -32
- package/skeletons/toolv2-skeleton/src/enums.ts +0 -11
- package/skeletons/toolv2-skeleton/src/helpers/fixture-generators.ts +0 -38
- package/skeletons/toolv2-skeleton/src/helpers/toolRuntimeConfig.ts +0 -15
- package/skeletons/toolv2-skeleton/src/interfaces.ts +0 -82
- package/skeletons/toolv2-skeleton/src/modules.d.ts +0 -8
- package/skeletons/toolv2-skeleton/src/routes/dynamic-schemas/exampleDynamicSchema.ts +0 -49
- package/skeletons/toolv2-skeleton/src/routes/dynamic-schemas/index.ts +0 -5
- package/skeletons/toolv2-skeleton/src/routes/health.ts +0 -14
- package/skeletons/toolv2-skeleton/src/routes/locales.ts +0 -31
- package/skeletons/toolv2-skeleton/src/routes/notifications/exampleNotification.ts +0 -46
- package/skeletons/toolv2-skeleton/src/routes/option-availability.ts +0 -27
- package/skeletons/toolv2-skeleton/src/routes/rendering-info/web.ts +0 -150
- package/skeletons/toolv2-skeleton/src/routes/routes.ts +0 -21
- package/skeletons/toolv2-skeleton/src/routes/schema.ts +0 -21
- package/skeletons/toolv2-skeleton/src/routes/stylesheet.ts +0 -31
- package/skeletons/toolv2-skeleton/src/styles/main.scss +0 -6
- package/skeletons/toolv2-skeleton/svelte.config.cjs +0 -6
- package/skeletons/toolv2-skeleton/tasks/compileStyleFiles.cjs +0 -101
- package/skeletons/toolv2-skeleton/tests/e2e-tests.spec.ts +0 -158
- package/skeletons/toolv2-skeleton/tests/helpers.ts +0 -21
- package/skeletons/toolv2-skeleton/tsconfig.json +0 -48
- /package/{bin/commands/qItem/updateItem → dist/assets}/updateSchema.json +0 -0
package/README.md
CHANGED
@@ -1,14 +1,4 @@
|
|
1
|
-
# Q cli
|
2
|
-
|
3
|
-
**Maintainer**: [Nicolas Staub](https://github.com/fromdusttilldawn)
|
4
|
-
|
5
|
-
## Table of contents
|
6
|
-
|
7
|
-
- [Installation](#installation)
|
8
|
-
- [Development](#development)
|
9
|
-
- [Github Actions](#github-actions)
|
10
|
-
- [Functionality](#functionality)
|
11
|
-
- [License](#license)
|
1
|
+
# Q cli
|
12
2
|
|
13
3
|
## Installation
|
14
4
|
|
@@ -16,39 +6,23 @@
|
|
16
6
|
npm install -g @nzz/q-cli
|
17
7
|
```
|
18
8
|
|
19
|
-
|
20
|
-
|
21
|
-
```
|
22
|
-
git clone git@github.com:nzzdev/Q-cli.git
|
23
|
-
cd Q-cli
|
24
|
-
nvm use
|
25
|
-
npm install
|
26
|
-
```
|
27
|
-
|
28
|
-
For testing local changes of Q-cli, one can link the local package to the global installation of Q-cli:
|
9
|
+
Some commands require certain environment variables. If you do not provide them, q cli tries to get them from your local 1Password installation. Make sure, that you have [1Password](https://1password.com/downloads/mac) installed.
|
29
10
|
|
30
|
-
|
31
|
-
cd Q-cli
|
32
|
-
npm link
|
33
|
-
```
|
34
|
-
|
35
|
-
Q commands will now use the local Q-cli.
|
36
|
-
|
37
|
-
To unlink, simply install Q-cli again globally:
|
11
|
+
## Development
|
38
12
|
|
39
13
|
```bash
|
40
|
-
|
14
|
+
pnpm i
|
41
15
|
```
|
42
16
|
|
43
|
-
|
17
|
+
There is a test script for each command in the `package.json`.
|
44
18
|
|
45
|
-
|
19
|
+
## GitHub Actions
|
46
20
|
|
47
|
-
|
21
|
+
To use the q cli in GitHub Actions there are special access tokens provided. You can find them in 1Password (vault: Q CLI). Editorial Tech manages those access tokens.
|
48
22
|
|
49
|
-
|
23
|
+
You will need to set the secrets in your GitHub repository under: `Settings > Secrets & variables > Actions > New repository secret`
|
50
24
|
|
51
|
-
|
25
|
+
Example:
|
52
26
|
|
53
27
|
```
|
54
28
|
- name: Run Q cli
|
@@ -60,301 +34,36 @@ You will need to set the secrets in github unders **settings > secrets & variabl
|
|
60
34
|
Q_PRODUCTION_ACCESSTOKEN: ${{ secrets.Q_PRODUCTION_ACCESSTOKEN }}
|
61
35
|
```
|
62
36
|
|
63
|
-
[to the top](#table-of-contents)
|
64
|
-
|
65
37
|
## Functionality
|
66
38
|
|
67
|
-
###
|
68
|
-
|
69
|
-
Once `Q` cli installed one can start Q dev server by running:
|
70
|
-
|
71
|
-
```bash
|
72
|
-
Q server
|
73
|
-
```
|
74
|
-
|
75
|
-
With the Q dev server running one can now test a tool with fixture data. Of course the respective tool has to be started as well.
|
76
|
-
|
77
|
-
- Default port is 5000 and can be overwritten by using `-p` or `--port` as option while starting Q dev server:
|
78
|
-
|
79
|
-
```bash
|
80
|
-
Q server -p 4001
|
81
|
-
```
|
82
|
-
|
83
|
-
- Default base url of the tool your are currently developing is `http://localhost:3000`, this can also be changed by passing the option `-b` or `--tool-base-url` while starting Q dev server.
|
84
|
-
|
85
|
-
```bash
|
86
|
-
Q server -b http://localhost:4000
|
87
|
-
```
|
88
|
-
|
89
|
-
- Default target is `nzz_ch` and can be overwritten by using `-t` or `--target`.
|
90
|
-
|
91
|
-
```bash
|
92
|
-
Q server -t your_target
|
93
|
-
```
|
94
|
-
|
95
|
-
- One can optionally specify a path to a config file by using option `-c` or `--config`, e.g.
|
96
|
-
|
97
|
-
```bash
|
98
|
-
Q server -c ./config-file-name.js
|
99
|
-
```
|
100
|
-
|
101
|
-
A config file should export an async function returning a config object. The config object has to contain an object for each target. Target objects can contain
|
102
|
-
|
103
|
-
- tool specific additionalRenderingInfo like additional stylesheets and scripts to load
|
104
|
-
- a target specific context which can also contain stylesheets, scripts or background information
|
105
|
-
- toolRuntimeConfig containing information which a tool might need at runtime
|
106
|
-
Config file example:
|
107
|
-
|
108
|
-
```js
|
109
|
-
async function getConfig() {
|
110
|
-
return {
|
111
|
-
nzz_ch: {
|
112
|
-
// target name
|
113
|
-
additionalRenderingInfo: {
|
114
|
-
// additionalRenderingInfo is tool based
|
115
|
-
stylesheets: [
|
116
|
-
{
|
117
|
-
url: "https://service.sophie.nzz.ch/bundle/sophie-q@1,sophie-font@1,sophie-color@1,sophie-viz-color@1,sophie-input@1.css",
|
118
|
-
},
|
119
|
-
],
|
120
|
-
},
|
121
|
-
context: {
|
122
|
-
// context is target based
|
123
|
-
stylesheets: [
|
124
|
-
{
|
125
|
-
url: "https://context-service.st.nzz.ch/stylesheet/all/nzz.ch.css",
|
126
|
-
},
|
127
|
-
],
|
128
|
-
background: {
|
129
|
-
color: "#fff",
|
130
|
-
},
|
131
|
-
},
|
132
|
-
toolRuntimeConfig: {
|
133
|
-
displayOptions: {
|
134
|
-
hideTitle: true,
|
135
|
-
},
|
136
|
-
},
|
137
|
-
},
|
138
|
-
};
|
139
|
-
}
|
140
|
-
|
141
|
-
module.exports = getConfig;
|
142
|
-
```
|
143
|
-
|
144
|
-
### Creating new Q server implementation
|
145
|
-
|
146
|
-
Once `Q` cli is installed one can create the skeleton of a Q server implementation by executing
|
147
|
-
|
148
|
-
```bash
|
149
|
-
Q new-server my-server-name
|
150
|
-
```
|
151
|
-
|
152
|
-
- The directory name where the server implementation is being created defaults to the server name and can be overwritten by using option `-d` or `--dir`
|
153
|
-
|
154
|
-
```bash
|
155
|
-
Q new-server my-server-name -d my-server-directory
|
156
|
-
```
|
157
|
-
|
158
|
-
### Creating new tool
|
159
|
-
|
160
|
-
Once `Q` cli is installed one can create the skeleton of a new tool by executing
|
161
|
-
|
162
|
-
```bash
|
163
|
-
Q new-tool my-tool-name
|
164
|
-
```
|
165
|
-
|
166
|
-
- The directory name where the new tool is being created defaults to the tool name and can be overwritten by using option `-d` or `--dir`
|
167
|
-
|
168
|
-
```bash
|
169
|
-
Q new-tool my-tool-name -d my-tool-directory
|
170
|
-
```
|
171
|
-
|
172
|
-
### Creating new custom code project
|
173
|
-
|
174
|
-
Once `Q` cli is installed one can create the skeleton of a new custom code project by executing
|
175
|
-
|
176
|
-
```bash
|
177
|
-
Q new-custom-code my-project-name
|
178
|
-
```
|
39
|
+
### Creating a new custom code project
|
179
40
|
|
180
|
-
|
41
|
+
Creates a new custom code project.
|
181
42
|
|
182
43
|
```bash
|
183
|
-
Q new-custom-code
|
44
|
+
Q new-custom-code -d my-custom-code-project
|
184
45
|
```
|
185
46
|
|
186
|
-
### Creating new
|
47
|
+
### Creating a new custom code item
|
187
48
|
|
188
|
-
|
49
|
+
Creates a new custom code item on the specified environment and adds the id of the newly created item to the specified `q.config.json`.
|
189
50
|
|
190
|
-
|
191
|
-
Q new-et-utils-package package-name package-author package-description
|
192
|
-
```
|
51
|
+
`q.config.json`: By default q cli will look for the config file in the current directory, if no path is specified.
|
193
52
|
|
194
|
-
|
53
|
+
This command requires the environment variables `Q_[ENVIRONMENT]_SERVER` and `Q_[ENVIRONMENT]_ACCESSTOKEN`.
|
195
54
|
|
196
55
|
```bash
|
197
|
-
Q
|
56
|
+
Q create-custom-code-item -e local -c ./tests/q.config.json -t 'TEST CUSTOM CODE ITEM'
|
198
57
|
```
|
199
58
|
|
200
|
-
|
201
|
-
|
202
|
-
New utility package projects should only be created inside the [ed-tech-utilities](https://github.com/nzzdev/ed-tech-utilities) repository.
|
203
|
-
|
204
|
-
### Q item actions
|
205
|
-
|
206
|
-
The `Q` cli can copy and/or update existing Q items.
|
207
|
-
|
208
|
-
#### Updating existing Q items
|
59
|
+
### Updating existing Q items
|
209
60
|
|
210
|
-
|
61
|
+
Reads the specified `q.config.json` and updates all q items there.
|
211
62
|
|
212
|
-
|
213
|
-
Q update-item
|
214
|
-
```
|
215
|
-
|
216
|
-
- The path to the config file can be set by using option `-c` or `--config`. By default the `update-item` command will look for a config file called `q.config.json` in the current directory
|
217
|
-
|
218
|
-
```bash
|
219
|
-
Q update-item -c [path]
|
220
|
-
```
|
63
|
+
`q.config.json`: By default q cli will look for the config file in the current directory, if no path is specified.
|
221
64
|
|
222
|
-
|
65
|
+
This command requires the environment variables `Q_[ENVIRONMENT]_SERVER` and `Q_[ENVIRONMENT]_ACCESSTOKEN`.
|
223
66
|
|
224
67
|
```bash
|
225
|
-
Q update-item -e
|
68
|
+
Q update-item -e local -c ./tests/q.config.json
|
226
69
|
```
|
227
|
-
|
228
|
-
- Stored configuration properties like Q-Server url or access tokens can be reset by using option `-r` or `--reset`
|
229
|
-
|
230
|
-
```bash
|
231
|
-
Q update-item -r
|
232
|
-
```
|
233
|
-
|
234
|
-
- Credentials can be provided as environment variables to avoid user prompts. The variable names are `Q_ENV_SERVER`, `Q_ENV_USERNAME`, `Q_ENV_PASSWORD`, `Q_ENV_ACCESSTOKEN`, where `ENV` is the uppercase version of the environment name.
|
235
|
-
|
236
|
-
```bash
|
237
|
-
Q_TEST_SERVER=[server_route] Q_TEST_USERNAME=[username] Q_TEST_PASSWORD=[password] Q update-item
|
238
|
-
```
|
239
|
-
|
240
|
-
or
|
241
|
-
|
242
|
-
```bash
|
243
|
-
Q_TEST_SERVER=[server_route] Q_TEST_ACCESSTOKEN=[accessToken] Q update-item
|
244
|
-
```
|
245
|
-
|
246
|
-
The config file has to follow [this json-schema](./bin/commands/qItem/updateItem/updateSchema.json). This schema will be extended by the respective tool schema of your Q item.
|
247
|
-
Here's an example:
|
248
|
-
|
249
|
-
```json
|
250
|
-
{
|
251
|
-
"items": [
|
252
|
-
{
|
253
|
-
"environments": [
|
254
|
-
// "environments" references the desired q items to be updated, at least 1 environment is required
|
255
|
-
{
|
256
|
-
"name": "production",
|
257
|
-
"id": "6dcf203a5c5f74b61aeea0cb0eef7e0b" // Id of your q item in the production environment
|
258
|
-
},
|
259
|
-
{
|
260
|
-
"name": "staging",
|
261
|
-
"id": "6dcf203a5c5f74b61aeea0cb0ef2ca9f" // Id of your q item in the staging environment
|
262
|
-
}
|
263
|
-
],
|
264
|
-
"item": {
|
265
|
-
// The actual content you want to update for your referenced q items listed in "environments"
|
266
|
-
"title": "Der Konsum in der Schweiz springt wieder an",
|
267
|
-
"subtitle": "Wöchentliche Ausgaben mittels Bankkarten in Mio. Fr. im Jahr 2020, zum Vergleich 2019",
|
268
|
-
"data": [
|
269
|
-
// "data" represents the data table of your q item inside the q-editor
|
270
|
-
["Datum", "2020", "2019"],
|
271
|
-
["2020-01-06", "690004302", "641528028"],
|
272
|
-
["2020-01-13", "662122373", "617653790"],
|
273
|
-
["2020-01-20", "688208667", "654303249"]
|
274
|
-
]
|
275
|
-
}
|
276
|
-
}
|
277
|
-
]
|
278
|
-
}
|
279
|
-
```
|
280
|
-
|
281
|
-
#### Copy existing Q items
|
282
|
-
|
283
|
-
Once `Q` cli installed one can copy one or many Q items by executing:
|
284
|
-
|
285
|
-
```bash
|
286
|
-
Q copy-item
|
287
|
-
```
|
288
|
-
|
289
|
-
- The path to the config file can be set by using option `-c` or `--config`. By default the `copy-item` command will look for a config file called `q.config.json` in the current directory
|
290
|
-
|
291
|
-
```bash
|
292
|
-
Q copy-item -c [path]
|
293
|
-
```
|
294
|
-
|
295
|
-
- Items of a specified environment can be updated by using the option `-e` or `--environment`. By default the `copy-item` command updates all item specified in the config file
|
296
|
-
|
297
|
-
```bash
|
298
|
-
Q copy-item -e [env]
|
299
|
-
```
|
300
|
-
|
301
|
-
- Stored configuration properties like Q-Server url or access tokens can be reset by using option `-r` or `--reset`
|
302
|
-
|
303
|
-
```bash
|
304
|
-
Q copy-item -r
|
305
|
-
```
|
306
|
-
|
307
|
-
- Credentials can be provided as environment variables to avoid user prompts. The variable names are `Q_ENV_SERVER`, `Q_ENV_USERNAME`, `Q_ENV_PASSWORD`, `Q_ENV_ACCESSTOKEN`, where `ENV` is the uppercase version of the environment name.
|
308
|
-
|
309
|
-
```bash
|
310
|
-
Q_TEST_SERVER=[server_route] Q_TEST_USERNAME=[username] Q_TEST_PASSWORD=[password] Q update-item
|
311
|
-
```
|
312
|
-
|
313
|
-
or
|
314
|
-
|
315
|
-
```bash
|
316
|
-
Q_TEST_SERVER=[server_route] Q_TEST_ACCESSTOKEN=[accessToken] Q update-item
|
317
|
-
```
|
318
|
-
|
319
|
-
The config file has to follow [this json-schema](./bin/commands/qItem/updateItem/updateSchema.json). This schema will be extended by the respective tool schema of your Q item.
|
320
|
-
Here's an example:
|
321
|
-
|
322
|
-
```json
|
323
|
-
{
|
324
|
-
"items": [
|
325
|
-
{
|
326
|
-
"environments": [
|
327
|
-
{
|
328
|
-
"name": "production",
|
329
|
-
"id": "6dcf203a5c5f74b61aeea0cb0eef7e0b" // Id of your q item in the production environment
|
330
|
-
},
|
331
|
-
{
|
332
|
-
"name": "staging",
|
333
|
-
"id": "6dcf203a5c5f74b61aeea0cb0ef2ca9f" // Id of your q item in the staging environment
|
334
|
-
}
|
335
|
-
],
|
336
|
-
"item": {
|
337
|
-
"title": "Russische Angriffe auf die Ukraine",
|
338
|
-
"subtitle": "Verzeichnete Angriffe in der ganzen Ukraine",
|
339
|
-
"files": [
|
340
|
-
// Adds or overwrites the listed files in your q item
|
341
|
-
{
|
342
|
-
"loadSyncBeforeInit": false, // Has to be set for the file upload to work
|
343
|
-
"file": {
|
344
|
-
"path": "./angriffsFlaechen.json" // Your local path to your file. The path is relative to where you execute the command.
|
345
|
-
}
|
346
|
-
}
|
347
|
-
]
|
348
|
-
}
|
349
|
-
}
|
350
|
-
]
|
351
|
-
}
|
352
|
-
```
|
353
|
-
|
354
|
-
[to the top](#table-of-contents)
|
355
|
-
|
356
|
-
## License
|
357
|
-
|
358
|
-
Copyright (c) Neue Zürcher Zeitung.
|
359
|
-
|
360
|
-
This software is licensed under the [MIT](LICENSE) License.
|
@@ -0,0 +1,70 @@
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8
|
+
});
|
9
|
+
};
|
10
|
+
import { logSuccess, logError, updateItem, getAccessToken, getQServerUrl } from './utils.js';
|
11
|
+
import { readFileSync, existsSync, writeFileSync } from 'fs';
|
12
|
+
import { resolve } from 'path';
|
13
|
+
export default function (command) {
|
14
|
+
return __awaiter(this, void 0, void 0, function* () {
|
15
|
+
const qConfigPath = resolve(command.config);
|
16
|
+
if (!existsSync(qConfigPath)) {
|
17
|
+
logError(`Couldn't find config file: '${qConfigPath}'.\nCreate a config file in the current directory or pass the path to the config file with the option -c <path>`);
|
18
|
+
return;
|
19
|
+
}
|
20
|
+
// Get the Q server URL and access token from the environment variables or 1Password
|
21
|
+
const qServerUrl = getQServerUrl(command.environment);
|
22
|
+
const accessToken = getAccessToken(command.environment);
|
23
|
+
const newCustomCodeDoc = {
|
24
|
+
acronym: 'Visuals',
|
25
|
+
assetGroups: [],
|
26
|
+
createdDate: '', // Will be set when saved
|
27
|
+
createdBy: 'editorial-tech@nzz.ch',
|
28
|
+
data: [],
|
29
|
+
// @ts-ignore
|
30
|
+
department: 'Visuals',
|
31
|
+
files: [],
|
32
|
+
options: {
|
33
|
+
previewDisabled: true,
|
34
|
+
},
|
35
|
+
// @ts-ignore
|
36
|
+
publication: 'nzz',
|
37
|
+
sophieModules: [],
|
38
|
+
title: command.title,
|
39
|
+
// @ts-ignore
|
40
|
+
tool: 'custom_code',
|
41
|
+
updatedDate: '', // Will be set when saved
|
42
|
+
updatedBy: 'editorial-tech@nzz.ch',
|
43
|
+
};
|
44
|
+
// Create the item on the Q server
|
45
|
+
const result = yield updateItem(newCustomCodeDoc, qServerUrl, accessToken);
|
46
|
+
if (!result.success) {
|
47
|
+
logError(result.msg);
|
48
|
+
process.exit(1);
|
49
|
+
}
|
50
|
+
const newCustomCodeDocId = result.id;
|
51
|
+
// Update the config file with the new item
|
52
|
+
const qConfig = JSON.parse(readFileSync(qConfigPath, 'utf-8'));
|
53
|
+
if (!qConfig.items) {
|
54
|
+
qConfig.items = [];
|
55
|
+
}
|
56
|
+
if (qConfig.items.length === 0) {
|
57
|
+
qConfig.items.push({
|
58
|
+
environments: [],
|
59
|
+
item: {}, // User needs to add the item later
|
60
|
+
});
|
61
|
+
}
|
62
|
+
const firstItem = qConfig.items[0];
|
63
|
+
firstItem.environments.push({
|
64
|
+
id: newCustomCodeDocId,
|
65
|
+
name: command.environment,
|
66
|
+
});
|
67
|
+
writeFileSync(qConfigPath, JSON.stringify(qConfig, null, 2));
|
68
|
+
logSuccess(`Successfully created item with id ${newCustomCodeDocId} on ${command.environment} environment`);
|
69
|
+
});
|
70
|
+
}
|
package/dist/enums.js
ADDED
package/dist/index.js
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
import { Command } from 'commander';
|
12
|
+
import packageJson from '../package.json' with { type: 'json' };
|
13
|
+
import updateItem from './updateItem.js';
|
14
|
+
import newCustomCode from './newCustomCode.js';
|
15
|
+
import createCustomCodeItem from './createCustomCodeItem.js';
|
16
|
+
const program = new Command();
|
17
|
+
// Get the version from the package.json file
|
18
|
+
const version = packageJson.version;
|
19
|
+
function main() {
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
21
|
+
program.version(version).description('Q Toolbox cli');
|
22
|
+
program
|
23
|
+
.command('new-custom-code')
|
24
|
+
.option('-d, --dir [path]', 'the base directory to bootstrap the new custom code project in')
|
25
|
+
.description('bootstrap a new custom code project')
|
26
|
+
.action((command) => {
|
27
|
+
newCustomCode(command);
|
28
|
+
});
|
29
|
+
program
|
30
|
+
.command('new-et-utils-package')
|
31
|
+
.option('-d, --dir [path]', 'the base directory to bootstrap the new tool in, defaults to the tools name')
|
32
|
+
.description('bootstrap a new ed-tech utility package')
|
33
|
+
.action(() => __awaiter(this, void 0, void 0, function* () {
|
34
|
+
// const name = program.args[1];
|
35
|
+
// const author = program.args[2] || 'TODO: Set package author name';
|
36
|
+
// const description = program.args[3] || 'TODO: Write a package description';
|
37
|
+
// if (!name) {
|
38
|
+
// console.error(errorColor('no package name given'));
|
39
|
+
// process.exit(1);
|
40
|
+
// }
|
41
|
+
// const baseDir = program.dir || name;
|
42
|
+
// const textReplacements = [
|
43
|
+
// { regex: new RegExp('<package-name>', 'g'), replaceWith: name },
|
44
|
+
// { regex: new RegExp('<author-name>', 'g'), replaceWith: author },
|
45
|
+
// {
|
46
|
+
// regex: new RegExp('<package-description>', 'g'),
|
47
|
+
// replaceWith: description,
|
48
|
+
// },
|
49
|
+
// ];
|
50
|
+
// await bootstrap('et-utils-package', baseDir, textReplacements);
|
51
|
+
}));
|
52
|
+
program
|
53
|
+
.command('update-item')
|
54
|
+
.description('update q item')
|
55
|
+
.option('-c, --config [path]', 'set config path which defines the q items to be updated. defaults to ./q.config.json', `${process.cwd()}/q.config.json`)
|
56
|
+
.option('-e, --environment [env]', 'set environment which should be updated, defaults to update all items of all environments defined in config')
|
57
|
+
.action((command) => __awaiter(this, void 0, void 0, function* () {
|
58
|
+
yield updateItem(command);
|
59
|
+
}));
|
60
|
+
program
|
61
|
+
.command('copy-item')
|
62
|
+
.description('copies an existing q item')
|
63
|
+
.option('-c, --config [path]', 'set config path which defines the q items to be copied. defaults to ./q.config.json', `${process.cwd()}/q.config.json`)
|
64
|
+
.option('-e, --environment [env]', 'set environment where the existing q item is found, defaults to copy all items of all environments defined in config')
|
65
|
+
.action((command) => __awaiter(this, void 0, void 0, function* () {
|
66
|
+
// await copyItem(command);
|
67
|
+
}));
|
68
|
+
program
|
69
|
+
.command('create-custom-code-item')
|
70
|
+
.description('creates a new q custom code item in the db and adds it to the q config file')
|
71
|
+
.option('-c, --config [path]', 'set config path to q.config.json. defaults to ./q.config.json', `${process.cwd()}/q.config.json`)
|
72
|
+
.option('-e, --environment [env]', 'set environment where the new q custom code item should be created in')
|
73
|
+
.option('-t, --title [title]', 'set title of the new q custom code item')
|
74
|
+
.action((command) => __awaiter(this, void 0, void 0, function* () {
|
75
|
+
yield createCustomCodeItem(command);
|
76
|
+
}));
|
77
|
+
yield program.parseAsync(process.argv);
|
78
|
+
});
|
79
|
+
}
|
80
|
+
main();
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,107 @@
|
|
1
|
+
import * as fs from 'fs';
|
2
|
+
import * as path from 'path';
|
3
|
+
import { execSync } from 'child_process';
|
4
|
+
import { logError, logSuccess } from './utils.js';
|
5
|
+
export default function (command) {
|
6
|
+
const { dir } = command;
|
7
|
+
if (!dir) {
|
8
|
+
logError('No custom-code project name/directory given');
|
9
|
+
process.exit(1);
|
10
|
+
}
|
11
|
+
if (fs.existsSync(dir)) {
|
12
|
+
logError(`Directory ${dir} already exists`);
|
13
|
+
process.exit(1);
|
14
|
+
}
|
15
|
+
const skeletonDir = 'skeletons';
|
16
|
+
const skeletonCustomCodeDir = path.join(skeletonDir, 'custom-code-project');
|
17
|
+
try {
|
18
|
+
// Create the target directory
|
19
|
+
fs.mkdirSync(dir);
|
20
|
+
// Change to the target directory
|
21
|
+
process.chdir(dir);
|
22
|
+
// Initialize git repository to pull the skeletons/custom-code-project content into a separate directory
|
23
|
+
console.log('Initializing git repository...');
|
24
|
+
execSync('git init');
|
25
|
+
execSync('git remote add origin https://github.com/nzzdev/Q.git');
|
26
|
+
// Enable sparse checkout and pull the content from remote
|
27
|
+
console.log(`Sparse checkout ${skeletonCustomCodeDir}...`);
|
28
|
+
execSync('git sparse-checkout init --cone');
|
29
|
+
execSync(`git sparse-checkout set ${skeletonCustomCodeDir}`);
|
30
|
+
console.log('Pulling content from remote...');
|
31
|
+
execSync('git pull origin main');
|
32
|
+
// Remove all files, except the skeletons directory
|
33
|
+
console.log('Cleaning up...');
|
34
|
+
const cwdFiles = fs.readdirSync(process.cwd());
|
35
|
+
for (const file of cwdFiles) {
|
36
|
+
if (file === skeletonDir)
|
37
|
+
continue; // Skip the skeletons directory
|
38
|
+
const filePath = path.join(process.cwd(), file);
|
39
|
+
if (fs.statSync(filePath).isDirectory()) {
|
40
|
+
fs.rmSync(filePath, { recursive: true, force: true });
|
41
|
+
}
|
42
|
+
else {
|
43
|
+
fs.unlinkSync(filePath);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
// Copy the skeletons/custom-code-project content to the root
|
47
|
+
const cwdSkeletonCustomCodeDir = path.join(process.cwd(), skeletonCustomCodeDir);
|
48
|
+
const skeletonFiles = fs.readdirSync(cwdSkeletonCustomCodeDir);
|
49
|
+
for (const file of skeletonFiles) {
|
50
|
+
const srcFilePath = path.join(cwdSkeletonCustomCodeDir, file);
|
51
|
+
const targetFilePath = path.join(process.cwd(), file);
|
52
|
+
if (fs.statSync(srcFilePath).isDirectory()) {
|
53
|
+
fs.cpSync(srcFilePath, targetFilePath, { recursive: true });
|
54
|
+
}
|
55
|
+
else {
|
56
|
+
fs.copyFileSync(srcFilePath, targetFilePath);
|
57
|
+
}
|
58
|
+
}
|
59
|
+
// Remove the now empty skeletons directory
|
60
|
+
fs.rmSync(path.join(process.cwd(), skeletonDir), { recursive: true, force: true });
|
61
|
+
// Update the package.json and q.config.json files with the custom code project name
|
62
|
+
const customCodeProjectName = path.basename(dir);
|
63
|
+
updateJsonValue(path.join(process.cwd(), 'package.json'), 'name', customCodeProjectName);
|
64
|
+
updateJsonValue(path.join(process.cwd(), 'q.config.json'), 'items.0.item.trackingComponent.componentInfo.componentName', customCodeProjectName);
|
65
|
+
logSuccess(`Successfully created new custom code project '${dir}'`);
|
66
|
+
}
|
67
|
+
catch (error) {
|
68
|
+
logError(error.message);
|
69
|
+
process.exit(1);
|
70
|
+
}
|
71
|
+
}
|
72
|
+
/**
|
73
|
+
* Reads a JSON file, updates a specific value, and writes the changes back to the file
|
74
|
+
* @param filePath - Path to the JSON file
|
75
|
+
* @param keyPath - Path to the key to update (use dot notation for nested objects, e.g., 'parent.child')
|
76
|
+
* @param newValue - New value to set
|
77
|
+
* @returns boolean indicating success
|
78
|
+
*/
|
79
|
+
function updateJsonValue(filePath, keyPath, newValue) {
|
80
|
+
try {
|
81
|
+
// Read the JSON file
|
82
|
+
const jsonContent = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
83
|
+
// Split the key path into parts for nested objects
|
84
|
+
const keys = keyPath.split('.');
|
85
|
+
let current = jsonContent;
|
86
|
+
// Navigate to the parent of the target property
|
87
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
88
|
+
if (!(keys[i] in current)) {
|
89
|
+
throw new Error(`Key path ${keyPath} not found in JSON file`);
|
90
|
+
}
|
91
|
+
current = current[keys[i]];
|
92
|
+
}
|
93
|
+
// Update the value
|
94
|
+
const lastKey = keys[keys.length - 1];
|
95
|
+
if (!(lastKey in current)) {
|
96
|
+
throw new Error(`Key ${lastKey} not found in JSON file`);
|
97
|
+
}
|
98
|
+
current[lastKey] = newValue;
|
99
|
+
// Write the updated JSON back to the file
|
100
|
+
fs.writeFileSync(filePath, JSON.stringify(jsonContent, null, 2));
|
101
|
+
return true;
|
102
|
+
}
|
103
|
+
catch (error) {
|
104
|
+
logError('Error updating JSON file:' + error.message);
|
105
|
+
return false;
|
106
|
+
}
|
107
|
+
}
|