@uipath/maestro-builder-sdk 6.70.4 → 6.70.6
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/compile-cli.js +16 -3
- package/dist/decompile.js +5 -3
- package/dist/path-within.d.ts +15 -17
- package/dist/path-within.js +44 -0
- package/package.json +2 -2
package/dist/compile-cli.js
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import { diagnosticLine, reportDiagnostics, reportResult, thrownDiagnostic } from './cli-result.js';
|
|
26
26
|
import { writeJsonFile } from './core/json-file.js';
|
|
27
|
-
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync } from 'node:fs';
|
|
27
|
+
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync } from 'node:fs';
|
|
28
28
|
import { basename, dirname, join, relative, resolve } from 'node:path';
|
|
29
29
|
import { resolveFlowFile, loadBuiltFlow } from './load.js';
|
|
30
30
|
import { serializeWithSidecars } from './serialize.js';
|
|
@@ -36,7 +36,7 @@ import { connectionResources, inlineAgentResources, mergeBindingsV2, refreshInli
|
|
|
36
36
|
import { readBindingsV2, readInlineAgentFiles } from './bindings-v2-files.js';
|
|
37
37
|
import { ensureTypeScriptRuntime } from './node-runtime.js';
|
|
38
38
|
import { defaultBindingsFile } from './workdir.js';
|
|
39
|
-
import { isWithin } from './path-within.js';
|
|
39
|
+
import { isWithin, physicalPath } from './path-within.js';
|
|
40
40
|
import { flowSources, resourceSourcesOfOtherFlows } from './project-resource-users.js';
|
|
41
41
|
import { fnv1aX4Uuid } from './core/stable-id.js';
|
|
42
42
|
import { CompileRefusal } from './core/compile-refusal.js';
|
|
@@ -86,7 +86,20 @@ export async function run(argv) {
|
|
|
86
86
|
// BYOA-only event on a connection `prepare` never checked
|
|
87
87
|
// (EVENT_BYOA_UNVERIFIED): printed in the same `✗ [CODE]` shape `check` uses
|
|
88
88
|
// for it. Nothing is written.
|
|
89
|
-
const
|
|
89
|
+
const explicitOut = flagValue(argv, '-o');
|
|
90
|
+
const out = explicitOut ?? `${built.name || basename(file).replace(/\.flow\.ts$|\.ts$/, '')}.flow`;
|
|
91
|
+
// The default is named after the flow, which decompile copies from the input: keep it inside cwd.
|
|
92
|
+
if (explicitOut === undefined) {
|
|
93
|
+
const target = physicalPath(resolve(out));
|
|
94
|
+
if (target === undefined || !isWithin(realpathSync.native(process.cwd()), target)) {
|
|
95
|
+
const message = `refusing to write ${out} outside the working directory: without -o the output is named after`
|
|
96
|
+
+ ` the flow (${JSON.stringify(built.name)}). Pass -o <file>.flow to choose where it is written`;
|
|
97
|
+
console.error(`compile: ${message}; not emitting.`);
|
|
98
|
+
diagnostics.push({ level: 'error', code: 'FLOW_NAME_OUTSIDE_WORKING_DIR', message });
|
|
99
|
+
reportDiagnostics(diagnostics);
|
|
100
|
+
return 1;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
90
103
|
const outDir = dirname(resolve(out));
|
|
91
104
|
// ONE FOLDER, ONE FLOW (#1184). An agent's `source` is the name of the folder
|
|
92
105
|
// beside the `.flow` that holds its `agent.json` and `resources/`. Decompile
|
package/dist/decompile.js
CHANGED
|
@@ -35,6 +35,7 @@ import { DEFAULT_TRIGGER_ID, Expr } from './core/expr.js';
|
|
|
35
35
|
import { FLOW_NODE_TYPES } from './flow-node-registry.js';
|
|
36
36
|
import { SUBFLOW_START_LABEL } from './core/subflow-start.js';
|
|
37
37
|
import { commentText } from './core/comment-text.js';
|
|
38
|
+
import { escapeRegExp } from './core/escape-regexp.js';
|
|
38
39
|
import { tsKey as key, tsLiteral, tsNumber, tsObject as objLit, tsOptions as opts, tsText } from './core/ts-literal.js';
|
|
39
40
|
import { wireExprBody } from './core/wire-expr.js';
|
|
40
41
|
import { hasExits } from './core/step-ports.js';
|
|
@@ -2864,7 +2865,7 @@ function emitChildFlow(name, childFile, ctx) {
|
|
|
2864
2865
|
*/
|
|
2865
2866
|
function readChildStartAsStart(child, startId) {
|
|
2866
2867
|
const renamed = renameVarRoot(child, startId, DEFAULT_TRIGGER_ID);
|
|
2867
|
-
const path = new RegExp(`^(=?vars\\.)${startId
|
|
2868
|
+
const path = new RegExp(`^(=?vars\\.)${escapeRegExp(startId)}(?![A-Za-z0-9_$])`);
|
|
2868
2869
|
const walk = (x, key, parentKey) => {
|
|
2869
2870
|
if (typeof x === 'string')
|
|
2870
2871
|
return key === 'binding' || parentKey === 'appInputBindings' ? x.replace(path, `$1${DEFAULT_TRIGGER_ID}`) : x;
|
|
@@ -2954,8 +2955,9 @@ const RAW_JS_FIELDS = new Set(['script', 'expression', 'condition', 'completionC
|
|
|
2954
2955
|
* script stays as written, the way `serialize` left it (#1092 review).
|
|
2955
2956
|
*/
|
|
2956
2957
|
function renameVarRoot(v, from, to) {
|
|
2957
|
-
const re = new RegExp(`\\$vars\\.${from
|
|
2958
|
-
|
|
2958
|
+
const re = new RegExp(`\\$vars\\.${escapeRegExp(from)}(?![A-Za-z0-9_$])`, 'g');
|
|
2959
|
+
// a function: `$&` in `to` is data
|
|
2960
|
+
const inCode = (js) => mapJsCode(js, (code) => code.replace(re, () => `$vars.${to}`));
|
|
2959
2961
|
const walk = (x, key) => {
|
|
2960
2962
|
if (typeof x === 'string') {
|
|
2961
2963
|
if (x.startsWith('=js:'))
|
package/dist/path-within.d.ts
CHANGED
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* path-within — the one path-containment test for anything that writes files.
|
|
3
|
-
*
|
|
4
|
-
* "Is `child` inside `parent`?" looks like a string-prefix question and is not
|
|
5
|
-
* one. `child.startsWith(parent + '/')` is correct only where the separator is
|
|
6
|
-
* `/`: on Windows `path.resolve` returns `C:\proj\P\x`, the check refuses every
|
|
7
|
-
* path, and compile refused every inline agent's `<source>/agent.json`
|
|
8
|
-
* (flow-builder-sdk#946). A prefix test without a trailing separator has the
|
|
9
|
-
* opposite bug: it accepts the sibling `C:\proj\P2\x` as inside `C:\proj\P`.
|
|
10
|
-
*
|
|
11
|
-
* So the test is `relative(parent, child)` instead, which gets both right on
|
|
12
|
-
* every platform, and Windows' case-insensitive drive letters and
|
|
13
|
-
* cross-drive paths (`relative` returns the absolute `D:\x` there) with them.
|
|
14
|
-
*
|
|
15
|
-
* The path implementation is a parameter so the Windows rules can be tested on
|
|
16
|
-
* a Linux runner (`isWithin(a, b, path.win32)`). Callers leave it out.
|
|
17
|
-
*/
|
|
18
1
|
import * as nodePath from 'node:path';
|
|
19
2
|
/** The slice of `node:path` the test needs; `path.win32` and `path.posix` both fit. */
|
|
20
3
|
export type PathApi = Pick<typeof nodePath, 'relative' | 'isAbsolute' | 'sep'>;
|
|
@@ -31,3 +14,18 @@ export type PathApi = Pick<typeof nodePath, 'relative' | 'isAbsolute' | 'sep'>;
|
|
|
31
14
|
* isWithin('C:\\proj\\P', 'D:\\agent.json', path.win32) // false — other drive
|
|
32
15
|
*/
|
|
33
16
|
export declare function isWithin(parent: string, child: string, path?: PathApi): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Where `dir` lands on disk: the real path of its deepest ancestor that
|
|
19
|
+
* exists, every link on the way followed, then the rest of `dir`, which does
|
|
20
|
+
* not exist yet and so holds no link. `undefined` when that ancestor's real
|
|
21
|
+
* path cannot be read: a link to nothing, or a loop of links. A caller treats
|
|
22
|
+
* `undefined` as outside.
|
|
23
|
+
*
|
|
24
|
+
* The agent SDK's CLI keeps a copy of this function for its default output
|
|
25
|
+
* folder, so both CLIs follow links the same way.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* // ./work/sw-basic/l is a link to /elsewhere, and X does not exist:
|
|
29
|
+
* physicalPath('/cwd/work/sw-basic/l/X') // '/elsewhere/X'
|
|
30
|
+
*/
|
|
31
|
+
export declare function physicalPath(dir: string): string | undefined;
|
package/dist/path-within.js
CHANGED
|
@@ -12,10 +12,16 @@
|
|
|
12
12
|
* every platform, and Windows' case-insensitive drive letters and
|
|
13
13
|
* cross-drive paths (`relative` returns the absolute `D:\x` there) with them.
|
|
14
14
|
*
|
|
15
|
+
* `isWithin` reads only the spelling of its paths, so a link inside `parent`
|
|
16
|
+
* that points out of it passes. A check that guards a write compares
|
|
17
|
+
* `physicalPath`s instead.
|
|
18
|
+
*
|
|
15
19
|
* The path implementation is a parameter so the Windows rules can be tested on
|
|
16
20
|
* a Linux runner (`isWithin(a, b, path.win32)`). Callers leave it out.
|
|
17
21
|
*/
|
|
22
|
+
import { lstatSync, realpathSync } from 'node:fs';
|
|
18
23
|
import * as nodePath from 'node:path';
|
|
24
|
+
import { basename, dirname, join } from 'node:path';
|
|
19
25
|
/**
|
|
20
26
|
* `child` is `parent` itself or somewhere beneath it.
|
|
21
27
|
*
|
|
@@ -39,3 +45,41 @@ export function isWithin(parent, child, path = nodePath) {
|
|
|
39
45
|
// Windows: a child on another drive has no relative spelling.
|
|
40
46
|
return !path.isAbsolute(rel);
|
|
41
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Where `dir` lands on disk: the real path of its deepest ancestor that
|
|
50
|
+
* exists, every link on the way followed, then the rest of `dir`, which does
|
|
51
|
+
* not exist yet and so holds no link. `undefined` when that ancestor's real
|
|
52
|
+
* path cannot be read: a link to nothing, or a loop of links. A caller treats
|
|
53
|
+
* `undefined` as outside.
|
|
54
|
+
*
|
|
55
|
+
* The agent SDK's CLI keeps a copy of this function for its default output
|
|
56
|
+
* folder, so both CLIs follow links the same way.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* // ./work/sw-basic/l is a link to /elsewhere, and X does not exist:
|
|
60
|
+
* physicalPath('/cwd/work/sw-basic/l/X') // '/elsewhere/X'
|
|
61
|
+
*/
|
|
62
|
+
export function physicalPath(dir) {
|
|
63
|
+
const rest = [];
|
|
64
|
+
let at = dir;
|
|
65
|
+
for (;;) {
|
|
66
|
+
try {
|
|
67
|
+
lstatSync(at);
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Missing: its parent, then.
|
|
72
|
+
}
|
|
73
|
+
const parent = dirname(at);
|
|
74
|
+
if (parent === at)
|
|
75
|
+
break;
|
|
76
|
+
rest.unshift(basename(at));
|
|
77
|
+
at = parent;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
return join(realpathSync.native(at), ...rest);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/maestro-builder-sdk",
|
|
3
|
-
"version": "6.70.
|
|
3
|
+
"version": "6.70.6",
|
|
4
4
|
"description": "Build UiPath Flow, Case, and BPMN artifacts by writing TypeScript.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://docs.uipath.com/maestro",
|
|
@@ -100,5 +100,5 @@
|
|
|
100
100
|
"@types/node": "^22.7.0",
|
|
101
101
|
"esbuild": "^0.28.1"
|
|
102
102
|
},
|
|
103
|
-
"gitref": "
|
|
103
|
+
"gitref": "acb0888df4770ee4db5ebb89ef2116cf400ee1b9"
|
|
104
104
|
}
|