@openfn/cli 1.15.1 → 1.16.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/dist/index.js +54 -1
- package/dist/process/runner.js +104 -47
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -134,6 +134,29 @@ var ensureLogOpts = (opts2) => {
|
|
|
134
134
|
};
|
|
135
135
|
var ensure_log_opts_default = ensureLogOpts;
|
|
136
136
|
|
|
137
|
+
// src/util/get-cli-option-object.ts
|
|
138
|
+
function getCLIOptionObject(arg) {
|
|
139
|
+
if (isObject(arg)) {
|
|
140
|
+
return arg;
|
|
141
|
+
} else if (typeof arg === "string") {
|
|
142
|
+
try {
|
|
143
|
+
const p = JSON.parse(arg);
|
|
144
|
+
if (isObject(p))
|
|
145
|
+
return p;
|
|
146
|
+
} catch (e) {
|
|
147
|
+
}
|
|
148
|
+
return Object.fromEntries(
|
|
149
|
+
arg.split(",").map((pair) => {
|
|
150
|
+
const [k, v] = pair.split("=");
|
|
151
|
+
return [k.trim(), v.trim()];
|
|
152
|
+
})
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function isObject(arg) {
|
|
157
|
+
return typeof arg === "object" && arg !== null && !Array.isArray(arg);
|
|
158
|
+
}
|
|
159
|
+
|
|
137
160
|
// src/options.ts
|
|
138
161
|
var setDefaultValue = (opts2, key2, value2) => {
|
|
139
162
|
const v = opts2[key2];
|
|
@@ -543,6 +566,21 @@ var workflow = {
|
|
|
543
566
|
description: "Name of the workflow to execute"
|
|
544
567
|
}
|
|
545
568
|
};
|
|
569
|
+
var removeUnmapped = {
|
|
570
|
+
name: "remove-unmapped",
|
|
571
|
+
yargs: {
|
|
572
|
+
boolean: true,
|
|
573
|
+
description: "Removes all workflows that didn't get mapped from the final project after merge"
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
var workflowMappings = {
|
|
577
|
+
name: "workflow-mappings",
|
|
578
|
+
yargs: {
|
|
579
|
+
type: "string",
|
|
580
|
+
coerce: getCLIOptionObject,
|
|
581
|
+
description: "A manual object mapping of which workflows in source and target should be matched for a merge."
|
|
582
|
+
}
|
|
583
|
+
};
|
|
546
584
|
|
|
547
585
|
// src/util/command-builders.ts
|
|
548
586
|
import c from "chalk";
|
|
@@ -1083,9 +1121,24 @@ var checkoutCommand = {
|
|
|
1083
1121
|
};
|
|
1084
1122
|
var command_default12 = checkoutCommand;
|
|
1085
1123
|
|
|
1124
|
+
// src/merge/command.ts
|
|
1125
|
+
var options11 = [
|
|
1126
|
+
projectName,
|
|
1127
|
+
projectPath,
|
|
1128
|
+
removeUnmapped,
|
|
1129
|
+
workflowMappings
|
|
1130
|
+
];
|
|
1131
|
+
var mergeCommand = {
|
|
1132
|
+
command: "merge [project-name]",
|
|
1133
|
+
describe: "Merges the specified project into the checked out project",
|
|
1134
|
+
handler: ensure("merge", options11),
|
|
1135
|
+
builder: (yargs2) => build(options11, yargs2)
|
|
1136
|
+
};
|
|
1137
|
+
var command_default13 = mergeCommand;
|
|
1138
|
+
|
|
1086
1139
|
// src/cli.ts
|
|
1087
1140
|
var y = yargs(hideBin(process.argv));
|
|
1088
|
-
var cmd = y.command(command_default7).command(command_default3).command(command_default2).command(command_default4).command(install).command(repo).command(command_default10).command(command_default6).command(command_default).command(command_default8).command(command_default5).command(command_default9).command(command_default11).command(command_default12).command({
|
|
1141
|
+
var cmd = y.command(command_default7).command(command_default3).command(command_default2).command(command_default4).command(install).command(repo).command(command_default10).command(command_default6).command(command_default).command(command_default8).command(command_default5).command(command_default9).command(command_default11).command(command_default12).command(command_default13).command({
|
|
1089
1142
|
command: "version",
|
|
1090
1143
|
describe: "Show the currently installed version of the CLI, compiler and runtime.",
|
|
1091
1144
|
handler: (argv) => {
|
package/dist/process/runner.js
CHANGED
|
@@ -127,14 +127,14 @@ var callApollo = async (apolloBaseUrl, serviceName, payload, logger) => {
|
|
|
127
127
|
});
|
|
128
128
|
});
|
|
129
129
|
};
|
|
130
|
-
var loadPayload = async (logger,
|
|
131
|
-
if (!
|
|
130
|
+
var loadPayload = async (logger, path15) => {
|
|
131
|
+
if (!path15) {
|
|
132
132
|
logger.warn("No JSON payload provided");
|
|
133
133
|
logger.warn("Most apollo services require JSON to be uploaded");
|
|
134
134
|
return {};
|
|
135
135
|
}
|
|
136
|
-
if (
|
|
137
|
-
const str = await readFile(
|
|
136
|
+
if (path15.endsWith(".json")) {
|
|
137
|
+
const str = await readFile(path15, "utf8");
|
|
138
138
|
const json = JSON.parse(str);
|
|
139
139
|
logger.debug("Loaded JSON payload");
|
|
140
140
|
return json;
|
|
@@ -256,13 +256,13 @@ var execute_default = async (plan, input, opts, logger) => {
|
|
|
256
256
|
};
|
|
257
257
|
function parseAdaptors(plan) {
|
|
258
258
|
const extractInfo = (specifier) => {
|
|
259
|
-
const [module,
|
|
259
|
+
const [module, path15] = specifier.split("=");
|
|
260
260
|
const { name, version } = getNameAndVersion(module);
|
|
261
261
|
const info = {
|
|
262
262
|
name
|
|
263
263
|
};
|
|
264
|
-
if (
|
|
265
|
-
info.path =
|
|
264
|
+
if (path15) {
|
|
265
|
+
info.path = path15;
|
|
266
266
|
}
|
|
267
267
|
if (version) {
|
|
268
268
|
info.version = version;
|
|
@@ -522,10 +522,10 @@ var stripVersionSpecifier = (specifier) => {
|
|
|
522
522
|
return specifier;
|
|
523
523
|
};
|
|
524
524
|
var resolveSpecifierPath = async (pattern, repoDir, log) => {
|
|
525
|
-
const [specifier,
|
|
526
|
-
if (
|
|
527
|
-
log.debug(`Resolved ${specifier} to path: ${
|
|
528
|
-
return
|
|
525
|
+
const [specifier, path15] = pattern.split("=");
|
|
526
|
+
if (path15) {
|
|
527
|
+
log.debug(`Resolved ${specifier} to path: ${path15}`);
|
|
528
|
+
return path15;
|
|
529
529
|
}
|
|
530
530
|
const repoPath = await getModulePath(specifier, repoDir, log);
|
|
531
531
|
if (repoPath) {
|
|
@@ -544,12 +544,12 @@ var loadTransformOptions = async (opts, log) => {
|
|
|
544
544
|
let exports;
|
|
545
545
|
const [specifier] = adaptorInput.split("=");
|
|
546
546
|
log.debug(`Trying to preload types for ${specifier}`);
|
|
547
|
-
const
|
|
548
|
-
if (
|
|
547
|
+
const path15 = await resolveSpecifierPath(adaptorInput, opts.repoDir, log);
|
|
548
|
+
if (path15) {
|
|
549
549
|
try {
|
|
550
|
-
exports = await preloadAdaptorExports(
|
|
550
|
+
exports = await preloadAdaptorExports(path15, log);
|
|
551
551
|
} catch (e) {
|
|
552
|
-
log.error(`Failed to load adaptor typedefs from path ${
|
|
552
|
+
log.error(`Failed to load adaptor typedefs from path ${path15}`);
|
|
553
553
|
log.error(e);
|
|
554
554
|
}
|
|
555
555
|
}
|
|
@@ -1001,8 +1001,8 @@ var loadXPlan = async (plan, options, logger, defaultName = "") => {
|
|
|
1001
1001
|
};
|
|
1002
1002
|
|
|
1003
1003
|
// src/util/assert-path.ts
|
|
1004
|
-
var assert_path_default = (
|
|
1005
|
-
if (!
|
|
1004
|
+
var assert_path_default = (path15) => {
|
|
1005
|
+
if (!path15) {
|
|
1006
1006
|
console.error("ERROR: no path provided!");
|
|
1007
1007
|
console.error("\nUsage:");
|
|
1008
1008
|
console.error(" open path/to/job");
|
|
@@ -1688,20 +1688,20 @@ var RETRY_COUNT = 20;
|
|
|
1688
1688
|
var TIMEOUT_MS = 1e3 * 60;
|
|
1689
1689
|
var actualDocGen = (specifier) => describePackage(specifier, {});
|
|
1690
1690
|
var ensurePath = (filePath) => mkdirSync(path7.dirname(filePath), { recursive: true });
|
|
1691
|
-
var generatePlaceholder = (
|
|
1692
|
-
writeFileSync(
|
|
1691
|
+
var generatePlaceholder = (path15) => {
|
|
1692
|
+
writeFileSync(path15, `{ "loading": true, "timestamp": ${Date.now()}}`);
|
|
1693
1693
|
};
|
|
1694
1694
|
var finish = (logger, resultPath) => {
|
|
1695
1695
|
logger.success("Done! Docs can be found at:\n");
|
|
1696
1696
|
logger.print(` ${path7.resolve(resultPath)}`);
|
|
1697
1697
|
};
|
|
1698
|
-
var generateDocs = async (specifier,
|
|
1698
|
+
var generateDocs = async (specifier, path15, docgen, logger) => {
|
|
1699
1699
|
const result = await docgen(specifier);
|
|
1700
|
-
await writeFile5(
|
|
1701
|
-
finish(logger,
|
|
1702
|
-
return
|
|
1700
|
+
await writeFile5(path15, JSON.stringify(result, null, 2));
|
|
1701
|
+
finish(logger, path15);
|
|
1702
|
+
return path15;
|
|
1703
1703
|
};
|
|
1704
|
-
var waitForDocs = async (docs,
|
|
1704
|
+
var waitForDocs = async (docs, path15, logger, retryDuration = RETRY_DURATION) => {
|
|
1705
1705
|
try {
|
|
1706
1706
|
if (docs.hasOwnProperty("loading")) {
|
|
1707
1707
|
logger.info("Docs are being loaded by another process. Waiting.");
|
|
@@ -1713,19 +1713,19 @@ var waitForDocs = async (docs, path14, logger, retryDuration = RETRY_DURATION) =
|
|
|
1713
1713
|
clearInterval(i);
|
|
1714
1714
|
reject(new Error("Timed out waiting for docs to load"));
|
|
1715
1715
|
}
|
|
1716
|
-
const updated = JSON.parse(readFileSync(
|
|
1716
|
+
const updated = JSON.parse(readFileSync(path15, "utf8"));
|
|
1717
1717
|
if (!updated.hasOwnProperty("loading")) {
|
|
1718
1718
|
logger.info("Docs found!");
|
|
1719
1719
|
clearInterval(i);
|
|
1720
|
-
resolve(
|
|
1720
|
+
resolve(path15);
|
|
1721
1721
|
}
|
|
1722
1722
|
count++;
|
|
1723
1723
|
}, retryDuration);
|
|
1724
1724
|
});
|
|
1725
1725
|
} else {
|
|
1726
|
-
logger.info(`Docs already written to cache at ${
|
|
1727
|
-
finish(logger,
|
|
1728
|
-
return
|
|
1726
|
+
logger.info(`Docs already written to cache at ${path15}`);
|
|
1727
|
+
finish(logger, path15);
|
|
1728
|
+
return path15;
|
|
1729
1729
|
}
|
|
1730
1730
|
} catch (e) {
|
|
1731
1731
|
logger.error("Existing doc JSON corrupt. Aborting");
|
|
@@ -1742,28 +1742,28 @@ var docgenHandler = (options, logger, docgen = actualDocGen, retryDuration = RET
|
|
|
1742
1742
|
process.exit(9);
|
|
1743
1743
|
}
|
|
1744
1744
|
logger.success(`Generating docs for ${specifier}`);
|
|
1745
|
-
const
|
|
1746
|
-
ensurePath(
|
|
1745
|
+
const path15 = `${repoDir}/docs/${specifier}.json`;
|
|
1746
|
+
ensurePath(path15);
|
|
1747
1747
|
const handleError2 = () => {
|
|
1748
1748
|
logger.info("Removing placeholder");
|
|
1749
|
-
rmSync(
|
|
1749
|
+
rmSync(path15);
|
|
1750
1750
|
};
|
|
1751
1751
|
try {
|
|
1752
|
-
const existing = readFileSync(
|
|
1752
|
+
const existing = readFileSync(path15, "utf8");
|
|
1753
1753
|
const json = JSON.parse(existing);
|
|
1754
1754
|
if (json && json.timeout && Date.now() - json.timeout >= TIMEOUT_MS) {
|
|
1755
1755
|
logger.info(`Expired placeholder found. Removing.`);
|
|
1756
|
-
rmSync(
|
|
1756
|
+
rmSync(path15);
|
|
1757
1757
|
throw new Error("TIMEOUT");
|
|
1758
1758
|
}
|
|
1759
|
-
return waitForDocs(json,
|
|
1759
|
+
return waitForDocs(json, path15, logger, retryDuration);
|
|
1760
1760
|
} catch (e) {
|
|
1761
1761
|
if (e.message !== "TIMEOUT") {
|
|
1762
|
-
logger.info(`Docs JSON not found at ${
|
|
1762
|
+
logger.info(`Docs JSON not found at ${path15}`);
|
|
1763
1763
|
}
|
|
1764
1764
|
logger.debug("Generating placeholder");
|
|
1765
|
-
generatePlaceholder(
|
|
1766
|
-
return generateDocs(specifier,
|
|
1765
|
+
generatePlaceholder(path15);
|
|
1766
|
+
return generateDocs(specifier, path15, docgen, logger).catch((e2) => {
|
|
1767
1767
|
logger.error("Error generating documentation");
|
|
1768
1768
|
logger.error(e2);
|
|
1769
1769
|
handleError2();
|
|
@@ -1814,7 +1814,7 @@ var docsHandler = async (options, logger) => {
|
|
|
1814
1814
|
logger.success(`Showing docs for ${adaptorName} v${version}`);
|
|
1815
1815
|
}
|
|
1816
1816
|
logger.info("Generating/loading documentation...");
|
|
1817
|
-
const
|
|
1817
|
+
const path15 = await handler_default7(
|
|
1818
1818
|
{
|
|
1819
1819
|
specifier: `${name}@${version}`,
|
|
1820
1820
|
repoDir
|
|
@@ -1823,8 +1823,8 @@ var docsHandler = async (options, logger) => {
|
|
|
1823
1823
|
createNullLogger()
|
|
1824
1824
|
);
|
|
1825
1825
|
let didError = false;
|
|
1826
|
-
if (
|
|
1827
|
-
const source = await readFile4(
|
|
1826
|
+
if (path15) {
|
|
1827
|
+
const source = await readFile4(path15, "utf8");
|
|
1828
1828
|
const data = JSON.parse(source);
|
|
1829
1829
|
let desc;
|
|
1830
1830
|
if (operation) {
|
|
@@ -2274,7 +2274,7 @@ var handler_default10 = pullHandler;
|
|
|
2274
2274
|
import { Workspace } from "@openfn/project";
|
|
2275
2275
|
import path11 from "path";
|
|
2276
2276
|
var projectsHandler = async (options, logger) => {
|
|
2277
|
-
const commandPath = path11.resolve(
|
|
2277
|
+
const commandPath = path11.resolve(options.projectPath ?? ".");
|
|
2278
2278
|
const workspace = new Workspace(commandPath);
|
|
2279
2279
|
if (!workspace.valid) {
|
|
2280
2280
|
logger.error("Command was run in an invalid openfn workspace");
|
|
@@ -2300,7 +2300,7 @@ import path12 from "path";
|
|
|
2300
2300
|
import fs6 from "fs";
|
|
2301
2301
|
import { rimraf as rimraf2 } from "rimraf";
|
|
2302
2302
|
var checkoutHandler = async (options, logger) => {
|
|
2303
|
-
const commandPath = path12.resolve(
|
|
2303
|
+
const commandPath = path12.resolve(options.projectPath ?? ".");
|
|
2304
2304
|
const workspace = new Workspace2(commandPath);
|
|
2305
2305
|
if (!workspace.valid) {
|
|
2306
2306
|
logger.error("Command was run in an invalid openfn workspace");
|
|
@@ -2309,7 +2309,7 @@ var checkoutHandler = async (options, logger) => {
|
|
|
2309
2309
|
const switchProject = workspace.get(options.projectName);
|
|
2310
2310
|
if (!switchProject) {
|
|
2311
2311
|
logger.error(
|
|
2312
|
-
`Project with id ${options.projectName} not found in the workspace`
|
|
2312
|
+
`Project with id/name ${options.projectName} not found in the workspace`
|
|
2313
2313
|
);
|
|
2314
2314
|
return;
|
|
2315
2315
|
}
|
|
@@ -2330,9 +2330,65 @@ var checkoutHandler = async (options, logger) => {
|
|
|
2330
2330
|
};
|
|
2331
2331
|
var handler_default12 = checkoutHandler;
|
|
2332
2332
|
|
|
2333
|
+
// src/merge/handler.ts
|
|
2334
|
+
import Project5, { Workspace as Workspace3 } from "@openfn/project";
|
|
2335
|
+
import path13 from "path";
|
|
2336
|
+
import { promises as fs7 } from "fs";
|
|
2337
|
+
var mergeHandler = async (options, logger) => {
|
|
2338
|
+
const commandPath = path13.resolve(options.projectPath ?? ".");
|
|
2339
|
+
const workspace = new Workspace3(commandPath);
|
|
2340
|
+
if (!workspace.valid) {
|
|
2341
|
+
logger.error("Command was run in an invalid openfn workspace");
|
|
2342
|
+
return;
|
|
2343
|
+
}
|
|
2344
|
+
const checkedProject = workspace.getActiveProject();
|
|
2345
|
+
if (!checkedProject) {
|
|
2346
|
+
logger.error(`No project currently checked out`);
|
|
2347
|
+
return;
|
|
2348
|
+
}
|
|
2349
|
+
const mProject = workspace.get(options.projectName);
|
|
2350
|
+
if (!mProject) {
|
|
2351
|
+
logger.error(
|
|
2352
|
+
`Project with id/name ${options.projectName} not found in the workspace`
|
|
2353
|
+
);
|
|
2354
|
+
return;
|
|
2355
|
+
}
|
|
2356
|
+
if (checkedProject.name === mProject.name) {
|
|
2357
|
+
logger.error("Merging into the same project not allowed");
|
|
2358
|
+
return;
|
|
2359
|
+
}
|
|
2360
|
+
if (!checkedProject.name) {
|
|
2361
|
+
logger.error("The checked out project has no name/id");
|
|
2362
|
+
return;
|
|
2363
|
+
}
|
|
2364
|
+
const finalPath = workspace.getProjectPath(checkedProject.name);
|
|
2365
|
+
if (!finalPath) {
|
|
2366
|
+
logger.error("Path to checked out project not found.");
|
|
2367
|
+
return;
|
|
2368
|
+
}
|
|
2369
|
+
const final = Project5.merge(mProject, checkedProject, {
|
|
2370
|
+
removeUnmapped: options.removeUnmapped,
|
|
2371
|
+
workflowMappings: options.workflowMappings
|
|
2372
|
+
});
|
|
2373
|
+
const yaml = final.serialize("state", { format: "yaml" });
|
|
2374
|
+
await fs7.writeFile(finalPath, yaml);
|
|
2375
|
+
await handler_default12(
|
|
2376
|
+
{
|
|
2377
|
+
command: "checkout",
|
|
2378
|
+
projectPath: commandPath,
|
|
2379
|
+
projectName: final.name || ""
|
|
2380
|
+
},
|
|
2381
|
+
logger
|
|
2382
|
+
);
|
|
2383
|
+
logger.success(
|
|
2384
|
+
`Project ${mProject.name} has been merged into Project ${checkedProject.name} successfully`
|
|
2385
|
+
);
|
|
2386
|
+
};
|
|
2387
|
+
var handler_default13 = mergeHandler;
|
|
2388
|
+
|
|
2333
2389
|
// src/util/print-versions.ts
|
|
2334
2390
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
2335
|
-
import
|
|
2391
|
+
import path14 from "node:path";
|
|
2336
2392
|
import url from "node:url";
|
|
2337
2393
|
import { getNameAndVersion as getNameAndVersion7 } from "@openfn/runtime";
|
|
2338
2394
|
import { mainSymbols } from "figures";
|
|
@@ -2344,7 +2400,7 @@ var { triangleRightSmall: t } = mainSymbols;
|
|
|
2344
2400
|
var loadVersionFromPath = (adaptorPath) => {
|
|
2345
2401
|
try {
|
|
2346
2402
|
const pkg = JSON.parse(
|
|
2347
|
-
readFileSync2(
|
|
2403
|
+
readFileSync2(path14.resolve(adaptorPath, "package.json"), "utf8")
|
|
2348
2404
|
);
|
|
2349
2405
|
return pkg.version;
|
|
2350
2406
|
} catch (e) {
|
|
@@ -2379,7 +2435,7 @@ var printVersions = async (logger, options = {}, includeComponents = false) => {
|
|
|
2379
2435
|
...[NODE, CLI2, RUNTIME2, COMPILER2, longestAdaptorName].map((s) => s.length)
|
|
2380
2436
|
);
|
|
2381
2437
|
const prefix = (str) => ` ${t} ${str.padEnd(longest + 4, " ")}`;
|
|
2382
|
-
const dirname3 =
|
|
2438
|
+
const dirname3 = path14.dirname(url.fileURLToPath(import.meta.url));
|
|
2383
2439
|
const pkg = JSON.parse(readFileSync2(`${dirname3}/../../package.json`, "utf8"));
|
|
2384
2440
|
const { version, dependencies } = pkg;
|
|
2385
2441
|
const compilerVersion = dependencies["@openfn/compiler"];
|
|
@@ -2434,6 +2490,7 @@ var handlers = {
|
|
|
2434
2490
|
pull: handler_default10,
|
|
2435
2491
|
projects: handler_default11,
|
|
2436
2492
|
checkout: handler_default12,
|
|
2493
|
+
merge: handler_default13,
|
|
2437
2494
|
["collections-get"]: handler_default4.get,
|
|
2438
2495
|
["collections-set"]: handler_default4.set,
|
|
2439
2496
|
["collections-remove"]: handler_default4.remove,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfn/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "CLI devtools for the OpenFn toolchain",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"@openfn/describe-package": "0.1.5",
|
|
53
53
|
"@openfn/lexicon": "^1.2.3",
|
|
54
54
|
"@openfn/logger": "1.0.6",
|
|
55
|
-
"@openfn/
|
|
56
|
-
"@openfn/
|
|
55
|
+
"@openfn/runtime": "1.7.3",
|
|
56
|
+
"@openfn/project": "^0.4.1"
|
|
57
57
|
},
|
|
58
58
|
"files": [
|
|
59
59
|
"dist",
|