sdn-flow 0.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/SKILLS.md +7 -0
- package/.claude/skills/sdn-plugin-abi-compliance/SKILL.md +56 -0
- package/.claude/todo/001-js-host-startup-and-deno.md +85 -0
- package/LICENSE +21 -0
- package/README.md +223 -0
- package/bin/sdn-flow-host.js +169 -0
- package/docs/.nojekyll +0 -0
- package/docs/ARCHITECTURE.md +200 -0
- package/docs/HOST_CAPABILITY_MODEL.md +317 -0
- package/docs/PLUGIN_ARCHITECTURE.md +145 -0
- package/docs/PLUGIN_COMPATIBILITY.md +61 -0
- package/docs/PLUGIN_COMPLIANCE_CHECKS.md +82 -0
- package/docs/PLUGIN_MANIFEST.md +94 -0
- package/docs/css/style.css +465 -0
- package/docs/index.html +218 -0
- package/docs/js/app.mjs +751 -0
- package/docs/js/editor-panel.mjs +203 -0
- package/docs/js/flow-canvas.mjs +515 -0
- package/docs/js/flow-model.mjs +391 -0
- package/docs/js/workers/emception.worker.js +146 -0
- package/docs/js/workers/pyodide.worker.js +134 -0
- package/native/flow_source_generator.cpp +1958 -0
- package/package.json +67 -0
- package/schemas/FlowRuntimeAbi.fbs +91 -0
- package/src/auth/canonicalize.js +5 -0
- package/src/auth/index.js +11 -0
- package/src/auth/permissions.js +8 -0
- package/src/compiler/CppFlowSourceGenerator.js +475 -0
- package/src/compiler/EmceptionCompilerAdapter.js +244 -0
- package/src/compiler/SignedArtifactCatalog.js +152 -0
- package/src/compiler/index.js +8 -0
- package/src/compiler/nativeFlowSourceGeneratorTool.js +144 -0
- package/src/compliance/index.js +13 -0
- package/src/compliance/pluginCompliance.js +11 -0
- package/src/deploy/FlowDeploymentClient.js +532 -0
- package/src/deploy/index.js +8 -0
- package/src/designer/FlowDesignerSession.js +158 -0
- package/src/designer/index.js +2 -0
- package/src/designer/requirements.js +184 -0
- package/src/generated/runtimeAbiLayouts.js +544 -0
- package/src/host/appHost.js +105 -0
- package/src/host/autoHost.js +113 -0
- package/src/host/browserHostAdapters.js +108 -0
- package/src/host/compiledFlowRuntimeHost.js +703 -0
- package/src/host/constants.js +55 -0
- package/src/host/dependencyRuntime.js +227 -0
- package/src/host/descriptorAbi.js +351 -0
- package/src/host/fetchService.js +237 -0
- package/src/host/httpHostAdapters.js +280 -0
- package/src/host/index.js +91 -0
- package/src/host/installedFlowHost.js +885 -0
- package/src/host/invocationAbi.js +440 -0
- package/src/host/normalize.js +372 -0
- package/src/host/packageManagers.js +369 -0
- package/src/host/profile.js +134 -0
- package/src/host/runtimeAbi.js +106 -0
- package/src/host/workspace.js +895 -0
- package/src/index.js +8 -0
- package/src/runtime/FlowRuntime.js +273 -0
- package/src/runtime/MethodRegistry.js +295 -0
- package/src/runtime/constants.js +44 -0
- package/src/runtime/index.js +19 -0
- package/src/runtime/normalize.js +377 -0
- package/src/transport/index.js +7 -0
- package/src/transport/pki.js +7 -0
- package/src/utils/crypto.js +7 -0
- package/src/utils/encoding.js +65 -0
- package/src/utils/wasmCrypto.js +69 -0
- package/tools/run-plugin-compliance-check.mjs +153 -0
|
@@ -0,0 +1,895 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
import { normalizeProgram } from "../runtime/index.js";
|
|
5
|
+
import {
|
|
6
|
+
createInstalledFlowFetchHandler,
|
|
7
|
+
} from "./fetchService.js";
|
|
8
|
+
import {
|
|
9
|
+
createInstalledFlowService,
|
|
10
|
+
discoverInstalledPluginPackages,
|
|
11
|
+
normalizeInstalledPluginPackage,
|
|
12
|
+
} from "./installedFlowHost.js";
|
|
13
|
+
import { normalizeHostedRuntimePlan } from "./normalize.js";
|
|
14
|
+
|
|
15
|
+
function normalizeString(value, fallback = null) {
|
|
16
|
+
if (typeof value !== "string") {
|
|
17
|
+
return fallback;
|
|
18
|
+
}
|
|
19
|
+
const normalized = value.trim();
|
|
20
|
+
return normalized.length > 0 ? normalized : fallback;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isObject(value) {
|
|
24
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function normalizeStringArray(values) {
|
|
28
|
+
if (!Array.isArray(values)) {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
return Array.from(
|
|
32
|
+
new Set(
|
|
33
|
+
values
|
|
34
|
+
.map((value) => normalizeString(value, null))
|
|
35
|
+
.filter((value) => value !== null),
|
|
36
|
+
),
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function resolvePathLike(value, baseDirectory) {
|
|
41
|
+
const normalized = normalizeString(value, null);
|
|
42
|
+
if (!normalized) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return path.resolve(baseDirectory ?? process.cwd(), normalized);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function relativizePathLike(value, baseDirectory) {
|
|
49
|
+
if (!value) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
return path.relative(baseDirectory, value) || ".";
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function normalizeMetadata(value) {
|
|
56
|
+
return isObject(value) ? { ...value } : {};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function normalizeWorkspacePluginPackage(pluginPackage = {}, baseDirectory = null) {
|
|
60
|
+
const normalizedPackage = normalizeInstalledPluginPackage(pluginPackage);
|
|
61
|
+
return {
|
|
62
|
+
...normalizedPackage,
|
|
63
|
+
packageRoot: resolvePathLike(
|
|
64
|
+
pluginPackage.packageRoot ?? normalizedPackage.packageRoot,
|
|
65
|
+
baseDirectory,
|
|
66
|
+
),
|
|
67
|
+
manifestPath: resolvePathLike(
|
|
68
|
+
pluginPackage.manifestPath ?? normalizedPackage.manifestPath,
|
|
69
|
+
baseDirectory,
|
|
70
|
+
),
|
|
71
|
+
modulePath: resolvePathLike(
|
|
72
|
+
pluginPackage.modulePath ?? normalizedPackage.modulePath,
|
|
73
|
+
baseDirectory,
|
|
74
|
+
),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function normalizeWorkspacePackageReference(reference = {}, baseDirectory = null) {
|
|
79
|
+
return {
|
|
80
|
+
packageId: normalizeString(reference.packageId, null),
|
|
81
|
+
pluginId: normalizeString(reference.pluginId, null),
|
|
82
|
+
version: normalizeString(reference.version, null),
|
|
83
|
+
sourceType:
|
|
84
|
+
normalizeString(reference.sourceType ?? reference.source_type, null) ??
|
|
85
|
+
"unknown",
|
|
86
|
+
sourceRef: normalizeString(
|
|
87
|
+
reference.sourceRef ?? reference.source_ref,
|
|
88
|
+
null,
|
|
89
|
+
),
|
|
90
|
+
installPath: resolvePathLike(
|
|
91
|
+
reference.installPath ?? reference.install_path,
|
|
92
|
+
baseDirectory,
|
|
93
|
+
),
|
|
94
|
+
status: normalizeString(reference.status, null) ?? "installed",
|
|
95
|
+
metadata: normalizeMetadata(reference.metadata),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function serializeWorkspacePluginPackage(pluginPackage, baseDirectory) {
|
|
100
|
+
return {
|
|
101
|
+
packageId: pluginPackage.packageId,
|
|
102
|
+
packageName: pluginPackage.packageName,
|
|
103
|
+
pluginId: pluginPackage.pluginId,
|
|
104
|
+
packageRoot: relativizePathLike(pluginPackage.packageRoot, baseDirectory),
|
|
105
|
+
manifestPath: relativizePathLike(pluginPackage.manifestPath, baseDirectory),
|
|
106
|
+
modulePath: relativizePathLike(pluginPackage.modulePath, baseDirectory),
|
|
107
|
+
runtimeTargets: pluginPackage.runtimeTargets,
|
|
108
|
+
capabilities: pluginPackage.capabilities,
|
|
109
|
+
startupPhase: pluginPackage.startupPhase,
|
|
110
|
+
autoStart: pluginPackage.autoStart,
|
|
111
|
+
metadata: pluginPackage.metadata,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function serializeWorkspacePackageReference(reference, baseDirectory) {
|
|
116
|
+
return {
|
|
117
|
+
packageId: reference.packageId,
|
|
118
|
+
pluginId: reference.pluginId,
|
|
119
|
+
version: reference.version,
|
|
120
|
+
sourceType: reference.sourceType,
|
|
121
|
+
sourceRef: reference.sourceRef,
|
|
122
|
+
installPath: relativizePathLike(reference.installPath, baseDirectory),
|
|
123
|
+
status: reference.status,
|
|
124
|
+
metadata: reference.metadata,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function packageReferenceKey(reference = {}) {
|
|
129
|
+
return (
|
|
130
|
+
reference.packageId ??
|
|
131
|
+
reference.pluginId ??
|
|
132
|
+
reference.sourceRef ??
|
|
133
|
+
reference.installPath
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function pluginPackageKey(pluginPackage = {}) {
|
|
138
|
+
return (
|
|
139
|
+
pluginPackage.pluginId ??
|
|
140
|
+
pluginPackage.packageId ??
|
|
141
|
+
pluginPackage.manifestPath ??
|
|
142
|
+
pluginPackage.packageRoot
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function removeWorkspacePluginPackageByKey(pluginPackages, key) {
|
|
147
|
+
return pluginPackages.filter((item) => pluginPackageKey(item) !== key);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async function resolveWorkspacePluginPackageInput(
|
|
151
|
+
pluginPackage,
|
|
152
|
+
baseDirectory,
|
|
153
|
+
) {
|
|
154
|
+
const normalizedPackage = normalizeWorkspacePluginPackage(
|
|
155
|
+
pluginPackage,
|
|
156
|
+
baseDirectory,
|
|
157
|
+
);
|
|
158
|
+
if (
|
|
159
|
+
normalizedPackage.manifestPath ||
|
|
160
|
+
normalizedPackage.modulePath ||
|
|
161
|
+
normalizedPackage.manifest ||
|
|
162
|
+
normalizedPackage.module ||
|
|
163
|
+
normalizedPackage.handlers
|
|
164
|
+
) {
|
|
165
|
+
return normalizedPackage;
|
|
166
|
+
}
|
|
167
|
+
if (!normalizedPackage.packageRoot) {
|
|
168
|
+
return normalizedPackage;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const discoveredPackages = await discoverInstalledPluginPackages({
|
|
172
|
+
rootDirectories: [normalizedPackage.packageRoot],
|
|
173
|
+
});
|
|
174
|
+
const discoveredPackage =
|
|
175
|
+
discoveredPackages.find(
|
|
176
|
+
(item) =>
|
|
177
|
+
item.pluginId === normalizedPackage.pluginId ||
|
|
178
|
+
item.packageId === normalizedPackage.packageId,
|
|
179
|
+
) ??
|
|
180
|
+
(discoveredPackages.length === 1 ? discoveredPackages[0] : null);
|
|
181
|
+
|
|
182
|
+
if (!discoveredPackage) {
|
|
183
|
+
throw new Error(
|
|
184
|
+
`Could not resolve an installed plugin package from "${normalizedPackage.packageRoot}".`,
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return normalizeWorkspacePluginPackage(
|
|
189
|
+
{
|
|
190
|
+
...discoveredPackage,
|
|
191
|
+
...pluginPackage,
|
|
192
|
+
packageRoot:
|
|
193
|
+
pluginPackage.packageRoot ?? discoveredPackage.packageRoot,
|
|
194
|
+
manifestPath:
|
|
195
|
+
pluginPackage.manifestPath ?? discoveredPackage.manifestPath,
|
|
196
|
+
modulePath: pluginPackage.modulePath ?? discoveredPackage.modulePath,
|
|
197
|
+
},
|
|
198
|
+
baseDirectory,
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async function readJsonFile(filePath) {
|
|
203
|
+
return JSON.parse(await readFile(filePath, "utf8"));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export function normalizeInstalledFlowWorkspace(workspace = {}, options = {}) {
|
|
207
|
+
const baseDirectory = path.resolve(
|
|
208
|
+
normalizeString(
|
|
209
|
+
options.baseDirectory ??
|
|
210
|
+
workspace.baseDirectory ??
|
|
211
|
+
workspace.workspaceRoot ??
|
|
212
|
+
process.cwd(),
|
|
213
|
+
process.cwd(),
|
|
214
|
+
),
|
|
215
|
+
);
|
|
216
|
+
const program =
|
|
217
|
+
workspace.program && isObject(workspace.program)
|
|
218
|
+
? normalizeProgram(workspace.program)
|
|
219
|
+
: null;
|
|
220
|
+
const hostPlan =
|
|
221
|
+
workspace.hostPlan && isObject(workspace.hostPlan)
|
|
222
|
+
? normalizeHostedRuntimePlan(workspace.hostPlan)
|
|
223
|
+
: null;
|
|
224
|
+
const flowPath = resolvePathLike(
|
|
225
|
+
workspace.flowPath ?? workspace.programPath,
|
|
226
|
+
baseDirectory,
|
|
227
|
+
);
|
|
228
|
+
const hostPlanPath = resolvePathLike(workspace.hostPlanPath, baseDirectory);
|
|
229
|
+
const pluginRootDirectories = normalizeStringArray(
|
|
230
|
+
workspace.pluginRootDirectories ?? workspace.rootDirectories,
|
|
231
|
+
).map((directory) => resolvePathLike(directory, baseDirectory));
|
|
232
|
+
const pluginPackages = Array.isArray(workspace.pluginPackages)
|
|
233
|
+
? workspace.pluginPackages.map((pluginPackage) =>
|
|
234
|
+
normalizeWorkspacePluginPackage(pluginPackage, baseDirectory),
|
|
235
|
+
)
|
|
236
|
+
: [];
|
|
237
|
+
const packageCatalog = Array.isArray(
|
|
238
|
+
workspace.packageCatalog ?? workspace.installedPackages,
|
|
239
|
+
)
|
|
240
|
+
? (workspace.packageCatalog ?? workspace.installedPackages).map(
|
|
241
|
+
(reference) =>
|
|
242
|
+
normalizeWorkspacePackageReference(reference, baseDirectory),
|
|
243
|
+
)
|
|
244
|
+
: [];
|
|
245
|
+
|
|
246
|
+
return {
|
|
247
|
+
workspaceId:
|
|
248
|
+
normalizeString(
|
|
249
|
+
workspace.workspaceId ?? workspace.id ?? workspace.name,
|
|
250
|
+
null,
|
|
251
|
+
) ?? "installed-flow-workspace",
|
|
252
|
+
description: normalizeString(workspace.description, null),
|
|
253
|
+
baseDirectory,
|
|
254
|
+
flowPath,
|
|
255
|
+
hostPlanPath,
|
|
256
|
+
pluginRootDirectories,
|
|
257
|
+
pluginPackages,
|
|
258
|
+
packageCatalog,
|
|
259
|
+
moduleCandidates: normalizeStringArray(workspace.moduleCandidates),
|
|
260
|
+
discover: workspace.discover !== false,
|
|
261
|
+
adapter: normalizeString(workspace.adapter ?? hostPlan?.adapter, null),
|
|
262
|
+
engine: normalizeString(workspace.engine ?? hostPlan?.engine, null),
|
|
263
|
+
program,
|
|
264
|
+
hostPlan,
|
|
265
|
+
fetch: normalizeMetadata(workspace.fetch),
|
|
266
|
+
service: normalizeMetadata(workspace.service),
|
|
267
|
+
metadata: normalizeMetadata(workspace.metadata),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export async function resolveInstalledFlowWorkspace(workspace = {}, options = {}) {
|
|
272
|
+
const normalizedWorkspace = normalizeInstalledFlowWorkspace(workspace, options);
|
|
273
|
+
let program = normalizedWorkspace.program;
|
|
274
|
+
let hostPlan = normalizedWorkspace.hostPlan;
|
|
275
|
+
|
|
276
|
+
if (!program && normalizedWorkspace.flowPath) {
|
|
277
|
+
program = normalizeProgram(await readJsonFile(normalizedWorkspace.flowPath));
|
|
278
|
+
}
|
|
279
|
+
if (!hostPlan && normalizedWorkspace.hostPlanPath) {
|
|
280
|
+
hostPlan = normalizeHostedRuntimePlan(
|
|
281
|
+
await readJsonFile(normalizedWorkspace.hostPlanPath),
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return {
|
|
286
|
+
...normalizedWorkspace,
|
|
287
|
+
adapter: normalizedWorkspace.adapter ?? hostPlan?.adapter ?? null,
|
|
288
|
+
engine: normalizedWorkspace.engine ?? hostPlan?.engine ?? null,
|
|
289
|
+
program,
|
|
290
|
+
hostPlan,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export async function readInstalledFlowWorkspace(workspacePath, options = {}) {
|
|
295
|
+
const resolvedWorkspacePath = path.resolve(workspacePath);
|
|
296
|
+
const workspace = await readJsonFile(resolvedWorkspacePath);
|
|
297
|
+
return resolveInstalledFlowWorkspace(workspace, {
|
|
298
|
+
...options,
|
|
299
|
+
baseDirectory: path.dirname(resolvedWorkspacePath),
|
|
300
|
+
workspacePath: resolvedWorkspacePath,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export async function writeInstalledFlowWorkspace(workspacePath, workspace, options = {}) {
|
|
305
|
+
const resolvedWorkspacePath = path.resolve(workspacePath);
|
|
306
|
+
const baseDirectory = path.dirname(resolvedWorkspacePath);
|
|
307
|
+
const normalizedWorkspace = normalizeInstalledFlowWorkspace(workspace, {
|
|
308
|
+
...options,
|
|
309
|
+
baseDirectory,
|
|
310
|
+
});
|
|
311
|
+
const payload = {
|
|
312
|
+
workspaceId: normalizedWorkspace.workspaceId,
|
|
313
|
+
description: normalizedWorkspace.description,
|
|
314
|
+
flowPath: relativizePathLike(normalizedWorkspace.flowPath, baseDirectory),
|
|
315
|
+
hostPlanPath: relativizePathLike(
|
|
316
|
+
normalizedWorkspace.hostPlanPath,
|
|
317
|
+
baseDirectory,
|
|
318
|
+
),
|
|
319
|
+
pluginRootDirectories: normalizedWorkspace.pluginRootDirectories.map(
|
|
320
|
+
(directory) => relativizePathLike(directory, baseDirectory),
|
|
321
|
+
),
|
|
322
|
+
pluginPackages: normalizedWorkspace.pluginPackages.map((pluginPackage) =>
|
|
323
|
+
serializeWorkspacePluginPackage(pluginPackage, baseDirectory),
|
|
324
|
+
),
|
|
325
|
+
packageCatalog: normalizedWorkspace.packageCatalog.map((reference) =>
|
|
326
|
+
serializeWorkspacePackageReference(reference, baseDirectory),
|
|
327
|
+
),
|
|
328
|
+
moduleCandidates: normalizedWorkspace.moduleCandidates,
|
|
329
|
+
discover: normalizedWorkspace.discover,
|
|
330
|
+
adapter: normalizedWorkspace.adapter,
|
|
331
|
+
engine: normalizedWorkspace.engine,
|
|
332
|
+
fetch: normalizedWorkspace.fetch,
|
|
333
|
+
service: normalizedWorkspace.service,
|
|
334
|
+
metadata: normalizedWorkspace.metadata,
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
if (normalizedWorkspace.program) {
|
|
338
|
+
payload.program = normalizedWorkspace.program;
|
|
339
|
+
}
|
|
340
|
+
if (normalizedWorkspace.hostPlan) {
|
|
341
|
+
payload.hostPlan = normalizedWorkspace.hostPlan;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
await mkdir(baseDirectory, { recursive: true });
|
|
345
|
+
await writeFile(
|
|
346
|
+
resolvedWorkspacePath,
|
|
347
|
+
`${JSON.stringify(payload, null, 2)}\n`,
|
|
348
|
+
"utf8",
|
|
349
|
+
);
|
|
350
|
+
return resolvedWorkspacePath;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export async function installWorkspacePluginPackage(
|
|
354
|
+
workspace,
|
|
355
|
+
pluginPackage,
|
|
356
|
+
options = {},
|
|
357
|
+
) {
|
|
358
|
+
const normalizedWorkspace = await resolveInstalledFlowWorkspace(
|
|
359
|
+
workspace,
|
|
360
|
+
options,
|
|
361
|
+
);
|
|
362
|
+
const resolvedPackage = await resolveWorkspacePluginPackageInput(
|
|
363
|
+
pluginPackage,
|
|
364
|
+
normalizedWorkspace.baseDirectory,
|
|
365
|
+
);
|
|
366
|
+
const packageKey =
|
|
367
|
+
resolvedPackage.pluginId ??
|
|
368
|
+
resolvedPackage.packageId ??
|
|
369
|
+
resolvedPackage.manifestPath ??
|
|
370
|
+
resolvedPackage.packageRoot;
|
|
371
|
+
const pluginPackages = normalizedWorkspace.pluginPackages.filter((item) => {
|
|
372
|
+
const itemKey =
|
|
373
|
+
item.pluginId ?? item.packageId ?? item.manifestPath ?? item.packageRoot;
|
|
374
|
+
return itemKey !== packageKey;
|
|
375
|
+
});
|
|
376
|
+
pluginPackages.push(resolvedPackage);
|
|
377
|
+
pluginPackages.sort((left, right) =>
|
|
378
|
+
`${left.packageName ?? ""}:${left.pluginId ?? left.packageId}`.localeCompare(
|
|
379
|
+
`${right.packageName ?? ""}:${right.pluginId ?? right.packageId}`,
|
|
380
|
+
),
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
return {
|
|
384
|
+
...normalizedWorkspace,
|
|
385
|
+
pluginPackages,
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export async function uninstallWorkspacePluginPackage(
|
|
390
|
+
workspace,
|
|
391
|
+
selector,
|
|
392
|
+
options = {},
|
|
393
|
+
) {
|
|
394
|
+
const normalizedWorkspace = await resolveInstalledFlowWorkspace(
|
|
395
|
+
workspace,
|
|
396
|
+
options,
|
|
397
|
+
);
|
|
398
|
+
const normalizedSelector = isObject(selector)
|
|
399
|
+
? {
|
|
400
|
+
pluginId: normalizeString(selector.pluginId, null),
|
|
401
|
+
packageId: normalizeString(selector.packageId, null),
|
|
402
|
+
packageRoot: resolvePathLike(selector.packageRoot, normalizedWorkspace.baseDirectory),
|
|
403
|
+
manifestPath: resolvePathLike(selector.manifestPath, normalizedWorkspace.baseDirectory),
|
|
404
|
+
modulePath: resolvePathLike(selector.modulePath, normalizedWorkspace.baseDirectory),
|
|
405
|
+
}
|
|
406
|
+
: {
|
|
407
|
+
pluginId: normalizeString(selector, null),
|
|
408
|
+
packageId: normalizeString(selector, null),
|
|
409
|
+
packageRoot: null,
|
|
410
|
+
manifestPath: null,
|
|
411
|
+
modulePath: null,
|
|
412
|
+
};
|
|
413
|
+
const pluginPackages = normalizedWorkspace.pluginPackages.filter((item) => {
|
|
414
|
+
if (normalizedSelector.pluginId && item.pluginId === normalizedSelector.pluginId) {
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
if (normalizedSelector.packageId && item.packageId === normalizedSelector.packageId) {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
if (
|
|
421
|
+
normalizedSelector.packageRoot &&
|
|
422
|
+
item.packageRoot === normalizedSelector.packageRoot
|
|
423
|
+
) {
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
if (
|
|
427
|
+
normalizedSelector.manifestPath &&
|
|
428
|
+
item.manifestPath === normalizedSelector.manifestPath
|
|
429
|
+
) {
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
if (
|
|
433
|
+
normalizedSelector.modulePath &&
|
|
434
|
+
item.modulePath === normalizedSelector.modulePath
|
|
435
|
+
) {
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
return true;
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
return {
|
|
442
|
+
...normalizedWorkspace,
|
|
443
|
+
pluginPackages,
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function requirePackageManager(options = {}) {
|
|
448
|
+
const packageManager = options.packageManager ?? null;
|
|
449
|
+
if (!packageManager) {
|
|
450
|
+
throw new Error(
|
|
451
|
+
"Workspace package-reference operations require a packageManager with install/update/remove methods.",
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
return packageManager;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function removeWorkspacePackageReferenceBySelector(
|
|
458
|
+
packageCatalog,
|
|
459
|
+
selector,
|
|
460
|
+
baseDirectory,
|
|
461
|
+
) {
|
|
462
|
+
const normalizedSelector = isObject(selector)
|
|
463
|
+
? normalizeWorkspacePackageReference(selector, baseDirectory)
|
|
464
|
+
: {
|
|
465
|
+
packageId: normalizeString(selector, null),
|
|
466
|
+
pluginId: normalizeString(selector, null),
|
|
467
|
+
version: null,
|
|
468
|
+
sourceType: null,
|
|
469
|
+
sourceRef: normalizeString(selector, null),
|
|
470
|
+
installPath: null,
|
|
471
|
+
status: null,
|
|
472
|
+
metadata: {},
|
|
473
|
+
};
|
|
474
|
+
return packageCatalog.filter((reference) => {
|
|
475
|
+
if (
|
|
476
|
+
normalizedSelector.packageId &&
|
|
477
|
+
reference.packageId === normalizedSelector.packageId
|
|
478
|
+
) {
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
if (
|
|
482
|
+
normalizedSelector.pluginId &&
|
|
483
|
+
reference.pluginId === normalizedSelector.pluginId
|
|
484
|
+
) {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
if (
|
|
488
|
+
normalizedSelector.sourceRef &&
|
|
489
|
+
reference.sourceRef === normalizedSelector.sourceRef
|
|
490
|
+
) {
|
|
491
|
+
return false;
|
|
492
|
+
}
|
|
493
|
+
if (
|
|
494
|
+
normalizedSelector.installPath &&
|
|
495
|
+
reference.installPath === normalizedSelector.installPath
|
|
496
|
+
) {
|
|
497
|
+
return false;
|
|
498
|
+
}
|
|
499
|
+
return true;
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function findWorkspacePackageReference(packageCatalog, selector, baseDirectory) {
|
|
504
|
+
return packageCatalog.find((reference) =>
|
|
505
|
+
removeWorkspacePackageReferenceBySelector(
|
|
506
|
+
[reference],
|
|
507
|
+
selector,
|
|
508
|
+
baseDirectory,
|
|
509
|
+
).length === 0,
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
function sortWorkspacePackageReferences(packageCatalog) {
|
|
514
|
+
packageCatalog.sort((left, right) =>
|
|
515
|
+
`${left.packageId ?? ""}:${left.pluginId ?? ""}:${left.sourceRef ?? ""}`.localeCompare(
|
|
516
|
+
`${right.packageId ?? ""}:${right.pluginId ?? ""}:${right.sourceRef ?? ""}`,
|
|
517
|
+
),
|
|
518
|
+
);
|
|
519
|
+
return packageCatalog;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
async function resolveInstalledPackageManagerRecord(record, baseDirectory) {
|
|
523
|
+
const normalizedReference = normalizeWorkspacePackageReference(
|
|
524
|
+
record,
|
|
525
|
+
baseDirectory,
|
|
526
|
+
);
|
|
527
|
+
const pluginPackage = await resolveWorkspacePluginPackageInput(
|
|
528
|
+
{
|
|
529
|
+
...(record.pluginPackage ?? {}),
|
|
530
|
+
packageId:
|
|
531
|
+
record.pluginPackage?.packageId ?? normalizedReference.packageId,
|
|
532
|
+
pluginId: record.pluginPackage?.pluginId ?? normalizedReference.pluginId,
|
|
533
|
+
packageRoot:
|
|
534
|
+
record.pluginPackage?.packageRoot ?? normalizedReference.installPath,
|
|
535
|
+
},
|
|
536
|
+
baseDirectory,
|
|
537
|
+
);
|
|
538
|
+
|
|
539
|
+
return {
|
|
540
|
+
packageReference: {
|
|
541
|
+
...normalizedReference,
|
|
542
|
+
packageId: normalizedReference.packageId ?? pluginPackage.packageId,
|
|
543
|
+
pluginId: normalizedReference.pluginId ?? pluginPackage.pluginId,
|
|
544
|
+
},
|
|
545
|
+
pluginPackage,
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
export async function installWorkspacePackageReference(
|
|
550
|
+
workspace,
|
|
551
|
+
packageReference,
|
|
552
|
+
options = {},
|
|
553
|
+
) {
|
|
554
|
+
const normalizedWorkspace = await resolveInstalledFlowWorkspace(
|
|
555
|
+
workspace,
|
|
556
|
+
options,
|
|
557
|
+
);
|
|
558
|
+
const packageManager = requirePackageManager(options);
|
|
559
|
+
const installRecord = await packageManager.install(
|
|
560
|
+
packageReference,
|
|
561
|
+
normalizedWorkspace,
|
|
562
|
+
options,
|
|
563
|
+
);
|
|
564
|
+
const resolvedRecord = await resolveInstalledPackageManagerRecord(
|
|
565
|
+
installRecord,
|
|
566
|
+
normalizedWorkspace.baseDirectory,
|
|
567
|
+
);
|
|
568
|
+
const referenceKey = packageReferenceKey(resolvedRecord.packageReference);
|
|
569
|
+
const packageCatalog = removeWorkspacePackageReferenceBySelector(
|
|
570
|
+
normalizedWorkspace.packageCatalog,
|
|
571
|
+
resolvedRecord.packageReference,
|
|
572
|
+
normalizedWorkspace.baseDirectory,
|
|
573
|
+
);
|
|
574
|
+
packageCatalog.push(resolvedRecord.packageReference);
|
|
575
|
+
sortWorkspacePackageReferences(packageCatalog);
|
|
576
|
+
|
|
577
|
+
const pluginPackages = removeWorkspacePluginPackageByKey(
|
|
578
|
+
normalizedWorkspace.pluginPackages,
|
|
579
|
+
referenceKey,
|
|
580
|
+
);
|
|
581
|
+
pluginPackages.push(resolvedRecord.pluginPackage);
|
|
582
|
+
pluginPackages.sort((left, right) =>
|
|
583
|
+
`${left.packageName ?? ""}:${left.pluginId ?? left.packageId}`.localeCompare(
|
|
584
|
+
`${right.packageName ?? ""}:${right.pluginId ?? right.packageId}`,
|
|
585
|
+
),
|
|
586
|
+
);
|
|
587
|
+
|
|
588
|
+
return {
|
|
589
|
+
...normalizedWorkspace,
|
|
590
|
+
pluginPackages,
|
|
591
|
+
packageCatalog,
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
export async function updateWorkspacePackageReference(
|
|
596
|
+
workspace,
|
|
597
|
+
selector,
|
|
598
|
+
options = {},
|
|
599
|
+
) {
|
|
600
|
+
const normalizedWorkspace = await resolveInstalledFlowWorkspace(
|
|
601
|
+
workspace,
|
|
602
|
+
options,
|
|
603
|
+
);
|
|
604
|
+
const packageManager = requirePackageManager(options);
|
|
605
|
+
const existingReference = findWorkspacePackageReference(
|
|
606
|
+
normalizedWorkspace.packageCatalog,
|
|
607
|
+
selector,
|
|
608
|
+
normalizedWorkspace.baseDirectory,
|
|
609
|
+
);
|
|
610
|
+
if (!existingReference) {
|
|
611
|
+
throw new Error("Workspace package reference was not found for update.");
|
|
612
|
+
}
|
|
613
|
+
const updateRecord = await packageManager.update(
|
|
614
|
+
existingReference,
|
|
615
|
+
normalizedWorkspace,
|
|
616
|
+
options,
|
|
617
|
+
);
|
|
618
|
+
|
|
619
|
+
return installWorkspacePackageReference(
|
|
620
|
+
{
|
|
621
|
+
...normalizedWorkspace,
|
|
622
|
+
packageCatalog: removeWorkspacePackageReferenceBySelector(
|
|
623
|
+
normalizedWorkspace.packageCatalog,
|
|
624
|
+
selector,
|
|
625
|
+
normalizedWorkspace.baseDirectory,
|
|
626
|
+
),
|
|
627
|
+
pluginPackages: removeWorkspacePluginPackageByKey(
|
|
628
|
+
normalizedWorkspace.pluginPackages,
|
|
629
|
+
existingReference.pluginId ??
|
|
630
|
+
existingReference.packageId ??
|
|
631
|
+
existingReference.installPath,
|
|
632
|
+
),
|
|
633
|
+
},
|
|
634
|
+
updateRecord,
|
|
635
|
+
{
|
|
636
|
+
...options,
|
|
637
|
+
packageManager: {
|
|
638
|
+
install(record) {
|
|
639
|
+
return record;
|
|
640
|
+
},
|
|
641
|
+
},
|
|
642
|
+
},
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
export async function removeWorkspacePackageReference(
|
|
647
|
+
workspace,
|
|
648
|
+
selector,
|
|
649
|
+
options = {},
|
|
650
|
+
) {
|
|
651
|
+
const normalizedWorkspace = await resolveInstalledFlowWorkspace(
|
|
652
|
+
workspace,
|
|
653
|
+
options,
|
|
654
|
+
);
|
|
655
|
+
const packageManager = requirePackageManager(options);
|
|
656
|
+
const existingReference = findWorkspacePackageReference(
|
|
657
|
+
normalizedWorkspace.packageCatalog,
|
|
658
|
+
selector,
|
|
659
|
+
normalizedWorkspace.baseDirectory,
|
|
660
|
+
);
|
|
661
|
+
if (!existingReference) {
|
|
662
|
+
return normalizedWorkspace;
|
|
663
|
+
}
|
|
664
|
+
if (typeof packageManager.remove === "function") {
|
|
665
|
+
await packageManager.remove(existingReference, normalizedWorkspace, options);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
return {
|
|
669
|
+
...normalizedWorkspace,
|
|
670
|
+
packageCatalog: removeWorkspacePackageReferenceBySelector(
|
|
671
|
+
normalizedWorkspace.packageCatalog,
|
|
672
|
+
selector,
|
|
673
|
+
normalizedWorkspace.baseDirectory,
|
|
674
|
+
),
|
|
675
|
+
pluginPackages: removeWorkspacePluginPackageByKey(
|
|
676
|
+
normalizedWorkspace.pluginPackages,
|
|
677
|
+
existingReference.pluginId ??
|
|
678
|
+
existingReference.packageId ??
|
|
679
|
+
existingReference.installPath,
|
|
680
|
+
),
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
export async function createInstalledFlowApp(options = {}) {
|
|
685
|
+
const workspacePath = normalizeString(options.workspacePath, null)
|
|
686
|
+
? path.resolve(options.workspacePath)
|
|
687
|
+
: null;
|
|
688
|
+
let workspace =
|
|
689
|
+
options.workspace !== undefined
|
|
690
|
+
? await resolveInstalledFlowWorkspace(options.workspace, options)
|
|
691
|
+
: workspacePath
|
|
692
|
+
? await readInstalledFlowWorkspace(workspacePath, options)
|
|
693
|
+
: await resolveInstalledFlowWorkspace({}, options);
|
|
694
|
+
|
|
695
|
+
const service = createInstalledFlowService({
|
|
696
|
+
program: workspace.program,
|
|
697
|
+
pluginRootDirectories: workspace.pluginRootDirectories,
|
|
698
|
+
pluginPackages: workspace.pluginPackages,
|
|
699
|
+
discover: workspace.discover,
|
|
700
|
+
moduleCandidates:
|
|
701
|
+
workspace.moduleCandidates.length > 0
|
|
702
|
+
? workspace.moduleCandidates
|
|
703
|
+
: undefined,
|
|
704
|
+
...(workspace.service ?? {}),
|
|
705
|
+
...(options.serviceOptions ?? {}),
|
|
706
|
+
importModule: options.importModule,
|
|
707
|
+
context: options.context ?? null,
|
|
708
|
+
runtimeOptions: options.runtimeOptions,
|
|
709
|
+
onSinkOutput: options.onSinkOutput,
|
|
710
|
+
});
|
|
711
|
+
const fetchHandler = async (request, context = {}) =>
|
|
712
|
+
createInstalledFlowFetchHandler({
|
|
713
|
+
service,
|
|
714
|
+
...(workspace.fetch ?? {}),
|
|
715
|
+
...(options.fetchOptions ?? {}),
|
|
716
|
+
})(request, context);
|
|
717
|
+
fetchHandler.service = service;
|
|
718
|
+
fetchHandler.start = () => service.start();
|
|
719
|
+
fetchHandler.stop = () => service.stop();
|
|
720
|
+
|
|
721
|
+
async function reloadWorkspace(reloadOptions = {}) {
|
|
722
|
+
if (!workspacePath) {
|
|
723
|
+
return workspace;
|
|
724
|
+
}
|
|
725
|
+
workspace = await readInstalledFlowWorkspace(workspacePath, {
|
|
726
|
+
...options,
|
|
727
|
+
...reloadOptions,
|
|
728
|
+
});
|
|
729
|
+
return workspace;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
return {
|
|
733
|
+
workspacePath,
|
|
734
|
+
host: service.host,
|
|
735
|
+
service,
|
|
736
|
+
fetchHandler,
|
|
737
|
+
getWorkspace() {
|
|
738
|
+
return workspace;
|
|
739
|
+
},
|
|
740
|
+
getSummary() {
|
|
741
|
+
return {
|
|
742
|
+
workspaceId: workspace.workspaceId,
|
|
743
|
+
programId: workspace.program?.programId ?? null,
|
|
744
|
+
adapter: workspace.adapter,
|
|
745
|
+
engine: workspace.engine,
|
|
746
|
+
pluginRootDirectories: workspace.pluginRootDirectories,
|
|
747
|
+
packageCatalogCount: workspace.packageCatalog.length,
|
|
748
|
+
hostId: workspace.hostPlan?.hostId ?? null,
|
|
749
|
+
};
|
|
750
|
+
},
|
|
751
|
+
async start() {
|
|
752
|
+
const startup = await service.start();
|
|
753
|
+
return {
|
|
754
|
+
...startup,
|
|
755
|
+
workspace: this.getSummary(),
|
|
756
|
+
};
|
|
757
|
+
},
|
|
758
|
+
stop() {
|
|
759
|
+
return service.stop();
|
|
760
|
+
},
|
|
761
|
+
async refresh(refreshOptions = {}) {
|
|
762
|
+
if (refreshOptions.reloadWorkspace !== false && workspacePath) {
|
|
763
|
+
await reloadWorkspace(refreshOptions);
|
|
764
|
+
}
|
|
765
|
+
const refreshResult = await service.refresh({
|
|
766
|
+
...refreshOptions,
|
|
767
|
+
program: workspace.program,
|
|
768
|
+
pluginRootDirectories: workspace.pluginRootDirectories,
|
|
769
|
+
pluginPackages: workspace.pluginPackages,
|
|
770
|
+
discover: workspace.discover,
|
|
771
|
+
moduleCandidates:
|
|
772
|
+
workspace.moduleCandidates.length > 0
|
|
773
|
+
? workspace.moduleCandidates
|
|
774
|
+
: undefined,
|
|
775
|
+
});
|
|
776
|
+
return {
|
|
777
|
+
...refreshResult,
|
|
778
|
+
workspace: this.getSummary(),
|
|
779
|
+
};
|
|
780
|
+
},
|
|
781
|
+
async reloadWorkspace(reloadOptions = {}) {
|
|
782
|
+
return reloadWorkspace(reloadOptions);
|
|
783
|
+
},
|
|
784
|
+
async save(saveOptions = {}) {
|
|
785
|
+
if (!workspacePath) {
|
|
786
|
+
throw new Error(
|
|
787
|
+
"Installed flow app cannot save workspace state without workspacePath.",
|
|
788
|
+
);
|
|
789
|
+
}
|
|
790
|
+
return writeInstalledFlowWorkspace(workspacePath, workspace, saveOptions);
|
|
791
|
+
},
|
|
792
|
+
async installPluginPackage(pluginPackage, installOptions = {}) {
|
|
793
|
+
workspace = await installWorkspacePluginPackage(
|
|
794
|
+
workspace,
|
|
795
|
+
pluginPackage,
|
|
796
|
+
installOptions,
|
|
797
|
+
);
|
|
798
|
+
if (workspacePath && installOptions.save !== false) {
|
|
799
|
+
await writeInstalledFlowWorkspace(workspacePath, workspace, installOptions);
|
|
800
|
+
}
|
|
801
|
+
if (installOptions.refresh === false) {
|
|
802
|
+
return workspace;
|
|
803
|
+
}
|
|
804
|
+
return this.refresh({
|
|
805
|
+
...installOptions,
|
|
806
|
+
reloadWorkspace: workspacePath ? installOptions.save !== false : false,
|
|
807
|
+
});
|
|
808
|
+
},
|
|
809
|
+
async uninstallPluginPackage(selector, uninstallOptions = {}) {
|
|
810
|
+
workspace = await uninstallWorkspacePluginPackage(
|
|
811
|
+
workspace,
|
|
812
|
+
selector,
|
|
813
|
+
uninstallOptions,
|
|
814
|
+
);
|
|
815
|
+
if (workspacePath && uninstallOptions.save !== false) {
|
|
816
|
+
await writeInstalledFlowWorkspace(
|
|
817
|
+
workspacePath,
|
|
818
|
+
workspace,
|
|
819
|
+
uninstallOptions,
|
|
820
|
+
);
|
|
821
|
+
}
|
|
822
|
+
if (uninstallOptions.refresh === false) {
|
|
823
|
+
return workspace;
|
|
824
|
+
}
|
|
825
|
+
return this.refresh({
|
|
826
|
+
...uninstallOptions,
|
|
827
|
+
reloadWorkspace: workspacePath ? uninstallOptions.save !== false : false,
|
|
828
|
+
});
|
|
829
|
+
},
|
|
830
|
+
async installPackageReference(packageReference, installOptions = {}) {
|
|
831
|
+
workspace = await installWorkspacePackageReference(
|
|
832
|
+
workspace,
|
|
833
|
+
packageReference,
|
|
834
|
+
installOptions,
|
|
835
|
+
);
|
|
836
|
+
if (workspacePath && installOptions.save !== false) {
|
|
837
|
+
await writeInstalledFlowWorkspace(workspacePath, workspace, installOptions);
|
|
838
|
+
}
|
|
839
|
+
if (installOptions.refresh === false) {
|
|
840
|
+
return workspace;
|
|
841
|
+
}
|
|
842
|
+
return this.refresh({
|
|
843
|
+
...installOptions,
|
|
844
|
+
reloadWorkspace: workspacePath ? installOptions.save !== false : false,
|
|
845
|
+
});
|
|
846
|
+
},
|
|
847
|
+
async updatePackageReference(selector, updateOptions = {}) {
|
|
848
|
+
workspace = await updateWorkspacePackageReference(
|
|
849
|
+
workspace,
|
|
850
|
+
selector,
|
|
851
|
+
updateOptions,
|
|
852
|
+
);
|
|
853
|
+
if (workspacePath && updateOptions.save !== false) {
|
|
854
|
+
await writeInstalledFlowWorkspace(workspacePath, workspace, updateOptions);
|
|
855
|
+
}
|
|
856
|
+
if (updateOptions.refresh === false) {
|
|
857
|
+
return workspace;
|
|
858
|
+
}
|
|
859
|
+
return this.refresh({
|
|
860
|
+
...updateOptions,
|
|
861
|
+
reloadWorkspace: workspacePath ? updateOptions.save !== false : false,
|
|
862
|
+
});
|
|
863
|
+
},
|
|
864
|
+
async removePackageReference(selector, removeOptions = {}) {
|
|
865
|
+
workspace = await removeWorkspacePackageReference(
|
|
866
|
+
workspace,
|
|
867
|
+
selector,
|
|
868
|
+
removeOptions,
|
|
869
|
+
);
|
|
870
|
+
if (workspacePath && removeOptions.save !== false) {
|
|
871
|
+
await writeInstalledFlowWorkspace(workspacePath, workspace, removeOptions);
|
|
872
|
+
}
|
|
873
|
+
if (removeOptions.refresh === false) {
|
|
874
|
+
return workspace;
|
|
875
|
+
}
|
|
876
|
+
return this.refresh({
|
|
877
|
+
...removeOptions,
|
|
878
|
+
reloadWorkspace: workspacePath ? removeOptions.save !== false : false,
|
|
879
|
+
});
|
|
880
|
+
},
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
export default {
|
|
885
|
+
createInstalledFlowApp,
|
|
886
|
+
installWorkspacePluginPackage,
|
|
887
|
+
installWorkspacePackageReference,
|
|
888
|
+
normalizeInstalledFlowWorkspace,
|
|
889
|
+
readInstalledFlowWorkspace,
|
|
890
|
+
removeWorkspacePackageReference,
|
|
891
|
+
resolveInstalledFlowWorkspace,
|
|
892
|
+
uninstallWorkspacePluginPackage,
|
|
893
|
+
updateWorkspacePackageReference,
|
|
894
|
+
writeInstalledFlowWorkspace,
|
|
895
|
+
};
|