workato-dev-api 1.1.0 → 1.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/CLAUDE.md +11 -6
- package/README.md +1 -1
- package/cli.js +5 -1
- package/lib.js +17 -2
- package/package.json +5 -2
- package/test/cli.test.js +101 -0
package/CLAUDE.md
CHANGED
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
Use `npx workato-dev-api <command>` (or `workato <command>` if installed globally) for all Workato operations — reads and writes alike.
|
|
6
6
|
|
|
7
|
-
Requires `WORKATO_API_TOKEN` in a `.env` file (cwd `.env` takes highest priority).
|
|
7
|
+
Requires `WORKATO_API_TOKEN` in a `.env` file (cwd `.env` takes highest priority).
|
|
8
|
+
|
|
9
|
+
Base URL is determined by `workato.sandbox` in the project's `package.json`:
|
|
10
|
+
- `false` (default): `https://app.workato.com/api`
|
|
11
|
+
- `true` (free sandbox): `https://app.trial.workato.com/api`
|
|
12
|
+
|
|
13
|
+
**If the user says they are on a Workato free sandbox or trial account, set `"sandbox": true` in the `workato` block of their `package.json` immediately.**
|
|
8
14
|
|
|
9
15
|
### Commands
|
|
10
16
|
|
|
@@ -127,13 +133,12 @@ Always use `workato get-data-table <id>` or read the recipe code to look up the
|
|
|
127
133
|
|
|
128
134
|
---
|
|
129
135
|
|
|
130
|
-
## Reference
|
|
131
|
-
|
|
132
|
-
**Transcribe Audio** (ID: 167603) — `https://app.trial.workato.com/recipes/167603-transcribe-audio`
|
|
136
|
+
## Reference Recipes
|
|
133
137
|
|
|
134
|
-
|
|
138
|
+
If you are unsure how to wire a particular connector or step type, ask the user:
|
|
139
|
+
> "Do you have an existing recipe that uses [connector/trigger type]? If so, share the recipe ID and I'll fetch it as a wiring reference."
|
|
135
140
|
|
|
136
|
-
|
|
141
|
+
Use `workato get <recipe_id>` to inspect the code and extract the correct `as` IDs, `provider` values, `input` structure, and `extended_output_schema` before building or patching a new recipe.
|
|
137
142
|
|
|
138
143
|
---
|
|
139
144
|
|
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ npx workato-dev-api bootstrap-claude
|
|
|
40
40
|
|
|
41
41
|
That's it. The first command saves your token to `.env`. The second drops a `CLAUDE.md` into the directory so Claude Code automatically has full context — recipe structure, wiring syntax, data table column names, and project reference IDs.
|
|
42
42
|
|
|
43
|
-
Then
|
|
43
|
+
Then open Claude Code in that directory and start working. If you're on a **Workato free sandbox**, just tell Claude — it will update your `package.json` automatically so the CLI points at the right URL.
|
|
44
44
|
|
|
45
45
|
## Commands
|
|
46
46
|
|
package/cli.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
const os = require('os');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const {
|
|
7
|
-
loadEnv,
|
|
7
|
+
loadEnv, setConfig, resolveBaseUrl, readProjectConfig,
|
|
8
8
|
cmdBootstrapClaude, cmdAuth,
|
|
9
9
|
cmdGet, cmdListRecipes, cmdListProjects, cmdListFolders,
|
|
10
10
|
cmdListConnections, cmdListDataTables, cmdGetDataTable,
|
|
@@ -40,6 +40,10 @@ if (!process.env.WORKATO_API_TOKEN) {
|
|
|
40
40
|
process.exit(1);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
// Apply base URL from workato.sandbox in cwd package.json
|
|
44
|
+
const { workato: _wCfg = {} } = readProjectConfig();
|
|
45
|
+
setConfig({ baseUrl: resolveBaseUrl(_wCfg.sandbox) });
|
|
46
|
+
|
|
43
47
|
// Parse argv: separate --flag value pairs from positional args
|
|
44
48
|
function parseArgs(argv) {
|
|
45
49
|
const positional = [];
|
package/lib.js
CHANGED
|
@@ -7,10 +7,25 @@ const crypto = require('crypto');
|
|
|
7
7
|
// ── Config ────────────────────────────────────────────────────────────────────
|
|
8
8
|
|
|
9
9
|
const _config = {
|
|
10
|
-
baseUrl: 'https://app.
|
|
10
|
+
baseUrl: 'https://app.workato.com/api',
|
|
11
11
|
token: null,
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
function resolveBaseUrl(sandbox) {
|
|
15
|
+
return sandbox === true
|
|
16
|
+
? 'https://app.trial.workato.com/api'
|
|
17
|
+
: 'https://app.workato.com/api';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function readProjectConfig(cwd) {
|
|
21
|
+
const pkgPath = path.join(cwd ?? process.cwd(), 'package.json');
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
24
|
+
} catch {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
14
29
|
function loadEnv(envPath) {
|
|
15
30
|
const p = envPath ?? path.join(process.cwd(), '.env');
|
|
16
31
|
if (!fs.existsSync(p)) return;
|
|
@@ -331,7 +346,7 @@ async function cmdDelete(recipeId) {
|
|
|
331
346
|
|
|
332
347
|
module.exports = {
|
|
333
348
|
// config
|
|
334
|
-
loadEnv, setConfig, getToken,
|
|
349
|
+
loadEnv, setConfig, getToken, resolveBaseUrl, readProjectConfig,
|
|
335
350
|
// http
|
|
336
351
|
apiGet, apiPost, apiPut, apiDelete,
|
|
337
352
|
// helpers
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "workato-dev-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "CLI for the Workato Developer API — recipes, connections, data tables, and more",
|
|
5
5
|
"bin": {
|
|
6
6
|
"workato": "cli.js"
|
|
@@ -18,5 +18,8 @@
|
|
|
18
18
|
"recipes",
|
|
19
19
|
"automation"
|
|
20
20
|
],
|
|
21
|
-
"license": "MIT"
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"workato": {
|
|
23
|
+
"sandbox": false
|
|
24
|
+
}
|
|
22
25
|
}
|
package/test/cli.test.js
CHANGED
|
@@ -982,6 +982,107 @@ describe('cmdUpdateStep — deeply nested step', () => {
|
|
|
982
982
|
});
|
|
983
983
|
});
|
|
984
984
|
|
|
985
|
+
// ── resolveBaseUrl ────────────────────────────────────────────────────────────
|
|
986
|
+
|
|
987
|
+
describe('resolveBaseUrl', () => {
|
|
988
|
+
test('returns production URL when sandbox is false', () => {
|
|
989
|
+
assert.equal(lib.resolveBaseUrl(false), 'https://app.workato.com/api');
|
|
990
|
+
});
|
|
991
|
+
|
|
992
|
+
test('returns production URL when sandbox is undefined', () => {
|
|
993
|
+
assert.equal(lib.resolveBaseUrl(undefined), 'https://app.workato.com/api');
|
|
994
|
+
});
|
|
995
|
+
|
|
996
|
+
test('returns production URL when sandbox is a string "false"', () => {
|
|
997
|
+
assert.equal(lib.resolveBaseUrl('false'), 'https://app.workato.com/api');
|
|
998
|
+
});
|
|
999
|
+
|
|
1000
|
+
test('returns sandbox URL when sandbox is true', () => {
|
|
1001
|
+
assert.equal(lib.resolveBaseUrl(true), 'https://app.trial.workato.com/api');
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
test('sandbox URL contains "trial"', () => {
|
|
1005
|
+
assert.ok(lib.resolveBaseUrl(true).includes('trial'));
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
test('production URL does not contain "trial"', () => {
|
|
1009
|
+
assert.ok(!lib.resolveBaseUrl(false).includes('trial'));
|
|
1010
|
+
});
|
|
1011
|
+
});
|
|
1012
|
+
|
|
1013
|
+
// ── readProjectConfig ─────────────────────────────────────────────────────────
|
|
1014
|
+
|
|
1015
|
+
describe('readProjectConfig', () => {
|
|
1016
|
+
function tmpDir() {
|
|
1017
|
+
const d = path.join(os.tmpdir(), `workato-cfg-test-${Date.now()}-${Math.random()}`);
|
|
1018
|
+
fs.mkdirSync(d, { recursive: true });
|
|
1019
|
+
return d;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
test('returns empty object when no package.json exists', () => {
|
|
1023
|
+
const dir = tmpDir();
|
|
1024
|
+
try {
|
|
1025
|
+
assert.deepEqual(lib.readProjectConfig(dir), {});
|
|
1026
|
+
} finally {
|
|
1027
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
1028
|
+
}
|
|
1029
|
+
});
|
|
1030
|
+
|
|
1031
|
+
test('returns parsed package.json contents', () => {
|
|
1032
|
+
const dir = tmpDir();
|
|
1033
|
+
try {
|
|
1034
|
+
fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify({ workato: { sandbox: true } }));
|
|
1035
|
+
const cfg = lib.readProjectConfig(dir);
|
|
1036
|
+
assert.equal(cfg.workato.sandbox, true);
|
|
1037
|
+
} finally {
|
|
1038
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
1039
|
+
}
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
test('returns empty object when package.json is malformed JSON', () => {
|
|
1043
|
+
const dir = tmpDir();
|
|
1044
|
+
try {
|
|
1045
|
+
fs.writeFileSync(path.join(dir, 'package.json'), 'not valid json {{{');
|
|
1046
|
+
assert.deepEqual(lib.readProjectConfig(dir), {});
|
|
1047
|
+
} finally {
|
|
1048
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
1051
|
+
|
|
1052
|
+
test('sandbox false in package.json resolves to production URL', () => {
|
|
1053
|
+
const dir = tmpDir();
|
|
1054
|
+
try {
|
|
1055
|
+
fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify({ workato: { sandbox: false } }));
|
|
1056
|
+
const { workato: wCfg = {} } = lib.readProjectConfig(dir);
|
|
1057
|
+
assert.equal(lib.resolveBaseUrl(wCfg.sandbox), 'https://app.workato.com/api');
|
|
1058
|
+
} finally {
|
|
1059
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
1060
|
+
}
|
|
1061
|
+
});
|
|
1062
|
+
|
|
1063
|
+
test('sandbox true in package.json resolves to trial URL', () => {
|
|
1064
|
+
const dir = tmpDir();
|
|
1065
|
+
try {
|
|
1066
|
+
fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify({ workato: { sandbox: true } }));
|
|
1067
|
+
const { workato: wCfg = {} } = lib.readProjectConfig(dir);
|
|
1068
|
+
assert.equal(lib.resolveBaseUrl(wCfg.sandbox), 'https://app.trial.workato.com/api');
|
|
1069
|
+
} finally {
|
|
1070
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
1071
|
+
}
|
|
1072
|
+
});
|
|
1073
|
+
|
|
1074
|
+
test('missing workato key resolves to production URL', () => {
|
|
1075
|
+
const dir = tmpDir();
|
|
1076
|
+
try {
|
|
1077
|
+
fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify({ name: 'my-project' }));
|
|
1078
|
+
const { workato: wCfg = {} } = lib.readProjectConfig(dir);
|
|
1079
|
+
assert.equal(lib.resolveBaseUrl(wCfg.sandbox), 'https://app.workato.com/api');
|
|
1080
|
+
} finally {
|
|
1081
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
1082
|
+
}
|
|
1083
|
+
});
|
|
1084
|
+
});
|
|
1085
|
+
|
|
985
1086
|
// ── cmdBootstrapClaude ────────────────────────────────────────────────────────
|
|
986
1087
|
|
|
987
1088
|
describe('cmdBootstrapClaude', () => {
|