@ossy/cli 1.16.10 → 1.17.3

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 CHANGED
@@ -18,95 +18,180 @@ ossy <command> --help
18
18
 
19
19
  For one-off use without installing, you can still run `npx @ossy/cli <command>`.
20
20
 
21
- ## Commands
21
+ ## How the CLI is organized
22
22
 
23
- | Command | Description |
24
- |---------|-------------|
25
- | `init [dir]` | Scaffold a new Ossy app (default: current directory) |
26
- | `build` | Production build |
27
- | `publish` | Queue a container deployment via `@ossy/deployment-tools` (**temporary**; see below), then upload `resourceTemplates` and **site build artifacts** (S3 presign + CMS resource) when `workspaceId` is set |
28
- | `cms upload` | Upload resource templates only (same API as publish’s upload step) |
29
- | `cms validate` | Validate ossy config and resource templates |
23
+ The contract for everything the platform can do is the **SDK action POJO** in [`@ossy/sdk`](../sdk) (`{ id, endpoint, method, payload }`). The CLI is one channel onto that catalog, organized in three layers:
30
24
 
31
- ## App: build
25
+ 1. **Local utilities** — no API call, or per-machine state. `auth`, `workspace`, `app init`, `app build`, `app validate`.
26
+ 2. **Action dispatcher** — `call <action.id>` invokes any action in the SDK catalog. New endpoints added to the SDK are callable from the terminal with no extra CLI wiring.
27
+ 3. **High-level workflows** — verbs that wrap one or more actions and add value the dispatcher doesn't (reading `src/config.js`, formatting output for CI, multi-step pipelines). Each workflow's docs name the underlying action(s) so you can drop down to `ossy call` if you outgrow the verb.
28
+
29
+ | Layer | Command | Description |
30
+ |-------|---------|-------------|
31
+ | Local | `auth login \| logout \| status` | Save / delete / inspect the Ossy API token under `~/.config/ossy/credentials.json` |
32
+ | Local | `workspace use <id> \| list \| current` | Manage the active workspace (saved to `~/.config/ossy/config.json`) |
33
+ | Local | `app init [dir]` | Scaffold a new Ossy app (default: current directory) |
34
+ | Local | `app build` | Production build of the app in the current directory |
35
+ | Local | `app validate` | Validate `src/config.js` (`workspaceId`, `resourceTemplates`) without calling the API |
36
+ | Dispatcher | `call <action.id>` | Invoke any Ossy SDK action by id (`ossy call --help` for the full catalog) |
37
+ | Workflow | `app upload` | Read `resourceTemplates` from `src/config.js` and call `workspaces.import-resource-templates` |
38
+ | Workflow | `app publish` | Upload resource templates and `build/` to the CMS (combines `app upload` + `upload-dir`) |
39
+ | Workflow | `upload-dir <dir> <location>` | Recursively mirror a local directory into the CMS (mkdir + upload per file) |
40
+ | Workflow | `registry ecr-push-credentials` | Call `registry.ecr-push-credentials`, format for `docker login` or GitHub Actions |
41
+
42
+ If you need an endpoint that no verb wraps, reach for `ossy call` — it's the universal channel.
43
+
44
+ ## Auth and active workspace
45
+
46
+ Once installed, the recommended flow is to log in once and pick an active workspace; subsequent commands inherit those:
32
47
 
33
48
  ```bash
34
- ossy build
49
+ ossy auth login # paste your Ossy API token
50
+ ossy workspace list # see workspaces you can access
51
+ ossy workspace use <workspace-id> # set the active one
52
+ ossy auth status # confirm
35
53
  ```
36
54
 
37
- Options: e.g. `--config` for `src/config.js`. See `packages/app/README.md` for app build behavior.
55
+ Credentials live in `~/.config/ossy/credentials.json` (`chmod 600`); the active workspace lives in `~/.config/ossy/config.json`. Both honor `XDG_CONFIG_HOME`.
38
56
 
39
- ## Publish (container / website)
57
+ Resolution order for every command that needs auth:
58
+ 1. `--authentication` / `-a` flag
59
+ 2. `OSSY_API_KEY` env var
60
+ 3. Saved credentials
40
61
 
41
- Publishes a site by sending a deployment request to your platform queue (same as `npx @ossy/deployment-tools deployment deploy`). Run from the **website package** directory (where `src/config.js` lives) so domain/platform can be read automatically.
62
+ Resolution order for the workspace id (when a command isn't reading it from `src/config.js`):
63
+ 1. `--workspace-id` / `-w` flag
64
+ 2. `OSSY_WORKSPACE_ID` env var
65
+ 3. Saved active workspace
42
66
 
43
- ### Temporary: no execution of `src/config.js` for CMS steps
67
+ So existing CI scripts that set `OSSY_API_KEY` keep working unchanged; you only need `ossy auth login` for interactive use.
44
68
 
45
- After deploy succeeds, **`publish`** still needs **`workspaceId`**, **`apiUrl`** (optional, for absolute URLs), and **`resourceTemplates`** from `src/config.js`. Those values are **not** loaded with `import()` anymore: running the real config in plain Node would execute imports such as `@ossy/themes`, which are only meant to be resolved during **`ossy build`** (Rollup).
69
+ ## Generic dispatcher: `ossy call`
46
70
 
47
- Instead, the CLI uses a **temporary** pipeline:
71
+ `ossy call` invokes any Ossy API action by id. The action catalog comes from `@ossy/sdk`, so any new endpoint added to the SDK is callable from the terminal with no extra wiring.
48
72
 
49
- - **`workspaceId`** and **`apiUrl`** — read with **string-literal regexes** (same idea as deploy hints).
50
- - **`resourceTemplates`** parsed with **`@babel/parser`** from `export default { … }` when that array is **JSON-like literals only** (no function calls, variables, spreads, or template literals in that subtree).
73
+ ```bash
74
+ # Discover what's available
75
+ ossy call --help # full catalog, grouped by domain
76
+ ossy call resources.create --help # one action's method, endpoint, default payload
51
77
 
52
- If `resourceTemplates` cannot be extracted, template upload is skipped. This is a **stopgap** until publish is driven by build output or platform events (see **Future direction**).
78
+ # Read calls
79
+ ossy call workspaces.get-current
80
+ ossy call resources.list --search 'location=/docs'
53
81
 
54
- ### Future direction (planned)
82
+ # Write calls — flag names map to payload keys (--first-name -> firstName)
83
+ ossy call resources.create-directory --location /docs --name images
84
+ ossy call workspaces.invite-user --email teammate@example.com
55
85
 
56
- The explicit **`deployment deploy`** step (SQS / deployment queue from **`@ossy/deployment-tools`**) is **intended to go away**: the platform should **react to a website upload / artifact event** (e.g. after the container image or site bundle is published) and roll out without the CLI calling deploy. When that exists, **`publish`** can shrink to CMS-only steps (resource templates + site artifacts), or those can move to separate workflows entirely. Treat the current **deploy + follow-ups** combo as **temporary** coupling.
86
+ # Use --json for nested or non-string payloads
87
+ ossy call resources.update-content --id res_abc --json '{"content":{"title":"Hi"}}'
57
88
 
58
- ---
89
+ # Upload a file: --file fills name/type/size as defaults, then PUTs the bytes
90
+ # when the response carries content.uploadUrl (works for resources.upload,
91
+ # resources.upload-named-version, etc.)
92
+ ossy call resources.upload --location /docs --file ./hero.jpg
93
+ ossy call resources.upload-named-version --id res_abc --name medium --file ./hero.jpg
59
94
 
60
- ### Authentication
95
+ # Per-call overrides (otherwise resolved from `ossy auth login` / `ossy workspace use`)
96
+ ossy call workspaces.get-all -a <jwt> --api-url http://localhost:3001/api/v0
97
+ ```
98
+
99
+ Output is JSON pretty-printed to stdout on success. Errors go to stderr with a non-zero exit. Add `--raw` to get the response body verbatim (useful for piping non-JSON responses).
100
+
101
+ `--file <path>` is a shortcut for upload-style actions: the CLI stats the file, fills `name`/`type`/`size` *as defaults* (any explicit `--name` / `--type` / `--size` flag wins), and after the dispatch it PUTs the bytes to `result.content.uploadUrl` with the right `Content-Type`/`Content-Length`. If the response doesn't include an upload URL, the bytes are skipped and a warning is printed.
102
+
103
+ ## App: build
104
+
105
+ ```bash
106
+ ossy app build
107
+ ```
108
+
109
+ Options: e.g. `--config` for `src/config.js`. See `packages/app/README.md` for app build behavior.
61
110
 
62
- **`publish`** requires **`--authentication` / `-a`** or **`OSSY_API_KEY`**: the **Ossy API JWT** (workspace API token). That same value is used for post-deploy CMS calls (resource templates, site artifacts).
111
+ ## App: publish
63
112
 
64
- Container deploys assume **Amazon ECR** in **`deployments.json`** (`registry` like `123456789012.dkr.ecr.eu-north-1.amazonaws.com`, **`image`** unchanged). The **worker** always pulls with **IAM** (`aws ecr get-login-password`); nothing in the queue carries a registry password. For **`docker push` from CI**, call **`POST /api/v0/registry/ecr/push-credentials`** with the same JWT and **`workspaceId`**, then **`docker login`** / **`docker push`**.
113
+ Publishes a website: uploads resource templates to the CMS and mirrors the `build/` folder to a CMS location. Run from the **website package** directory (where `src/config.js` lives) so config values are read automatically.
65
114
 
66
115
  ```bash
67
116
  cd packages/my-website
68
- export OSSY_API_KEY=<ossy-api-jwt> # or pass --authentication <ossy-api-jwt>
117
+ npm run build # produce build/ first
118
+ ossy app publish # reads src/config.js, uploads templates + build/
119
+ ```
120
+
121
+ **This is a two-step workflow:**
122
+ 1. Upload resource templates → `POST /resource-templates` (same as `app upload`).
123
+ 2. Upload `build/` to the CMS → `resources.create-directory` + `resources.upload` per file (same as `upload-dir`), mirrored to `/sites/{domain}` by default.
124
+
125
+ ### Config extraction
126
+
127
+ `publish` reads `workspaceId`, `apiUrl`, `domain`, and `resourceTemplates` from `src/config.js` **without executing** it (static regex + Babel AST parse), so imports like `@ossy/themes` that only resolve under Rollup are never run.
128
+
129
+ If `resourceTemplates` cannot be extracted, the template upload step is skipped silently.
69
130
 
70
- ossy publish \
71
- --platforms-path ../infrastructure/platforms.json \
72
- --deployments-path "../infrastructure/deployments/**/*.json"
131
+ ### Authentication
132
+
133
+ Requires `--authentication` / `-a` or `OSSY_API_KEY`: an Ossy API JWT (workspace API token).
134
+
135
+ ```bash
136
+ cd packages/my-website
137
+ export OSSY_API_KEY=<ossy-api-jwt>
138
+ npm run build
139
+ ossy app publish
140
+ # or with explicit options:
141
+ ossy app publish \
142
+ --config src/config.js \
143
+ --build-dir ./build \
144
+ --build-dest /sites/my-site.se
73
145
  ```
74
146
 
75
- **Non-ECR container registries** are not supported; container rows in **`deployments.json`** must use **ECR** and a **`registry`** endpoint as described above.
147
+ ### Options
76
148
 
77
- API and worker packages can use the same pattern: a minimal **`src/config.js`** with string-literal **`domain`** (and optional **`platform`**) matching **`deployments.json`**, then run **`publish`** from **`packages/api`** or **`packages/worker`** with **`--skip-resource-templates`** and **`--skip-site-artifacts`** (no website `workspaceId` / `build/` flow).
149
+ | Flag | Description |
150
+ |------|-------------|
151
+ | `-a, --authentication` | Ossy API JWT (or `OSSY_API_KEY`, or `ossy auth login`) |
152
+ | `-c, --config` | Path to `src/config.js` (default: `./src/config.js`) |
153
+ | `--build-dir` | Override build directory (default: `<package>/build`) |
154
+ | `--build-dest` | Override remote CMS location (default: `/sites/{domain}`) |
155
+ | `--skip-resource-templates` | Skip the resource template upload step |
156
+ | `--api-url` | API base URL (or `OSSY_API_URL`; relative `apiUrl` in config is ignored) |
78
157
 
79
- - **`--domain` / `--platform`** — Optional if `src/config.js` contains string literals `domain: '…'` and `platform: '…'` (or `targetDeploymentPlatform`).
80
- - **`--config`** — Path to another `config.js` if not `./src/config.js`.
81
- - If `platform` is omitted but `domain` is set (from flags or config), it is inferred from `deployments.json` when that domain appears under exactly one `targetDeploymentPlatform`.
82
- - **`--all`** — Runs `deployment deploy-all` for the platform; requires `--platform` or `platform` in config.
83
- - **Resource templates** — After a successful deploy, the CLI reads **`workspaceId`** / **`resourceTemplates`** from `./src/config.js` (or `--config`) using the **static extraction** described above (not `import()`). If **`workspaceId`** is set and **`resourceTemplates`** is a non-empty array, they are **POST**ed to **`{api}/resource-templates`** with the **`workspaceId`** header (same as the CMS). Skipped when **`--skip-resource-templates`** is set, or when `workspaceId` / `resourceTemplates` are missing or not extractable.
84
- - **Site artifacts** — Uses the same **static `workspaceId` / `apiUrl` extraction** as resource templates. If **`workspaceId`** is set and **`build/`** exists next to `src/` (i.e. run **`npm run build`** first), the CLI calls **`/site-artifacts/presign-batch`**, **PUT**s each file to S3, then **`/site-artifacts/commit-batch`** so a **`@ossy/platform/site-artifact-batch`** resource is created in the CMS. Skipped with **`--skip-site-artifacts`**, when there is no **`build/`**, or when **`workspaceId`** is missing. Override the build output directory with **`--site-artifacts-build-dir`** (absolute or cwd-relative).
85
- - **`--api-url`** — Optional API base for CMS calls (e.g. `https://api.ossy.se/api/v0`). Otherwise **`OSSY_API_URL`**, else an **absolute** `apiUrl` from config, else `https://api.ossy.se/api/v0`. Relative app `apiUrl` values (e.g. `/@ossy`) are ignored unless you pass **`--api-url`** or set **`OSSY_API_URL`**.
158
+ ### CI example
86
159
 
87
- Requires network access so `npx` can run `@ossy/deployment-tools`.
160
+ ```yaml
161
+ - name: Publish
162
+ run: |
163
+ npm run build
164
+ npx --yes @ossy/cli app publish \
165
+ --authentication ${{ secrets.OSSY_API_KEY }}
166
+ ```
88
167
 
89
- ## CMS: upload
168
+ ## App: upload
90
169
 
91
170
  Upload resource templates to your workspace so they can be used in the UI.
92
171
 
93
- Prefer **`--authentication` / `-a`** for the **Ossy API JWT** (same as **`publish`**); it matches **`OSSY_API_KEY`** in CI.
172
+ Wraps the SDK action **`workspaces.import-resource-templates`** and adds: reading `resourceTemplates` and `workspaceId` from `src/config.js` (so you don't have to inline the templates JSON yourself). If you already have the templates as a JSON object, the equivalent dispatcher call is:
94
173
 
95
174
  ```bash
96
- ossy cms upload --authentication <ossy-api-jwt> --config src/config.js
175
+ ossy call workspaces.import-resource-templates --json '{"templates":[…]}'
176
+ ```
177
+
178
+ Prefer **`--authentication` / `-a`** for the **Ossy API JWT** (same as **`app publish`**); it matches **`OSSY_API_KEY`** in CI.
179
+
180
+ ```bash
181
+ ossy app upload --authentication <ossy-api-jwt> --config src/config.js
97
182
  # optional: --api-url https://api.ossy.se/api/v0 (or set OSSY_API_URL)
98
183
  # In CI you may omit --authentication when OSSY_API_KEY is set
99
184
  ```
100
185
 
101
- When **`--config`** is omitted, **`./src/config.js`** is used if it exists (same as **`publish`**).
186
+ When **`--config`** is omitted, **`./src/config.js`** is used if it exists (same as **`app publish`**).
102
187
 
103
188
  ### Config consistency
104
189
 
105
- - **App** (`build`), **CMS** (`cms upload` / `cms validate`), and **publish** all use **`--config`** (`-c`) for the app / workspace config file (`src/config.js` by default when present).
190
+ - **App** (`build`), **app** (`app upload` / `app validate` / `app publish`), and **upload-dir** all use **`--config`** (`-c`) for the app / workspace config file (`src/config.js` by default when present).
106
191
 
107
192
  ### Workflow example
108
193
 
109
- Prefer **`publish`** so deploy and template upload run together (see **Publish** above). For template-only updates, `cms upload` still works.
194
+ Prefer **`app publish`** so templates and build files are uploaded together. For template-only updates, `app upload` still works.
110
195
 
111
196
  ```yaml
112
197
  name: "[CMS] Upload resource templates"
@@ -125,17 +210,17 @@ jobs:
125
210
  node-version: "16"
126
211
  - name: Upload
127
212
  run: |
128
- npx --yes @ossy/cli cms upload \
213
+ npx --yes @ossy/cli app upload \
129
214
  --authentication ${{ secrets.OSSY_API_KEY }} \
130
215
  --config src/config.js
131
216
  ```
132
217
 
133
- ### cms validate
218
+ ### app validate
134
219
 
135
220
  Validate an ossy config file before uploading:
136
221
 
137
222
  ```bash
138
- ossy cms validate --config src/config.js
223
+ ossy app validate --config src/config.js
139
224
  ```
140
225
 
141
226
  When **`--config`** is omitted, **`./src/config.js`** is used if it exists.
@@ -148,13 +233,70 @@ When **`--config`** is omitted, **`./src/config.js`** is used if it exists.
148
233
  | --config, -c | App config (`workspaceId`, `resourceTemplates`, …) | Optional if `./src/config.js` exists |
149
234
  | --api-url | API base URL for upload (`…/api/v0`) | No |
150
235
 
151
- ## init
236
+ ## Upload a directory
237
+
238
+ Recursively mirrors a local directory tree into the Ossy CMS, preserving the folder structure.
239
+
240
+ ```bash
241
+ ossy upload-dir ./public /my-folder
242
+ ```
243
+
244
+ This:
245
+ 1. Walks the local tree and collects all subdirectories (breadth-first) and files.
246
+ 2. Creates each remote directory with `resources.create-directory` (parents before children; already-existing directories are skipped silently).
247
+ 3. Uploads each file with `resources.upload` + S3 presigned PUT, in the same order they were discovered.
248
+ 4. Logs per-item progress and prints a summary at the end.
249
+
250
+ Per-item errors are logged and skipped — the command continues to the next item and exits non-zero when any item failed.
251
+
252
+ **Options:**
253
+
254
+ | Flag | Description |
255
+ |------|-------------|
256
+ | `--dry-run` | Print what would happen without making any API calls |
257
+ | `-a, --authentication` | Ossy API JWT (or `OSSY_API_KEY`, or `ossy auth login`) |
258
+ | `-w, --workspace-id` | Workspace id (or `OSSY_WORKSPACE_ID`, or `ossy workspace use`) |
259
+ | `--api-url` | Override the API base URL |
260
+
261
+ **Examples:**
262
+
263
+ ```bash
264
+ # Preview before committing
265
+ ossy upload-dir ./public /my-folder --dry-run
266
+
267
+ # Upload into a nested location
268
+ ossy upload-dir ./assets /projects/2026/assets
269
+
270
+ # Point at a local API
271
+ ossy upload-dir ./public /my-folder --api-url http://localhost:3001/api/v0
272
+ ```
273
+
274
+ ## Registry: ecr-push-credentials
275
+
276
+ Fetch a short-lived ECR password so CI can `docker login` and `docker push` to the workspace's ECR registry.
277
+
278
+ Wraps the SDK action **`registry.ecr-push-credentials`** and adds: response validation, JSON pretty-printing, and a `--format github-actions` mode that writes `registry`/`username`/`password`/`expires_at` to `$GITHUB_OUTPUT` and emits `::add-mask::<password>` so the secret never appears in logs.
279
+
280
+ ```bash
281
+ ossy registry ecr-push-credentials # JSON to stdout
282
+ ossy registry ecr-push-credentials --format github-actions # writes to $GITHUB_OUTPUT
283
+ ```
284
+
285
+ Auth and workspace are resolved from the usual chain (`-a` flag → `OSSY_API_KEY` → saved credentials; `-w` flag → `OSSY_WORKSPACE_ID` → saved active workspace). The plain dispatcher equivalent is:
286
+
287
+ ```bash
288
+ ossy call registry.ecr-push-credentials
289
+ ```
290
+
291
+ …but you lose the GitHub Actions output formatting and the `::add-mask::` line, so prefer the verb in CI.
292
+
293
+ ## App: init
152
294
 
153
295
  Scaffold a new Ossy app:
154
296
 
155
297
  ```bash
156
- ossy init
157
- ossy init my-app
298
+ ossy app init
299
+ ossy app init my-app
158
300
  ```
159
301
 
160
302
  Creates `src/home.page.jsx`, `src/config.js`, and `package.json` (if missing).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ossy/cli",
3
- "version": "1.16.10",
3
+ "version": "1.17.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ossy-se/packages.git"
@@ -20,7 +20,8 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@babel/parser": "^7.28.6",
23
- "@ossy/app": "^1.16.10",
23
+ "@ossy/app": "^1.17.3",
24
+ "@ossy/sdk": "^1.17.3",
24
25
  "arg": "^5.0.2",
25
26
  "glob": "^10.3.10"
26
27
  },
@@ -32,5 +33,5 @@
32
33
  "/src",
33
34
  "README.md"
34
35
  ],
35
- "gitHead": "5821b2cea64c9ca0ece35d65a463006852abf167"
36
+ "gitHead": "f96e3c98e87f9a19b92f7eab0d54e4de12509007"
36
37
  }
@@ -1,12 +1,16 @@
1
1
  import { readFileSync, existsSync } from 'fs'
2
2
  import { pathToFileURL } from 'url'
3
3
  import arg from 'arg'
4
+ import { build } from '@ossy/app'
4
5
  import { logInfo, logError } from '../log.js'
5
6
  import { resolveAppConfigPath } from '../resolve-app-config-path.js'
7
+ import { getAuth } from '../state.js'
8
+ import { init } from '../init/cli.js'
6
9
  import {
7
10
  postResourceTemplates,
8
11
  resolveApiBaseUrlForUpload,
9
12
  } from './upload-resource-templates.js'
13
+ import { publish } from './publish.js'
10
14
 
11
15
  const resolveConfigImport = (filePath) =>
12
16
  filePath.endsWith('json')
@@ -22,14 +26,13 @@ const upload = (options) => {
22
26
  '--api-url': String,
23
27
  }, { argv: options })
24
28
 
25
- const token =
26
- parsedArgs['--authentication'] || process.env.OSSY_API_KEY
29
+ const token = getAuth({ flag: parsedArgs['--authentication'] })
27
30
  const apiUrlFlag = parsedArgs['--api-url']
28
31
 
29
32
  if (!token) {
30
33
  logError({
31
34
  message:
32
- '[@ossy/cli] No token provided. Use --authentication / -a or set OSSY_API_KEY',
35
+ '[@ossy/cli] No token provided. Use --authentication / -a, set OSSY_API_KEY, or run `ossy auth login`.',
33
36
  })
34
37
  process.exit(1)
35
38
  }
@@ -150,19 +153,22 @@ const validate = (options) => {
150
153
  }
151
154
 
152
155
  const subcommands = {
156
+ init: (options) => init(options),
157
+ build: async (options) => { await build(options) },
153
158
  upload,
154
159
  validate,
160
+ publish: (options) => publish(options),
155
161
  }
156
162
 
157
- export const handler = ([subcommand, ...options]) => {
163
+ export const handler = async ([subcommand, ...options]) => {
158
164
  if (!subcommand) {
159
- logError({ message: '[@ossy/cli] cms: no subcommand. Use: ossy cms upload | validate' })
165
+ logError({ message: '[@ossy/cli] app: no subcommand. Use: ossy app init | build | upload | validate | publish' })
160
166
  process.exit(1)
161
167
  }
162
168
  const fn = subcommands[subcommand]
163
169
  if (!fn) {
164
- logError({ message: `[@ossy/cli] cms: unknown subcommand "${subcommand}". Use: ossy cms upload | validate` })
170
+ logError({ message: `[@ossy/cli] app: unknown subcommand "${subcommand}". Use: ossy app init | build | upload | validate | publish` })
165
171
  process.exit(1)
166
172
  }
167
- fn(options)
173
+ await fn(options)
168
174
  }
@@ -1,7 +1,6 @@
1
1
  import { readFileSync } from 'fs'
2
2
  import { resolve } from 'path'
3
3
  import { parse } from '@babel/parser'
4
- import { pathToFileURL } from 'url'
5
4
 
6
5
  /** @returns {unknown | undefined} `undefined` if the AST cannot be reduced to JSON-like data */
7
6
  function astNodeToLiteralValue (node) {
@@ -58,7 +57,7 @@ function astNodeToLiteralValue (node) {
58
57
 
59
58
  /**
60
59
  * Reads `resourceTemplates` from `export default { ... }` when it is a literal array
61
- * (no imports, calls, or templates). Matches typical OSSY website configs.
60
+ * (no imports, calls, or templates). Matches typical Ossy website configs.
62
61
  *
63
62
  * @param {string} source
64
63
  * @returns {unknown[] | undefined}
@@ -98,16 +97,13 @@ function extractResourceTemplatesFromSource (source) {
98
97
  }
99
98
 
100
99
  /**
101
- * Reads fields needed for `ossy publish` follow-up steps **without executing** `config.js`.
102
- * Avoids resolving imports such as `@ossy/themes` in CI (publish runs after deploy, outside Rollup).
103
- *
104
- * **Temporary** — prefer a build-time `publish-meta.json` or platform events once deploy is decoupled
105
- * from the CLI; see `packages/cli/README.md` → *Publish* → *Temporary: no execution of src/config.js*.
100
+ * Reads fields from `src/config.js` **without executing** it.
101
+ * Avoids resolving imports such as `@ossy/themes` in CI.
106
102
  *
107
103
  * @param {string} configPath Absolute or cwd-relative path to `src/config.js`
108
- * @returns {{ workspaceId?: string, apiUrl?: string, resourceTemplates?: unknown[] }}
104
+ * @returns {{ workspaceId?: string, apiUrl?: string, domain?: string, resourceTemplates?: unknown[] }}
109
105
  */
110
- export function readPublishFieldsFromWebsiteConfig (configPath) {
106
+ export function readAppConfig (configPath) {
111
107
  const abs = resolve(configPath)
112
108
  const source = readFileSync(abs, 'utf8')
113
109
 
@@ -126,17 +122,7 @@ export function readPublishFieldsFromWebsiteConfig (configPath) {
126
122
  return {
127
123
  workspaceId: pickString('workspaceId'),
128
124
  apiUrl: pickString('apiUrl'),
125
+ domain: pickString('domain'),
129
126
  resourceTemplates,
130
127
  }
131
128
  }
132
-
133
- /**
134
- * @deprecated Prefer {@link readPublishFieldsFromWebsiteConfig} for publish — dynamic import
135
- * runs all side effects and `import`s in config (e.g. `@ossy/themes`), which breaks in plain Node.
136
- * @param {string} configPath Absolute or cwd-relative path to config file
137
- */
138
- export async function loadWebsiteConfig (configPath) {
139
- const abs = resolve(configPath)
140
- const mod = await import(pathToFileURL(abs).href)
141
- return mod.default ?? mod
142
- }