@termix-ssh/plugin-sdk 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/PLUGIN-GUIDE.md +780 -0
  3. package/README.md +2 -1
  4. package/cli/commands/build.mjs +7 -7
  5. package/cli/commands/migrations.mjs +2 -2
  6. package/cli/commands/validate.mjs +5 -0
  7. package/cli/index.mjs +0 -0
  8. package/dist/changelog.d.ts +3 -1
  9. package/dist/changelog.js +12 -2
  10. package/dist/db.d.ts +1 -1
  11. package/dist/db.js +1 -1
  12. package/dist/ddl.js +4 -1
  13. package/dist/host/{chunk-RU4E5XLY.js → chunk-26DAYAKC.js} +323 -216
  14. package/dist/host/{chunk-O2OHNVFX.js → chunk-DIOJ3KW2.js} +1 -1
  15. package/dist/host/{chunk-F5RZH6HE.js → chunk-NZG6HNQH.js} +14 -13
  16. package/dist/host/core-classes.json +1 -1
  17. package/dist/host/{linked-server-4VWYYABP.js → linked-server-QAKKDBFM.js} +1 -1
  18. package/dist/host/{rbac-api-WIJVZH3M.js → rbac-api-5267EMX7.js} +1 -1
  19. package/dist/host/testing-host.js +3 -3
  20. package/dist/host/types/src/types/credential-sidebar-preferences.d.ts +1 -1
  21. package/dist/host/types/src/types/onboarding.d.ts +1 -0
  22. package/dist/host/types/src/ui/api/plugins-api.d.ts +51 -0
  23. package/dist/host/types/src/ui/components/panel-layout.d.ts +0 -4
  24. package/dist/host/types/src/ui/hooks/use-mobile.d.ts +1 -0
  25. package/dist/host/types/src/ui/i18n/i18n.d.ts +1 -36
  26. package/dist/host/types/src/ui/i18n/languages.d.ts +13 -0
  27. package/dist/host/types/src/ui/lib/error-message.d.ts +1 -1
  28. package/dist/host/types/src/ui/lib/host-key-fingerprint.d.ts +5 -0
  29. package/dist/host/types/src/ui/lib/server-time.d.ts +5 -0
  30. package/dist/host/types/src/ui/main-axios.d.ts +5 -2
  31. package/dist/host/types/src/ui/ssh/dialogs/HostKeyVerificationDialog.d.ts +1 -1
  32. package/dist/host/ui.js +439 -69
  33. package/dist/host/{use-permissions-KIQCJ35M.js → use-permissions-2P2TP6GY.js} +1 -1
  34. package/dist/host-commands.js +1 -1
  35. package/package.json +14 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
 
3
- <img src="https://raw.githubusercontent.com/Termix-SSH/Termix/main/public/icon.svg" width="120" height="120" alt="Termix Logo" />
3
+ <img src="https://termix.site/img/logo.svg" width="120" alt="Termix Logo" />
4
4
 
5
5
  <h1>Termix Plugin SDK</h1>
6
6
 
@@ -28,6 +28,7 @@ npm install --save-dev @termix-ssh/plugin-sdk
28
28
 
29
29
  ```bash
30
30
  npx termix-plugin build # bundle dist/backend.js and dist/frontend.js
31
+ npx termix-plugin patch # apply the plugin's dependency patches (build does this too)
31
32
  npx termix-plugin test # run the plugin's Vitest suite
32
33
  npx termix-plugin validate # check manifest.json and the files it names
33
34
  npx termix-plugin openapi # write dist/openapi.json from @openapi comments
@@ -108,13 +108,6 @@ const HOST_DIR = path.join(
108
108
  const THEME_CSS = path.join(HOST_DIR, "theme.css");
109
109
  const CORE_CLASSES = path.join(HOST_DIR, "core-classes.json");
110
110
 
111
- /**
112
- * Compiles the Tailwind classes the plugin's frontend uses into
113
- * dist/frontend.css, against the theme core ships in the SDK. Core only
114
- * compiles its own classes, so a class no core file happens to use would
115
- * otherwise have no CSS at all. Appended to whatever CSS the bundle already
116
- * produced (a library's stylesheet the plugin imports).
117
- */
118
111
  /**
119
112
  * Moves a plugin's Tailwind layers under their own names. Core orders
120
113
  * termix-plugin-utilities above its base styles and below its own utilities,
@@ -136,6 +129,13 @@ function readCoreClasses() {
136
129
  return new Set(JSON.parse(fs.readFileSync(CORE_CLASSES, "utf8")));
137
130
  }
138
131
 
132
+ /**
133
+ * Compiles the Tailwind classes the plugin's frontend uses into
134
+ * dist/frontend.css, against the theme core ships in the SDK. Core only
135
+ * compiles its own classes, so a class no core file happens to use would
136
+ * otherwise have no CSS at all. Appended to whatever CSS the bundle already
137
+ * produced (a library's stylesheet the plugin imports).
138
+ */
139
139
  export async function buildTailwind(cwd, outDir) {
140
140
  const { compile, optimize } = await import("@tailwindcss/node");
141
141
  const { Scanner } = await import("@tailwindcss/oxide");
@@ -17,7 +17,7 @@
17
17
 
18
18
  import fs from "node:fs";
19
19
  import path from "node:path";
20
- import { fileURLToPath } from "node:url";
20
+ import { fileURLToPath, pathToFileURL } from "node:url";
21
21
  import * as esbuild from "esbuild";
22
22
  import { BACKEND_EXTERNALS } from "../lib/externals.mjs";
23
23
  import { readManifest, resolveEntry } from "../lib/plugin-dir.mjs";
@@ -53,7 +53,7 @@ async function loadDefinitions(cwd) {
53
53
  external: BACKEND_EXTERNALS,
54
54
  });
55
55
 
56
- const module = await import(`file://${outfile.split(path.sep).join("/")}`);
56
+ const module = await import(pathToFileURL(outfile).href);
57
57
  const tables = module.tables ?? module.default;
58
58
  if (!Array.isArray(tables)) {
59
59
  throw new Error(
@@ -218,6 +218,11 @@ async function validateMigrations(cwd, pluginId) {
218
218
  const present = DIALECTS.filter((dialect) =>
219
219
  fs.existsSync(path.join(root, dialect)),
220
220
  );
221
+ for (const dialect of DIALECTS) {
222
+ if (present.length > 0 && !present.includes(dialect)) {
223
+ problems.push(`migrations/${dialect} is missing`);
224
+ }
225
+ }
221
226
 
222
227
  const byDialect = new Map();
223
228
  for (const dialect of present) {
package/cli/index.mjs CHANGED
File without changes
@@ -52,7 +52,9 @@ export declare function parseChangelog(markdown: string): {
52
52
  };
53
53
  /**
54
54
  * Checks a CHANGELOG.md. With a manifest version, the newest release has to
55
- * be that version, so a release never ships without its notes.
55
+ * be that version, so a release never ships without its notes. A beta like
56
+ * 1.1.0-beta.2 gets its notes from git, so it only needs the newest release
57
+ * to be 1.1.0 or older.
56
58
  */
57
59
  export declare function validateChangelog(markdown: string, manifestVersion?: string): string[];
58
60
  /**
package/dist/changelog.js CHANGED
@@ -145,7 +145,9 @@ export function parseChangelog(markdown) {
145
145
  }
146
146
  /**
147
147
  * Checks a CHANGELOG.md. With a manifest version, the newest release has to
148
- * be that version, so a release never ships without its notes.
148
+ * be that version, so a release never ships without its notes. A beta like
149
+ * 1.1.0-beta.2 gets its notes from git, so it only needs the newest release
150
+ * to be 1.1.0 or older.
149
151
  */
150
152
  export function validateChangelog(markdown, manifestVersion) {
151
153
  const { changelog, problems } = parseChangelog(markdown);
@@ -154,7 +156,15 @@ export function validateChangelog(markdown, manifestVersion) {
154
156
  return problems;
155
157
  }
156
158
  const newest = changelog.releases[0].version;
157
- if (manifestVersion && newest !== manifestVersion) {
159
+ const base = manifestVersion
160
+ ? semver.valid(semver.coerce(manifestVersion))
161
+ : null;
162
+ const betaOk = !!manifestVersion &&
163
+ !!semver.prerelease(manifestVersion) &&
164
+ !!base &&
165
+ !!semver.valid(newest) &&
166
+ semver.lte(newest, base);
167
+ if (manifestVersion && newest !== manifestVersion && !betaOk) {
158
168
  problems.push(`the newest release is ${newest}, but the manifest version is ${manifestVersion}`);
159
169
  }
160
170
  return problems;
package/dist/db.d.ts CHANGED
@@ -37,7 +37,7 @@ interface Builder<T extends PluginColumn = PluginColumn> {
37
37
  }
38
38
  /** Auto-incrementing surrogate key: integer on sqlite, serial, auto_increment. */
39
39
  export declare const id: () => Builder<PluginColumn>;
40
- /** Unbounded string. Never indexable: MySQL cannot index TEXT. */
40
+ /** Unbounded string, LONGTEXT on MySQL. Never indexable: MySQL cannot index TEXT. */
41
41
  export declare const text: () => Builder<PluginColumn>;
42
42
  /** Bounded string. Indexable on every engine. */
43
43
  export declare const varchar: (length?: number) => Builder<PluginColumn>;
package/dist/db.js CHANGED
@@ -28,7 +28,7 @@ function builder(column) {
28
28
  }
29
29
  /** Auto-incrementing surrogate key: integer on sqlite, serial, auto_increment. */
30
30
  export const id = () => builder({ type: "id", primaryKey: true, notNull: true });
31
- /** Unbounded string. Never indexable: MySQL cannot index TEXT. */
31
+ /** Unbounded string, LONGTEXT on MySQL. Never indexable: MySQL cannot index TEXT. */
32
32
  export const text = () => builder({ type: "text" });
33
33
  /** Bounded string. Indexable on every engine. */
34
34
  export const varchar = (length = KEY_LENGTH) => builder({ type: "varchar", length });
package/dist/ddl.js CHANGED
@@ -67,10 +67,13 @@ function columnType(dialect, column, keyed) {
67
67
  // text/json column, so in practice this only catches a primary key.
68
68
  if (keyed && dialect !== "sqlite")
69
69
  return `varchar(${KEY_LENGTH})`;
70
+ // MySQL TEXT stops at 64KB, so free text, json and secrets go long.
71
+ if (dialect === "mysql" && column.type !== "timestamp")
72
+ return "longtext";
70
73
  return "text";
71
74
  }
72
75
  }
73
- /** Column types that are TEXT on MySQL when nothing keys them. */
76
+ /** Column types that are TEXT or LONGTEXT on MySQL when nothing keys them. */
74
77
  const TEXT_ON_MYSQL = new Set([
75
78
  "text",
76
79
  "json",