@jtl-software/create-cloud-app 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -15
- package/dist/index.js +702 -388
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @jtl-software/create-cloud-app
|
|
2
2
|
|
|
3
|
-
CLI for [JTL Platform](https://www.jtl-software.com/) cloud apps. Scaffolds a new app project
|
|
3
|
+
CLI for [JTL Platform](https://www.jtl-software.com/) cloud apps. Scaffolds a new app project, registers it against the cloud, and pushes its store listing.
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
@@ -8,10 +8,13 @@ Node.js **24** (current LTS) or newer. The scaffolded project sets the same floo
|
|
|
8
8
|
|
|
9
9
|
## Commands
|
|
10
10
|
|
|
11
|
-
The CLI has
|
|
11
|
+
The CLI has three entry points:
|
|
12
12
|
|
|
13
13
|
- The default invocation (no arguments) scaffolds a new project.
|
|
14
|
-
- `register` registers or updates
|
|
14
|
+
- `register` registers or updates the app's identity (`app.json`) against the JTL Cloud — do this when you start building.
|
|
15
|
+
- `listing` pushes the app's store listing (`listing.json`) — do this once you're done building and ready to publish.
|
|
16
|
+
|
|
17
|
+
Registration and listing are two independent resources on two independent files. `register` must happen first — `listing` pushes against the app that `register` created and will fail with a clear error if it hasn't run yet.
|
|
15
18
|
|
|
16
19
|
### `npm create @jtl-software/cloud-app@latest`
|
|
17
20
|
|
|
@@ -24,7 +27,7 @@ npm create @jtl-software/cloud-app@latest
|
|
|
24
27
|
You'll be prompted for:
|
|
25
28
|
|
|
26
29
|
- **App name**: directory name, package name, and manifest identifier
|
|
27
|
-
- **Description**: placed in the
|
|
30
|
+
- **Description**: placed in the listing
|
|
28
31
|
- **Backend**: Node.js (Express + TypeScript) or .NET (ASP.NET Core + FastEndpoints)
|
|
29
32
|
- **Frontend**: React (Vite + Tailwind + JTL Platform UI)
|
|
30
33
|
|
|
@@ -42,12 +45,14 @@ The generated project includes:
|
|
|
42
45
|
- A monorepo wired up with [Turborepo](https://turbo.build/)
|
|
43
46
|
- A frontend with welcome pages explaining each app mode and manifest mapping
|
|
44
47
|
- A backend with JWT verification, tenant connection, and ERP API proxy
|
|
45
|
-
- A ready-to-register `
|
|
48
|
+
- A ready-to-register `app.json` (identity: `technicalName`, `version`, `lifecycle`, `capabilities`)
|
|
49
|
+
- A ready-to-push `listing.json` (store metadata: `name`, `description`, `media`, `pricing`, etc.)
|
|
46
50
|
- An `npm run register` script that delegates to `npx -y @jtl-software/create-cloud-app@latest register`
|
|
51
|
+
- An `npm run listing` script that delegates to `npx -y @jtl-software/create-cloud-app@latest listing`
|
|
47
52
|
|
|
48
53
|
### `register`
|
|
49
54
|
|
|
50
|
-
Register a new app or update an existing app's manifest. Reads `
|
|
55
|
+
Register a new app or update an existing app's manifest. Reads `app.json` from the current working directory and pushes it to the App Service.
|
|
51
56
|
|
|
52
57
|
```bash
|
|
53
58
|
npx @jtl-software/create-cloud-app register
|
|
@@ -73,11 +78,23 @@ Flags:
|
|
|
73
78
|
|
|
74
79
|
Tokens are cached under `~/.config/jtl-cli/tokens.json` (mode `0600`). Override the path with the `JTL_CLI_TOKEN_CACHE_FILE` environment variable.
|
|
75
80
|
|
|
76
|
-
|
|
81
|
+
### `listing`
|
|
82
|
+
|
|
83
|
+
Push the app's store listing. Reads `listing.json` and the `technicalName` from `app.json` (both in the current working directory), then pushes the listing for that app.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npx @jtl-software/create-cloud-app listing
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Like `register`, it's interactive by default: OAuth login, then a tenant prompt. It also asks two questions about the listing itself — distribution type (`PUBLIC`/`PRIVATE`) and default locale — pre-filled from whatever's already in `listing.json` and written back there once answered, so re-running `listing` later remembers your choice. Unlike `register`, there's no create-vs-update choice or local credential file to write — a listing is always pushed against the app `register` already created, keyed by `technicalName`. If no registered app matches, the command fails with a message telling you to run `register` first.
|
|
90
|
+
|
|
91
|
+
Flags: `--api-host`, `--auth-host`, `--hub-host`, `--client-id`, `--scope`, `--reauth`, `--yes`/`-y`, `--tenant` — same meaning as the equivalent `register` flags above. There's no `--existing-app-id`, `--new`, or `--on-collision` since listing has nothing to disambiguate or overwrite locally.
|
|
77
92
|
|
|
78
|
-
|
|
93
|
+
## CI usage: keep your deployed app.json and listing.json in sync with the repo
|
|
79
94
|
|
|
80
|
-
|
|
95
|
+
A common setup is to commit `app.json` and `listing.json` to source control and have CI push them to the cloud whenever they change, so the deployed app always matches what's on `main`.
|
|
96
|
+
|
|
97
|
+
Both `register` and `listing` support this. You need three things:
|
|
81
98
|
|
|
82
99
|
1. **Pin the tenant and app ID** so the run is deterministic.
|
|
83
100
|
2. **Run with `--yes`** so prompts don't block.
|
|
@@ -98,23 +115,25 @@ The cached token will be silently refreshed on every CI run, so it stays valid a
|
|
|
98
115
|
|
|
99
116
|
### Step 2: look up your tenant and app ID
|
|
100
117
|
|
|
101
|
-
You can read them off the previous interactive run (the CLI prints both). The tenant slug is the stable, human-friendly identifier. The app ID is a UUID printed in the "Review" section
|
|
118
|
+
You can read them off the previous interactive run (the CLI prints both). The tenant slug is the stable, human-friendly identifier. The app ID is a UUID printed in the "Review" section — only `register` needs it; `listing` only needs the tenant, since it resolves the app by `technicalName`.
|
|
102
119
|
|
|
103
120
|
### Step 3: CI workflow
|
|
104
121
|
|
|
105
|
-
GitHub Actions example:
|
|
122
|
+
GitHub Actions example — one job per file, each triggered only when its own file changes:
|
|
106
123
|
|
|
107
124
|
```yaml
|
|
108
|
-
name: Update
|
|
125
|
+
name: Update app.json and listing.json
|
|
109
126
|
|
|
110
127
|
on:
|
|
111
128
|
push:
|
|
112
129
|
branches: [main]
|
|
113
130
|
paths:
|
|
114
|
-
-
|
|
131
|
+
- app.json
|
|
132
|
+
- listing.json
|
|
115
133
|
|
|
116
134
|
jobs:
|
|
117
135
|
register:
|
|
136
|
+
if: contains(github.event.head_commit.modified, 'app.json')
|
|
118
137
|
runs-on: ubuntu-latest
|
|
119
138
|
steps:
|
|
120
139
|
- uses: actions/checkout@v4
|
|
@@ -136,15 +155,41 @@ jobs:
|
|
|
136
155
|
--yes \
|
|
137
156
|
--tenant my-tenant-slug \
|
|
138
157
|
--existing-app-id 00000000-0000-0000-0000-000000000000
|
|
158
|
+
|
|
159
|
+
listing:
|
|
160
|
+
if: contains(github.event.head_commit.modified, 'listing.json')
|
|
161
|
+
runs-on: ubuntu-latest
|
|
162
|
+
steps:
|
|
163
|
+
- uses: actions/checkout@v4
|
|
164
|
+
- uses: actions/setup-node@v4
|
|
165
|
+
with:
|
|
166
|
+
node-version: 24
|
|
167
|
+
- name: Write token cache
|
|
168
|
+
env:
|
|
169
|
+
JTL_CLI_TOKENS: ${{ secrets.JTL_CLI_TOKENS }}
|
|
170
|
+
run: |
|
|
171
|
+
mkdir -p "$RUNNER_TEMP/jtl-cli"
|
|
172
|
+
printf '%s' "$JTL_CLI_TOKENS" > "$RUNNER_TEMP/jtl-cli/tokens.json"
|
|
173
|
+
chmod 600 "$RUNNER_TEMP/jtl-cli/tokens.json"
|
|
174
|
+
- name: Update listing
|
|
175
|
+
env:
|
|
176
|
+
JTL_CLI_TOKEN_CACHE_FILE: ${{ runner.temp }}/jtl-cli/tokens.json
|
|
177
|
+
run: |
|
|
178
|
+
npx -y @jtl-software/create-cloud-app@latest listing \
|
|
179
|
+
--yes \
|
|
180
|
+
--tenant my-tenant-slug
|
|
139
181
|
```
|
|
140
182
|
|
|
141
|
-
|
|
183
|
+
Note `listing` doesn't take `--existing-app-id` — it only needs `--tenant` to pin the target, since the app is resolved by `technicalName`.
|
|
184
|
+
|
|
185
|
+
`--yes` keeps each job non-interactive, and the `if:` conditions mean only the file that actually changed gets pushed — an `app.json`-only commit doesn't re-push an unchanged listing, and vice versa.
|
|
142
186
|
|
|
143
187
|
## After scaffolding
|
|
144
188
|
|
|
145
|
-
1. Register your
|
|
189
|
+
1. Register your app's identity in the [Partner Portal](https://partner.jtl-cloud.com/) or with `npm run register`
|
|
146
190
|
2. Add your Client ID and Secret to the backend config
|
|
147
191
|
3. Install the app from [JTL-Cloud Hub](https://hub.jtl-cloud.com/) under "Apps in development"
|
|
192
|
+
4. Once you're done building, push the store listing with `npm run listing`
|
|
148
193
|
|
|
149
194
|
## Documentation
|
|
150
195
|
|