@aiot-nexus/plugin-sdk 1.0.0 → 1.0.2

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/src/dev.js CHANGED
@@ -23,11 +23,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.preparePluginDev = exports.runPluginDev = exports.PluginDevError = void 0;
26
+ exports.buildPluginRendererForDevelopment = exports.buildPluginForDevelopment = exports.preparePluginBrowserDebugTarget = exports.preparePluginDebugTarget = exports.preparePluginDev = exports.runPluginDev = exports.PluginDevError = void 0;
27
27
  const child_process_1 = require("child_process");
28
28
  const fs = __importStar(require("fs"));
29
29
  const module_1 = require("module");
30
30
  const path = __importStar(require("path"));
31
+ const plugin_framework_version_1 = require("../.generated/plugin-framework-version");
31
32
  const validation_1 = require("./validation");
32
33
  class PluginDevError extends Error {
33
34
  constructor(message) {
@@ -43,12 +44,13 @@ function runPluginDev(options, io) {
43
44
  assertPluginProject(projectDirectory);
44
45
  if (options.build) {
45
46
  io.stdout("Building plugin with development source maps: " + projectDirectory);
46
- runProjectBuild(projectDirectory);
47
+ buildPluginForDevelopment(projectDirectory);
47
48
  }
48
49
  const target = preparePluginDev({ ...options, projectDirectory });
49
50
  io.stdout("Starting plugin dev host: " + target.pluginId
50
51
  + "\nPlugin package: " + target.packageDirectory
51
- + "\nContribution: " + target.surface + ":" + target.contributionId);
52
+ + "\nContribution: " + target.surface + ":" + target.contributionId
53
+ + "\nSimulated Nexus application version: " + target.hostVersion);
52
54
  if (options.inspectorMode) {
53
55
  io.stdout("Main process debugger: " + options.inspectorMode
54
56
  + " on 127.0.0.1:" + String(options.inspectorPort || 9229));
@@ -57,7 +59,7 @@ function runPluginDev(options, io) {
57
59
  if (options.inspectorMode) {
58
60
  electronArgs.push("--" + options.inspectorMode + "=" + String(options.inspectorPort || 9229));
59
61
  }
60
- electronArgs.push(target.devHostMainPath, "--plugin-package=" + target.packageDirectory, "--project-directory=" + target.projectDirectory, "--surface=" + target.surface, "--contribution-id=" + target.contributionId, "--language=" + target.language, "--theme=" + target.themeMode);
62
+ electronArgs.push(target.devHostMainPath, "--plugin-package=" + target.packageDirectory, "--project-directory=" + target.projectDirectory, "--surface=" + target.surface, "--contribution-id=" + target.contributionId, "--language=" + target.language, "--theme=" + target.themeMode, "--host-version=" + target.hostVersion);
61
63
  if (!options.openDevTools) {
62
64
  electronArgs.push("--no-devtools");
63
65
  }
@@ -79,39 +81,76 @@ function runPluginDev(options, io) {
79
81
  }
80
82
  exports.runPluginDev = runPluginDev;
81
83
  function preparePluginDev(options) {
84
+ const target = preparePluginDebugTarget(options);
85
+ const hostVersion = normalizeHostVersion(options.hostVersion || readDefaultHostVersion());
86
+ const hostVersionComparison = (0, plugin_framework_version_1.comparePluginVersions)(target.manifest.minHostVersion, hostVersion);
87
+ if (hostVersionComparison === undefined) {
88
+ throw new PluginDevError("Plugin or simulated Nexus application version is invalid.");
89
+ }
90
+ if (hostVersionComparison > 0) {
91
+ throw new PluginDevError("Plugin requires Nexus " + target.manifest.minHostVersion
92
+ + " or newer; simulated host version is " + hostVersion + ".");
93
+ }
94
+ const electronExecutable = resolveElectronExecutable(target.projectDirectory);
95
+ const devHostMainPath = path.join(resolvePackageRoot(), "dev-host", "main.js");
96
+ if (!fs.existsSync(devHostMainPath) || !fs.statSync(devHostMainPath).isFile()) {
97
+ throw new PluginDevError("Plugin SDK dev host is missing: " + devHostMainPath);
98
+ }
99
+ return {
100
+ ...target,
101
+ electronExecutable,
102
+ devHostMainPath,
103
+ hostVersion
104
+ };
105
+ }
106
+ exports.preparePluginDev = preparePluginDev;
107
+ function preparePluginDebugTarget(options) {
82
108
  const projectDirectory = path.resolve(options.projectDirectory);
83
109
  assertPluginProject(projectDirectory);
84
110
  const sourceManifest = readManifest(path.join(projectDirectory, "src", "manifest.json"), "Plugin source manifest");
85
111
  const packageDirectory = path.join(projectDirectory, "dist", sourceManifest.pluginId);
86
- const validation = (0, validation_1.validatePluginPackage)(packageDirectory);
112
+ return preparePluginDebugTargetFromPackage(options, projectDirectory, packageDirectory, sourceManifest, "package");
113
+ }
114
+ exports.preparePluginDebugTarget = preparePluginDebugTarget;
115
+ function preparePluginBrowserDebugTarget(options, packageKind = "auto") {
116
+ const projectDirectory = path.resolve(options.projectDirectory);
117
+ assertPluginProject(projectDirectory);
118
+ const sourceManifest = readManifest(path.join(projectDirectory, "src", "manifest.json"), "Plugin source manifest");
119
+ const webPackageDirectory = path.join(projectDirectory, ".nexus-plugin-dev", "web-package", sourceManifest.pluginId);
120
+ const packageDirectory = packageKind === "package"
121
+ ? path.join(projectDirectory, "dist", sourceManifest.pluginId)
122
+ : packageKind === "web" || fs.existsSync(webPackageDirectory)
123
+ ? webPackageDirectory
124
+ : path.join(projectDirectory, "dist", sourceManifest.pluginId);
125
+ return preparePluginDebugTargetFromPackage(options, projectDirectory, packageDirectory, sourceManifest, "renderer");
126
+ }
127
+ exports.preparePluginBrowserDebugTarget = preparePluginBrowserDebugTarget;
128
+ function preparePluginDebugTargetFromPackage(options, projectDirectory, packageDirectory, sourceManifest, validationTarget) {
129
+ const validation = (0, validation_1.validatePluginPackage)(packageDirectory, { target: validationTarget });
87
130
  if (!validation.valid) {
88
131
  throw new PluginDevError("Plugin package is not ready for debugging: " + packageDirectory
89
132
  + "\n" + validation.errors.map((error) => " - " + error).join("\n"));
90
133
  }
91
- const manifest = readManifest(path.join(packageDirectory, "manifest.json"), "Built plugin manifest");
92
- if (manifest.pluginId !== sourceManifest.pluginId) {
134
+ const manifestValue = readManifest(path.join(packageDirectory, "manifest.json"), "Built plugin manifest");
135
+ if (manifestValue.pluginId !== sourceManifest.pluginId) {
93
136
  throw new PluginDevError("Built plugin id does not match src/manifest.json.");
94
137
  }
95
- const contribution = resolveContribution(manifest, options.surface, options.contributionId);
96
- const electronExecutable = resolveElectronExecutable(projectDirectory);
97
- const devHostMainPath = path.join(resolvePackageRoot(), "dev-host", "main.js");
98
- if (!fs.existsSync(devHostMainPath) || !fs.statSync(devHostMainPath).isFile()) {
99
- throw new PluginDevError("Plugin SDK dev host is missing: " + devHostMainPath);
138
+ if (!manifestValue.rendererEntry) {
139
+ throw new PluginDevError("Built plugin rendererEntry is required for independent debugging.");
100
140
  }
141
+ const manifest = manifestValue;
142
+ const contribution = resolveContribution(manifest, options.surface, options.contributionId);
101
143
  return {
102
144
  projectDirectory,
103
145
  packageDirectory,
104
146
  pluginId: manifest.pluginId,
105
147
  manifest,
106
- electronExecutable,
107
- devHostMainPath,
108
148
  surface: contribution.surface,
109
149
  contributionId: contribution.contributionId,
110
150
  language: normalizeLanguage(options.language, manifest),
111
151
  themeMode: options.themeMode || "system"
112
152
  };
113
153
  }
114
- exports.preparePluginDev = preparePluginDev;
115
154
  function assertPluginProject(projectDirectory) {
116
155
  if (!fs.existsSync(projectDirectory) || !fs.statSync(projectDirectory).isDirectory()) {
117
156
  throw new PluginDevError("Plugin project directory does not exist: " + projectDirectory);
@@ -121,19 +160,61 @@ function assertPluginProject(projectDirectory) {
121
160
  throw new PluginDevError("Plugin project package.json is missing: " + packageJsonPath);
122
161
  }
123
162
  }
124
- function runProjectBuild(projectDirectory) {
163
+ function buildPluginForDevelopment(projectDirectory) {
164
+ runPluginBuildScript(projectDirectory, "build", "Plugin development build");
165
+ }
166
+ exports.buildPluginForDevelopment = buildPluginForDevelopment;
167
+ function buildPluginRendererForDevelopment(projectDirectory) {
168
+ if (hasPluginBuildScript(projectDirectory, "build:web")) {
169
+ runPluginBuildScript(projectDirectory, "build:web", "Plugin browser UI development build");
170
+ return "web";
171
+ }
172
+ buildPluginForDevelopment(projectDirectory);
173
+ return "package";
174
+ }
175
+ exports.buildPluginRendererForDevelopment = buildPluginRendererForDevelopment;
176
+ function runPluginBuildScript(projectDirectory, scriptName, label) {
177
+ assertPluginProject(projectDirectory);
178
+ if (!hasPluginBuildScript(projectDirectory, scriptName)) {
179
+ throw new PluginDevError("Plugin project is missing the npm script required for debugging: " + scriptName + ".");
180
+ }
125
181
  const command = process.platform === "win32" ? "npm.cmd" : "npm";
126
- const result = (0, child_process_1.spawnSync)(command, ["run", "build"], {
182
+ const result = (0, child_process_1.spawnSync)(command, ["run", scriptName], {
127
183
  cwd: projectDirectory,
128
184
  env: { ...process.env, NEXUS_PLUGIN_DEV: "1" },
129
185
  stdio: "inherit"
130
186
  });
131
187
  if (result.error) {
132
- throw new PluginDevError("Plugin development build could not start: " + result.error.message);
188
+ throw new PluginDevError(label + " could not start: " + result.error.message);
133
189
  }
134
190
  if (result.status !== 0) {
135
- throw new PluginDevError("Plugin development build failed with exit code " + String(result.status === null ? 1 : result.status) + ".");
191
+ throw new PluginDevError(label + " failed with exit code " + String(result.status === null ? 1 : result.status) + ".");
192
+ }
193
+ }
194
+ function hasPluginBuildScript(projectDirectory, scriptName) {
195
+ assertPluginProject(projectDirectory);
196
+ const packageJson = readJsonRecord(path.join(projectDirectory, "package.json"), "Plugin project package metadata");
197
+ const scripts = packageJson.scripts;
198
+ return Boolean(scripts
199
+ && typeof scripts === "object"
200
+ && !Array.isArray(scripts)
201
+ && typeof scripts[scriptName] === "string");
202
+ }
203
+ function readDefaultHostVersion() {
204
+ const metadataPath = path.join(resolvePackageRoot(), "dist", "dev-host-metadata.json");
205
+ const metadata = readJsonRecord(metadataPath, "Plugin SDK dev host metadata");
206
+ if (typeof metadata.nexusApplicationVersion !== "string") {
207
+ throw new PluginDevError("Plugin SDK dev host metadata does not contain a Nexus application version.");
208
+ }
209
+ return metadata.nexusApplicationVersion;
210
+ }
211
+ function normalizeHostVersion(value) {
212
+ const normalized = value.trim();
213
+ const match = /^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$/.exec(normalized);
214
+ if (!match || [match[1], match[2], match[3]].some((segment) => !Number.isSafeInteger(Number(segment)))) {
215
+ throw new PluginDevError("Simulated Nexus host version must use X.Y.Z format: " + value);
136
216
  }
217
+ return normalized;
137
218
  }
138
219
  function readManifest(filePath, label) {
139
220
  if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {
@@ -1,5 +1,5 @@
1
1
  import pluginManifestSchema from "../.generated/plugin-manifest.schema.json";
2
- export declare const PLUGIN_SDK_VERSION = "1.0.0";
2
+ export declare const PLUGIN_SDK_VERSION = "1.0.2";
3
3
  export { pluginManifestSchema };
4
4
  export * from "../.generated/plugin-framework-version";
5
5
  export * from "./types";
package/dist/src/index.js CHANGED
@@ -20,7 +20,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
20
20
  exports.pluginManifestSchema = exports.PLUGIN_SDK_VERSION = void 0;
21
21
  const plugin_manifest_schema_json_1 = __importDefault(require("../.generated/plugin-manifest.schema.json"));
22
22
  exports.pluginManifestSchema = plugin_manifest_schema_json_1.default;
23
- exports.PLUGIN_SDK_VERSION = "1.0.0";
23
+ exports.PLUGIN_SDK_VERSION = "1.0.2";
24
24
  __exportStar(require("../.generated/plugin-framework-version"), exports);
25
25
  __exportStar(require("./types"), exports);
26
26
  __exportStar(require("./browser/frame-client"), exports);
@@ -199,7 +199,9 @@ function vendorSdkArchive(pluginDirectory, sourcePath) {
199
199
  function createPackageJson(options, sdkSource) {
200
200
  const scripts = {
201
201
  build: "node scripts/build.js && npm run validate",
202
+ "build:web": "node scripts/build.js --renderer-only",
202
203
  dev: "nexus-plugin dev .",
204
+ "dev:web": "nexus-plugin dev:web .",
203
205
  "dev:debug": "nexus-plugin dev . --inspect-brk=9229",
204
206
  typecheck: "tsc -p tsconfig.main.json --noEmit && tsc -p tsconfig.renderer.json --noEmit",
205
207
  validate: "nexus-plugin validate dist/" + options.pluginId
@@ -6,4 +6,7 @@ export interface PluginPackageValidationResult {
6
6
  manifest?: PluginManifest;
7
7
  errors: string[];
8
8
  }
9
- export declare function validatePluginPackage(packageDirectory: string): PluginPackageValidationResult;
9
+ export interface PluginPackageValidationOptions {
10
+ target?: "package" | "renderer";
11
+ }
12
+ export declare function validatePluginPackage(packageDirectory: string, options?: PluginPackageValidationOptions): PluginPackageValidationResult;
@@ -34,17 +34,17 @@ const plugin_manifest_schema_json_1 = __importDefault(require("../.generated/plu
34
34
  const plugin_framework_version_1 = require("../.generated/plugin-framework-version");
35
35
  const manifestValidator = new _2020_1.default({ allErrors: true, strict: true })
36
36
  .compile(plugin_manifest_schema_json_1.default);
37
- function validatePluginPackage(packageDirectory) {
37
+ function validatePluginPackage(packageDirectory, options = {}) {
38
38
  const resolvedDirectory = path.resolve(packageDirectory);
39
39
  try {
40
- return validateResolvedPluginPackage(resolvedDirectory);
40
+ return validateResolvedPluginPackage(resolvedDirectory, options);
41
41
  }
42
42
  catch (error) {
43
43
  return invalid(resolvedDirectory, "Plugin package could not be inspected: " + errorMessage(error));
44
44
  }
45
45
  }
46
46
  exports.validatePluginPackage = validatePluginPackage;
47
- function validateResolvedPluginPackage(resolvedDirectory) {
47
+ function validateResolvedPluginPackage(resolvedDirectory, options) {
48
48
  const errors = [];
49
49
  if (!fs.existsSync(resolvedDirectory)) {
50
50
  return invalid(resolvedDirectory, "Plugin package directory does not exist.");
@@ -88,7 +88,7 @@ function validateResolvedPluginPackage(resolvedDirectory) {
88
88
  if (!(0, plugin_framework_version_1.parsePluginCompatibleVersion)(manifest.minHostVersion)) {
89
89
  errors.push("minHostVersion contains an unsupported numeric version.");
90
90
  }
91
- validateEntry(resolvedDirectory, "mainEntry", manifest.mainEntry, errors);
91
+ validateEntry(resolvedDirectory, "mainEntry", manifest.mainEntry, errors, options.target !== "renderer");
92
92
  validateEntry(resolvedDirectory, "rendererEntry", manifest.rendererEntry, errors);
93
93
  if (manifest.rendererEntry && path.extname(manifest.rendererEntry).toLowerCase() !== ".html") {
94
94
  errors.push("rendererEntry must point to an HTML file.");
@@ -104,7 +104,7 @@ function validateResolvedPluginPackage(resolvedDirectory) {
104
104
  errors
105
105
  };
106
106
  }
107
- function validateEntry(rootDirectory, fieldName, relativePath, errors) {
107
+ function validateEntry(rootDirectory, fieldName, relativePath, errors, requireExistingFile = true) {
108
108
  if (!relativePath) {
109
109
  return;
110
110
  }
@@ -118,7 +118,9 @@ function validateEntry(rootDirectory, fieldName, relativePath, errors) {
118
118
  return;
119
119
  }
120
120
  if (!fs.existsSync(entryPath)) {
121
- errors.push(fieldName + " does not exist: " + relativePath);
121
+ if (requireExistingFile) {
122
+ errors.push(fieldName + " does not exist: " + relativePath);
123
+ }
122
124
  return;
123
125
  }
124
126
  const entryStat = fs.lstatSync(entryPath);
@@ -0,0 +1,11 @@
1
+ /// <reference types="node" />
2
+ import * as http from "http";
3
+ import { type PluginDebugSelection, type PluginDebugTarget, type PluginDevIo } from "./dev";
4
+ export interface PluginWebDevOptions extends PluginDebugSelection {
5
+ build: boolean;
6
+ openBrowser: boolean;
7
+ port: number;
8
+ }
9
+ export declare function runPluginWebDev(options: PluginWebDevOptions, io: PluginDevIo): number;
10
+ export declare function createPluginWebDevServer(target: PluginDebugTarget, io: PluginDevIo): http.Server;
11
+ export declare function pluginWebDevServerUrl(server: http.Server): string;