putitoutthere 0.1.44 → 0.1.46

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 (58) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/MIGRATIONS.md +82 -5
  3. package/README.md +16 -42
  4. package/action.yml +2 -2
  5. package/dist/cascade.d.ts +1 -1
  6. package/dist/cascade.js +2 -2
  7. package/dist/cli.d.ts +5 -0
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +7 -383
  10. package/dist/cli.js.map +1 -1
  11. package/dist/config.d.ts +6 -55
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/config.js +1 -32
  14. package/dist/config.js.map +1 -1
  15. package/dist/publish.d.ts +0 -10
  16. package/dist/publish.d.ts.map +1 -1
  17. package/dist/publish.js +6 -52
  18. package/dist/publish.js.map +1 -1
  19. package/dist/types.d.ts +1 -21
  20. package/dist/types.d.ts.map +1 -1
  21. package/dist/types.js.map +1 -1
  22. package/package.json +3 -2
  23. package/dist/auth.d.ts +0 -68
  24. package/dist/auth.d.ts.map +0 -1
  25. package/dist/auth.js +0 -285
  26. package/dist/auth.js.map +0 -1
  27. package/dist/doctor.d.ts +0 -115
  28. package/dist/doctor.d.ts.map +0 -1
  29. package/dist/doctor.js +0 -292
  30. package/dist/doctor.js.map +0 -1
  31. package/dist/keyring.d.ts +0 -35
  32. package/dist/keyring.d.ts.map +0 -1
  33. package/dist/keyring.js +0 -88
  34. package/dist/keyring.js.map +0 -1
  35. package/dist/oidc-policy.d.ts +0 -145
  36. package/dist/oidc-policy.d.ts.map +0 -1
  37. package/dist/oidc-policy.js +0 -388
  38. package/dist/oidc-policy.js.map +0 -1
  39. package/dist/preflight-run.d.ts +0 -47
  40. package/dist/preflight-run.d.ts.map +0 -1
  41. package/dist/preflight-run.js +0 -197
  42. package/dist/preflight-run.js.map +0 -1
  43. package/dist/registries/crates-trust.d.ts +0 -69
  44. package/dist/registries/crates-trust.d.ts.map +0 -1
  45. package/dist/registries/crates-trust.js +0 -95
  46. package/dist/registries/crates-trust.js.map +0 -1
  47. package/dist/release.d.ts +0 -36
  48. package/dist/release.d.ts.map +0 -1
  49. package/dist/release.js +0 -102
  50. package/dist/release.js.map +0 -1
  51. package/dist/token-scope.d.ts +0 -65
  52. package/dist/token-scope.d.ts.map +0 -1
  53. package/dist/token-scope.js +0 -163
  54. package/dist/token-scope.js.map +0 -1
  55. package/dist/token.d.ts +0 -211
  56. package/dist/token.d.ts.map +0 -1
  57. package/dist/token.js +0 -719
  58. package/dist/token.js.map +0 -1
@@ -1,69 +0,0 @@
1
- /**
2
- * crates.io trusted-publishing read API.
3
- *
4
- * Issue #189. crates.io exposes `GET /api/v1/trusted_publishing/github_configs?crate=<name>`
5
- * that returns each registered GitHub trust-policy config — enough to
6
- * diff against a local `[package.trust_policy]` declaration and catch
7
- * the `release.yml → patch-release.yml` rename landmine before it
8
- * breaks a live publish.
9
- *
10
- * PyPI and npm do NOT have a usable read API from CI: PyPI has no
11
- * current-policy endpoint (only past provenance via PEP 740), and
12
- * npm's equivalent requires 2FA/OTP on every call and rejects
13
- * bypass-2FA tokens. See `docs/guide/auth.md` for the full matrix.
14
- */
15
- /** One `GitHubConfig` entry from crates.io's trust-policy API. */
16
- export interface CratesGithubConfig {
17
- id: number;
18
- repository_owner: string;
19
- repository_name: string;
20
- workflow_filename: string;
21
- environment: string | null;
22
- }
23
- export type CratesTrustFetchResult = {
24
- kind: 'ok';
25
- configs: CratesGithubConfig[];
26
- }
27
- /** Transient failure — timeout, network error, or 5xx. Neutral-skip in doctor. */
28
- | {
29
- kind: 'skip-transient';
30
- reason: string;
31
- }
32
- /** Token rejected (401). Fails the phase; user must fix the token. */
33
- | {
34
- kind: 'auth-failed';
35
- reason: string;
36
- };
37
- export interface FetchOptions {
38
- /** Override for tests; defaults to `API_BASE`. */
39
- apiBase?: string;
40
- /** Override for tests; defaults to `AbortSignal.timeout(5000)`. */
41
- signal?: AbortSignal;
42
- }
43
- /**
44
- * Fetches the crates.io trust-policy configs for a crate. Wraps the
45
- * network call in a 5s timeout; transient failures (timeout, 5xx,
46
- * network error) return `skip-transient` so `doctor` doesn't turn red
47
- * because crates.io is having a bad minute. A 401 returns
48
- * `auth-failed` — the token is the user's responsibility to fix.
49
- */
50
- export declare function fetchCratesTrustPolicy(crate: string, token: string, opts?: FetchOptions): Promise<CratesTrustFetchResult>;
51
- /** Issue emitted when a declared trust policy disagrees with crates.io. */
52
- export interface CratesTrustMismatch {
53
- crate: string;
54
- field: 'workflow_filename' | 'environment' | 'repository';
55
- declared: string;
56
- registered: string | null;
57
- }
58
- /**
59
- * Compare a `[package.trust_policy]` declaration against each registered
60
- * crates.io config for the same crate. Returns one mismatch per field
61
- * per config; empty when every field agrees across every registered
62
- * config.
63
- */
64
- export declare function diffCratesTrust(crate: string, declared: {
65
- workflow: string;
66
- environment?: string | undefined;
67
- repository?: string | undefined;
68
- }, configs: readonly CratesGithubConfig[]): CratesTrustMismatch[];
69
- //# sourceMappingURL=crates-trust.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crates-trust.d.ts","sourceRoot":"","sources":["../../src/registries/crates-trust.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,kEAAkE;AAClE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,kBAAkB,EAAE,CAAA;CAAE;AAC/C,kFAAkF;GAChF;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAC5C,sEAAsE;GACpE;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5C,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,sBAAsB,CAAC,CA8BjC;AAED,2EAA2E;AAC3E,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,mBAAmB,GAAG,aAAa,GAAG,YAAY,CAAC;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,EACjG,OAAO,EAAE,SAAS,kBAAkB,EAAE,GACrC,mBAAmB,EAAE,CAgCvB"}
@@ -1,95 +0,0 @@
1
- /**
2
- * crates.io trusted-publishing read API.
3
- *
4
- * Issue #189. crates.io exposes `GET /api/v1/trusted_publishing/github_configs?crate=<name>`
5
- * that returns each registered GitHub trust-policy config — enough to
6
- * diff against a local `[package.trust_policy]` declaration and catch
7
- * the `release.yml → patch-release.yml` rename landmine before it
8
- * breaks a live publish.
9
- *
10
- * PyPI and npm do NOT have a usable read API from CI: PyPI has no
11
- * current-policy endpoint (only past provenance via PEP 740), and
12
- * npm's equivalent requires 2FA/OTP on every call and rejects
13
- * bypass-2FA tokens. See `docs/guide/auth.md` for the full matrix.
14
- */
15
- import { USER_AGENT } from '../version.js';
16
- const API_BASE = 'https://crates.io';
17
- /**
18
- * Fetches the crates.io trust-policy configs for a crate. Wraps the
19
- * network call in a 5s timeout; transient failures (timeout, 5xx,
20
- * network error) return `skip-transient` so `doctor` doesn't turn red
21
- * because crates.io is having a bad minute. A 401 returns
22
- * `auth-failed` — the token is the user's responsibility to fix.
23
- */
24
- export async function fetchCratesTrustPolicy(crate, token, opts = {}) {
25
- const base = opts.apiBase ?? API_BASE;
26
- const url = `${base}/api/v1/trusted_publishing/github_configs?crate=${encodeURIComponent(crate)}`;
27
- const signal = opts.signal ?? AbortSignal.timeout(5000);
28
- let res;
29
- try {
30
- res = await fetch(url, {
31
- method: 'GET',
32
- headers: {
33
- 'user-agent': USER_AGENT,
34
- authorization: `Bearer ${token}`,
35
- },
36
- signal,
37
- });
38
- }
39
- catch (err) {
40
- /* v8 ignore next -- fetch always throws an Error; the String(err) fallback is defensive */
41
- const message = err instanceof Error ? err.message : String(err);
42
- return { kind: 'skip-transient', reason: message };
43
- }
44
- if (res.status === 401) {
45
- return { kind: 'auth-failed', reason: 'crates.io rejected CRATES_IO_DOCTOR_TOKEN (401)' };
46
- }
47
- if (res.status >= 500) {
48
- return { kind: 'skip-transient', reason: `crates.io returned HTTP ${res.status}` };
49
- }
50
- if (res.status !== 200) {
51
- return { kind: 'skip-transient', reason: `crates.io returned unexpected HTTP ${res.status}` };
52
- }
53
- const body = (await res.json());
54
- return { kind: 'ok', configs: body.github_configs ?? [] };
55
- }
56
- /**
57
- * Compare a `[package.trust_policy]` declaration against each registered
58
- * crates.io config for the same crate. Returns one mismatch per field
59
- * per config; empty when every field agrees across every registered
60
- * config.
61
- */
62
- export function diffCratesTrust(crate, declared, configs) {
63
- const out = [];
64
- for (const cfg of configs) {
65
- if (cfg.workflow_filename !== declared.workflow) {
66
- out.push({
67
- crate,
68
- field: 'workflow_filename',
69
- declared: declared.workflow,
70
- registered: cfg.workflow_filename,
71
- });
72
- }
73
- if (declared.environment !== undefined && cfg.environment !== declared.environment) {
74
- out.push({
75
- crate,
76
- field: 'environment',
77
- declared: declared.environment,
78
- registered: cfg.environment,
79
- });
80
- }
81
- if (declared.repository !== undefined) {
82
- const registeredRepo = `${cfg.repository_owner}/${cfg.repository_name}`;
83
- if (registeredRepo !== declared.repository) {
84
- out.push({
85
- crate,
86
- field: 'repository',
87
- declared: declared.repository,
88
- registered: registeredRepo,
89
- });
90
- }
91
- }
92
- }
93
- return out;
94
- }
95
- //# sourceMappingURL=crates-trust.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crates-trust.js","sourceRoot":"","sources":["../../src/registries/crates-trust.ts"],"names":[],"mappings":"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"}
package/dist/release.d.ts DELETED
@@ -1,36 +0,0 @@
1
- /**
2
- * GitHub Release creation.
3
- *
4
- * After a successful tag push (§13.6), create a Release on GitHub so
5
- * the new version shows up in the repo's Releases UI with body notes
6
- * generated from the commit history since the previous tag.
7
- *
8
- * No external action dependency -- uses the GitHub REST API via
9
- * fetch with the caller-supplied GITHUB_TOKEN (or the default
10
- * GITHUB_TOKEN available to every Actions run).
11
- *
12
- * Issue #26. Plan: §15.
13
- */
14
- export interface CreateReleaseOptions {
15
- tag: string;
16
- title: string;
17
- body: string;
18
- /** Override for tests. Defaults to global fetch. */
19
- fetchFn?: typeof fetch;
20
- }
21
- export interface ReleaseResult {
22
- url: string;
23
- }
24
- /**
25
- * Generate release notes from `git log <prev_tag>..<this_tag>` subject
26
- * lines. If no prior tag exists for this package, falls back to the
27
- * full history (first release).
28
- *
29
- * The filter is subject-only -- commit bodies add noise and are
30
- * already available on the tag itself.
31
- */
32
- export declare function generateReleaseNotes(packageName: string, tagName: string, opts: {
33
- cwd: string;
34
- }): string;
35
- export declare function createGitHubRelease(opts: CreateReleaseOptions): Promise<ReleaseResult | null>;
36
- //# sourceMappingURL=release.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GACpB,MAAM,CAKR;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,oBAAoB,GACzB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAiC/B"}
package/dist/release.js DELETED
@@ -1,102 +0,0 @@
1
- /**
2
- * GitHub Release creation.
3
- *
4
- * After a successful tag push (§13.6), create a Release on GitHub so
5
- * the new version shows up in the repo's Releases UI with body notes
6
- * generated from the commit history since the previous tag.
7
- *
8
- * No external action dependency -- uses the GitHub REST API via
9
- * fetch with the caller-supplied GITHUB_TOKEN (or the default
10
- * GITHUB_TOKEN available to every Actions run).
11
- *
12
- * Issue #26. Plan: §15.
13
- */
14
- import { execFileSync } from 'node:child_process';
15
- /**
16
- * Generate release notes from `git log <prev_tag>..<this_tag>` subject
17
- * lines. If no prior tag exists for this package, falls back to the
18
- * full history (first release).
19
- *
20
- * The filter is subject-only -- commit bodies add noise and are
21
- * already available on the tag itself.
22
- */
23
- export function generateReleaseNotes(packageName, tagName, opts) {
24
- const prev = findPreviousTag(packageName, tagName, opts.cwd);
25
- const range = prev ? `${prev}..${tagName}` : tagName;
26
- const out = runGit(['log', range, '--format=- %s', '--no-merges'], opts.cwd);
27
- return out.trim();
28
- }
29
- export async function createGitHubRelease(opts) {
30
- const token = process.env.GITHUB_TOKEN;
31
- const repository = process.env.GITHUB_REPOSITORY;
32
- if (!token || !repository) {
33
- // Local runs (putitoutthere doctor, operator on laptop) don't have
34
- // these. Silent-skip so we don't confuse operators with a failure
35
- // that doesn't matter outside Actions.
36
- return null;
37
- }
38
- const fetchFn = opts.fetchFn ?? fetch;
39
- const url = `https://api.github.com/repos/${repository}/releases`;
40
- const res = await fetchFn(url, {
41
- method: 'POST',
42
- headers: {
43
- authorization: `Bearer ${token}`,
44
- 'content-type': 'application/json',
45
- accept: 'application/vnd.github+json',
46
- 'user-agent': 'putitoutthere',
47
- },
48
- body: JSON.stringify({
49
- tag_name: opts.tag,
50
- name: opts.title,
51
- body: opts.body,
52
- draft: false,
53
- prerelease: isPrerelease(opts.tag),
54
- }),
55
- });
56
- if (!res.ok) {
57
- const msg = await res.text().catch(() => '');
58
- throw new Error(`GitHub release API ${res.status}: ${msg}`);
59
- }
60
- const data = (await res.json());
61
- return { url: data.html_url ?? '' };
62
- }
63
- /* ------------------------------ internals ------------------------------ */
64
- function isPrerelease(tag) {
65
- return /-(rc|beta|alpha)(\.|$)/.test(tag);
66
- }
67
- function runGit(args, cwd) {
68
- try {
69
- return execFileSync('git', args, { cwd, encoding: 'utf8' });
70
- /* v8 ignore start -- defensive wrap */
71
- }
72
- catch (err) {
73
- const stderr = err.stderr?.toString('utf8') ?? '';
74
- throw new Error(`git ${args.join(' ')} failed: ${stderr.trim()}`, { cause: err });
75
- }
76
- /* v8 ignore stop */
77
- }
78
- function findPreviousTag(packageName, currentTag, cwd) {
79
- const prefix = `${packageName}-v`;
80
- const tags = runGit(['tag', '-l', `${prefix}*.*.*`], cwd)
81
- .split('\n')
82
- .filter((t) => t && t !== currentTag)
83
- .sort(compareSemverTags(prefix));
84
- return tags.length > 0 ? tags[tags.length - 1] : null;
85
- }
86
- function compareSemverTags(prefix) {
87
- return (a, b) => {
88
- const [am, an, ap] = parseVer(a.slice(prefix.length));
89
- const [bm, bn, bp] = parseVer(b.slice(prefix.length));
90
- if (am !== bm)
91
- return am - bm;
92
- if (an !== bn)
93
- return an - bn;
94
- return ap - bp;
95
- };
96
- }
97
- function parseVer(v) {
98
- const parts = v.split('.').map((n) => parseInt(n, 10));
99
- /* v8 ignore next -- tag-glob filter already enforces x.y.z shape */
100
- return [parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0];
101
- }
102
- //# sourceMappingURL=release.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"release.js","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"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"}
@@ -1,65 +0,0 @@
1
- /**
2
- * Token scope checking — compares what a token is allowed to publish
3
- * against what `putitoutthere.toml` says the package is.
4
- *
5
- * Runs as a deep extension of `doctor` (#110) and as an opt-in gate in
6
- * `publish --preflight-check`. Per registry:
7
- *
8
- * - PyPI: project-name macaroon caveats. Full-scope tokens pass; any
9
- * restriction list that excludes the package name is a hard
10
- * mismatch.
11
- * - npm: granular `pkg:<name>` scopes on the matched tokens row. A
12
- * bare `@scope` grant still counts when the package name lives
13
- * under that scope. Legacy (non-granular) tokens are treated as
14
- * full-scope (`match: 'ok'`, note surfaced).
15
- * - crates.io: the bearer row is not identifiable, so we can never
16
- * prove mismatch. Always `match: 'unknown'` — callers that need a
17
- * block/warn decision should treat `unknown` as warn-only.
18
- *
19
- * Never logs or returns token values. Digests are threaded through from
20
- * `inspect` for traceability.
21
- */
22
- import type { InspectOptions, InspectResult } from './token.js';
23
- import type { Package } from './config.js';
24
- import type { Kind } from './types.js';
25
- export type ScopeMatch = 'ok' | 'mismatch' | 'unknown' | 'error';
26
- export interface DeepCheckRow {
27
- package: string;
28
- kind: Kind;
29
- scope: string;
30
- match: ScopeMatch;
31
- /** Populated on mismatch or error; omitted when `ok` / `unknown`. */
32
- detail?: string;
33
- }
34
- export type InspectFn = (opts: InspectOptions) => Promise<InspectResult>;
35
- /**
36
- * Registry-facing publish name. Handlers use the override field when
37
- * present; we mirror that so the scope check talks about the same name
38
- * the upload will use.
39
- */
40
- export declare function publishNameFor(pkg: Package): string;
41
- export interface ScopeFromResult {
42
- scope: string;
43
- match: ScopeMatch;
44
- detail?: string;
45
- }
46
- /**
47
- * Translate an `InspectResult` + the package it's meant to publish into
48
- * a scope display + match verdict. Pure; never hits the network.
49
- */
50
- export declare function scopeFromInspect(result: InspectResult, pkg: Package): ScopeFromResult;
51
- export interface DeepCheckOptions {
52
- packages: readonly Package[];
53
- /** envVar-per-package mapping, as computed by preflight.checkAuth. */
54
- envVarForPackage: Map<string, string>;
55
- env?: NodeJS.ProcessEnv;
56
- /** Override for tests; defaults to the real `inspect`. */
57
- inspect?: InspectFn;
58
- }
59
- /**
60
- * Call `inspect` for every package that has a resolvable token in the
61
- * env, and return one `DeepCheckRow` per package. Packages whose env
62
- * var is absent or empty are emitted with `match: 'error'`.
63
- */
64
- export declare function deepCheck(opts: DeepCheckOptions): Promise<DeepCheckRow[]>;
65
- //# sourceMappingURL=token-scope.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"token-scope.d.ts","sourceRoot":"","sources":["../src/token-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAGd,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;AAEjE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,CAAC;IAClB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,cAAc,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAEzE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAInD;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,GAAG,eAAe,CASrF;AAyFD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7B,sEAAsE;IACtE,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA6B/E"}
@@ -1,163 +0,0 @@
1
- /**
2
- * Token scope checking — compares what a token is allowed to publish
3
- * against what `putitoutthere.toml` says the package is.
4
- *
5
- * Runs as a deep extension of `doctor` (#110) and as an opt-in gate in
6
- * `publish --preflight-check`. Per registry:
7
- *
8
- * - PyPI: project-name macaroon caveats. Full-scope tokens pass; any
9
- * restriction list that excludes the package name is a hard
10
- * mismatch.
11
- * - npm: granular `pkg:<name>` scopes on the matched tokens row. A
12
- * bare `@scope` grant still counts when the package name lives
13
- * under that scope. Legacy (non-granular) tokens are treated as
14
- * full-scope (`match: 'ok'`, note surfaced).
15
- * - crates.io: the bearer row is not identifiable, so we can never
16
- * prove mismatch. Always `match: 'unknown'` — callers that need a
17
- * block/warn decision should treat `unknown` as warn-only.
18
- *
19
- * Never logs or returns token values. Digests are threaded through from
20
- * `inspect` for traceability.
21
- */
22
- import { inspect as realInspect, isError } from './token.js';
23
- /**
24
- * Registry-facing publish name. Handlers use the override field when
25
- * present; we mirror that so the scope check talks about the same name
26
- * the upload will use.
27
- */
28
- export function publishNameFor(pkg) {
29
- if (pkg.kind === 'pypi')
30
- return pkg.pypi ?? pkg.name;
31
- if (pkg.kind === 'npm')
32
- return pkg.npm ?? pkg.name;
33
- return pkg.crate ?? pkg.name;
34
- }
35
- /**
36
- * Translate an `InspectResult` + the package it's meant to publish into
37
- * a scope display + match verdict. Pure; never hits the network.
38
- */
39
- export function scopeFromInspect(result, pkg) {
40
- if (isError(result)) {
41
- return { scope: '(inspect failed)', match: 'error', detail: result.error };
42
- }
43
- if (result.registry === 'pypi')
44
- return scopeFromPypi(result, pkg);
45
- if (result.registry === 'npm')
46
- return scopeFromNpm(result, pkg);
47
- // crates.io: we can't prove mismatch.
48
- return { scope: 'unknown (see account tokens)', match: 'unknown' };
49
- }
50
- function scopeFromPypi(result, pkg) {
51
- const allowed = collectPypiProjectNames(result);
52
- if (allowed === null) {
53
- return { scope: '(full-scope)', match: 'ok' };
54
- }
55
- const want = publishNameFor(pkg);
56
- if (allowed.includes(want)) {
57
- return { scope: `projects=[${allowed.join(', ')}]`, match: 'ok' };
58
- }
59
- return {
60
- scope: `projects=[${allowed.join(', ')}]`,
61
- match: 'mismatch',
62
- detail: `PyPI token restricted to [${allowed.join(', ')}] but config publishes '${want}'`,
63
- };
64
- }
65
- function collectPypiProjectNames(result) {
66
- const names = [];
67
- let sawProjectRestriction = false;
68
- for (const r of result.restrictions) {
69
- if (r.type === 'ProjectNames') {
70
- sawProjectRestriction = true;
71
- for (const n of r.names)
72
- names.push(n);
73
- }
74
- }
75
- return sawProjectRestriction ? dedupe(names) : null;
76
- }
77
- function scopeFromNpm(result, pkg) {
78
- const want = publishNameFor(pkg);
79
- const row = result.scope_row;
80
- if (row === null) {
81
- // Legacy UUID or non-granular token: we can't introspect scope.
82
- // Treat as full-scope ok; doctor will still flag via note.
83
- return { scope: `(${result.format}; no scope row)`, match: 'ok' };
84
- }
85
- const allowedPkgs = row.packages ?? [];
86
- const allowedScopes = (row.scopes ?? []).map((s) => (s.startsWith('@') ? s : `@${s}`));
87
- const allowedOrgs = row.orgs ?? [];
88
- const noRestrictions = allowedPkgs.length === 0 && allowedScopes.length === 0 && allowedOrgs.length === 0;
89
- if (noRestrictions) {
90
- return { scope: '(account-wide)', match: 'ok' };
91
- }
92
- if (allowedPkgs.includes(want)) {
93
- return { scope: renderNpmScope(row), match: 'ok' };
94
- }
95
- const atScope = scopeOf(want);
96
- if (atScope !== null && allowedScopes.includes(atScope)) {
97
- return { scope: renderNpmScope(row), match: 'ok' };
98
- }
99
- // Orgs aren't a pre-publish allowlist at the name level (npm doesn't
100
- // bind "org:foo" to a package name directly), so we don't use them to
101
- // prove a match. We still render them for visibility.
102
- return {
103
- scope: renderNpmScope(row),
104
- match: 'mismatch',
105
- detail: `npm token allowlist [${[...allowedPkgs, ...allowedScopes].join(', ')}] does not include '${want}'`,
106
- };
107
- }
108
- function renderNpmScope(row) {
109
- const parts = [];
110
- if (row.packages && row.packages.length > 0)
111
- parts.push(`pkgs=[${row.packages.join(', ')}]`);
112
- if (row.scopes && row.scopes.length > 0)
113
- parts.push(`scopes=[${row.scopes.join(', ')}]`);
114
- if (row.orgs && row.orgs.length > 0)
115
- parts.push(`orgs=[${row.orgs.join(', ')}]`);
116
- /* v8 ignore next -- caller only invokes this when at least one list is populated */
117
- return parts.length === 0 ? '(empty)' : parts.join(' ');
118
- }
119
- function scopeOf(name) {
120
- if (!name.startsWith('@'))
121
- return null;
122
- const slash = name.indexOf('/');
123
- /* v8 ignore next -- scoped npm names always carry a slash separator */
124
- return slash === -1 ? null : name.slice(0, slash);
125
- }
126
- function dedupe(arr) {
127
- return Array.from(new Set(arr));
128
- }
129
- /**
130
- * Call `inspect` for every package that has a resolvable token in the
131
- * env, and return one `DeepCheckRow` per package. Packages whose env
132
- * var is absent or empty are emitted with `match: 'error'`.
133
- */
134
- export async function deepCheck(opts) {
135
- const env = opts.env ?? process.env;
136
- const inspectFn = opts.inspect ?? realInspect;
137
- const rows = [];
138
- for (const pkg of opts.packages) {
139
- const envVar = opts.envVarForPackage.get(pkg.name);
140
- const tokenValue = envVar !== undefined ? env[envVar] : undefined;
141
- if (tokenValue === undefined || tokenValue.trim() === '') {
142
- rows.push({
143
- package: pkg.name,
144
- kind: pkg.kind,
145
- scope: '(no token resolved)',
146
- match: 'error',
147
- detail: `no token value found in ${envVar ?? '<unknown env var>'}`,
148
- });
149
- continue;
150
- }
151
- const result = await inspectFn({ token: tokenValue, registry: pkg.kind });
152
- const verdict = scopeFromInspect(result, pkg);
153
- rows.push({
154
- package: pkg.name,
155
- kind: pkg.kind,
156
- scope: verdict.scope,
157
- match: verdict.match,
158
- ...(verdict.detail !== undefined ? { detail: verdict.detail } : {}),
159
- });
160
- }
161
- return rows;
162
- }
163
- //# sourceMappingURL=token-scope.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"token-scope.js","sourceRoot":"","sources":["../src/token-scope.ts"],"names":[],"mappings":"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"}