@capybara-hq/plugin-tools 0.1.0-rc.3 → 0.1.0-rc.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 +17 -10
- package/dist/check/applied-migrations.d.ts +23 -0
- package/dist/check/applied-migrations.js +86 -0
- package/dist/check/cli.d.ts +2 -1
- package/dist/check/cli.js +7 -3
- package/dist/check/config-forms.d.ts +13 -0
- package/dist/check/config-forms.js +71 -0
- package/dist/check/index.d.ts +3 -1
- package/dist/check/index.js +3 -1
- package/dist/check/migrations.d.ts +1 -1
- package/dist/check/migrations.js +30 -1
- package/dist/check/org-override.d.ts +10 -0
- package/dist/check/org-override.js +62 -0
- package/dist/check/plugin-permissions.d.ts +14 -0
- package/dist/check/plugin-permissions.js +28 -3
- package/dist/check/release-metadata.d.ts +5 -0
- package/dist/check/release-metadata.js +47 -0
- package/dist/check/report.d.ts +4 -3
- package/dist/check/report.js +13 -3
- package/dist/check/run.d.ts +1 -1
- package/dist/check/run.js +4 -0
- package/dist/check/source.d.ts +7 -0
- package/dist/check/source.js +2 -0
- package/dist/marketplace/cli.d.ts +9 -7
- package/dist/marketplace/cli.js +19 -10
- package/dist/marketplace/marketplace.d.ts +38 -24
- package/dist/marketplace/marketplace.js +206 -60
- package/dist/pack/config-schemas.d.ts +34 -0
- package/dist/pack/config-schemas.js +151 -0
- package/dist/pack/index.d.ts +2 -1
- package/dist/pack/index.js +2 -1
- package/dist/pack/pack.d.ts +7 -1
- package/dist/pack/pack.js +77 -35
- package/package.json +4 -4
package/dist/check/report.js
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import { relative } from "node:path";
|
|
2
|
+
import { errorsOf } from "./source.js";
|
|
2
3
|
/** One finding as a line: `<file relative to root>:<line> <rule> <message>`. */
|
|
3
4
|
export const formatFinding = (f, root) => `${relative(root, f.file) || f.file}:${f.line} ${f.rule} ${f.message}`;
|
|
4
5
|
/**
|
|
5
|
-
* Prints the result of one check: `[name] passed
|
|
6
|
-
*
|
|
6
|
+
* Prints the result of one check: `[name] passed` (`passed with N warning(s)` and one line per
|
|
7
|
+
* warning when it has only warnings), or the finding count and one line per finding (stderr).
|
|
8
|
+
* Returns whether it passed (warnings do not fail it).
|
|
7
9
|
*/
|
|
8
10
|
export function printCheck(name, findings, root) {
|
|
11
|
+
const errors = errorsOf(findings);
|
|
9
12
|
if (findings.length === 0) {
|
|
10
13
|
console.log(`[${name}] passed`);
|
|
11
14
|
return true;
|
|
12
15
|
}
|
|
13
|
-
|
|
16
|
+
if (errors.length === 0) {
|
|
17
|
+
console.error(`[${name}] passed with ${findings.length} warning(s)`);
|
|
18
|
+
for (const f of findings)
|
|
19
|
+
console.error(` ${formatFinding(f, root)}`);
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
const warnings = findings.length - errors.length;
|
|
23
|
+
console.error(`[${name}] ${errors.length} finding(s)${warnings > 0 ? ` and ${warnings} warning(s)` : ""}`);
|
|
14
24
|
for (const f of findings)
|
|
15
25
|
console.error(` ${formatFinding(f, root)}`);
|
|
16
26
|
return false;
|
package/dist/check/run.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface PluginCheckScope {
|
|
|
8
8
|
root: string;
|
|
9
9
|
/**
|
|
10
10
|
* Plugin directories: every check runs on each (dependency boundary, extension state,
|
|
11
|
-
* permissions, pack, tool design, test imports, release metadata, and the migrations in
|
|
11
|
+
* permissions, pack, config forms, tool design, test imports, release metadata, and the migrations in
|
|
12
12
|
* `<plugin>/migrations`).
|
|
13
13
|
*/
|
|
14
14
|
plugins: string[];
|
package/dist/check/run.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
+
import { checkConfigForms } from "./config-forms.js";
|
|
2
3
|
import { checkDeps } from "./deps.js";
|
|
3
4
|
import { checkMigrations } from "./migrations.js";
|
|
5
|
+
import { checkOrgOverride } from "./org-override.js";
|
|
4
6
|
import { checkPluginPack } from "./plugin-pack.js";
|
|
5
7
|
import { checkPluginPermissions } from "./plugin-permissions.js";
|
|
6
8
|
import { checkPluginState } from "./plugin-state.js";
|
|
@@ -27,6 +29,8 @@ export function pluginChecks(scope) {
|
|
|
27
29
|
{ name: "Extension state", run: () => checkPluginState(plugins) },
|
|
28
30
|
{ name: "Extension permissions", run: () => checkPluginPermissions(plugins) },
|
|
29
31
|
{ name: "Plugin pack", run: () => checkPluginPack(plugins) },
|
|
32
|
+
{ name: "Config forms", run: () => checkConfigForms(plugins) },
|
|
33
|
+
{ name: "Org override", run: () => checkOrgOverride(plugins) },
|
|
30
34
|
{
|
|
31
35
|
name: "Tool design",
|
|
32
36
|
run: () => checkToolDesign([...(scope.toolDesignDirs ?? []), ...plugins]),
|
package/dist/check/source.d.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { type Comment } from "oxc-parser";
|
|
2
|
+
/**
|
|
3
|
+
* One finding of a check. `severity: "warning"` is printed but does not fail the check (only a
|
|
4
|
+
* few rules warn, e.g. `release-description-zh`); without it the finding is an error.
|
|
5
|
+
*/
|
|
2
6
|
export type Finding = {
|
|
3
7
|
file: string;
|
|
4
8
|
line: number;
|
|
5
9
|
rule: string;
|
|
6
10
|
message: string;
|
|
11
|
+
severity?: "warning";
|
|
7
12
|
};
|
|
13
|
+
/** The findings that fail a check (every finding that is not a warning). */
|
|
14
|
+
export declare const errorsOf: (findings: Finding[]) => Finding[];
|
|
8
15
|
/** ESTree 节点(oxc-parser 的输出)。只声明本检查用到的公共字段。 */
|
|
9
16
|
export interface Node {
|
|
10
17
|
type: string;
|
package/dist/check/source.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { parseSync } from "oxc-parser";
|
|
4
|
+
/** The findings that fail a check (every finding that is not a warning). */
|
|
5
|
+
export const errorsOf = (findings) => findings.filter((f) => f.severity !== "warning");
|
|
4
6
|
const SOURCE_EXT = /\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/;
|
|
5
7
|
const TEST_FILE = /\.(?:test|spec)\.[cm]?[jt]sx?$/;
|
|
6
8
|
/** 只在插件根目录下才有特殊含义的目录名(更深处同名目录是普通源码目录,必须扫描)。 */
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
export declare const MARKETPLACE_USAGE: string;
|
|
2
2
|
/**
|
|
3
3
|
* `capybara-plugin marketplace`: writes (`--write`) or checks (`--check`) the repository's
|
|
4
|
-
* marketplace manifest
|
|
4
|
+
* marketplace manifest, one entry per public plugin at its current version, against reproducible
|
|
5
|
+
* packs of its public plugins ({@link syncMarketplace}).
|
|
5
6
|
*
|
|
6
7
|
* - `--root <dir>`: the repository (default: the current directory);
|
|
7
8
|
* - `--file <path>`: the manifest, relative to the root (default `.capybara-plugin/marketplace.json`);
|
|
8
9
|
* - `--plugins <glob>`: the plugin directories, relative to the root (default `plugins/*`, or the
|
|
9
10
|
* root itself when it is a plugin).
|
|
10
11
|
*
|
|
11
|
-
* - `--base <rev>` (with `--check`, on pull requests):
|
|
12
|
-
*
|
|
13
|
-
* match the tree's packs (`marketplace-integrity`).
|
|
12
|
+
* - `--base <rev>` (with `--check`, on pull requests): an entry's version may only increase over the
|
|
13
|
+
* versions `<rev>` lists (`marketplace-version-decrease`), a version `<rev>` lists keeps its
|
|
14
|
+
* integrity, and the entries added since must match the tree's packs (`marketplace-integrity`).
|
|
14
15
|
*
|
|
15
|
-
* `--check` exits 1 on any finding (`marketplace-missing`,
|
|
16
|
-
* `marketplace-
|
|
17
|
-
*
|
|
16
|
+
* `--check` exits 1 on any finding that is not a warning (`marketplace-missing`,
|
|
17
|
+
* `marketplace-display-stale`, `marketplace-integrity`, `marketplace-version-decrease`,
|
|
18
|
+
* `marketplace-invalid`); `--write` writes each plugin's entry (replacing its other versions,
|
|
19
|
+
* refreshing a listed entry's summary and displayName) and exits 1 only on `marketplace-invalid`.
|
|
18
20
|
* Relative paths resolve against `cwd`. Returns the exit code.
|
|
19
21
|
*/
|
|
20
22
|
export declare function marketplaceCommand(args: string[], cwd: string): Promise<number>;
|
package/dist/marketplace/cli.js
CHANGED
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
2
|
import { parseArgs } from "node:util";
|
|
3
3
|
import { formatFinding } from "../check/report.js";
|
|
4
|
+
import { errorsOf } from "../check/source.js";
|
|
4
5
|
import { MARKETPLACE_FILE, syncMarketplace } from "./marketplace.js";
|
|
5
6
|
export const MARKETPLACE_USAGE = "capybara-plugin marketplace --write|--check [--base <rev>] [--root <dir>] [--file <path>]\n" +
|
|
6
7
|
" [--plugins <glob>]";
|
|
7
8
|
/**
|
|
8
9
|
* `capybara-plugin marketplace`: writes (`--write`) or checks (`--check`) the repository's
|
|
9
|
-
* marketplace manifest
|
|
10
|
+
* marketplace manifest, one entry per public plugin at its current version, against reproducible
|
|
11
|
+
* packs of its public plugins ({@link syncMarketplace}).
|
|
10
12
|
*
|
|
11
13
|
* - `--root <dir>`: the repository (default: the current directory);
|
|
12
14
|
* - `--file <path>`: the manifest, relative to the root (default `.capybara-plugin/marketplace.json`);
|
|
13
15
|
* - `--plugins <glob>`: the plugin directories, relative to the root (default `plugins/*`, or the
|
|
14
16
|
* root itself when it is a plugin).
|
|
15
17
|
*
|
|
16
|
-
* - `--base <rev>` (with `--check`, on pull requests):
|
|
17
|
-
*
|
|
18
|
-
* match the tree's packs (`marketplace-integrity`).
|
|
18
|
+
* - `--base <rev>` (with `--check`, on pull requests): an entry's version may only increase over the
|
|
19
|
+
* versions `<rev>` lists (`marketplace-version-decrease`), a version `<rev>` lists keeps its
|
|
20
|
+
* integrity, and the entries added since must match the tree's packs (`marketplace-integrity`).
|
|
19
21
|
*
|
|
20
|
-
* `--check` exits 1 on any finding (`marketplace-missing`,
|
|
21
|
-
* `marketplace-
|
|
22
|
-
*
|
|
22
|
+
* `--check` exits 1 on any finding that is not a warning (`marketplace-missing`,
|
|
23
|
+
* `marketplace-display-stale`, `marketplace-integrity`, `marketplace-version-decrease`,
|
|
24
|
+
* `marketplace-invalid`); `--write` writes each plugin's entry (replacing its other versions,
|
|
25
|
+
* refreshing a listed entry's summary and displayName) and exits 1 only on `marketplace-invalid`.
|
|
23
26
|
* Relative paths resolve against `cwd`. Returns the exit code.
|
|
24
27
|
*/
|
|
25
28
|
export async function marketplaceCommand(args, cwd) {
|
|
@@ -59,14 +62,20 @@ export async function marketplaceCommand(args, cwd) {
|
|
|
59
62
|
});
|
|
60
63
|
for (const f of r.findings)
|
|
61
64
|
console.error(formatFinding(f, root));
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
const errors = errorsOf(r.findings);
|
|
66
|
+
if (errors.length > 0) {
|
|
67
|
+
console.error(`\n${errors.length} marketplace finding(s)`);
|
|
64
68
|
return 1;
|
|
65
69
|
}
|
|
66
70
|
if (values.write) {
|
|
67
71
|
for (const e of r.added)
|
|
68
72
|
console.log(`added ${e.name}@${e.version}`);
|
|
69
|
-
|
|
73
|
+
for (const k of r.removed)
|
|
74
|
+
console.log(`removed ${k}`);
|
|
75
|
+
for (const k of r.refreshed)
|
|
76
|
+
console.log(`refreshed ${k}`);
|
|
77
|
+
const changed = r.added.length + r.removed.length + r.refreshed.length > 0;
|
|
78
|
+
console.log(changed ? `wrote ${file}` : "marketplace is up to date");
|
|
70
79
|
}
|
|
71
80
|
else {
|
|
72
81
|
console.log("marketplace is up to date");
|
|
@@ -9,44 +9,58 @@ export interface SyncMarketplaceOptions {
|
|
|
9
9
|
file: string;
|
|
10
10
|
/** Plugin directories relative to `root` (`*` within one segment); default as `discoverPlugins`. */
|
|
11
11
|
plugins?: string;
|
|
12
|
-
/**
|
|
12
|
+
/** Write the plugins' entries into `file` (`--write`); otherwise only report them (`--check`). */
|
|
13
13
|
write: boolean;
|
|
14
14
|
/**
|
|
15
15
|
* A git revision (`--check --base <rev>`, pull requests): the entries the file had there are
|
|
16
|
-
* published
|
|
17
|
-
*
|
|
18
|
-
* (`marketplace-
|
|
16
|
+
* published. An entry of a version the base lists must keep its source and integrity
|
|
17
|
+
* (`marketplace-integrity`); an entry of a version the base does not list must be newer than
|
|
18
|
+
* every version the base lists for that plugin (`marketplace-version-decrease`) and, when it is
|
|
19
|
+
* the tree's version, match the tree's pack (`marketplace-integrity`). A file the base does not
|
|
20
|
+
* have constrains nothing.
|
|
19
21
|
*/
|
|
20
22
|
base?: string;
|
|
21
23
|
}
|
|
22
24
|
/** The result of {@link syncMarketplace}. */
|
|
23
25
|
export interface SyncMarketplaceResult {
|
|
24
|
-
/**
|
|
26
|
+
/** New entries: plugins not listed at their current version (written with `write`). */
|
|
25
27
|
added: MarketplaceEntry[];
|
|
28
|
+
/** `name@version` of the other entries of the tree's plugins (dropped with `write`). */
|
|
29
|
+
removed: string[];
|
|
26
30
|
/**
|
|
27
|
-
* `
|
|
28
|
-
*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
* `name@version` of listed entries whose `summary` / `displayName` differ from plugin.json
|
|
32
|
+
* (rewritten with `write`; source and integrity never change).
|
|
33
|
+
*/
|
|
34
|
+
refreshed: string[];
|
|
35
|
+
/**
|
|
36
|
+
* `marketplace-invalid` (the file does not parse, or would not after writing),
|
|
37
|
+
* `marketplace-integrity` and `marketplace-version-decrease` (with a base, see
|
|
38
|
+
* {@link SyncMarketplaceOptions.base}) and, without `write`, `marketplace-missing` (one per
|
|
39
|
+
* plugin whose current version is not listed, or not as its only entry) and
|
|
40
|
+
* `marketplace-display-stale` (a listed entry's summary / displayName differ from plugin.json).
|
|
31
41
|
*/
|
|
32
42
|
findings: Finding[];
|
|
33
43
|
}
|
|
34
44
|
/**
|
|
35
|
-
* `capybara-plugin marketplace`: keeps a plugin repository's `marketplace.json` listing
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* entry `{ name, version, summary, homepage?, permissions, source: { npm: {
|
|
40
|
-
* integrity } } }`
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* Entries of
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
45
|
+
* `capybara-plugin marketplace`: keeps a plugin repository's `marketplace.json` listing one entry
|
|
46
|
+
* per public plugin, its current version (plugin component management spec §13.2, replacing the
|
|
47
|
+
* one-entry-per-version rule of the package ecosystem spec §5.2). Each public plugin (not
|
|
48
|
+
* `"private": true`) not listed at its version is packed reproducibly with {@link packPlugin} and
|
|
49
|
+
* gets an entry `{ name, version, summary, displayName?, homepage?, permissions, source: { npm: {
|
|
50
|
+
* package, version, integrity } } }` (`summary` from the plugin.json `description`, a string being
|
|
51
|
+
* `en`; `displayName` copied from plugin.json; `integrity` the pack's sha512, which the release
|
|
52
|
+
* then publishes byte for byte; `permissions` display only). The new entry takes the place of the
|
|
53
|
+
* plugin's first entry (a version that moved), the plugin's other entries are dropped (also those
|
|
54
|
+
* of a file written in the older one-entry-per-version form), and a plugin not listed yet is
|
|
55
|
+
* appended. Entries of plugins not in the tree are kept. A version already listed is not packed or
|
|
56
|
+
* compared: once published, its bytes are the release gate's business (`release --marketplace`),
|
|
57
|
+
* so a later source or toolchain change at the same version is not a finding; only its display
|
|
58
|
+
* fields (`summary`, `displayName`) are refreshed from the source plugin.json. Every other field
|
|
59
|
+
* of a kept entry stays as written, among them `deprecated`, which the maintainer sets by hand on
|
|
60
|
+
* a published version's entry (not in plugin.json: that would change the packed bytes); a new
|
|
61
|
+
* version's entry has none, and no rule compares it with the base. With `base`, see
|
|
62
|
+
* {@link SyncMarketplaceOptions.base}. The file is written formatted as Biome formats it
|
|
63
|
+
* ({@link formatMarketplaceJson}); nothing is written when there is any other finding.
|
|
50
64
|
*/
|
|
51
65
|
export declare function syncMarketplace(opts: SyncMarketplaceOptions): Promise<SyncMarketplaceResult>;
|
|
52
66
|
/**
|