@webboxes/plugin-hub 0.0.0-stage → 0.1.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 (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +8 -2
  3. package/dist/contract.d.ts +63 -0
  4. package/dist/contract.d.ts.map +1 -0
  5. package/dist/contract.js +310 -0
  6. package/dist/contract.js.map +1 -0
  7. package/dist/folders.d.ts +28 -0
  8. package/dist/folders.d.ts.map +1 -0
  9. package/dist/folders.js +88 -0
  10. package/dist/folders.js.map +1 -0
  11. package/dist/github-cli.d.ts +18 -0
  12. package/dist/github-cli.d.ts.map +1 -0
  13. package/dist/github-cli.js +140 -0
  14. package/dist/github-cli.js.map +1 -0
  15. package/dist/http.d.ts +17 -0
  16. package/dist/http.d.ts.map +1 -0
  17. package/dist/http.js +57 -0
  18. package/dist/http.js.map +1 -0
  19. package/dist/hub.d.ts +129 -0
  20. package/dist/hub.d.ts.map +1 -0
  21. package/dist/hub.js +148 -0
  22. package/dist/hub.js.map +1 -0
  23. package/dist/index.d.ts +17 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +20 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/name.d.ts +31 -0
  28. package/dist/name.d.ts.map +1 -0
  29. package/dist/name.js +57 -0
  30. package/dist/name.js.map +1 -0
  31. package/dist/npm-cli.d.ts +11 -0
  32. package/dist/npm-cli.d.ts.map +1 -0
  33. package/dist/npm-cli.js +102 -0
  34. package/dist/npm-cli.js.map +1 -0
  35. package/dist/npm-publish.d.ts +36 -0
  36. package/dist/npm-publish.d.ts.map +1 -0
  37. package/dist/npm-publish.js +63 -0
  38. package/dist/npm-publish.js.map +1 -0
  39. package/dist/pack.d.ts +32 -0
  40. package/dist/pack.d.ts.map +1 -0
  41. package/dist/pack.js +137 -0
  42. package/dist/pack.js.map +1 -0
  43. package/dist/pull.d.ts +53 -0
  44. package/dist/pull.d.ts.map +1 -0
  45. package/dist/pull.js +121 -0
  46. package/dist/pull.js.map +1 -0
  47. package/dist/save.d.ts +10 -0
  48. package/dist/save.d.ts.map +1 -0
  49. package/dist/save.js +15 -0
  50. package/dist/save.js.map +1 -0
  51. package/dist/share.d.ts +65 -0
  52. package/dist/share.d.ts.map +1 -0
  53. package/dist/share.js +133 -0
  54. package/dist/share.js.map +1 -0
  55. package/dist/source.d.ts +38 -0
  56. package/dist/source.d.ts.map +1 -0
  57. package/dist/source.js +122 -0
  58. package/dist/source.js.map +1 -0
  59. package/dist/store.d.ts +43 -0
  60. package/dist/store.d.ts.map +1 -0
  61. package/dist/store.js +112 -0
  62. package/dist/store.js.map +1 -0
  63. package/dist/tarball.d.ts +16 -0
  64. package/dist/tarball.d.ts.map +1 -0
  65. package/dist/tarball.js +138 -0
  66. package/dist/tarball.js.map +1 -0
  67. package/dist/version.d.ts +16 -0
  68. package/dist/version.d.ts.map +1 -0
  69. package/dist/version.js +69 -0
  70. package/dist/version.js.map +1 -0
  71. package/package.json +44 -3
package/dist/pull.js ADDED
@@ -0,0 +1,121 @@
1
+ // Pulling a plugin into the store (spec 044 lifecycle.md, "Pull: the sources"): resolve the source, fetch its tarball, check its sha512, read
2
+ // what it is, and keep it. Installing it into an app is the next layer's job (DSH's `pluginManager.installBundle` on the stored file), after
3
+ // the app checks the service contract; this module never runs a plugin's code and never runs a package manager.
4
+ import { readFileSync } from 'node:fs';
5
+ import { parsePluginName } from './name.js';
6
+ import { manifestOfTarball } from './pack.js';
7
+ import { formatPluginSource } from './source.js';
8
+ import { PluginStore } from './store.js';
9
+ import { integrityOf, readTarball } from './tarball.js';
10
+ import { parseVersion } from './version.js';
11
+ export class PullError extends Error {
12
+ source;
13
+ reason;
14
+ constructor(source, reason) {
15
+ super(`cannot pull ${source}: ${reason}`);
16
+ this.source = source;
17
+ this.reason = reason;
18
+ this.name = 'PullError';
19
+ }
20
+ }
21
+ function need(port, what, source) {
22
+ if (port === undefined)
23
+ throw new PullError(source, `this app has no ${what} connection`);
24
+ return port;
25
+ }
26
+ async function fetchSource(source, ports, label) {
27
+ switch (source.kind) {
28
+ case 'folder':
29
+ throw new PullError(label, 'a folder is a plugin you edit, not a release; install it as a source plugin (acryl plugin add <folder>)');
30
+ case 'store': {
31
+ const stored = ports.store.get(source.name.full, source.version);
32
+ if (stored === undefined)
33
+ throw new PullError(label, `the store has no ${source.name.full}${source.version === undefined ? '' : `@${source.version}`}`);
34
+ return stored;
35
+ }
36
+ case 'name': {
37
+ const stored = ports.store.get(source.name.full, source.version);
38
+ if (stored !== undefined)
39
+ return stored;
40
+ return fetchSource({ kind: 'npm', name: source.name, ...(source.version === undefined ? {} : { version: source.version }) }, ports, label);
41
+ }
42
+ case 'npm': {
43
+ const registry = need(ports.registry, 'npm registry', label);
44
+ const resolved = await registry.resolve(source.name.full, source.version);
45
+ if (resolved === undefined)
46
+ throw new PullError(label, `npm has no ${source.name.full}${source.version === undefined ? '' : `@${source.version}`}`);
47
+ return { bytes: await registry.download(resolved.tarball), fetchedFrom: resolved.tarball, ...(resolved.integrity === undefined ? {} : { vouched: resolved.integrity }), expectName: source.name.full, expectVersion: resolved.version };
48
+ }
49
+ case 'github': {
50
+ const releases = need(ports.releases, 'GitHub', label);
51
+ const release = await releases.release(source.owner, source.repo, source.version === undefined ? undefined : `v${source.version}`);
52
+ if (release === undefined) {
53
+ throw new PullError(label, source.version === undefined
54
+ ? `${source.owner}/${source.repo} has no release that this app can see; ask its author to publish one (if it is private, sign in with gh as someone who can read it), or pull a folder`
55
+ : `${source.owner}/${source.repo} has no release v${source.version}`);
56
+ }
57
+ const tarballs = release.assets.filter(asset => /\.tgz$/u.test(asset.name));
58
+ if (tarballs.length !== 1)
59
+ throw new PullError(label, `release ${release.tag} of ${source.owner}/${source.repo} has ${tarballs.length} .tgz files; a plugin release attaches exactly one`);
60
+ const asset = tarballs[0];
61
+ const version = release.tag.replace(/^v/u, '');
62
+ return { bytes: await releases.download(asset.url), fetchedFrom: asset.url, ...(parseVersion(version) === undefined ? {} : { expectVersion: version }) };
63
+ }
64
+ case 'tarball-file':
65
+ try {
66
+ return { bytes: readFileSync(source.path), fetchedFrom: source.path };
67
+ }
68
+ catch (cause) {
69
+ throw new PullError(label, `the file cannot be read (${cause instanceof Error ? cause.message : String(cause)})`);
70
+ }
71
+ case 'tarball-url':
72
+ return { bytes: await need(ports.download, 'download', label)(source.url), fetchedFrom: source.url };
73
+ }
74
+ }
75
+ /** Pull a plugin into the store. Every check runs before anything is stored; a failed pull leaves the store as it was. */
76
+ export async function pullPlugin(source, ports, options = {}) {
77
+ const label = formatPluginSource(source);
78
+ const fetched = await fetchSource(source, ports, label);
79
+ if ('storedAt' in fetched) {
80
+ if (options.expectIntegrity !== undefined && options.expectIntegrity !== fetched.integrity)
81
+ throw new PullError(label, `the stored ${fetched.name}@${fetched.version} has checksum ${fetched.integrity}, not the expected ${options.expectIntegrity}`);
82
+ const manifest = manifestOfTarball(readTarball(readFileSync(fetched.path)));
83
+ return { stored: fetched, added: false, manifest, fetchedFrom: fetched.path };
84
+ }
85
+ const integrity = integrityOf(fetched.bytes);
86
+ for (const expected of [fetched.vouched, options.expectIntegrity]) {
87
+ if (expected !== undefined && expected !== integrity)
88
+ throw new PullError(label, `the downloaded file's checksum ${integrity} is not the expected ${expected}; nothing was installed`);
89
+ }
90
+ let manifest;
91
+ try {
92
+ manifest = manifestOfTarball(readTarball(fetched.bytes));
93
+ }
94
+ catch (cause) {
95
+ throw new PullError(label, `it is not a plugin tarball (${cause instanceof Error ? cause.message : String(cause)})`);
96
+ }
97
+ const name = typeof manifest['name'] === 'string' ? manifest['name'] : '';
98
+ const version = typeof manifest['version'] === 'string' ? manifest['version'] : '';
99
+ try {
100
+ parsePluginName(name);
101
+ }
102
+ catch (cause) {
103
+ throw new PullError(label, cause instanceof Error ? cause.message : String(cause));
104
+ }
105
+ if (parseVersion(version) === undefined)
106
+ throw new PullError(label, `its package.json has no semantic version (${JSON.stringify(version)})`);
107
+ if (fetched.expectName !== undefined && fetched.expectName !== name)
108
+ throw new PullError(label, `the tarball is ${name}, not ${fetched.expectName}`);
109
+ if (fetched.expectVersion !== undefined && fetched.expectVersion !== version)
110
+ throw new PullError(label, `the release is v${fetched.expectVersion} but the tarball inside is ${version}`);
111
+ const acryl = typeof manifest['acryl'] === 'object' && manifest['acryl'] !== null ? manifest['acryl'] : {};
112
+ const record = {
113
+ from: label,
114
+ ...(typeof acryl['requires'] === 'object' && acryl['requires'] !== null ? { requires: acryl['requires'] } : {}),
115
+ ...(typeof acryl['provides'] === 'object' && acryl['provides'] !== null ? { provides: acryl['provides'] } : {}),
116
+ ...(typeof manifest['description'] === 'string' ? { description: manifest['description'] } : {}),
117
+ };
118
+ const { added, stored } = ports.store.put(name, version, fetched.bytes, record);
119
+ return { stored, added, manifest, fetchedFrom: fetched.fetchedFrom };
120
+ }
121
+ //# sourceMappingURL=pull.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.js","sourceRoot":"","sources":["../src/pull.ts"],"names":[],"mappings":"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"}
package/dist/save.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { type PackedPlugin } from './pack.js';
2
+ import type { PluginStore, StoredVersion } from './store.js';
3
+ export interface SavedPlugin {
4
+ readonly packed: PackedPlugin;
5
+ readonly stored: StoredVersion;
6
+ /** False when this exact version and content was already saved. */
7
+ readonly added: boolean;
8
+ }
9
+ export declare function savePlugin(dir: string, store: PluginStore, now?: Date): SavedPlugin;
10
+ //# sourceMappingURL=save.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../src/save.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE5D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CACxB;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,OAAa,GAAG,WAAW,CAUzF"}
package/dist/save.js ADDED
@@ -0,0 +1,15 @@
1
+ // Saving a plugin you edit into the store (spec 044 lifecycle.md, "Save"): pack its source folder and keep the tarball, so this machine can
2
+ // install that exact version again, offline, into any app instance, and a later change has to be a new version.
3
+ import { packFolder } from './pack.js';
4
+ export function savePlugin(dir, store, now = new Date()) {
5
+ const packed = packFolder(dir);
6
+ const acryl = typeof packed.manifest['acryl'] === 'object' && packed.manifest['acryl'] !== null ? packed.manifest['acryl'] : {};
7
+ const { added, stored } = store.put(packed.name.full, packed.version, packed.tarball, {
8
+ from: dir,
9
+ ...(typeof acryl['requires'] === 'object' && acryl['requires'] !== null ? { requires: acryl['requires'] } : {}),
10
+ ...(typeof acryl['provides'] === 'object' && acryl['provides'] !== null ? { provides: acryl['provides'] } : {}),
11
+ ...(typeof packed.manifest['description'] === 'string' ? { description: packed.manifest['description'] } : {}),
12
+ }, now);
13
+ return { packed, stored, added };
14
+ }
15
+ //# sourceMappingURL=save.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save.js","sourceRoot":"","sources":["../src/save.ts"],"names":[],"mappings":"AAAA,4IAA4I;AAC5I,gHAAgH;AAChH,OAAO,EAAE,UAAU,EAAqB,MAAM,WAAW,CAAA;AAUzD,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,KAAkB,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE;IAC1E,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;IAC9B,MAAM,KAAK,GAAG,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAA4B,CAAC,CAAC,CAAC,EAAE,CAAA;IAC1J,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE;QACpF,IAAI,EAAE,GAAG;QACT,GAAG,CAAC,OAAO,KAAK,CAAC,UAAU,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,CAA6B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3I,GAAG,CAAC,OAAO,KAAK,CAAC,UAAU,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,CAA6B,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3I,GAAG,CAAC,OAAO,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/G,EAAE,GAAG,CAAC,CAAA;IACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;AAClC,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { type SecretFinding } from '@webboxes/app-persistence';
2
+ import { type PackedPlugin } from './pack.js';
3
+ import type { PluginStore } from './store.js';
4
+ /** The labels catalogs list a plugin by (decision 1): npm keywords and GitHub topics alike. */
5
+ export declare const PLUGIN_LABELS: readonly ["acryl-package", "cordis-plugin", "dsh-plugin"];
6
+ export type Visibility = 'private' | 'public';
7
+ /** The git host, through the user's own login. */
8
+ export interface RepositoryHostPort {
9
+ /** The signed-in user, the default owner. */
10
+ login(): string;
11
+ repository(owner: string, repo: string): {
12
+ readonly visibility: Visibility;
13
+ readonly url: string;
14
+ } | undefined;
15
+ createRepository(owner: string, repo: string, visibility: Visibility, description: string): void;
16
+ setVisibility(owner: string, repo: string, visibility: Visibility): void;
17
+ addTopics(owner: string, repo: string, topics: readonly string[]): void;
18
+ releaseExists(owner: string, repo: string, tag: string): boolean;
19
+ createRelease(owner: string, repo: string, tag: string, title: string, notes: string, assetPath: string): string;
20
+ /** A URL `git` can clone and push with the user's credential helper. */
21
+ cloneUrl(owner: string, repo: string): string;
22
+ }
23
+ /** The user's own git, in a temporary working copy. */
24
+ export interface PublishGitPort {
25
+ clone(url: string, dir: string): void;
26
+ /** Stage everything, commit; false when there was nothing to commit. */
27
+ commitAll(dir: string, message: string): boolean;
28
+ tag(dir: string, tag: string, message: string): void;
29
+ /** Push the current branch (named `fallbackBranch` when the repository was empty) and the tag. */
30
+ push(dir: string, tag: string, fallbackBranch: string): void;
31
+ }
32
+ export interface ShareOptions {
33
+ readonly owner?: string;
34
+ readonly repo?: string;
35
+ /** `public` lists it (the labels make catalogs find it); default: the plugin's `acryl.visibility`, else private. */
36
+ readonly visibility?: Visibility;
37
+ readonly notes?: string;
38
+ }
39
+ export type ShareResult = {
40
+ readonly status: 'shared';
41
+ readonly owner: string;
42
+ readonly repo: string;
43
+ readonly url: string;
44
+ readonly visibility: Visibility;
45
+ readonly created: boolean;
46
+ readonly tag: string;
47
+ readonly releaseUrl: string;
48
+ readonly name: string;
49
+ readonly version: string;
50
+ readonly integrity: string;
51
+ readonly files: readonly string[];
52
+ /** What was written into the plugin's package.json on the way (contract, labels, repository). */
53
+ readonly updatedManifest: readonly string[];
54
+ } | {
55
+ readonly status: 'refused';
56
+ readonly reason: string;
57
+ readonly secrets?: readonly SecretFinding[];
58
+ };
59
+ export declare function secretsIn(packed: PackedPlugin): SecretFinding[];
60
+ export declare function sharePlugin(folder: string, options: ShareOptions, ports: {
61
+ readonly host: RepositoryHostPort;
62
+ readonly git: PublishGitPort;
63
+ readonly store: PluginStore;
64
+ }): Promise<ShareResult>;
65
+ //# sourceMappingURL=share.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"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"}
package/dist/share.js ADDED
@@ -0,0 +1,133 @@
1
+ // Sharing a plugin to its own git repository with a release (spec 044, decisions 1-4, lifecycle.md "Publish: the methods"): the same steps the
2
+ // first push of acryl-quick-notes was done with by hand, as one operation whose guards nobody has to remember.
3
+ //
4
+ // 1. the target: <owner>/<repo> from the options, else package.json `repository`, else the user's own login and the plugin's name
5
+ // 2. package.json brought in line: the generated service contract and slots, the three labels, `repository`
6
+ // 3. pack, then the secret check over exactly the packed files; any finding refuses
7
+ // 4. the guards: a version is released once; a private plugin never goes to a public repository; a public one needs a license
8
+ // 5. the repository (created private unless asked public), a commit of exactly the packed files, tag v<version>, push
9
+ // 6. the release v<version> with the tarball attached, the labels as topics
10
+ // 7. the same tarball kept in the local store
11
+ //
12
+ // Credentials are the user's own (`git`, `gh`); nothing here reads, stores or asks for a token.
13
+ import { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
14
+ import { tmpdir } from 'node:os';
15
+ import { dirname, join } from 'node:path';
16
+ import { findSecrets } from '@webboxes/app-persistence';
17
+ import { syncServiceContract } from './contract.js';
18
+ import { parsePluginName } from './name.js';
19
+ import { bundleProblem, packFolder } from './pack.js';
20
+ import { readTarball } from './tarball.js';
21
+ /** The labels catalogs list a plugin by (decision 1): npm keywords and GitHub topics alike. */
22
+ export const PLUGIN_LABELS = ['acryl-package', 'cordis-plugin', 'dsh-plugin'];
23
+ const GITHUB_REPOSITORY = /github\.com[/:]([^/]+)\/([^/#]+?)(?:\.git)?(?:#.*)?$/u;
24
+ function repositoryOf(manifest) {
25
+ const field = manifest['repository'];
26
+ const url = typeof field === 'string' ? field : typeof field === 'object' && field !== null ? field.url : undefined;
27
+ if (typeof url !== 'string')
28
+ return undefined;
29
+ const match = GITHUB_REPOSITORY.exec(url);
30
+ return match?.[1] === undefined || match[2] === undefined ? undefined : { owner: match[1], repo: match[2] };
31
+ }
32
+ function writeManifest(folder, manifest) {
33
+ writeFileSync(join(folder, 'package.json'), `${JSON.stringify(manifest, null, 2)}\n`);
34
+ }
35
+ /** The plugin's own package.json, with the labels and its repository; returns what it changed. */
36
+ function prepareManifest(folder, owner, repo, visibility) {
37
+ const manifest = JSON.parse(readFileSync(join(folder, 'package.json'), 'utf8'));
38
+ const changed = [];
39
+ const keywords = Array.isArray(manifest['keywords']) ? manifest['keywords'].filter((word) => typeof word === 'string') : [];
40
+ const missing = PLUGIN_LABELS.filter(label => !keywords.includes(label));
41
+ if (missing.length > 0) {
42
+ manifest['keywords'] = [...keywords, ...missing];
43
+ changed.push(`keywords +${missing.join(', +')}`);
44
+ }
45
+ if (repositoryOf(manifest) === undefined) {
46
+ manifest['repository'] = { type: 'git', url: `git+https://github.com/${owner}/${repo}.git` };
47
+ changed.push('repository');
48
+ }
49
+ const acryl = typeof manifest['acryl'] === 'object' && manifest['acryl'] !== null ? manifest['acryl'] : undefined;
50
+ if (acryl !== undefined && acryl['visibility'] !== visibility && visibility === 'public') {
51
+ manifest['acryl'] = { ...acryl, visibility };
52
+ changed.push('acryl.visibility public');
53
+ }
54
+ if (changed.length > 0)
55
+ writeManifest(folder, manifest);
56
+ return changed;
57
+ }
58
+ export function secretsIn(packed) {
59
+ return findSecrets(readTarball(packed.tarball).map(file => ({ path: file.path, text: Buffer.from(file.content).toString('utf8') })));
60
+ }
61
+ /** Replace a working copy's files (all but `.git`) with exactly the packed ones. */
62
+ function replaceWorkingCopy(dir, packed) {
63
+ for (const entry of readdirSync(dir))
64
+ if (entry !== '.git')
65
+ rmSync(join(dir, entry), { recursive: true, force: true });
66
+ for (const file of readTarball(packed.tarball)) {
67
+ const path = join(dir, ...file.path.split('/'));
68
+ mkdirSync(dirname(path), { recursive: true });
69
+ writeFileSync(path, file.content, { mode: file.executable === true ? 0o755 : 0o644 });
70
+ }
71
+ }
72
+ export async function sharePlugin(folder, options, ports) {
73
+ const refuse = (reason, secrets) => ({ status: 'refused', reason, ...(secrets === undefined ? {} : { secrets }) });
74
+ if (!existsSync(join(folder, 'package.json')))
75
+ return refuse(`${folder} has no package.json`);
76
+ const before = JSON.parse(readFileSync(join(folder, 'package.json'), 'utf8'));
77
+ const name = parsePluginName(String(before['name']));
78
+ const declared = repositoryOf(before);
79
+ const owner = options.owner ?? declared?.owner ?? name.owner ?? ports.host.login();
80
+ const repo = options.repo ?? declared?.repo ?? name.local;
81
+ const acryl = before['acryl'];
82
+ const visibility = options.visibility ?? (acryl?.visibility === 'public' ? 'public' : 'private');
83
+ if (visibility === 'public' && typeof before['license'] !== 'string')
84
+ return refuse('a public plugin needs a "license" in its package.json (for example "MIT")');
85
+ const contract = await syncServiceContract(folder);
86
+ if (!contract.ok)
87
+ return refuse(`its service contract cannot be read: ${contract.errors.join('; ')}`);
88
+ const updatedManifest = [...(contract.written ? ['service contract and slots'] : []), ...prepareManifest(folder, owner, repo, visibility)];
89
+ const packed = packFolder(folder);
90
+ const notBundle = bundleProblem(packed);
91
+ if (notBundle !== undefined)
92
+ return refuse(notBundle);
93
+ const secrets = secretsIn(packed);
94
+ if (secrets.length > 0)
95
+ return refuse(`the secret check found ${String(secrets.length)} possible secret(s) in the files that would be shared; nothing was sent`, secrets);
96
+ const tag = `v${packed.version}`;
97
+ const existing = ports.host.repository(owner, repo);
98
+ if (existing !== undefined && existing.visibility === 'public' && visibility === 'private')
99
+ return refuse(`${owner}/${repo} is public and this plugin is private; a private plugin is never sent to a public repository`);
100
+ if (existing !== undefined && ports.host.releaseExists(owner, repo, tag))
101
+ return refuse(`${owner}/${repo} already has release ${tag}; a version is released once, so give this change a new version (acryl plugin version patch)`);
102
+ const kept = ports.store.list().find(entry => entry.name === packed.name.full && entry.version === packed.version);
103
+ if (kept !== undefined && kept.integrity !== packed.integrity)
104
+ return refuse(`${packed.name.full} ${packed.version} was already saved here with different files; give this change a new version (acryl plugin version patch)`);
105
+ const created = existing === undefined;
106
+ if (created)
107
+ ports.host.createRepository(owner, repo, visibility, typeof before['description'] === 'string' ? before['description'] : packed.name.full);
108
+ const work = mkdtempSync(join(tmpdir(), 'plugin-hub-share-'));
109
+ try {
110
+ const dir = join(work, 'repo');
111
+ ports.git.clone(ports.host.cloneUrl(owner, repo), dir);
112
+ replaceWorkingCopy(dir, packed);
113
+ ports.git.commitAll(dir, `${packed.name.full} ${packed.version}`);
114
+ ports.git.tag(dir, tag, `${packed.name.full} ${packed.version}`);
115
+ ports.git.push(dir, tag, 'main');
116
+ const asset = join(work, packed.fileName);
117
+ writeFileSync(asset, packed.tarball);
118
+ const notes = options.notes ?? `${packed.name.full} ${packed.version}\n\nTarball: ${packed.fileName}\nIntegrity: ${packed.integrity}\nFiles: ${String(packed.files.length)}`;
119
+ const releaseUrl = ports.host.createRelease(owner, repo, tag, `${packed.name.full} ${packed.version}`, notes, asset);
120
+ if (existing !== undefined && existing.visibility === 'private' && visibility === 'public')
121
+ ports.host.setVisibility(owner, repo, 'public');
122
+ ports.host.addTopics(owner, repo, PLUGIN_LABELS);
123
+ ports.store.put(packed.name.full, packed.version, packed.tarball, { from: folder });
124
+ return {
125
+ status: 'shared', owner, repo, url: `https://github.com/${owner}/${repo}`, visibility, created, tag, releaseUrl,
126
+ name: packed.name.full, version: packed.version, integrity: packed.integrity, files: packed.files, updatedManifest,
127
+ };
128
+ }
129
+ finally {
130
+ rmSync(work, { recursive: true, force: true });
131
+ }
132
+ }
133
+ //# sourceMappingURL=share.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share.js","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { type PluginName } from './name.js';
2
+ export type PluginSource = {
3
+ readonly kind: 'store';
4
+ readonly name: PluginName;
5
+ readonly version?: string;
6
+ } | {
7
+ readonly kind: 'github';
8
+ readonly owner: string;
9
+ readonly repo: string;
10
+ readonly version?: string;
11
+ } | {
12
+ readonly kind: 'npm';
13
+ readonly name: PluginName;
14
+ readonly version?: string;
15
+ } | {
16
+ readonly kind: 'name';
17
+ readonly name: PluginName;
18
+ readonly version?: string;
19
+ } | {
20
+ readonly kind: 'tarball-file';
21
+ readonly path: string;
22
+ } | {
23
+ readonly kind: 'tarball-url';
24
+ readonly url: string;
25
+ } | {
26
+ readonly kind: 'folder';
27
+ readonly path: string;
28
+ };
29
+ export declare class InvalidPluginSourceError extends Error {
30
+ readonly input: string;
31
+ readonly reason: string;
32
+ constructor(input: string, reason: string);
33
+ }
34
+ /** Read the source argument. A path must be absolute: a relative one means nothing to a browser page or a background engine. */
35
+ export declare function parsePluginSource(input: string): PluginSource;
36
+ /** The argument that names a source, so a result or a record can be read back by `parsePluginSource`. */
37
+ export declare function formatPluginSource(source: PluginSource): string;
38
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"AAcA,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,WAAW,CAAA;AAG5D,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAChF;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACrG;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/E;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtD,qBAAa,wBAAyB,SAAQ,KAAK;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM;gBAAtC,KAAK,EAAE,MAAM,EAAW,MAAM,EAAE,MAAM;CAI5D;AAkCD,gIAAgI;AAChI,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CA4B7D;AAED,yGAAyG;AACzG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAW/D"}
package/dist/source.js ADDED
@@ -0,0 +1,122 @@
1
+ // The one argument every face takes to say where a plugin comes from (spec 044 lifecycle.md, "Pull: the sources"):
2
+ //
3
+ // store:<name>[@<version>] the local store on this machine
4
+ // github:<owner>/<repo>[@<version>] that repository's release tarball (latest release when no version)
5
+ // https://github.com/<owner>/<repo> the same, written as the repository's address
6
+ // npm:<name>[@<version>] the npm registry
7
+ // /absolute/path/plugin-1.0.0.tgz a tarball file
8
+ // https://host/path/plugin-1.0.0.tgz a tarball URL
9
+ // /absolute/path/folder a source folder (installed as a plugin you edit, not pulled)
10
+ // <name>[@<version>] the store if it has the name, else npm
11
+ //
12
+ // A raw git address (`git+https://...`, `git@host:...`, `github:owner/repo#branch`) is refused: it installs whatever a branch holds at that
13
+ // moment, with no release and no checksum (spec 044 decision 3, D7).
14
+ import { isAbsolute } from 'node:path';
15
+ import { parsePluginName } from './name.js';
16
+ import { parseVersion } from './version.js';
17
+ export class InvalidPluginSourceError extends Error {
18
+ input;
19
+ reason;
20
+ constructor(input, reason) {
21
+ super(`${JSON.stringify(input)} cannot be pulled: ${reason}`);
22
+ this.input = input;
23
+ this.reason = reason;
24
+ this.name = 'InvalidPluginSourceError';
25
+ }
26
+ }
27
+ const TARBALL = /\.(?:tgz|tar\.gz)$/iu;
28
+ const GITHUB_OWNER = /^[a-z0-9](?:[a-z0-9-]{0,38})$/iu;
29
+ const GITHUB_REPO = /^[a-z0-9._-]{1,100}$/iu;
30
+ const RAW_GIT = /^(?:git\+|git:|git@|ssh:\/\/|gitlab:|bitbucket:|gist:)/iu;
31
+ /** `name@1.2.3` or `@scope/name@1.2.3` into its name and version; the `@` of a scope is not a version separator. */
32
+ function splitVersion(input, raw) {
33
+ const at = input.lastIndexOf('@');
34
+ if (at <= 0)
35
+ return { base: input };
36
+ const base = input.slice(0, at);
37
+ const version = input.slice(at + 1).replace(/^v(?=\d)/u, '');
38
+ if (parseVersion(version) === undefined)
39
+ throw new InvalidPluginSourceError(raw, `${JSON.stringify(input.slice(at + 1))} is not an exact version such as 1.2.3`);
40
+ return { base, version };
41
+ }
42
+ function named(kind, rest, raw) {
43
+ const { base, version } = splitVersion(rest, raw);
44
+ let name;
45
+ try {
46
+ name = parsePluginName(base);
47
+ }
48
+ catch (cause) {
49
+ throw new InvalidPluginSourceError(raw, cause instanceof Error ? cause.message : String(cause));
50
+ }
51
+ return { kind, name, ...(version === undefined ? {} : { version }) };
52
+ }
53
+ function github(owner, repoWithVersion, raw) {
54
+ if (repoWithVersion.includes('#'))
55
+ throw new InvalidPluginSourceError(raw, 'a branch or commit is not a release; name a released version (github:owner/repo@1.2.3) or leave it out for the latest release');
56
+ const { base: repo, version } = splitVersion(repoWithVersion.replace(/\.git$/u, ''), raw);
57
+ if (!GITHUB_OWNER.test(owner))
58
+ throw new InvalidPluginSourceError(raw, `${JSON.stringify(owner)} is not a GitHub user or organization`);
59
+ if (!GITHUB_REPO.test(repo))
60
+ throw new InvalidPluginSourceError(raw, `${JSON.stringify(repo)} is not a GitHub repository name`);
61
+ return { kind: 'github', owner, repo, ...(version === undefined ? {} : { version }) };
62
+ }
63
+ /** Read the source argument. A path must be absolute: a relative one means nothing to a browser page or a background engine. */
64
+ export function parsePluginSource(input) {
65
+ const raw = input.trim();
66
+ if (raw === '')
67
+ throw new InvalidPluginSourceError(input, 'it is empty');
68
+ if (RAW_GIT.test(raw))
69
+ throw new InvalidPluginSourceError(raw, 'a git address installs whatever a branch holds, with no release and no checksum; pull a released version (github:owner/repo@1.2.3) or a folder');
70
+ if (raw.startsWith('store:'))
71
+ return named('store', raw.slice('store:'.length), raw);
72
+ if (raw.startsWith('npm:'))
73
+ return named('npm', raw.slice('npm:'.length), raw);
74
+ if (raw.startsWith('github:')) {
75
+ const [owner, repo, extra] = raw.slice('github:'.length).split('/');
76
+ if (owner === undefined || repo === undefined || extra !== undefined)
77
+ throw new InvalidPluginSourceError(raw, 'write github:<owner>/<repository>[@<version>]');
78
+ return github(owner, repo, raw);
79
+ }
80
+ if (/^https?:\/\//iu.test(raw)) {
81
+ let url;
82
+ try {
83
+ url = new URL(raw);
84
+ }
85
+ catch {
86
+ throw new InvalidPluginSourceError(raw, 'it is not a valid URL');
87
+ }
88
+ if (url.protocol !== 'https:')
89
+ throw new InvalidPluginSourceError(raw, 'only https is accepted, so nobody on the network can change what is installed');
90
+ if (TARBALL.test(url.pathname))
91
+ return { kind: 'tarball-url', url: url.href };
92
+ if (url.hostname === 'github.com') {
93
+ const parts = url.pathname.split('/').filter(Boolean);
94
+ const [owner, repo, section, sub, tag] = parts;
95
+ if (owner !== undefined && repo !== undefined && parts.length === 2 && url.hash === '')
96
+ return github(owner, repo, raw);
97
+ if (owner !== undefined && repo !== undefined && section === 'releases' && sub === 'tag' && tag !== undefined && parts.length === 5)
98
+ return github(owner, `${repo}@${tag}`, raw);
99
+ throw new InvalidPluginSourceError(raw, 'name the repository (https://github.com/owner/repo) or one of its releases (.../releases/tag/v1.2.3)');
100
+ }
101
+ throw new InvalidPluginSourceError(raw, 'a URL must point to a .tgz file or a GitHub repository');
102
+ }
103
+ if (isAbsolute(raw))
104
+ return TARBALL.test(raw) ? { kind: 'tarball-file', path: raw } : { kind: 'folder', path: raw };
105
+ if (/^\.{1,2}(?:[\\/]|$)/u.test(raw) || raw.includes('\\'))
106
+ throw new InvalidPluginSourceError(raw, 'a path must be absolute');
107
+ return named('name', raw, raw);
108
+ }
109
+ /** The argument that names a source, so a result or a record can be read back by `parsePluginSource`. */
110
+ export function formatPluginSource(source) {
111
+ const at = (version) => (version === undefined ? '' : `@${version}`);
112
+ switch (source.kind) {
113
+ case 'store': return `store:${source.name.full}${at(source.version)}`;
114
+ case 'npm': return `npm:${source.name.full}${at(source.version)}`;
115
+ case 'name': return `${source.name.full}${at(source.version)}`;
116
+ case 'github': return `github:${source.owner}/${source.repo}${at(source.version)}`;
117
+ case 'tarball-file': return source.path;
118
+ case 'tarball-url': return source.url;
119
+ case 'folder': return source.path;
120
+ }
121
+ }
122
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ export interface StoreRecord {
2
+ readonly integrity: string;
3
+ /** ISO time it entered the store. */
4
+ readonly storedAt: string;
5
+ /** Where it came from, as a source argument (`parsePluginSource` reads it back): a folder for a save, the pulled source otherwise. */
6
+ readonly from: string;
7
+ /** The service contract and slots as its package.json declared them, so a list can say whether an app runs it without opening the tarball. */
8
+ readonly requires?: Readonly<Record<string, readonly string[]>>;
9
+ readonly provides?: Readonly<Record<string, readonly string[]>>;
10
+ readonly description?: string;
11
+ }
12
+ export interface StoredVersion extends StoreRecord {
13
+ readonly name: string;
14
+ readonly version: string;
15
+ /** Absolute path of the tarball. */
16
+ readonly path: string;
17
+ }
18
+ export declare class StoreConflictError extends Error {
19
+ readonly pluginName: string;
20
+ readonly version: string;
21
+ constructor(pluginName: string, version: string);
22
+ }
23
+ export declare class PluginStore {
24
+ readonly root: string;
25
+ constructor(root: string);
26
+ private get indexPath();
27
+ private read;
28
+ /** Where a version's tarball lives, whether or not it is stored yet. */
29
+ tarballPath(name: string, version: string): string;
30
+ /**
31
+ * Keep a tarball. Storing the same bytes again is a no-op (`added: false`); different bytes under a stored version are refused.
32
+ * The tarball is written before the index, so an interrupted put leaves at most an unlisted file, never a listed version without one.
33
+ */
34
+ put(name: string, version: string, tarball: Uint8Array, record: Omit<StoreRecord, 'integrity' | 'storedAt'>, now?: Date): {
35
+ readonly added: boolean;
36
+ readonly stored: StoredVersion;
37
+ };
38
+ /** One version, or the newest when no version is given. A listed version whose file is gone or changed is reported, not returned. */
39
+ get(name: string, version?: string): StoredVersion | undefined;
40
+ /** Every stored version, by name, newest first. */
41
+ list(): StoredVersion[];
42
+ }
43
+ //# sourceMappingURL=store.d.ts.map