initiative-plugin-sdk 2.0.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.
Files changed (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +656 -0
  3. package/dist/build.d.ts +52 -0
  4. package/dist/build.js +229 -0
  5. package/dist/build.js.map +1 -0
  6. package/dist/cli.d.ts +24 -0
  7. package/dist/cli.js +160 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/client.d.ts +288 -0
  10. package/dist/client.js +539 -0
  11. package/dist/client.js.map +1 -0
  12. package/dist/contract.d.ts +1247 -0
  13. package/dist/contract.js +167 -0
  14. package/dist/contract.js.map +1 -0
  15. package/dist/define.d.ts +336 -0
  16. package/dist/define.js +120 -0
  17. package/dist/define.js.map +1 -0
  18. package/dist/dev.d.ts +28 -0
  19. package/dist/dev.js +147 -0
  20. package/dist/dev.js.map +1 -0
  21. package/dist/expression.d.ts +28 -0
  22. package/dist/expression.js +67 -0
  23. package/dist/expression.js.map +1 -0
  24. package/dist/init.d.ts +14 -0
  25. package/dist/init.js +52 -0
  26. package/dist/init.js.map +1 -0
  27. package/dist/keys.d.ts +85 -0
  28. package/dist/keys.js +109 -0
  29. package/dist/keys.js.map +1 -0
  30. package/dist/manifest.d.ts +8 -0
  31. package/dist/manifest.js +8 -0
  32. package/dist/manifest.js.map +1 -0
  33. package/dist/pack.d.ts +35 -0
  34. package/dist/pack.js +84 -0
  35. package/dist/pack.js.map +1 -0
  36. package/dist/plugin-api.generated.d.ts +4263 -0
  37. package/dist/plugin-api.generated.js +1019 -0
  38. package/dist/plugin-api.generated.js.map +1 -0
  39. package/dist/server.d.ts +75 -0
  40. package/dist/server.js +408 -0
  41. package/dist/server.js.map +1 -0
  42. package/dist/testing.d.ts +116 -0
  43. package/dist/testing.js +386 -0
  44. package/dist/testing.js.map +1 -0
  45. package/dist/tokens.d.ts +161 -0
  46. package/dist/tokens.js +215 -0
  47. package/dist/tokens.js.map +1 -0
  48. package/dist/validate.d.ts +86 -0
  49. package/dist/validate.js +997 -0
  50. package/dist/validate.js.map +1 -0
  51. package/dist/widget.d.ts +235 -0
  52. package/dist/widget.js +26 -0
  53. package/dist/widget.js.map +1 -0
  54. package/examples/minimal/README.md +48 -0
  55. package/examples/minimal/assets/avatar.png +0 -0
  56. package/examples/minimal/package.json +22 -0
  57. package/examples/minimal/src/plugin.ts +77 -0
  58. package/examples/minimal/src/widgets/open-issues.ts +11 -0
  59. package/examples/minimal/test/fixtures/issues-statistics.json +9 -0
  60. package/examples/minimal/test/issue-counts.test.ts +48 -0
  61. package/examples/minimal/tsconfig.json +14 -0
  62. package/manifest.contract.json +1886 -0
  63. package/package.json +92 -0
  64. package/schemas/plugin-manifest.json +1747 -0
@@ -0,0 +1,52 @@
1
+ /**
2
+ * `initiative-plugin build`: the files a plug-in's definition produces.
3
+ *
4
+ * - `manifest.json`: the manifest, with each widget's module bundled into its
5
+ * `module_source`, after `validateManifest` has passed it. That parses
6
+ * every JSONata expression a declarative plug-in gives, so one that does not
7
+ * parse fails the build at its place in the manifest.
8
+ * - With `--registry <dir>`, the plug-in's registry source under
9
+ * `<dir>/<publisher>/<uid>/`: `listing.json`, this version's
10
+ * `<version>/manifest.json` and the avatar. It is written only while the
11
+ * listing names the package's own version: between releases the package
12
+ * runs ahead of its listing, and what the listing already publishes is left
13
+ * as it was.
14
+ *
15
+ * With `--check` nothing is written, and any file that differs from what would
16
+ * be written is a failure.
17
+ *
18
+ * Bundling uses esbuild, which the plug-in installs beside the SDK
19
+ * (`npm install --save-dev esbuild`). Nothing at run time needs it.
20
+ */
21
+ import { type AnyPlugin } from "./define.js";
22
+ import type { Manifest } from "./contract.js";
23
+ export interface BuildOptions {
24
+ /** The plug-in's package directory. */
25
+ root: string;
26
+ /** The module whose default export is the plug-in's definition, relative to `root`. */
27
+ plugin: string;
28
+ /** Where registry sources live; the plug-in's is written under `<publisher>/<uid>/`. */
29
+ registry?: string;
30
+ check: boolean;
31
+ }
32
+ type Esbuild = typeof import("esbuild");
33
+ /** esbuild, or null after saying how to install it. */
34
+ export declare function bundler(command: string): Promise<Esbuild | null>;
35
+ /** What a definition builds: the plug-in and its manifest, or every problem that stops it. */
36
+ export type Compiled = {
37
+ plugin: AnyPlugin;
38
+ manifest: Manifest;
39
+ problems?: never;
40
+ } | {
41
+ problems: string[];
42
+ };
43
+ /**
44
+ * Load the plug-in's definition, bundle its widgets and check the manifest they
45
+ * make, with nothing written.
46
+ */
47
+ export declare function compile(esbuild: Esbuild, root: string, entry: string): Promise<Compiled>;
48
+ /** Build, or check, the plug-in's files. Answers the process's exit code. */
49
+ export declare function build(options: BuildOptions): Promise<number>;
50
+ /** A listing's registration: the plug-in's kind, and a container's image and Compose service. */
51
+ export declare function registrationOf(plugin: AnyPlugin): Record<string, unknown>;
52
+ export {};
package/dist/build.js ADDED
@@ -0,0 +1,229 @@
1
+ /**
2
+ * `initiative-plugin build`: the files a plug-in's definition produces.
3
+ *
4
+ * - `manifest.json`: the manifest, with each widget's module bundled into its
5
+ * `module_source`, after `validateManifest` has passed it. That parses
6
+ * every JSONata expression a declarative plug-in gives, so one that does not
7
+ * parse fails the build at its place in the manifest.
8
+ * - With `--registry <dir>`, the plug-in's registry source under
9
+ * `<dir>/<publisher>/<uid>/`: `listing.json`, this version's
10
+ * `<version>/manifest.json` and the avatar. It is written only while the
11
+ * listing names the package's own version: between releases the package
12
+ * runs ahead of its listing, and what the listing already publishes is left
13
+ * as it was.
14
+ *
15
+ * With `--check` nothing is written, and any file that differs from what would
16
+ * be written is a failure.
17
+ *
18
+ * Bundling uses esbuild, which the plug-in installs beside the SDK
19
+ * (`npm install --save-dev esbuild`). Nothing at run time needs it.
20
+ */
21
+ import { createHash } from "node:crypto";
22
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
23
+ import { basename, dirname, join, relative, resolve } from "node:path";
24
+ import { pathToFileURL } from "node:url";
25
+ import { CAPS } from "./contract.js";
26
+ import { manifestOf } from "./define.js";
27
+ import { validateManifest } from "./validate.js";
28
+ /** esbuild, or null after saying how to install it. */
29
+ export async function bundler(command) {
30
+ try {
31
+ return await import("esbuild");
32
+ }
33
+ catch {
34
+ process.stderr.write(`initiative-plugin ${command} bundles with esbuild: npm install --save-dev esbuild\n`);
35
+ return null;
36
+ }
37
+ }
38
+ /**
39
+ * Load the plug-in's definition, bundle its widgets and check the manifest they
40
+ * make, with nothing written.
41
+ */
42
+ export async function compile(esbuild, root, entry) {
43
+ const plugin = await loadPlugin(esbuild, root, entry);
44
+ const modules = {};
45
+ const problems = [];
46
+ for (const [id, widget] of Object.entries(plugin.widgets ?? {})) {
47
+ const source = await bundleWidget(esbuild, root, widget.module);
48
+ const bytes = Buffer.byteLength(source, "utf-8");
49
+ if (bytes > CAPS.moduleSourceBytes) {
50
+ problems.push(`widget ${id}: ${widget.module} bundles to ${bytes} bytes, over the ${CAPS.moduleSourceBytes}-byte cap`);
51
+ }
52
+ modules[id] = source;
53
+ }
54
+ const manifest = manifestOf(plugin, modules);
55
+ problems.push(...validateManifest(manifest, { publicId: plugin.publicId }).map((problem) => `manifest${problem.where}: ${problem.message}`));
56
+ problems.push(...kindProblems(plugin));
57
+ if (plugin.listing?.compose)
58
+ problems.push(...composeProblems(plugin.listing.compose));
59
+ return problems.length ? { problems } : { plugin, manifest };
60
+ }
61
+ /** Build, or check, the plug-in's files. Answers the process's exit code. */
62
+ export async function build(options) {
63
+ const esbuild = await bundler("build");
64
+ if (!esbuild)
65
+ return 1;
66
+ const root = resolve(options.root);
67
+ const compiled = await compile(esbuild, root, options.plugin);
68
+ if (compiled.problems) {
69
+ for (const problem of compiled.problems)
70
+ process.stderr.write(`${problem}\n`);
71
+ return 1;
72
+ }
73
+ const { plugin, manifest } = compiled;
74
+ const manifestText = `${JSON.stringify(manifest, null, 2)}\n`;
75
+ const outputs = [[join(root, "manifest.json"), manifestText]];
76
+ if (options.registry !== undefined) {
77
+ const listing = plugin.listing;
78
+ if (!listing) {
79
+ process.stderr.write("--registry was given, but the plug-in declares no listing\n");
80
+ return 1;
81
+ }
82
+ const version = JSON.parse(readFileSync(join(root, "package.json"), "utf-8")).version;
83
+ if (version === listing.version) {
84
+ const avatar = readFileSync(resolve(root, listing.avatar));
85
+ const source = resolve(root, options.registry, listing.publisher, plugin.uid);
86
+ outputs.push([join(source, "listing.json"), `${JSON.stringify(listingSource(plugin, avatar), null, 2)}\n`], [join(source, listing.version, "manifest.json"), manifestText], [join(source, "assets", basename(listing.avatar)), avatar]);
87
+ }
88
+ else {
89
+ process.stdout.write(`the registry source lists ${listing.version}; ${version} is listed at its release\n`);
90
+ }
91
+ }
92
+ let stale = false;
93
+ for (const [path, content] of outputs) {
94
+ const name = relative(process.cwd(), path);
95
+ if (options.check) {
96
+ const current = existsSync(path) ? readFileSync(path) : null;
97
+ if (!current || !current.equals(Buffer.from(content))) {
98
+ process.stderr.write(`${name} is out of date: run initiative-plugin build\n`);
99
+ stale = true;
100
+ }
101
+ }
102
+ else {
103
+ mkdirSync(dirname(path), { recursive: true });
104
+ writeFileSync(path, content);
105
+ process.stdout.write(`wrote ${name}\n`);
106
+ }
107
+ }
108
+ return stale ? 1 : 0;
109
+ }
110
+ /** The plug-in's definition, compiled from its TypeScript and imported. */
111
+ async function loadPlugin(esbuild, root, entry) {
112
+ const outfile = join(root, "node_modules", ".cache", "initiative-plugin", `plugin-${process.pid}-${Date.now()}.mjs`);
113
+ await esbuild.build({
114
+ entryPoints: [resolve(root, entry)],
115
+ outfile,
116
+ bundle: true,
117
+ platform: "node",
118
+ format: "esm",
119
+ packages: "external",
120
+ logLevel: "error",
121
+ });
122
+ try {
123
+ const loaded = (await import(pathToFileURL(outfile).href));
124
+ const plugin = loaded.default;
125
+ if (!plugin || typeof plugin.publicId !== "string") {
126
+ throw new Error(`${entry} must export the plug-in's definition as its default export`);
127
+ }
128
+ return plugin;
129
+ }
130
+ finally {
131
+ rmSync(outfile, { force: true });
132
+ }
133
+ }
134
+ /**
135
+ * One widget as the single script the sandbox runs: its module and everything
136
+ * it imports, with `render` left as a global.
137
+ */
138
+ async function bundleWidget(esbuild, root, module) {
139
+ const path = `./${relative(root, resolve(root, module)).split("\\").join("/")}`;
140
+ const result = await esbuild.build({
141
+ stdin: {
142
+ contents: `import { render } from ${JSON.stringify(path)};\nglobalThis.render = render;\n`,
143
+ resolveDir: root,
144
+ sourcefile: "widget.js",
145
+ loader: "js",
146
+ },
147
+ bundle: true,
148
+ write: false,
149
+ format: "iife",
150
+ platform: "neutral",
151
+ target: "es2020",
152
+ charset: "utf8",
153
+ legalComments: "none",
154
+ logLevel: "error",
155
+ });
156
+ return result.outputFiles[0].text.trimEnd();
157
+ }
158
+ /**
159
+ * What a definition says that its manifest does not show: a declarative plug-in
160
+ * runs no hooks and asks for no scopes, and only a container plug-in's listing
161
+ * names an image.
162
+ */
163
+ function kindProblems(plugin) {
164
+ const problems = [];
165
+ if (plugin.hosts) {
166
+ if (Object.keys(plugin.hooks ?? {}).length)
167
+ problems.push("hooks: a declarative plug-in runs no hooks");
168
+ if (plugin.scopes)
169
+ problems.push("scopes: a declarative plug-in asks for none, since it does not call Initiative");
170
+ if (plugin.listing?.image || plugin.listing?.compose)
171
+ problems.push("listing: a declarative plug-in has no image or compose service");
172
+ }
173
+ else if (plugin.listing && !plugin.listing.image) {
174
+ problems.push("listing: a container plug-in names its image");
175
+ }
176
+ return problems;
177
+ }
178
+ /** The registry's rules for a compose snippet: its size, its two placeholders, its address. */
179
+ function composeProblems({ service, baseUrl }) {
180
+ const problems = [];
181
+ if (!service || service.length > 4096) {
182
+ problems.push("listing compose: the service is 1 to 4096 characters");
183
+ }
184
+ for (const [placeholder] of service.matchAll(/\$\{(?!(?:IMAGE|INITIATIVE_URL)\})[^}]*\}?/g)) {
185
+ problems.push(`listing compose: ${placeholder} is not a placeholder; Initiative fills \${IMAGE} and \${INITIATIVE_URL}`);
186
+ }
187
+ if (baseUrl.length > 512 || !/^https?:\/\/[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:\/[^\s?#]*)?$/.test(baseUrl)) {
188
+ problems.push("listing compose: baseUrl is an http or https URL of at most 512 characters");
189
+ }
190
+ return problems;
191
+ }
192
+ /** The registry source listing: what the catalogue shows, this version, and the registration, a container's or a declarative plug-in's. */
193
+ function listingSource(plugin, avatar) {
194
+ const listing = plugin.listing;
195
+ return {
196
+ schema: 1,
197
+ uid: plugin.uid,
198
+ public_id: plugin.publicId,
199
+ publisher: listing.publisher,
200
+ kind: "plugin",
201
+ name: plugin.name,
202
+ summary: listing.summary,
203
+ ...(listing.description !== undefined ? { description: listing.description } : {}),
204
+ avatar: {
205
+ path: `assets/${basename(listing.avatar)}`,
206
+ sha256: createHash("sha256").update(avatar).digest("hex"),
207
+ },
208
+ versions: [
209
+ {
210
+ version: listing.version,
211
+ definition: `${listing.version}/manifest.json`,
212
+ ...(listing.minAppVersion !== undefined ? { min_app_version: listing.minAppVersion } : {}),
213
+ ...(listing.releaseNotes !== undefined ? { release_notes: listing.releaseNotes } : {}),
214
+ },
215
+ ],
216
+ registration: registrationOf(plugin),
217
+ };
218
+ }
219
+ /** A listing's registration: the plug-in's kind, and a container's image and Compose service. */
220
+ export function registrationOf(plugin) {
221
+ const listing = plugin.listing;
222
+ return {
223
+ ...(plugin.hosts ? { kind: "declarative" } : { kind: "container", image: listing.image }),
224
+ scope_ceiling: [...(listing.scopeCeiling ?? plugin.scopes ?? [])],
225
+ reference_sectors: [...(listing.referenceSectors ?? [])],
226
+ ...(listing.compose ? { compose: { service: listing.compose.service, base_url: listing.compose.baseUrl } } : {}),
227
+ };
228
+ }
229
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `initiative-plugin`: start, build, pack and upload a plug-in, and keys and
4
+ * manifest checks.
5
+ *
6
+ * initiative-plugin init [dir] [--example minimal]
7
+ * initiative-plugin build [--plugin <file>] [--registry <dir>] [--check]
8
+ * initiative-plugin pack [--plugin <file>] [--out <file>]
9
+ * initiative-plugin dev --initiative <url> [--api-key <key>] [--plugin <file>]
10
+ * initiative-plugin keygen [--alg RS256|ES256] [--kid <id>] [--out <dir>]
11
+ * initiative-plugin validate <file.json> a manifest, or a served manifest document
12
+ * initiative-plugin schema print the schema a manifest is checked against
13
+ * initiative-plugin uid mint a catalog uid
14
+ *
15
+ * `build` reads the plug-in's definition (default `src/plugin.ts`) and writes
16
+ * `manifest.json`, and with `--registry` the plug-in's registry source; see
17
+ * `build.ts`. `pack` writes the plug-in's listing file, which a self-hosted
18
+ * deployment publishes as its own plug-in (`pack.ts`), and `dev` uploads it to one
19
+ * and again on each change (`dev.ts`); its key may be given as
20
+ * `INITIATIVE_API_KEY` instead. `init` copies an example (`init.ts`).
21
+ * `keygen` writes `private-key.pem` (mode 0600) and `jwks.json`
22
+ * into `--out` and refuses to overwrite either.
23
+ */
24
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `initiative-plugin`: start, build, pack and upload a plug-in, and keys and
4
+ * manifest checks.
5
+ *
6
+ * initiative-plugin init [dir] [--example minimal]
7
+ * initiative-plugin build [--plugin <file>] [--registry <dir>] [--check]
8
+ * initiative-plugin pack [--plugin <file>] [--out <file>]
9
+ * initiative-plugin dev --initiative <url> [--api-key <key>] [--plugin <file>]
10
+ * initiative-plugin keygen [--alg RS256|ES256] [--kid <id>] [--out <dir>]
11
+ * initiative-plugin validate <file.json> a manifest, or a served manifest document
12
+ * initiative-plugin schema print the schema a manifest is checked against
13
+ * initiative-plugin uid mint a catalog uid
14
+ *
15
+ * `build` reads the plug-in's definition (default `src/plugin.ts`) and writes
16
+ * `manifest.json`, and with `--registry` the plug-in's registry source; see
17
+ * `build.ts`. `pack` writes the plug-in's listing file, which a self-hosted
18
+ * deployment publishes as its own plug-in (`pack.ts`), and `dev` uploads it to one
19
+ * and again on each change (`dev.ts`); its key may be given as
20
+ * `INITIATIVE_API_KEY` instead. `init` copies an example (`init.ts`).
21
+ * `keygen` writes `private-key.pem` (mode 0600) and `jwks.json`
22
+ * into `--out` and refuses to overwrite either.
23
+ */
24
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
25
+ import { join } from "node:path";
26
+ import { build } from "./build.js";
27
+ import { dev } from "./dev.js";
28
+ import { init, mintUid } from "./init.js";
29
+ import { generatePluginKeys } from "./keys.js";
30
+ import { pack } from "./pack.js";
31
+ import { manifestSchema, validateDocument, validateManifest } from "./validate.js";
32
+ function usage() {
33
+ process.stderr.write([
34
+ "usage:",
35
+ " initiative-plugin init [dir] [--example minimal]",
36
+ " initiative-plugin build [--plugin <file>] [--registry <dir>] [--check]",
37
+ " initiative-plugin pack [--plugin <file>] [--out <file>]",
38
+ " initiative-plugin dev --initiative <url> [--api-key <key>] [--plugin <file>]",
39
+ " initiative-plugin keygen [--alg RS256|ES256] [--kid <id>] [--out <dir>]",
40
+ " initiative-plugin validate <file.json>",
41
+ " initiative-plugin schema",
42
+ " initiative-plugin uid",
43
+ "",
44
+ ].join("\n"));
45
+ process.exit(2);
46
+ }
47
+ /** `--name value` pairs and the `--name` switches in `switches`, and nothing else. */
48
+ function flags(args, values, switches = []) {
49
+ const out = {};
50
+ for (let index = 0; index < args.length; index += 1) {
51
+ const name = args[index].startsWith("--") ? args[index].slice(2) : "";
52
+ if (switches.includes(name)) {
53
+ out[name] = true;
54
+ }
55
+ else if (values.includes(name) && args[index + 1] !== undefined) {
56
+ out[name] = args[index + 1];
57
+ index += 1;
58
+ }
59
+ else
60
+ usage();
61
+ }
62
+ return out;
63
+ }
64
+ function keygen(args) {
65
+ const options = flags(args, ["alg", "kid", "out"]);
66
+ const alg = (options.alg ?? "RS256");
67
+ if (alg !== "RS256" && alg !== "ES256") {
68
+ process.stderr.write(`unsupported --alg ${alg}: use RS256 or ES256\n`);
69
+ return 2;
70
+ }
71
+ const dir = options.out ?? ".";
72
+ const keyPath = join(dir, "private-key.pem");
73
+ const jwksPath = join(dir, "jwks.json");
74
+ for (const path of [keyPath, jwksPath]) {
75
+ if (existsSync(path)) {
76
+ process.stderr.write(`${path} already exists; choose another --out\n`);
77
+ return 1;
78
+ }
79
+ }
80
+ const keys = generatePluginKeys({ alg, ...(options.kid ? { kid: options.kid } : {}) });
81
+ mkdirSync(dir, { recursive: true });
82
+ writeFileSync(keyPath, keys.privateKeyPem, { mode: 0o600, flag: "wx" });
83
+ writeFileSync(jwksPath, `${JSON.stringify(keys.jwks, null, 2)}\n`, { flag: "wx" });
84
+ process.stdout.write([
85
+ `wrote ${keyPath} (keep it secret)`,
86
+ `wrote ${jwksPath} (the public half, for the plug-in's listing or a deployment's operator)`,
87
+ `kid: ${keys.kid}`,
88
+ `alg: ${keys.alg}`,
89
+ "",
90
+ ].join("\n"));
91
+ return 0;
92
+ }
93
+ function validate(path) {
94
+ if (!path)
95
+ usage();
96
+ let body;
97
+ try {
98
+ body = JSON.parse(readFileSync(path, "utf-8"));
99
+ }
100
+ catch (error) {
101
+ process.stderr.write(`${path}: ${error.message}\n`);
102
+ return 1;
103
+ }
104
+ // A served document carries the manifest as its `definition`.
105
+ const document = typeof body === "object" && body !== null && "definition" in body;
106
+ const problems = document ? validateDocument(body) : validateManifest(body);
107
+ if (problems.length === 0) {
108
+ process.stdout.write(`${path}: no problems found (checked as a ${document ? "document" : "manifest"})\n`);
109
+ return 0;
110
+ }
111
+ for (const problem of problems)
112
+ process.stderr.write(`${path}${problem.where}: ${problem.message}\n`);
113
+ return 1;
114
+ }
115
+ async function main(argv) {
116
+ const [command, ...rest] = argv;
117
+ switch (command) {
118
+ case "init": {
119
+ const dir = rest[0]?.startsWith("--") === false ? rest.shift() : ".";
120
+ const options = flags(rest, ["example"]);
121
+ return init({ dir, example: options.example ?? "minimal" });
122
+ }
123
+ case "build": {
124
+ const options = flags(rest, ["plugin", "registry"], ["check"]);
125
+ return build({
126
+ root: process.cwd(),
127
+ plugin: typeof options.plugin === "string" ? options.plugin : "src/plugin.ts",
128
+ ...(typeof options.registry === "string" ? { registry: options.registry } : {}),
129
+ check: options.check === true,
130
+ });
131
+ }
132
+ case "pack": {
133
+ const options = flags(rest, ["plugin", "out"]);
134
+ return pack({ root: process.cwd(), plugin: options.plugin ?? "src/plugin.ts", out: options.out });
135
+ }
136
+ case "dev": {
137
+ const options = flags(rest, ["initiative", "api-key", "plugin"]);
138
+ const apiKey = options["api-key"] ?? process.env.INITIATIVE_API_KEY;
139
+ if (!options.initiative || !apiKey) {
140
+ process.stderr.write("dev uploads the plug-in to your deployment: give --initiative <url> and --api-key <key>\n");
141
+ return 2;
142
+ }
143
+ return dev({ root: process.cwd(), plugin: options.plugin ?? "src/plugin.ts", initiative: options.initiative, apiKey });
144
+ }
145
+ case "keygen":
146
+ return keygen(rest);
147
+ case "validate":
148
+ return validate(rest[0]);
149
+ case "schema":
150
+ process.stdout.write(`${JSON.stringify(manifestSchema(), null, 2)}\n`);
151
+ return 0;
152
+ case "uid":
153
+ process.stdout.write(`${mintUid()}\n`);
154
+ return 0;
155
+ default:
156
+ usage();
157
+ }
158
+ }
159
+ process.exit(await main(process.argv.slice(2)));
160
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}