@ossy/cli 1.40.0 → 1.40.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/README.md CHANGED
@@ -23,8 +23,8 @@ For one-off use without installing, you can still run `npx @ossy/cli <command>`.
23
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:
24
24
 
25
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.
26
+ 2. **Action dispatcher** — `invoke <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 invoke` if you outgrow the verb.
28
28
 
29
29
  | Layer | Command | Description |
30
30
  |-------|---------|-------------|
@@ -33,12 +33,12 @@ The contract for everything the platform can do is the **SDK action POJO** in [`
33
33
  | Local | `app init [dir]` | Scaffold a new Ossy app (default: current directory) |
34
34
  | Local | `app build` | Production build of the app in the current directory |
35
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) |
36
+ | Dispatcher | `invoke <action.id>` | Invoke any Ossy SDK action by id (`ossy invoke --help` for the full catalog) |
37
37
  | Workflow | `app upload` | Read `resourceTemplates` from `src/config.js` and call `workspaces.import-resource-templates` |
38
38
  | Workflow | `app publish` | Upload resource templates and `build/` to the CMS (combines `app upload` + `upload-dir`) |
39
39
  | Workflow | `upload-dir <dir> <location>` | Recursively mirror a local directory into the CMS (mkdir + upload per file) |
40
40
 
41
- If you need an endpoint that no verb wraps, reach for `ossy call` — it's the universal channel.
41
+ If you need an endpoint that no verb wraps, reach for `ossy invoke` — it's the universal channel.
42
42
 
43
43
  ## Auth and active workspace
44
44
 
@@ -65,34 +65,34 @@ Resolution order for the workspace id (when a command isn't reading it from `src
65
65
 
66
66
  So existing CI scripts that set `OSSY_API_KEY` keep working unchanged; you only need `ossy auth login` for interactive use.
67
67
 
68
- ## Generic dispatcher: `ossy call`
68
+ ## Generic dispatcher: `ossy invoke`
69
69
 
70
- `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.
70
+ `ossy invoke` 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.
71
71
 
72
72
  ```bash
73
73
  # Discover what's available
74
- ossy call --help # full catalog, grouped by domain
75
- ossy call resources.create --help # one action's method, endpoint, default payload
74
+ ossy invoke --help # full catalog, grouped by domain
75
+ ossy invoke resources.create --help # one action's method, endpoint, default payload
76
76
 
77
77
  # Read calls
78
- ossy call workspaces.get-current
79
- ossy call resources.list --search 'location=/docs'
78
+ ossy invoke workspaces.get-current
79
+ ossy invoke resources.list --search 'location=/docs'
80
80
 
81
81
  # Write calls — flag names map to payload keys (--first-name -> firstName)
82
- ossy call resources.create-directory --location /docs --name images
83
- ossy call workspaces.invite-user --email teammate@example.com
82
+ ossy invoke resources.create-directory --location /docs --name images
83
+ ossy invoke workspaces.invite-user --email teammate@example.com
84
84
 
85
85
  # Use --json for nested or non-string payloads
86
- ossy call resources.update-content --id res_abc --json '{"content":{"title":"Hi"}}'
86
+ ossy invoke resources.update-content --id res_abc --json '{"content":{"title":"Hi"}}'
87
87
 
88
88
  # Upload a file: --file fills name/type/size as defaults, then PUTs the bytes
89
89
  # when the response carries content.uploadUrl (works for resources.upload,
90
90
  # resources.upload-named-version, etc.)
91
- ossy call resources.upload --location /docs --file ./hero.jpg
92
- ossy call resources.upload-named-version --id res_abc --name medium --file ./hero.jpg
91
+ ossy invoke resources.upload --location /docs --file ./hero.jpg
92
+ ossy invoke resources.upload-named-version --id res_abc --name medium --file ./hero.jpg
93
93
 
94
94
  # Per-call overrides (otherwise resolved from `ossy auth login` / `ossy workspace use`)
95
- ossy call workspaces.get-all -a <jwt> --api-url http://localhost:3001/api/v0
95
+ ossy invoke workspaces.get-all -a <jwt> --api-url http://localhost:3001/api/v0
96
96
  ```
97
97
 
98
98
  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).
@@ -171,7 +171,7 @@ Upload resource templates to your workspace so they can be used in the UI.
171
171
  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:
172
172
 
173
173
  ```bash
174
- ossy call workspaces.import-resource-templates --json '{"templates":[…]}'
174
+ ossy invoke workspaces.import-resource-templates --json '{"templates":[…]}'
175
175
  ```
176
176
 
177
177
  Prefer **`--authentication` / `-a`** for the **Ossy API JWT** (same as **`app publish`**); it matches **`OSSY_API_KEY`** in CI.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ossy/cli",
3
- "version": "1.40.0",
3
+ "version": "1.40.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ossy-se/packages.git"
@@ -20,8 +20,8 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@babel/parser": "^7.28.6",
23
- "@ossy/app": "^1.40.0",
24
- "@ossy/sdk": "^1.40.0",
23
+ "@ossy/app": "^1.40.2",
24
+ "@ossy/sdk": "^1.40.2",
25
25
  "arg": "^5.0.2",
26
26
  "glob": "^13.0.6"
27
27
  },
@@ -33,5 +33,5 @@
33
33
  "/src",
34
34
  "README.md"
35
35
  ],
36
- "gitHead": "d9d31182be64a448d575da432af2830d909ad4b9"
36
+ "gitHead": "2b8745d57fee8b6c08787e2755b4df489291a5cd"
37
37
  }
@@ -115,7 +115,7 @@ export async function publish (options) {
115
115
  const parent = i === 0 ? '/' : '/' + destSegments.slice(0, i).join('/')
116
116
  const name = destSegments[i]
117
117
  try {
118
- await sdk.makeRequest(createDir)({ location: parent, name })
118
+ await sdk.invoke(createDir, { location: parent, name })
119
119
  } catch (err) {
120
120
  const status = err && err.status
121
121
  if (status !== 409 && status !== 422) {
@@ -133,7 +133,7 @@ export async function publish (options) {
133
133
  const parent = normaliseLoc(remoteDest + path.dirname(rel))
134
134
  const name = path.basename(d)
135
135
  try {
136
- await sdk.makeRequest(createDir)({ location: parent, name })
136
+ await sdk.invoke(createDir, { location: parent, name })
137
137
  } catch (err) {
138
138
  const status = err && err.status
139
139
  if (status !== 409 && status !== 422) {
@@ -164,7 +164,7 @@ export async function publish (options) {
164
164
 
165
165
  let result
166
166
  try {
167
- result = await sdk.makeRequest(uploadAction)({
167
+ result = await sdk.invoke(uploadAction, {
168
168
  location: remoteDir,
169
169
  name: fileMeta.name,
170
170
  type: fileMeta.type,
package/src/call/cli.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as Sdk from '@ossy/sdk'
2
+ import { resolveActionId } from '@ossy/sdk'
2
3
  import { logError } from '../log.js'
3
4
  import { getAuth, getApiUrl, getWorkspaceId } from '../state.js'
4
5
  import { prepareFileUpload, uploadFileToUrl } from '../file.js'
@@ -8,16 +9,19 @@ const ACTIONS = Object.values(Sdk).filter(
8
9
  v
9
10
  && typeof v === 'object'
10
11
  && typeof v.id === 'string'
11
- && typeof v.endpoint === 'string'
12
- && typeof v.method === 'string'
12
+ && v.id.includes('/')
13
13
  )
14
14
 
15
- const ACTION_BY_ID = new Map(ACTIONS.map((a) => [a.id, a]))
15
+ const ACTION_BY_ID = new Map()
16
+ for (const action of ACTIONS) {
17
+ ACTION_BY_ID.set(action.id, action)
18
+ ACTION_BY_ID.set(action.id.replace(/\//g, '.'), action)
19
+ }
16
20
 
17
21
  function listActionsByDomain () {
18
22
  const grouped = new Map()
19
23
  for (const action of ACTIONS) {
20
- const domain = action.id.split('.')[0]
24
+ const domain = action.id.split('/')[0]
21
25
  if (!grouped.has(domain)) grouped.set(domain, [])
22
26
  grouped.get(domain).push(action.id)
23
27
  }
@@ -31,7 +35,7 @@ function buildHelp () {
31
35
  for (const [domain, ids] of grouped) {
32
36
  blocks.push(` ${domain}\n${ids.map((id) => ` ${id}`).join('\n')}`)
33
37
  }
34
- return `ossy call <action.id> [--key value]... [--json '{...}'] [options]
38
+ return `ossy invoke <action.id> [--key value]... [--json '{...}'] [options]
35
39
 
36
40
  Generic dispatcher for any Ossy API action. Flags become payload fields
37
41
  (--first-name -> firstName); --json '{...}' is merged on top.
@@ -46,7 +50,7 @@ Options:
46
50
  --raw Print response body without JSON pretty-printing
47
51
 
48
52
  Per-action help:
49
- ossy call <action.id> --help
53
+ ossy invoke <action.id> --help
50
54
 
51
55
  Available actions:
52
56
 
@@ -56,11 +60,11 @@ ${blocks.join('\n\n')}
56
60
 
57
61
  function actionHelp (action) {
58
62
  const def = action.payload ? `Default payload:\n ${JSON.stringify(action.payload)}\n\n` : ''
59
- return `${action.id} ${action.method} ${action.endpoint}
63
+ return `${action.id} POST /actions { action: "${action.id}", payload: … }
60
64
 
61
65
  ${def}Examples:
62
- ossy call ${action.id} --key value --other value
63
- ossy call ${action.id} --json '{"key":"value"}'
66
+ ossy invoke ${action.id} --key value --other value
67
+ ossy invoke ${action.id} --json '{"key":"value"}'
64
68
  `
65
69
  }
66
70
 
@@ -211,7 +215,7 @@ async function call (args) {
211
215
  return
212
216
  }
213
217
 
214
- const action = ACTION_BY_ID.get(parsed.actionId)
218
+ const action = ACTION_BY_ID.get(parsed.actionId) ?? ACTION_BY_ID.get(resolveActionId(parsed.actionId))
215
219
  if (!action) {
216
220
  logError({
217
221
  message: `[@ossy/cli] call: unknown action "${parsed.actionId}". Run \`ossy call --help\` for the list.`,
@@ -249,7 +253,7 @@ async function call (args) {
249
253
 
250
254
  let result
251
255
  try {
252
- result = await sdk.makeRequest(action)(parsed.payload)
256
+ result = await sdk.invoke(action, parsed.payload)
253
257
  } catch (err) {
254
258
  if (isResponseLike(err)) {
255
259
  const text = await err.text().catch(() => '')
package/src/index.js CHANGED
@@ -25,7 +25,7 @@ Local utilities:
25
25
  app <subcommand> App commands: init | build | upload | validate | publish
26
26
 
27
27
  Action dispatcher (any Ossy SDK action, no per-action wiring needed):
28
- call <action.id> Run \`ossy call --help\` for the full catalog
28
+ invoke <action.id> Run \`ossy invoke --help\` for the full catalog
29
29
 
30
30
  Workflows (wrap one or more actions with extra ergonomics):
31
31
  upload-dir <dir> <loc> Recursively upload a local directory to the CMS
@@ -120,7 +120,12 @@ const run = async () => {
120
120
  await Workspace.handler(restArgs)
121
121
  return
122
122
  }
123
+ if (command === 'invoke') {
124
+ await Call.handler(restArgs)
125
+ return
126
+ }
123
127
  if (command === 'call') {
128
+ process.stderr.write('[@ossy/cli] `ossy call` is deprecated — use `ossy invoke` instead.\n')
124
129
  await Call.handler(restArgs)
125
130
  return
126
131
  }
@@ -198,7 +198,7 @@ export async function handler (args) {
198
198
  const name = path.basename(d)
199
199
  logInfo({ message: `[@ossy/cli] upload-dir: mkdir ${parent}/${name}` })
200
200
  try {
201
- await sdk.makeRequest(createDir)({ location: parent, name })
201
+ await sdk.invoke(createDir, { location: parent, name })
202
202
  dirsMade++
203
203
  } catch (err) {
204
204
  // Treat "already exists" (HTTP 409 / 422 / resource conflict) as success
@@ -231,7 +231,7 @@ export async function handler (args) {
231
231
 
232
232
  let result
233
233
  try {
234
- result = await sdk.makeRequest(uploadAction)({
234
+ result = await sdk.invoke(uploadAction, {
235
235
  location: remoteDir,
236
236
  name: fileMeta.name,
237
237
  type: fileMeta.type,