jitsu-cli 1.10.4 → 2.14.0-beta.101
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/bin/jitsu +3 -0
- package/build.mts +39 -0
- package/compiled/package.json +26 -29
- package/compiled/src/commands/build.js +43 -55
- package/compiled/src/commands/config/handlers.js +292 -0
- package/compiled/src/commands/config/index.js +148 -0
- package/compiled/src/commands/config/resources.js +88 -0
- package/compiled/src/commands/default-workspace.js +39 -0
- package/compiled/src/commands/deploy.js +90 -58
- package/compiled/src/commands/init.js +17 -21
- package/compiled/src/commands/login.js +24 -27
- package/compiled/src/commands/shared.js +12 -17
- package/compiled/src/commands/spec.js +31 -0
- package/compiled/src/commands/test.js +7 -10
- package/compiled/src/commands/whoami.js +8 -12
- package/compiled/src/index.js +39 -23
- package/compiled/src/lib/api-client.js +52 -0
- package/compiled/src/lib/auth-file.js +67 -0
- package/compiled/src/lib/body-builder.js +53 -0
- package/compiled/src/lib/body-fields.js +47 -0
- package/compiled/src/lib/chalk-code-highlight.js +15 -20
- package/compiled/src/lib/compiled-function.js +27 -29
- package/compiled/src/lib/dotted.js +34 -0
- package/compiled/src/lib/indent.js +3 -8
- package/compiled/src/lib/renderer.js +33 -0
- package/compiled/src/lib/spec.js +11 -0
- package/compiled/src/lib/template.js +7 -11
- package/compiled/src/lib/version.js +13 -20
- package/compiled/src/templates/functions.js +13 -18
- package/dist/main.js +45727 -86292
- package/dist/main.js.map +7 -1
- package/package.json +26 -29
- package/src/commands/build.ts +22 -27
- package/src/commands/config/handlers.ts +339 -0
- package/src/commands/config/index.ts +171 -0
- package/src/commands/config/resources.ts +110 -0
- package/src/commands/default-workspace.ts +44 -0
- package/src/commands/deploy.ts +96 -20
- package/src/commands/login.ts +3 -1
- package/src/commands/spec.ts +32 -0
- package/src/index.ts +34 -17
- package/src/lib/api-client.ts +64 -0
- package/src/lib/auth-file.ts +83 -0
- package/src/lib/body-builder.ts +68 -0
- package/src/lib/body-fields.ts +61 -0
- package/src/lib/compiled-function.ts +30 -23
- package/src/lib/dotted.ts +43 -0
- package/src/lib/renderer.ts +44 -0
- package/src/lib/spec.ts +32 -0
- package/tsconfig.json +2 -19
- package/.turbo/turbo-build.log +0 -28
- package/.turbo/turbo-clean.log +0 -5
- package/babel.config.cjs +0 -4
- package/dist/140.js +0 -452
- package/dist/140.js.map +0 -1
- package/dist/233.js +0 -4890
- package/dist/233.js.map +0 -1
- package/dist/445e7f36f8a19c2bf682.js +0 -900
- package/webpack.config.js +0 -49
package/bin/jitsu
ADDED
package/build.mts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as esbuild from "esbuild";
|
|
2
|
+
import { mkdirSync } from "fs";
|
|
3
|
+
|
|
4
|
+
// Ensure dist directory exists
|
|
5
|
+
mkdirSync("./dist", { recursive: true });
|
|
6
|
+
|
|
7
|
+
// External modules that should not be bundled
|
|
8
|
+
// These are either native modules or need to be loaded at runtime
|
|
9
|
+
const externalModules = [
|
|
10
|
+
// Native/binary modules
|
|
11
|
+
"figlet", // ASCII art library with data files
|
|
12
|
+
"fsevents", // macOS-only native file system events
|
|
13
|
+
"esbuild", // esbuild has native binaries, used at runtime to build user functions
|
|
14
|
+
|
|
15
|
+
// Large runtime dependencies
|
|
16
|
+
"typescript", // TypeScript compiler (large, used at runtime)
|
|
17
|
+
"jest-cli", // Jest test runner
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
// Bundle the CLI
|
|
21
|
+
esbuild
|
|
22
|
+
.build({
|
|
23
|
+
entryPoints: ["./src/index.ts"],
|
|
24
|
+
bundle: true,
|
|
25
|
+
platform: "node",
|
|
26
|
+
target: "node20",
|
|
27
|
+
format: "cjs",
|
|
28
|
+
outfile: "./dist/main.js",
|
|
29
|
+
sourcemap: true,
|
|
30
|
+
minify: false,
|
|
31
|
+
external: externalModules,
|
|
32
|
+
logLevel: "info",
|
|
33
|
+
loader: {
|
|
34
|
+
".json": "json",
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
.then(() => {
|
|
38
|
+
console.log("\nBuild complete!");
|
|
39
|
+
});
|
package/compiled/package.json
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jitsu-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.14.0-beta.101",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/jitsucom/jitsu",
|
|
7
|
+
"directory": "cli/jitsu-cli"
|
|
8
|
+
},
|
|
4
9
|
"description": "",
|
|
5
10
|
"author": "Jitsu Dev Team <dev@jitsu.com>",
|
|
6
11
|
"publishConfig": {
|
|
7
12
|
"access": "public"
|
|
8
13
|
},
|
|
9
|
-
"bin":
|
|
14
|
+
"bin": {
|
|
15
|
+
"jitsu-cli": "./bin/jitsu-cli",
|
|
16
|
+
"jitsu": "./bin/jitsu"
|
|
17
|
+
},
|
|
10
18
|
"license": "MIT",
|
|
11
19
|
"private": false,
|
|
12
20
|
"scripts": {
|
|
13
|
-
"clean": "rm -rf ./dist",
|
|
14
|
-
"
|
|
15
|
-
"build": "
|
|
21
|
+
"clean": "rm -rf ./dist ./compiled",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"build": "tsc && tsx build.mts",
|
|
24
|
+
"cli": "tsx src/index.ts",
|
|
16
25
|
"run": "pnpm build && node dist/main.js",
|
|
17
26
|
"login": "pnpm build && node dist/main.js login",
|
|
18
27
|
"init child": "pnpm build && node dist/main.js init",
|
|
@@ -22,31 +31,23 @@
|
|
|
22
31
|
"deploy child": "pnpm build && node dist/main.js deploy"
|
|
23
32
|
},
|
|
24
33
|
"dependencies": {
|
|
34
|
+
"esbuild": "catalog:",
|
|
25
35
|
"figlet": "^1.6.0",
|
|
26
36
|
"jest-cli": "^29.7.0",
|
|
27
|
-
"tslib": "
|
|
28
|
-
"typescript": "
|
|
37
|
+
"tslib": "catalog:",
|
|
38
|
+
"typescript": "catalog:"
|
|
29
39
|
},
|
|
30
40
|
"devDependencies": {
|
|
31
|
-
"@
|
|
32
|
-
"@babel/preset-typescript": "^7.23.2",
|
|
41
|
+
"@jitsu/common-config": "workspace:*",
|
|
33
42
|
"@jitsu/functions-lib": "workspace:*",
|
|
34
43
|
"@jitsu/protocols": "workspace:*",
|
|
35
|
-
"@rollup/plugin-commonjs": "^28.0.2",
|
|
36
|
-
"@rollup/plugin-json": "^6.0.0",
|
|
37
|
-
"@rollup/plugin-node-resolve": "^16.0.0",
|
|
38
|
-
"@rollup/plugin-terser": "^0.4.3",
|
|
39
|
-
"@rollup/plugin-typescript": "^11.1.3",
|
|
40
44
|
"@types/chalk": "^2.2.0",
|
|
41
45
|
"@types/commander": "^2.12.2",
|
|
42
46
|
"@types/express": "^4.17.21",
|
|
43
47
|
"@types/inquirer": "^9.0.3",
|
|
44
|
-
"@types/
|
|
45
|
-
"@types/
|
|
46
|
-
"@
|
|
47
|
-
"@types/webpack": "^5.28.5",
|
|
48
|
-
"@webpack-cli/generators": "^3.0.7",
|
|
49
|
-
"babel-loader": "^9.1.3",
|
|
48
|
+
"@types/lodash": "catalog:",
|
|
49
|
+
"@types/node": "catalog:",
|
|
50
|
+
"@vitest/ui": "catalog:",
|
|
50
51
|
"chalk": "^5.3.0",
|
|
51
52
|
"commander": "^11.0.0",
|
|
52
53
|
"cross-fetch": "^4.0.0",
|
|
@@ -54,18 +55,14 @@
|
|
|
54
55
|
"etag": "^1.8.1",
|
|
55
56
|
"inquirer": "^9.2.11",
|
|
56
57
|
"jest": "^29.7.0",
|
|
58
|
+
"js-yaml": "^4.1.0",
|
|
59
|
+
"@types/js-yaml": "^4.0.9",
|
|
57
60
|
"json5": "^2.2.3",
|
|
58
61
|
"juava": "workspace:*",
|
|
59
|
-
"lodash": "
|
|
60
|
-
"node-fetch": "^3.3.2",
|
|
61
|
-
"node-loader": "^2.0.0",
|
|
62
|
+
"lodash": "catalog:",
|
|
62
63
|
"prismjs": "^1.30.0",
|
|
63
|
-
"rollup": "^3.29.5",
|
|
64
64
|
"semver": "^7.5.4",
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"ts-node": "^10.9.2",
|
|
68
|
-
"webpack": "^5.99.5",
|
|
69
|
-
"webpack-cli": "^6.0.1"
|
|
65
|
+
"tsx": "catalog:",
|
|
66
|
+
"vitest": "catalog:"
|
|
70
67
|
}
|
|
71
68
|
}
|
|
@@ -1,22 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
const child_process_1 = require("child_process");
|
|
13
|
-
const shared_1 = require("./shared");
|
|
14
|
-
const chalk_code_highlight_1 = require("../lib/chalk-code-highlight");
|
|
15
|
-
const compiled_function_1 = require("../lib/compiled-function");
|
|
16
|
-
const ts = tslib_1.__importStar(require("typescript"));
|
|
17
|
-
async function build({ dir }) {
|
|
18
|
-
const { packageJson, projectDir } = await (0, shared_1.loadPackageJson)(dir || process.cwd());
|
|
19
|
-
console.log(`Building ${(0, chalk_code_highlight_1.b)(packageJson.name)} project`);
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { mkdirSync, readdirSync, existsSync, lstatSync } from "fs";
|
|
3
|
+
import * as esbuild from "esbuild";
|
|
4
|
+
import { exec } from "child_process";
|
|
5
|
+
import { loadPackageJson } from "./shared";
|
|
6
|
+
import { b, green, red } from "../lib/chalk-code-highlight";
|
|
7
|
+
import { getFunctionFromFilePath } from "../lib/compiled-function";
|
|
8
|
+
import * as ts from "typescript";
|
|
9
|
+
export async function build({ dir }) {
|
|
10
|
+
const { packageJson, projectDir } = await loadPackageJson(dir || process.cwd());
|
|
11
|
+
console.log(`Building ${b(packageJson.name)} project`);
|
|
20
12
|
const errors = checkTypescript(projectDir);
|
|
21
13
|
if (errors) {
|
|
22
14
|
console.error(`Found ${errors.length} errors in functions files. Exiting`);
|
|
@@ -29,10 +21,10 @@ async function build({ dir }) {
|
|
|
29
21
|
catch (e) {
|
|
30
22
|
throw new Error(`Some of the functions failed to compile. See details above. Last error: ${e.message || "unknown"}`);
|
|
31
23
|
}
|
|
32
|
-
console.log(`${
|
|
24
|
+
console.log(`${b("Build finished.")}`);
|
|
33
25
|
}
|
|
34
26
|
const run = async (cmd) => {
|
|
35
|
-
const child =
|
|
27
|
+
const child = exec(cmd, err => {
|
|
36
28
|
if (err) {
|
|
37
29
|
console.error(err);
|
|
38
30
|
return;
|
|
@@ -44,20 +36,20 @@ const run = async (cmd) => {
|
|
|
44
36
|
};
|
|
45
37
|
async function buildFiles(projectDir, dir = "") {
|
|
46
38
|
let lastError = undefined;
|
|
47
|
-
const srcDir =
|
|
48
|
-
if (!
|
|
49
|
-
console.info(`${
|
|
39
|
+
const srcDir = path.resolve(projectDir, "src", dir);
|
|
40
|
+
if (!existsSync(srcDir)) {
|
|
41
|
+
console.info(`${b(dir)} directory not found in ${b(path.resolve(projectDir, "src"))}`);
|
|
50
42
|
return;
|
|
51
43
|
}
|
|
52
|
-
const files =
|
|
44
|
+
const files = readdirSync(srcDir);
|
|
53
45
|
if (files.length === 0) {
|
|
54
|
-
console.warn(`No functions found in ${
|
|
46
|
+
console.warn(`No functions found in ${b(srcDir)} directory`);
|
|
55
47
|
return;
|
|
56
48
|
}
|
|
57
49
|
for (const file of files) {
|
|
58
|
-
if (
|
|
50
|
+
if (lstatSync(path.resolve(srcDir, file)).isDirectory()) {
|
|
59
51
|
try {
|
|
60
|
-
await buildFiles(projectDir,
|
|
52
|
+
await buildFiles(projectDir, path.join(dir, file));
|
|
61
53
|
}
|
|
62
54
|
catch (e) {
|
|
63
55
|
lastError = e;
|
|
@@ -69,7 +61,7 @@ async function buildFiles(projectDir, dir = "") {
|
|
|
69
61
|
}
|
|
70
62
|
catch (e) {
|
|
71
63
|
console.error([
|
|
72
|
-
`${
|
|
64
|
+
`${red(`⚠`)} Function ${b(file)} failed to compile: ${red(e?.message)}. See details below`,
|
|
73
65
|
...(e?.stack?.split("\n") || []).map(s => ` ${s}`),
|
|
74
66
|
]
|
|
75
67
|
.filter(Boolean)
|
|
@@ -82,55 +74,51 @@ async function buildFiles(projectDir, dir = "") {
|
|
|
82
74
|
}
|
|
83
75
|
}
|
|
84
76
|
async function buildFile(projectDir, dir, fileName) {
|
|
85
|
-
const funcFile =
|
|
77
|
+
const funcFile = path.resolve(projectDir, "src", path.join(dir, fileName));
|
|
86
78
|
process.chdir(projectDir);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
79
|
+
mkdirSync(path.resolve(projectDir, "dist/" + dir), { recursive: true });
|
|
80
|
+
const compiledFunctionPath = `dist/${dir}/${fileName.replace(".ts", ".js")}`;
|
|
81
|
+
await esbuild.build({
|
|
82
|
+
entryPoints: [funcFile],
|
|
83
|
+
absWorkingDir: projectDir,
|
|
84
|
+
bundle: true,
|
|
85
|
+
platform: "neutral",
|
|
86
|
+
format: "esm",
|
|
87
|
+
outfile: path.resolve(projectDir, compiledFunctionPath),
|
|
96
88
|
external: ["@jitsu/functions-lib"],
|
|
97
89
|
logLevel: "silent",
|
|
90
|
+
loader: {
|
|
91
|
+
".json": "json",
|
|
92
|
+
},
|
|
93
|
+
nodePaths: [path.resolve(projectDir, "node_modules")],
|
|
98
94
|
});
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
dir: projectDir,
|
|
102
|
-
format: format,
|
|
103
|
-
});
|
|
104
|
-
(0, fs_1.mkdirSync)(path_1.default.resolve(projectDir, "dist/" + dir), { recursive: true });
|
|
105
|
-
const compiledFunctionPath = `dist/${dir}/${fileName.replace(".ts", ".js")}`;
|
|
106
|
-
(0, fs_1.writeFileSync)(path_1.default.resolve(projectDir, compiledFunctionPath), output.output[0].code);
|
|
107
|
-
const compiledFunction = await (0, compiled_function_1.getFunctionFromFilePath)(path_1.default.resolve(projectDir, compiledFunctionPath), "function");
|
|
108
|
-
console.log([`${(0, chalk_code_highlight_1.green)(`✓`)} Function ${(0, chalk_code_highlight_1.b)(fileName)} compiled successfully`, ` slug = ${(0, chalk_code_highlight_1.b)(compiledFunction.meta.slug)}`]
|
|
95
|
+
const compiledFunction = await getFunctionFromFilePath(projectDir, path.resolve(projectDir, compiledFunctionPath), "function");
|
|
96
|
+
console.log([`${green(`✓`)} Function ${b(fileName)} compiled successfully`, ` slug = ${b(compiledFunction.meta.slug)}`]
|
|
109
97
|
.filter(Boolean)
|
|
110
98
|
.join("\n"));
|
|
111
99
|
}
|
|
112
100
|
function checkTypescript(projectDir) {
|
|
113
|
-
const tsconfigPath =
|
|
114
|
-
if (!
|
|
115
|
-
console.info(`No ${
|
|
101
|
+
const tsconfigPath = path.resolve(projectDir, "tsconfig.json");
|
|
102
|
+
if (!existsSync(tsconfigPath)) {
|
|
103
|
+
console.info(`No ${b("tsconfig.json")} file found in ${b(projectDir)}. Assuming JavaScript project`);
|
|
116
104
|
return;
|
|
117
105
|
}
|
|
118
|
-
console.log(`Checking TypeScript files in ${(0, chalk_code_highlight_1.b)(projectDir)}`);
|
|
119
106
|
let compilerOptions = {};
|
|
120
107
|
let filenames = [];
|
|
121
108
|
const tsconfig = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
|
|
122
109
|
tsconfig.config.compilerOptions = {
|
|
123
110
|
...tsconfig.config.compilerOptions,
|
|
124
|
-
typeRoots: [
|
|
111
|
+
typeRoots: [path.resolve(projectDir, "node_modules", "@types")],
|
|
125
112
|
checkJs: true,
|
|
126
113
|
allowJs: true,
|
|
114
|
+
skipLibCheck: true,
|
|
127
115
|
noEmit: true,
|
|
128
116
|
esModuleInterop: typeof compilerOptions.esModuleInterop !== "undefined" ? compilerOptions.esModuleInterop : true,
|
|
129
117
|
moduleResolution: typeof compilerOptions.moduleResolution !== "undefined" ? compilerOptions.moduleResolution : "node",
|
|
130
118
|
target: "esnext",
|
|
131
119
|
module: "esnext",
|
|
132
120
|
};
|
|
133
|
-
const parsed = ts.parseJsonConfigFileContent(tsconfig.config, ts.sys,
|
|
121
|
+
const parsed = ts.parseJsonConfigFileContent(tsconfig.config, ts.sys, path.dirname(tsconfigPath));
|
|
134
122
|
filenames = parsed.fileNames;
|
|
135
123
|
compilerOptions = parsed.options;
|
|
136
124
|
let program = ts.createProgram(filenames, compilerOptions);
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { ApiClient, ApiError } from "../../lib/api-client";
|
|
2
|
+
import { readDefaultWorkspace, resolveAuth } from "../../lib/auth-file";
|
|
3
|
+
import { buildBody } from "../../lib/body-builder";
|
|
4
|
+
import { consumeBodyFields } from "../../lib/body-fields";
|
|
5
|
+
import { print } from "../../lib/renderer";
|
|
6
|
+
async function resolveWorkspaceId(client, idOrSlug) {
|
|
7
|
+
try {
|
|
8
|
+
const ws = await client.request({
|
|
9
|
+
method: "GET",
|
|
10
|
+
path: `/api/workspace/${encodeURIComponent(idOrSlug)}`,
|
|
11
|
+
});
|
|
12
|
+
return ws.id;
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
if (e instanceof ApiError && e.status === 404) {
|
|
16
|
+
throw new Error(`Workspace '${idOrSlug}' not found (or you don't have access)`);
|
|
17
|
+
}
|
|
18
|
+
throw e;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function gatherBody(opts) {
|
|
22
|
+
const fields = consumeBodyFields();
|
|
23
|
+
return buildBody({ file: opts.file, json: opts.json, fields });
|
|
24
|
+
}
|
|
25
|
+
function requireWorkspace(opts) {
|
|
26
|
+
if (opts.workspace)
|
|
27
|
+
return opts.workspace;
|
|
28
|
+
const fallback = readDefaultWorkspace();
|
|
29
|
+
if (fallback)
|
|
30
|
+
return fallback;
|
|
31
|
+
throw new Error("--workspace / -w is required (or set a default via `jitsu set-default-workspace <id-or-slug>`)");
|
|
32
|
+
}
|
|
33
|
+
async function requireResolvedWorkspaceId(opts, client) {
|
|
34
|
+
return resolveWorkspaceId(client, requireWorkspace(opts));
|
|
35
|
+
}
|
|
36
|
+
export async function runList(resource, opts) {
|
|
37
|
+
const auth = resolveAuth(opts);
|
|
38
|
+
const client = new ApiClient(auth);
|
|
39
|
+
switch (resource.kind) {
|
|
40
|
+
case "workspace": {
|
|
41
|
+
const data = await client.request({ method: "GET", path: "/api/workspace" });
|
|
42
|
+
print(data, opts.output);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
case "configObject": {
|
|
46
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
47
|
+
const data = await client.request({
|
|
48
|
+
method: "GET",
|
|
49
|
+
path: `/api/${encodeURIComponent(ws)}/config/${resource.type}`,
|
|
50
|
+
});
|
|
51
|
+
print(data.objects ?? data, opts.output);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
case "link": {
|
|
55
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
56
|
+
const data = await client.request({
|
|
57
|
+
method: "GET",
|
|
58
|
+
path: `/api/${encodeURIComponent(ws)}/config/link`,
|
|
59
|
+
});
|
|
60
|
+
print(data.links ?? data, opts.output);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
case "profile-builder": {
|
|
64
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
65
|
+
const data = await client.request({
|
|
66
|
+
method: "GET",
|
|
67
|
+
path: `/api/${encodeURIComponent(ws)}/config/profile-builder`,
|
|
68
|
+
});
|
|
69
|
+
print(data.profileBuilders ?? data, opts.output);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export async function runGet(resource, id, opts) {
|
|
75
|
+
const auth = resolveAuth(opts);
|
|
76
|
+
const client = new ApiClient(auth);
|
|
77
|
+
switch (resource.kind) {
|
|
78
|
+
case "workspace": {
|
|
79
|
+
const data = await client.request({ method: "GET", path: `/api/workspace/${encodeURIComponent(id)}` });
|
|
80
|
+
print(data, opts.output);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
case "configObject": {
|
|
84
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
85
|
+
const data = await client.request({
|
|
86
|
+
method: "GET",
|
|
87
|
+
path: `/api/${encodeURIComponent(ws)}/config/${resource.type}/${encodeURIComponent(id)}`,
|
|
88
|
+
});
|
|
89
|
+
print(data, opts.output);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
default:
|
|
93
|
+
throw new Error(`get is not supported for ${resource.noun}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export async function runCreate(resource, opts) {
|
|
97
|
+
const auth = resolveAuth(opts);
|
|
98
|
+
const client = new ApiClient(auth);
|
|
99
|
+
const body = gatherBody(opts) ?? {};
|
|
100
|
+
switch (resource.kind) {
|
|
101
|
+
case "workspace": {
|
|
102
|
+
const data = await client.request({ method: "POST", path: "/api/workspace", body });
|
|
103
|
+
print(data, opts.output);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
case "configObject": {
|
|
107
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
108
|
+
const data = await client.request({
|
|
109
|
+
method: "POST",
|
|
110
|
+
path: `/api/${encodeURIComponent(ws)}/config/${resource.type}`,
|
|
111
|
+
body,
|
|
112
|
+
});
|
|
113
|
+
print(data, opts.output);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
case "link": {
|
|
117
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
118
|
+
const data = await client.request({
|
|
119
|
+
method: "POST",
|
|
120
|
+
path: `/api/${encodeURIComponent(ws)}/config/link`,
|
|
121
|
+
body,
|
|
122
|
+
});
|
|
123
|
+
print(data, opts.output);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
case "profile-builder": {
|
|
127
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
128
|
+
const data = await client.request({
|
|
129
|
+
method: "POST",
|
|
130
|
+
path: `/api/${encodeURIComponent(ws)}/config/profile-builder`,
|
|
131
|
+
body,
|
|
132
|
+
});
|
|
133
|
+
print(data, opts.output);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
export async function runUpdate(resource, id, opts) {
|
|
139
|
+
const auth = resolveAuth(opts);
|
|
140
|
+
const client = new ApiClient(auth);
|
|
141
|
+
const body = gatherBody(opts);
|
|
142
|
+
if (body === undefined) {
|
|
143
|
+
throw new Error("update requires at least one of -f, --json, or --field.path=value flags");
|
|
144
|
+
}
|
|
145
|
+
switch (resource.kind) {
|
|
146
|
+
case "workspace": {
|
|
147
|
+
if (!id)
|
|
148
|
+
throw new Error("workspace id or slug is required");
|
|
149
|
+
const data = await client.request({
|
|
150
|
+
method: "PUT",
|
|
151
|
+
path: `/api/workspace/${encodeURIComponent(id)}`,
|
|
152
|
+
body,
|
|
153
|
+
});
|
|
154
|
+
print(data, opts.output);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
case "configObject": {
|
|
158
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
159
|
+
if (!id)
|
|
160
|
+
throw new Error("id is required");
|
|
161
|
+
const data = await client.request({
|
|
162
|
+
method: "PUT",
|
|
163
|
+
path: `/api/${encodeURIComponent(ws)}/config/${resource.type}/${encodeURIComponent(id)}`,
|
|
164
|
+
body,
|
|
165
|
+
});
|
|
166
|
+
print(data ?? { ok: true }, opts.output);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
case "link": {
|
|
170
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
171
|
+
const finalBody = mergePositionalId(body, id, "id");
|
|
172
|
+
const data = await client.request({
|
|
173
|
+
method: "PUT",
|
|
174
|
+
path: `/api/${encodeURIComponent(ws)}/config/link`,
|
|
175
|
+
body: finalBody,
|
|
176
|
+
});
|
|
177
|
+
print(data, opts.output);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
case "profile-builder": {
|
|
181
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
182
|
+
if (!id)
|
|
183
|
+
throw new Error("id is required");
|
|
184
|
+
const finalBody = mergeNestedPositionalId(body, id, "profileBuilder", "id");
|
|
185
|
+
const data = await client.request({
|
|
186
|
+
method: "PUT",
|
|
187
|
+
path: `/api/${encodeURIComponent(ws)}/config/profile-builder`,
|
|
188
|
+
body: finalBody,
|
|
189
|
+
});
|
|
190
|
+
print(data, opts.output);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function mergePositionalId(body, id, key) {
|
|
196
|
+
if (id === undefined)
|
|
197
|
+
return body;
|
|
198
|
+
if (body && typeof body === "object" && body[key] !== undefined && body[key] !== id) {
|
|
199
|
+
throw new Error(`positional id '${id}' conflicts with body.${key} '${body[key]}'`);
|
|
200
|
+
}
|
|
201
|
+
return { ...(body && typeof body === "object" ? body : {}), [key]: id };
|
|
202
|
+
}
|
|
203
|
+
function mergeNestedPositionalId(body, id, outer, inner) {
|
|
204
|
+
const base = body && typeof body === "object" ? body : {};
|
|
205
|
+
const nested = base[outer] && typeof base[outer] === "object" ? base[outer] : {};
|
|
206
|
+
if (nested[inner] !== undefined && nested[inner] !== id) {
|
|
207
|
+
throw new Error(`positional id '${id}' conflicts with body.${outer}.${inner} '${nested[inner]}'`);
|
|
208
|
+
}
|
|
209
|
+
return { ...base, [outer]: { ...nested, [inner]: id } };
|
|
210
|
+
}
|
|
211
|
+
export async function runDelete(resource, id, opts) {
|
|
212
|
+
const auth = resolveAuth(opts);
|
|
213
|
+
const client = new ApiClient(auth);
|
|
214
|
+
switch (resource.kind) {
|
|
215
|
+
case "workspace": {
|
|
216
|
+
if (!id)
|
|
217
|
+
throw new Error("workspace id is required");
|
|
218
|
+
const data = await client.request({
|
|
219
|
+
method: "DELETE",
|
|
220
|
+
path: "/api/workspace",
|
|
221
|
+
body: { workspaceId: id },
|
|
222
|
+
});
|
|
223
|
+
print(data, opts.output);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
case "configObject": {
|
|
227
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
228
|
+
if (!id)
|
|
229
|
+
throw new Error("id is required");
|
|
230
|
+
const query = {};
|
|
231
|
+
if (opts.cascade)
|
|
232
|
+
query.cascade = "true";
|
|
233
|
+
if (opts.strict)
|
|
234
|
+
query.strict = "true";
|
|
235
|
+
const data = await client.request({
|
|
236
|
+
method: "DELETE",
|
|
237
|
+
path: `/api/${encodeURIComponent(ws)}/config/${resource.type}/${encodeURIComponent(id)}`,
|
|
238
|
+
query,
|
|
239
|
+
});
|
|
240
|
+
print(data ?? { ok: true }, opts.output);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
case "link": {
|
|
244
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
245
|
+
const query = {};
|
|
246
|
+
if (id) {
|
|
247
|
+
query.id = id;
|
|
248
|
+
}
|
|
249
|
+
else if (opts.from && opts.to) {
|
|
250
|
+
query.fromId = opts.from;
|
|
251
|
+
query.toId = opts.to;
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
throw new Error("connection delete requires either <id> or both --from and --to");
|
|
255
|
+
}
|
|
256
|
+
const data = await client.request({
|
|
257
|
+
method: "DELETE",
|
|
258
|
+
path: `/api/${encodeURIComponent(ws)}/config/link`,
|
|
259
|
+
query,
|
|
260
|
+
});
|
|
261
|
+
print(data ?? { ok: true }, opts.output);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
case "profile-builder": {
|
|
265
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
266
|
+
if (!id)
|
|
267
|
+
throw new Error("id is required");
|
|
268
|
+
const data = await client.request({
|
|
269
|
+
method: "DELETE",
|
|
270
|
+
path: `/api/${encodeURIComponent(ws)}/config/profile-builder`,
|
|
271
|
+
query: { id },
|
|
272
|
+
});
|
|
273
|
+
print(data ?? { ok: true }, opts.output);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
export async function runTest(resource, opts) {
|
|
279
|
+
if (resource.kind !== "configObject" || !resource.supportsTest) {
|
|
280
|
+
throw new Error(`test is not supported for ${resource.noun}`);
|
|
281
|
+
}
|
|
282
|
+
const auth = resolveAuth(opts);
|
|
283
|
+
const client = new ApiClient(auth);
|
|
284
|
+
const ws = await requireResolvedWorkspaceId(opts, client);
|
|
285
|
+
const body = gatherBody(opts) ?? {};
|
|
286
|
+
const data = await client.request({
|
|
287
|
+
method: "POST",
|
|
288
|
+
path: `/api/${encodeURIComponent(ws)}/config/${resource.type}/test`,
|
|
289
|
+
body,
|
|
290
|
+
});
|
|
291
|
+
print(data, opts.output);
|
|
292
|
+
}
|