@octonodes/cli 0.0.3 → 0.1.5
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/README.md +162 -18
- package/dist/auth.js.map +1 -1
- package/dist/connect.d.ts +3 -0
- package/dist/connect.d.ts.map +1 -0
- package/dist/connect.js +84 -0
- package/dist/connect.js.map +1 -0
- package/dist/index.js +20 -1
- package/dist/index.js.map +1 -1
- package/dist/plugins/artifact.d.ts +11 -0
- package/dist/plugins/artifact.d.ts.map +1 -0
- package/dist/plugins/artifact.js +116 -0
- package/dist/plugins/artifact.js.map +1 -0
- package/dist/plugins/build.d.ts +3 -0
- package/dist/plugins/build.d.ts.map +1 -0
- package/dist/plugins/build.js +278 -0
- package/dist/plugins/build.js.map +1 -0
- package/dist/plugins/constants.d.ts +6 -0
- package/dist/plugins/constants.d.ts.map +1 -0
- package/dist/plugins/constants.js +29 -0
- package/dist/plugins/constants.js.map +1 -0
- package/dist/plugins/create.d.ts +2 -0
- package/dist/plugins/create.d.ts.map +1 -0
- package/dist/plugins/create.js +64 -0
- package/dist/plugins/create.js.map +1 -0
- package/dist/plugins/index.d.ts +3 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +85 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/publish.d.ts +2 -0
- package/dist/plugins/publish.d.ts.map +1 -0
- package/dist/plugins/publish.js +53 -0
- package/dist/plugins/publish.js.map +1 -0
- package/dist/plugins/types.d.ts +19 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +3 -0
- package/dist/plugins/types.js.map +1 -0
- package/package.json +15 -8
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildPlugins = buildPlugins;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const node_module_1 = require("node:module");
|
|
7
|
+
const esbuild_1 = require("esbuild");
|
|
8
|
+
const yaml_1 = require("yaml");
|
|
9
|
+
const plugins_1 = require("@octonodes/sdk/plugins");
|
|
10
|
+
const compiler_1 = require("@octonodes/sdk/definitions/compiler");
|
|
11
|
+
const npm_1 = require("@octonodes/sdk/definitions/npm");
|
|
12
|
+
const constants_1 = require("./constants");
|
|
13
|
+
const artifact_1 = require("./artifact");
|
|
14
|
+
function directory(root, path) {
|
|
15
|
+
let current = root;
|
|
16
|
+
for (const part of path.split("/")) {
|
|
17
|
+
current = (0, node_path_1.join)(current, part);
|
|
18
|
+
if (!(0, node_fs_1.existsSync)(current))
|
|
19
|
+
(0, node_fs_1.mkdirSync)(current);
|
|
20
|
+
const stat = (0, node_fs_1.lstatSync)(current);
|
|
21
|
+
if (stat.isSymbolicLink() || !stat.isDirectory())
|
|
22
|
+
throw new Error(`Build directory must be a real directory: ${current}`);
|
|
23
|
+
}
|
|
24
|
+
return current;
|
|
25
|
+
}
|
|
26
|
+
async function buildPlugins(entry, root = process.cwd()) {
|
|
27
|
+
root = (0, node_path_1.resolve)(root);
|
|
28
|
+
if (entry && (0, node_path_1.resolve)(root, entry) !== (0, node_path_1.resolve)(root, compiler_1.PLUGIN_FILENAME))
|
|
29
|
+
throw new Error("Plugin definitions must be in octonode.plugin.ts; arbitrary entry files are not supported");
|
|
30
|
+
(0, compiler_1.generateNodeCatalog)(root);
|
|
31
|
+
const definition = (0, compiler_1.compileDefinition)(root, [], "plugin");
|
|
32
|
+
if (!definition || definition.kind !== "plugin" || !definition.manifest)
|
|
33
|
+
throw new Error("Default-export definePlugin({...}) from octonode.plugin.ts");
|
|
34
|
+
const entries = [(0, node_path_1.resolve)(root, compiler_1.PLUGIN_FILENAME)];
|
|
35
|
+
const manifestDefinition = definition.manifest;
|
|
36
|
+
const workflowNodes = definition.nodes.filter((node) => node.workflow);
|
|
37
|
+
if (workflowNodes.length && workflowNodes.length !== definition.nodes.length)
|
|
38
|
+
throw new Error("Keep exported workflows in their own plugin package");
|
|
39
|
+
const workflow = workflowNodes[0]?.workflow;
|
|
40
|
+
if (workflowNodes.some((node) => JSON.stringify(node.workflow.files) !== JSON.stringify(workflow.files)))
|
|
41
|
+
throw new Error("Workflow handles must come from the same generated export");
|
|
42
|
+
const npmNodes = definition.nodes.filter((node) => node.npm);
|
|
43
|
+
if (npmNodes.length && npmNodes.length !== definition.nodes.length)
|
|
44
|
+
throw new Error("Keep npm adapters and local implementations in separate plugin packages");
|
|
45
|
+
if (new Set(npmNodes.map((node) => node.npm.packageName + "@" + node.npm.packageVersion)).size > 1)
|
|
46
|
+
throw new Error("An npm plugin must target one package version");
|
|
47
|
+
const npm = npmNodes[0]?.npm;
|
|
48
|
+
const npmFiles = npm
|
|
49
|
+
? (0, npm_1.emitNpmJsFiles)({
|
|
50
|
+
manifest: manifestDefinition,
|
|
51
|
+
packageName: npm.packageName,
|
|
52
|
+
packageVersion: npm.packageVersion,
|
|
53
|
+
warnings: [],
|
|
54
|
+
nodes: npmNodes.map((node, index) => ({
|
|
55
|
+
...node.npm.descriptor,
|
|
56
|
+
id: manifestDefinition.nodes[index].id,
|
|
57
|
+
bindings: node.customization.bindings,
|
|
58
|
+
})),
|
|
59
|
+
})
|
|
60
|
+
: undefined;
|
|
61
|
+
const imports = definition.nodes
|
|
62
|
+
.map((node, index) => `import { ${node.exportName} as implementation${index} } from ${JSON.stringify((0, node_path_1.resolve)(root, node.path))};`)
|
|
63
|
+
.join("\n");
|
|
64
|
+
const handlers = definition.nodes
|
|
65
|
+
.map((node, index) => `${JSON.stringify(manifestDefinition.nodes[index].id)}: async (inputs) => (await implementation${index}(${node.parameters.map((name) => `inputs[${JSON.stringify(name)}]`).join(", ")})) ?? null`)
|
|
66
|
+
.join(",\n");
|
|
67
|
+
const workflowSource = `import { execFileSync } from "node:child_process"; import { join } from "node:path";
|
|
68
|
+
const invokeWorkflow = (key, inputs, context) => {
|
|
69
|
+
const result = JSON.parse(execFileSync(process.execPath, ["workflow.cjs", key], {
|
|
70
|
+
cwd: join(__dirname, "../workflow-runtime"), encoding: "utf8", maxBuffer: 16 * 1024 * 1024,
|
|
71
|
+
input: JSON.stringify({octonode:"1",type:"invoke",invocationId:"workflow",inputs,context})
|
|
72
|
+
}));
|
|
73
|
+
if (result.status !== "ok") throw new Error(result.error?.message ?? "Workflow failed");
|
|
74
|
+
return result.outputs;
|
|
75
|
+
};`;
|
|
76
|
+
const runnerSource = `${workflow ? workflowSource : npmFiles ? 'const { invokeNode } = require("../nodes/npm.cjs");' : imports}
|
|
77
|
+
import { definePlugin, startPlugin } from "@octonodes/sdk/plugins";
|
|
78
|
+
export { startPlugin };
|
|
79
|
+
export const plugin = definePlugin(${JSON.stringify(manifestDefinition)}, {${workflow ? workflowNodes.map((node, index) => `${JSON.stringify(manifestDefinition.nodes[index].id)}: (inputs, context) => invokeWorkflow(${JSON.stringify(node.workflow.key)}, inputs, context)`).join(",") : npmFiles ? manifestDefinition.nodes.map((node) => `${JSON.stringify(node.id)}: (inputs) => invokeNode(${JSON.stringify(node.id)}, inputs)`).join(",") : handlers}});`;
|
|
80
|
+
const output = directory(root, "dist/plugins");
|
|
81
|
+
const staging = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)(output, ".build-"));
|
|
82
|
+
const prepared = [];
|
|
83
|
+
try {
|
|
84
|
+
// Inspect CommonJS bundles independently of the author's package module type.
|
|
85
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(staging, "package.json"), '{"type":"commonjs"}\n');
|
|
86
|
+
for (const [index, source] of entries.entries()) {
|
|
87
|
+
const sourcePath = (0, node_path_1.relative)(root, source).replaceAll("\\", "/");
|
|
88
|
+
(0, artifact_1.safePath)(sourcePath);
|
|
89
|
+
const staged = (0, node_path_1.join)(staging, String(index));
|
|
90
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(staged, "dist"), { recursive: true });
|
|
91
|
+
const runner = (0, node_path_1.join)(staged, "dist/index.js");
|
|
92
|
+
if (workflow) {
|
|
93
|
+
for (const [path, hash] of Object.entries(workflow.files)) {
|
|
94
|
+
(0, artifact_1.safePath)(path);
|
|
95
|
+
let source = root;
|
|
96
|
+
for (const part of path.split("/")) {
|
|
97
|
+
source = (0, node_path_1.join)(source, part);
|
|
98
|
+
if ((0, node_fs_1.lstatSync)(source).isSymbolicLink())
|
|
99
|
+
throw new Error(`Workflow runtime cannot be a symlink: ${path}`);
|
|
100
|
+
}
|
|
101
|
+
if ((0, artifact_1.fileHash)(source) !== hash)
|
|
102
|
+
throw new Error(`Workflow runtime changed: ${path}; export again`);
|
|
103
|
+
const destination = (0, node_path_1.join)(staged, "workflow-runtime", path);
|
|
104
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(destination), { recursive: true });
|
|
105
|
+
(0, node_fs_1.cpSync)(source, destination);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (npmFiles) {
|
|
109
|
+
for (const [path, content] of Object.entries(npmFiles)) {
|
|
110
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)((0, node_path_1.join)(staged, path)), { recursive: true });
|
|
111
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(staged, path), content);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const result = await (0, esbuild_1.build)({
|
|
115
|
+
absWorkingDir: root,
|
|
116
|
+
stdin: {
|
|
117
|
+
contents: runnerSource,
|
|
118
|
+
resolveDir: root,
|
|
119
|
+
sourcefile: "octonode-entry.ts",
|
|
120
|
+
loader: "ts",
|
|
121
|
+
},
|
|
122
|
+
outfile: runner,
|
|
123
|
+
bundle: true,
|
|
124
|
+
external: npmFiles ? ["../nodes/npm.cjs"] : [],
|
|
125
|
+
platform: "node",
|
|
126
|
+
format: "cjs",
|
|
127
|
+
target: "node24",
|
|
128
|
+
metafile: true,
|
|
129
|
+
logLevel: "silent",
|
|
130
|
+
legalComments: "eof",
|
|
131
|
+
banner: {
|
|
132
|
+
js: 'globalThis.console = new (require("node:console").Console)({ stdout: process.stderr, stderr: process.stderr });',
|
|
133
|
+
},
|
|
134
|
+
logOverride: {
|
|
135
|
+
"unsupported-require-call": "warning",
|
|
136
|
+
"unsupported-dynamic-import": "warning",
|
|
137
|
+
"empty-import-meta": "error",
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
// esbuild cannot make computed imports or native modules portable. Fail instead of shipping a broken bundle.
|
|
141
|
+
if (result.warnings.length)
|
|
142
|
+
throw new Error(result.warnings.map((warning) => warning.text).join("\n"));
|
|
143
|
+
for (const info of Object.values(result.metafile.outputs)) {
|
|
144
|
+
for (const dependency of info.imports) {
|
|
145
|
+
if (dependency.external &&
|
|
146
|
+
!(0, node_module_1.isBuiltin)(dependency.path) &&
|
|
147
|
+
!(npmFiles && dependency.path === "../nodes/npm.cjs"))
|
|
148
|
+
throw new Error(`Unbundled dependency: ${dependency.path}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const metadata = { manifest: manifestDefinition, assets: definition.assets };
|
|
152
|
+
const manifest = plugins_1.PluginManifest.parse(metadata.manifest);
|
|
153
|
+
if (!manifest.nodes.length)
|
|
154
|
+
throw new Error(`Plugin ${manifest.id} must expose at least one node`);
|
|
155
|
+
if (prepared.some((plugin) => plugin.manifest.id === manifest.id))
|
|
156
|
+
throw new Error(`Duplicate plugin id: ${manifest.id}`);
|
|
157
|
+
const uiDeclarations = manifest.nodes.flatMap((node) => Object.entries(node.ui?.renderers ?? {}).flatMap(([renderer, definition]) => Object.entries(definition.targets).map(([target, path]) => ({
|
|
158
|
+
nodeId: node.id,
|
|
159
|
+
apiVersion: node.ui.apiVersion,
|
|
160
|
+
renderer,
|
|
161
|
+
target: target,
|
|
162
|
+
path,
|
|
163
|
+
}))));
|
|
164
|
+
const uiEntries = [...new Set(uiDeclarations.map(({ path }) => path))];
|
|
165
|
+
for (const entry of uiEntries) {
|
|
166
|
+
(0, artifact_1.safePath)(entry);
|
|
167
|
+
if (constants_1.RESERVED_ASSETS.has(entry.split("/")[0]))
|
|
168
|
+
throw new Error(`UI entry overwrites a generated file: ${entry}`);
|
|
169
|
+
}
|
|
170
|
+
if (!Array.isArray(metadata.assets) || metadata.assets.some((path) => typeof path !== "string"))
|
|
171
|
+
throw new Error("assets must be an array of file paths");
|
|
172
|
+
for (const asset of metadata.assets) {
|
|
173
|
+
(0, artifact_1.safePath)(asset);
|
|
174
|
+
if (uiEntries.includes(asset))
|
|
175
|
+
throw new Error(`Asset duplicates a UI entry: ${asset}`);
|
|
176
|
+
if (constants_1.RESERVED_ASSETS.has(asset.split("/")[0]))
|
|
177
|
+
throw new Error(`Asset overwrites a generated file: ${asset}`);
|
|
178
|
+
let current = root;
|
|
179
|
+
for (const part of asset.split("/")) {
|
|
180
|
+
current = (0, node_path_1.join)(current, part);
|
|
181
|
+
if ((0, node_fs_1.lstatSync)(current).isSymbolicLink())
|
|
182
|
+
throw new Error(`Asset cannot be a symbolic link: ${asset}`);
|
|
183
|
+
}
|
|
184
|
+
if (!(0, node_fs_1.lstatSync)(current).isFile())
|
|
185
|
+
throw new Error(`Declare individual asset files: ${asset}`);
|
|
186
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)((0, node_path_1.join)(staged, asset)), { recursive: true });
|
|
187
|
+
(0, node_fs_1.cpSync)(current, (0, node_path_1.join)(staged, asset));
|
|
188
|
+
}
|
|
189
|
+
for (const entry of uiEntries) {
|
|
190
|
+
let current = root;
|
|
191
|
+
for (const part of entry.split("/")) {
|
|
192
|
+
current = (0, node_path_1.join)(current, part);
|
|
193
|
+
if ((0, node_fs_1.lstatSync)(current).isSymbolicLink())
|
|
194
|
+
throw new Error(`UI entry cannot be a symbolic link: ${entry}`);
|
|
195
|
+
}
|
|
196
|
+
if (!(0, node_fs_1.lstatSync)(current).isFile())
|
|
197
|
+
throw new Error(`UI entry must be a file: ${entry}`);
|
|
198
|
+
directory(staged, (0, node_path_1.dirname)(entry));
|
|
199
|
+
const ui = await (0, esbuild_1.build)({
|
|
200
|
+
absWorkingDir: root,
|
|
201
|
+
stdin: {
|
|
202
|
+
contents: `import extension from ${JSON.stringify(current)}; import { startExtension } from "@octonodes/ui-extensions/react"; startExtension(extension);`,
|
|
203
|
+
resolveDir: root,
|
|
204
|
+
sourcefile: "octonode-ui-entry.ts",
|
|
205
|
+
loader: "ts",
|
|
206
|
+
},
|
|
207
|
+
outfile: (0, node_path_1.join)(staged, entry),
|
|
208
|
+
bundle: true,
|
|
209
|
+
platform: "browser",
|
|
210
|
+
format: "iife",
|
|
211
|
+
target: "es2021",
|
|
212
|
+
minify: true,
|
|
213
|
+
metafile: true,
|
|
214
|
+
logLevel: "silent",
|
|
215
|
+
legalComments: "eof",
|
|
216
|
+
});
|
|
217
|
+
if (ui.warnings.length)
|
|
218
|
+
throw new Error(ui.warnings.map((warning) => warning.text).join("\n"));
|
|
219
|
+
if (Object.values(ui.metafile.outputs).some((output) => output.imports.some((dependency) => dependency.external)))
|
|
220
|
+
throw new Error(`UI entry has an unbundled dependency: ${entry}`);
|
|
221
|
+
if ((0, node_fs_1.statSync)((0, node_path_1.join)(staged, entry)).size > plugins_1.PLUGIN_UI_BUNDLE_MAX_BYTES)
|
|
222
|
+
throw new Error(`UI entry exceeds 512 KiB: ${entry}`);
|
|
223
|
+
}
|
|
224
|
+
const serialized = JSON.stringify(manifest);
|
|
225
|
+
(0, node_fs_1.writeFileSync)(runner, (0, node_fs_1.readFileSync)(runner, "utf8") +
|
|
226
|
+
`\nif (require.main === module) {
|
|
227
|
+
if (JSON.stringify(module.exports.plugin.manifest) !== ${JSON.stringify(serialized)}) throw new Error("Plugin definition changed at runtime; keep metadata independent of the environment");
|
|
228
|
+
module.exports.startPlugin(module.exports.plugin);
|
|
229
|
+
}\n`);
|
|
230
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(staged, "octonode.yml"), (0, yaml_1.stringify)({ apiVersion: plugins_1.SETTINGS_API_VERSION, plugin: manifest }));
|
|
231
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(staged, "package.json"), JSON.stringify({
|
|
232
|
+
name: `octonode-plugin-${manifest.id}`,
|
|
233
|
+
version: manifest.version,
|
|
234
|
+
private: true,
|
|
235
|
+
type: "commonjs",
|
|
236
|
+
engines: { node: ">=24" },
|
|
237
|
+
license: manifest.license,
|
|
238
|
+
...(workflow ? { dependencies: workflow.dependencies } : {}),
|
|
239
|
+
}, null, 2) + "\n");
|
|
240
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(staged, "README.md"), `# ${manifest.name}\n\n${manifest.description ?? ""}\n\n${manifest.nodes
|
|
241
|
+
.map((node) => `## ${node.label ?? node.id}\n\n${node.description ?? ""}\n\nNode: \`${manifest.id}/${node.id}\`\n\nInputs:\n\`\`\`json\n${JSON.stringify(node.inputs ?? {}, null, 2)}\n\`\`\`\n\nOutputs:\n\`\`\`json\n${JSON.stringify(node.outputs ?? {}, null, 2)}\n\`\`\`\n`)
|
|
242
|
+
.join("\n")}\nCredentials (supplied by each installer):\n\`\`\`json\n${JSON.stringify(manifest.connections ?? {}, null, 2)}\n\`\`\`\n`);
|
|
243
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(staged, constants_1.BUILD_RECORD), JSON.stringify({
|
|
244
|
+
format: 1,
|
|
245
|
+
files: Object.fromEntries((0, artifact_1.pluginFiles)(staged).map((file) => [file, (0, artifact_1.fileHash)((0, node_path_1.join)(staged, file))])),
|
|
246
|
+
ui: uiDeclarations.map((declaration) => ({
|
|
247
|
+
...declaration,
|
|
248
|
+
size: (0, node_fs_1.statSync)((0, node_path_1.join)(staged, declaration.path)).size,
|
|
249
|
+
sha256: (0, artifact_1.fileHash)((0, node_path_1.join)(staged, declaration.path)),
|
|
250
|
+
})),
|
|
251
|
+
}, null, 2) + "\n");
|
|
252
|
+
(0, artifact_1.verifyBuild)(staged);
|
|
253
|
+
const destination = (0, node_path_1.join)(output, manifest.id);
|
|
254
|
+
// Only replace a complete, unchanged artifact produced by this builder.
|
|
255
|
+
if ((0, node_fs_1.existsSync)(destination))
|
|
256
|
+
(0, artifact_1.verifyBuild)(destination);
|
|
257
|
+
prepared.push({ manifest, directory: destination, staged });
|
|
258
|
+
}
|
|
259
|
+
for (const [index, plugin] of prepared.entries()) {
|
|
260
|
+
const backup = (0, node_path_1.join)(staging, `previous-${index}`);
|
|
261
|
+
if ((0, node_fs_1.existsSync)(plugin.directory))
|
|
262
|
+
(0, node_fs_1.renameSync)(plugin.directory, backup);
|
|
263
|
+
try {
|
|
264
|
+
(0, node_fs_1.renameSync)(plugin.staged, plugin.directory);
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
if ((0, node_fs_1.existsSync)(backup))
|
|
268
|
+
(0, node_fs_1.renameSync)(backup, plugin.directory);
|
|
269
|
+
throw error;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return prepared.map(({ manifest, directory }) => ({ manifest, directory }));
|
|
273
|
+
}
|
|
274
|
+
finally {
|
|
275
|
+
(0, node_fs_1.rmSync)(staging, { recursive: true, force: true });
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/plugins/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const BUILD_RECORD = "octonode-build.json";
|
|
2
|
+
export declare const DEFINITION_FILES: string[];
|
|
3
|
+
export declare const FORBIDDEN_PART: RegExp;
|
|
4
|
+
export declare const RESERVED_ASSETS: Set<string>;
|
|
5
|
+
export declare const PLUGIN_HELP = "Usage:\n octonodes plugin create <name>\n octonodes plugin nodes [--check]\n octonodes plugin build [octonode.plugin.ts]\n octonodes plugin validate <built-directory>\n octonodes plugin test <built-directory> [node-id] --input <json>\n octonodes plugin publish <built-directory> --registry <url> [--org <id>] [--team <id>]\n\nBuild reads octonode.plugin.ts and writes dist/plugins/<id>.\nNode inventories are generated in octonode.nodes.ts. Metadata is inspected without execution.\nPublishing uses OCTONODE_MARKETPLACE_URL and OCTONODE_MARKETPLACE_TOKEN when set,\nor the saved octonodes login / OCTONODE_TOKEN. It never publishes to npm.\n";
|
|
6
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/plugins/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,wBAAwB,CAAC;AAClD,eAAO,MAAM,gBAAgB,UAA6E,CAAC;AAC3G,eAAO,MAAM,cAAc,QAA4D,CAAC;AACxF,eAAO,MAAM,eAAe,aAQ1B,CAAC;AACH,eAAO,MAAM,WAAW,4oBAYvB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PLUGIN_HELP = exports.RESERVED_ASSETS = exports.FORBIDDEN_PART = exports.DEFINITION_FILES = exports.BUILD_RECORD = void 0;
|
|
4
|
+
exports.BUILD_RECORD = "octonode-build.json";
|
|
5
|
+
exports.DEFINITION_FILES = ["octonode.yml", "octonode.yaml", "octonode.json", "octonode.plugin.json"];
|
|
6
|
+
exports.FORBIDDEN_PART = /^(?:\.env(?:\..*)?|\.git|node_modules)$|\.(?:pem|key)$/i;
|
|
7
|
+
exports.RESERVED_ASSETS = new Set([
|
|
8
|
+
...exports.DEFINITION_FILES,
|
|
9
|
+
exports.BUILD_RECORD,
|
|
10
|
+
"package.json",
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"nodes",
|
|
14
|
+
"workflow-runtime",
|
|
15
|
+
]);
|
|
16
|
+
exports.PLUGIN_HELP = `Usage:
|
|
17
|
+
octonodes plugin create <name>
|
|
18
|
+
octonodes plugin nodes [--check]
|
|
19
|
+
octonodes plugin build [octonode.plugin.ts]
|
|
20
|
+
octonodes plugin validate <built-directory>
|
|
21
|
+
octonodes plugin test <built-directory> [node-id] --input <json>
|
|
22
|
+
octonodes plugin publish <built-directory> --registry <url> [--org <id>] [--team <id>]
|
|
23
|
+
|
|
24
|
+
Build reads octonode.plugin.ts and writes dist/plugins/<id>.
|
|
25
|
+
Node inventories are generated in octonode.nodes.ts. Metadata is inspected without execution.
|
|
26
|
+
Publishing uses OCTONODE_MARKETPLACE_URL and OCTONODE_MARKETPLACE_TOKEN when set,
|
|
27
|
+
or the saved octonodes login / OCTONODE_TOKEN. It never publishes to npm.
|
|
28
|
+
`;
|
|
29
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/plugins/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,YAAY,GAAG,qBAAqB,CAAC;AACrC,QAAA,gBAAgB,GAAG,CAAC,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,sBAAsB,CAAC,CAAC;AAC9F,QAAA,cAAc,GAAG,yDAAyD,CAAC;AAC3E,QAAA,eAAe,GAAG,IAAI,GAAG,CAAC;IACrC,GAAG,QAAA,gBAAgB;IACnB,QAAA,YAAY;IACZ,cAAc;IACd,MAAM;IACN,WAAW;IACX,OAAO;IACP,kBAAkB;CACnB,CAAC,CAAC;AACU,QAAA,WAAW,GAAG;;;;;;;;;;;;CAY1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/plugins/create.ts"],"names":[],"mappings":"AAIA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAiFlE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createPlugin = createPlugin;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const compiler_1 = require("@octonodes/sdk/definitions/compiler");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
function createPlugin(name, version) {
|
|
8
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(name))
|
|
9
|
+
throw new Error("Plugin name must be lowercase alphanumeric/dash");
|
|
10
|
+
const root = (0, node_path_1.resolve)(name);
|
|
11
|
+
(0, node_fs_1.mkdirSync)(root); // Never overwrite an existing project.
|
|
12
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(root, "src"));
|
|
13
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(root, "tests"));
|
|
14
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "package.json"), JSON.stringify({
|
|
15
|
+
name,
|
|
16
|
+
private: true,
|
|
17
|
+
engines: { node: ">=24" },
|
|
18
|
+
scripts: {
|
|
19
|
+
build: "octonodes plugin build",
|
|
20
|
+
test: "npm run build && node --test tests/*.test.cjs",
|
|
21
|
+
},
|
|
22
|
+
dependencies: { "@octonodes/sdk": version },
|
|
23
|
+
devDependencies: {
|
|
24
|
+
"@octonodes/cli": version,
|
|
25
|
+
typescript: "5.9.3",
|
|
26
|
+
"@types/node": "^24.0.0",
|
|
27
|
+
},
|
|
28
|
+
}, null, 2) + "\n");
|
|
29
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "tsconfig.json"), JSON.stringify({
|
|
30
|
+
compilerOptions: {
|
|
31
|
+
target: "ES2024",
|
|
32
|
+
module: "Node16",
|
|
33
|
+
strict: true,
|
|
34
|
+
skipLibCheck: true,
|
|
35
|
+
noEmit: true,
|
|
36
|
+
},
|
|
37
|
+
include: ["octonode.plugin.ts", "octonode.nodes.ts", "src/**/*.ts"],
|
|
38
|
+
}, null, 2) + "\n");
|
|
39
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, ".gitignore"), "node_modules/\ndist/\n.env\n.env.*\n");
|
|
40
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "src/echo.ts"), "export function echo(text: string): { text: string } { return { text }; }\n");
|
|
41
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "octonode.plugin.ts"), `import { definePlugin, defineNode } from "@octonodes/sdk/plugin";
|
|
42
|
+
import { nodes } from "./octonode.nodes.js";
|
|
43
|
+
export default definePlugin({
|
|
44
|
+
id: ${JSON.stringify(name)}, name: ${JSON.stringify(name)}, version: "0.1.0", license: "MIT",
|
|
45
|
+
nodes: [defineNode(nodes.echo, { label: "Echo text", defaults: { text: "hello" } })],
|
|
46
|
+
});
|
|
47
|
+
`);
|
|
48
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "tests/plugin.test.cjs"), `const { test } = require("node:test");
|
|
49
|
+
const assert = require("node:assert/strict");
|
|
50
|
+
const { execFileSync } = require("node:child_process");
|
|
51
|
+
test("echo runs through the packaged plugin", () => {
|
|
52
|
+
const result = JSON.parse(execFileSync(process.execPath, ["dist/index.js", "echo"], {
|
|
53
|
+
cwd: ${JSON.stringify(`dist/plugins/${name}`)}, encoding: "utf8",
|
|
54
|
+
input: JSON.stringify({octonode:"1",type:"invoke",invocationId:"test",inputs:{text:"hello"}}),
|
|
55
|
+
}));
|
|
56
|
+
assert.equal(result.status, "ok");
|
|
57
|
+
assert.deepEqual(result.outputs, {text:"hello"});
|
|
58
|
+
});
|
|
59
|
+
`);
|
|
60
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "README.md"), `# ${name}\n\nRun \`npm install\`, then \`npm test\`. Keep all definitions in \`octonode.plugin.ts\`; import handles from \`octonode.nodes.ts\` and implement functions in \`src/\`.\n\nAll metadata belongs in code; \`dist/plugins/<id>/octonode.yml\` is generated.\nSet \`scope: ["public"]\` to share publicly. Configure \`OCTONODE_MARKETPLACE_URL\`, run \`octonodes login\`, then \`octonodes plugin publish dist/plugins/${name}\`.\nConfig compilation reads definitions without executing application code. Keep secrets out of definitions and assets.\n`);
|
|
61
|
+
(0, compiler_1.generateNodeCatalog)(root);
|
|
62
|
+
return root;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/plugins/create.ts"],"names":[],"mappings":";;;AAAA,qCAAmD;AACnD,kEAA0E;AAC1E,yCAA0C;AAE1C,sBAA6B,IAAY,EAAE,OAAe;IACxD,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC3G,MAAM,IAAI,GAAG,IAAA,mBAAO,EAAC,IAAI,CAAC,CAAC;IAC3B,IAAA,mBAAS,EAAC,IAAI,CAAC,CAAC,CAAC,uCAAuC;IACxD,IAAA,mBAAS,EAAC,IAAA,gBAAI,EAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7B,IAAA,mBAAS,EAAC,IAAA,gBAAI,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/B,IAAA,uBAAa,EACX,IAAA,gBAAI,EAAC,IAAI,EAAE,cAAc,CAAC,EAC1B,IAAI,CAAC,SAAS,CACZ;QACE,IAAI;QACJ,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;QACzB,OAAO,EAAE;YACP,KAAK,EAAE,wBAAwB;YAC/B,IAAI,EAAE,+CAA+C;SACtD;QACD,YAAY,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE;QAC3C,eAAe,EAAE;YACf,gBAAgB,EAAE,OAAO;YACzB,UAAU,EAAE,OAAO;YACnB,aAAa,EAAE,SAAS;SACzB;KACF,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,CACT,CAAC;IACF,IAAA,uBAAa,EACX,IAAA,gBAAI,EAAC,IAAI,EAAE,eAAe,CAAC,EAC3B,IAAI,CAAC,SAAS,CACZ;QACE,eAAe,EAAE;YACf,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,IAAI;YACZ,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,IAAI;SACb;QACD,OAAO,EAAE,CAAC,oBAAoB,EAAE,mBAAmB,EAAE,aAAa,CAAC;KACpE,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,CACT,CAAC;IACF,IAAA,uBAAa,EAAC,IAAA,gBAAI,EAAC,IAAI,EAAE,YAAY,CAAC,EAAE,sCAAsC,CAAC,CAAC;IAChF,IAAA,uBAAa,EACX,IAAA,gBAAI,EAAC,IAAI,EAAE,aAAa,CAAC,EACzB,6EAA6E,CAC9E,CAAC;IACF,IAAA,uBAAa,EACX,IAAA,gBAAI,EAAC,IAAI,EAAE,oBAAoB,CAAC,EAChC;;;QAGI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;;;CAG1D,CACE,CAAC;IACF,IAAA,uBAAa,EACX,IAAA,gBAAI,EAAC,IAAI,EAAE,uBAAuB,CAAC,EACnC;;;;;WAKO,IAAI,CAAC,SAAS,CAAC,gBAAgB,IAAI,EAAE,CAAC;;;;;;CAMhD,CACE,CAAC;IACF,IAAA,uBAAa,EACX,IAAA,gBAAI,EAAC,IAAI,EAAE,WAAW,CAAC,EACvB,KAAK,IAAI,4ZAA4Z,IAAI,6HAA6H,CACviB,CAAC;IACF,IAAA,8BAAmB,EAAC,IAAI,CAAC,CAAC;IAC1B,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoElF"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PLUGIN_HELP = void 0;
|
|
4
|
+
exports.pluginCommand = pluginCommand;
|
|
5
|
+
const node_child_process_1 = require("node:child_process");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const node_util_1 = require("node:util");
|
|
8
|
+
const auth_1 = require("../auth");
|
|
9
|
+
const artifact_1 = require("./artifact");
|
|
10
|
+
const build_1 = require("./build");
|
|
11
|
+
const create_1 = require("./create");
|
|
12
|
+
const publish_1 = require("./publish");
|
|
13
|
+
const compiler_1 = require("@octonodes/sdk/definitions/compiler");
|
|
14
|
+
var constants_1 = require("./constants");
|
|
15
|
+
Object.defineProperty(exports, "PLUGIN_HELP", { enumerable: true, get: function () { return constants_1.PLUGIN_HELP; } });
|
|
16
|
+
async function pluginCommand(args, version) {
|
|
17
|
+
const command = args[0];
|
|
18
|
+
const { values, positionals } = (0, node_util_1.parseArgs)({
|
|
19
|
+
args: args.slice(1),
|
|
20
|
+
allowPositionals: true,
|
|
21
|
+
options: {
|
|
22
|
+
input: { type: "string" },
|
|
23
|
+
registry: { type: "string" },
|
|
24
|
+
org: { type: "string" },
|
|
25
|
+
team: { type: "string" },
|
|
26
|
+
check: { type: "boolean" },
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
const [target, nodeId] = positionals;
|
|
30
|
+
if (command === "nodes") {
|
|
31
|
+
(0, compiler_1.generateNodeCatalog)(process.cwd(), undefined, values.check);
|
|
32
|
+
process.stdout.write(values.check ? "Node inventory is current\n" : "Node inventory generated\n");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (positionals.length > (command === "test" ? 2 : 1))
|
|
36
|
+
throw new Error("Too many plugin command arguments");
|
|
37
|
+
if (command === "build") {
|
|
38
|
+
process.stdout.write(JSON.stringify(await (0, build_1.buildPlugins)(target), null, 2) + "\n");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!target)
|
|
42
|
+
throw new Error(`plugin ${command ?? "command"} requires a target; run octonodes plugin --help`);
|
|
43
|
+
if (command === "create") {
|
|
44
|
+
process.stdout.write(`Created ${(0, create_1.createPlugin)(target, version)}\nNext: npm install, then npm test in that directory.\n`);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const directory = (0, node_path_1.resolve)(target);
|
|
48
|
+
if (command === "validate") {
|
|
49
|
+
process.stdout.write(JSON.stringify((0, artifact_1.verifyBuild)(directory).manifest, null, 2) + "\n");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (command === "test") {
|
|
53
|
+
const { manifest } = (0, artifact_1.verifyBuild)(directory);
|
|
54
|
+
const selected = nodeId ?? (manifest.nodes.length === 1 ? manifest.nodes[0].id : undefined);
|
|
55
|
+
if (!manifest.nodes.some((node) => node.id === selected))
|
|
56
|
+
throw new Error(`Choose a node: ${manifest.nodes.map((node) => node.id).join(", ")}`);
|
|
57
|
+
const output = (0, node_child_process_1.execFileSync)(process.execPath, ["--experimental-import-meta-resolve", "dist/index.js", selected], {
|
|
58
|
+
cwd: directory,
|
|
59
|
+
encoding: "utf8",
|
|
60
|
+
timeout: 30_000,
|
|
61
|
+
input: JSON.stringify({
|
|
62
|
+
octonode: "1",
|
|
63
|
+
type: "invoke",
|
|
64
|
+
invocationId: "plugin-test",
|
|
65
|
+
inputs: JSON.parse(values.input ?? "{}"),
|
|
66
|
+
}) + "\n",
|
|
67
|
+
});
|
|
68
|
+
process.stdout.write(output);
|
|
69
|
+
if (JSON.parse(output).status !== "ok")
|
|
70
|
+
throw new Error("Plugin test failed");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (command === "publish") {
|
|
74
|
+
const registry = values.registry ?? process.env.OCTONODE_MARKETPLACE_URL;
|
|
75
|
+
if (!registry)
|
|
76
|
+
throw new Error("Set OCTONODE_MARKETPLACE_URL or pass --registry <url>");
|
|
77
|
+
const token = process.env.OCTONODE_MARKETPLACE_TOKEN ?? (await (0, auth_1.accessToken)());
|
|
78
|
+
if (!token)
|
|
79
|
+
throw new Error('Run "octonodes login" or set OCTONODE_TOKEN');
|
|
80
|
+
process.stdout.write(JSON.stringify(await (0, publish_1.publishPlugin)(directory, registry, token, values.org, values.team), null, 2) + "\n");
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
throw new Error(`Unknown plugin command: ${command}`);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/plugins/publish.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC,CAmDlB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.publishPlugin = publishPlugin;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_os_1 = require("node:os");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const artifact_1 = require("./artifact");
|
|
9
|
+
async function publishPlugin(directory, registry, token, orgId, teamId) {
|
|
10
|
+
const url = new URL(registry);
|
|
11
|
+
if (url.username ||
|
|
12
|
+
url.password ||
|
|
13
|
+
url.search ||
|
|
14
|
+
url.hash ||
|
|
15
|
+
(url.protocol !== "https:" &&
|
|
16
|
+
!(url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname)))) {
|
|
17
|
+
throw new Error("Registry must use HTTPS (HTTP is allowed only on loopback)");
|
|
18
|
+
}
|
|
19
|
+
const temp = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "octonodes-publish-"));
|
|
20
|
+
try {
|
|
21
|
+
const verified = (0, artifact_1.verifyBuild)(directory);
|
|
22
|
+
const snapshot = (0, node_path_1.join)(temp, "plugin");
|
|
23
|
+
(0, node_fs_1.mkdirSync)(snapshot);
|
|
24
|
+
for (const file of verified.files) {
|
|
25
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)((0, node_path_1.join)(snapshot, file)), { recursive: true });
|
|
26
|
+
(0, node_fs_1.cpSync)((0, node_path_1.join)(directory, file), (0, node_path_1.join)(snapshot, file));
|
|
27
|
+
}
|
|
28
|
+
const { manifest, files } = (0, artifact_1.verifyBuild)(snapshot);
|
|
29
|
+
const bundle = (0, node_path_1.join)(temp, "bundle.tar.gz");
|
|
30
|
+
(0, node_child_process_1.execFileSync)("tar", ["-czf", bundle, "-C", snapshot, "--", ...files]);
|
|
31
|
+
const form = new FormData();
|
|
32
|
+
form.set("manifest", JSON.stringify(manifest));
|
|
33
|
+
form.set("bundle", new Blob([(0, node_fs_1.readFileSync)(bundle)], { type: "application/gzip" }), "bundle.tar.gz");
|
|
34
|
+
if (orgId)
|
|
35
|
+
form.set("orgId", orgId);
|
|
36
|
+
if (teamId)
|
|
37
|
+
form.set("teamId", teamId);
|
|
38
|
+
const response = await fetch(`${registry.replace(/\/$/, "")}/marketplace/plugins/${encodeURIComponent(manifest.id)}/versions`, {
|
|
39
|
+
method: "POST",
|
|
40
|
+
headers: { authorization: `Bearer ${token}` },
|
|
41
|
+
body: form,
|
|
42
|
+
redirect: "error",
|
|
43
|
+
signal: AbortSignal.timeout(120_000),
|
|
44
|
+
});
|
|
45
|
+
if (!response.ok)
|
|
46
|
+
throw new Error(`Plugin publish failed (HTTP ${response.status}): ${(await response.text()).slice(0, 1000)}`);
|
|
47
|
+
return response.json();
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
(0, node_fs_1.rmSync)(temp, { recursive: true, force: true });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=publish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/plugins/publish.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PluginManifest } from "@octonodes/sdk/plugins";
|
|
2
|
+
export interface PluginBuild {
|
|
3
|
+
manifest: PluginManifest;
|
|
4
|
+
directory: string;
|
|
5
|
+
}
|
|
6
|
+
export interface PluginBuildRecord {
|
|
7
|
+
format: 1;
|
|
8
|
+
files: Record<string, string>;
|
|
9
|
+
ui?: Array<{
|
|
10
|
+
nodeId: string;
|
|
11
|
+
apiVersion: "1";
|
|
12
|
+
renderer: string;
|
|
13
|
+
target: "node.inspector.inputs";
|
|
14
|
+
path: string;
|
|
15
|
+
size: number;
|
|
16
|
+
sha256: string;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plugins/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,CAAC,CAAC;IACV,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,EAAE,CAAC,EAAE,KAAK,CAAC;QACT,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,GAAG,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,uBAAuB,CAAC;QAChC,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ"}
|