putitoutthere 0.1.43 → 0.1.45
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/CHANGELOG.md +115 -0
- package/MIGRATIONS.md +632 -0
- package/README.md +342 -94
- package/action.yml +5 -5
- package/dist/action.js +2 -2
- package/dist/action.js.map +1 -1
- package/dist/cascade.d.ts +1 -1
- package/dist/cascade.js +2 -2
- package/dist/cli.d.ts +9 -6
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +12 -426
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +13 -61
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +31 -45
- package/dist/config.js.map +1 -1
- package/dist/git.js +1 -1
- package/dist/git.js.map +1 -1
- package/dist/handlers/npm-platform.d.ts.map +1 -1
- package/dist/handlers/npm-platform.js +5 -1
- package/dist/handlers/npm-platform.js.map +1 -1
- package/dist/handlers/pypi.d.ts.map +1 -1
- package/dist/handlers/pypi.js +29 -6
- package/dist/handlers/pypi.js.map +1 -1
- package/dist/plan.d.ts +0 -1
- package/dist/plan.d.ts.map +1 -1
- package/dist/plan.js +19 -18
- package/dist/plan.js.map +1 -1
- package/dist/preflight.js +1 -1
- package/dist/preflight.js.map +1 -1
- package/dist/publish.d.ts +0 -10
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +6 -52
- package/dist/publish.js.map +1 -1
- package/dist/types.d.ts +1 -21
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +5 -3
- package/dist/auth.d.ts +0 -68
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js +0 -285
- package/dist/auth.js.map +0 -1
- package/dist/doctor.d.ts +0 -115
- package/dist/doctor.d.ts.map +0 -1
- package/dist/doctor.js +0 -292
- package/dist/doctor.js.map +0 -1
- package/dist/init.d.ts +0 -59
- package/dist/init.d.ts.map +0 -1
- package/dist/init.js +0 -181
- package/dist/init.js.map +0 -1
- package/dist/keyring.d.ts +0 -35
- package/dist/keyring.d.ts.map +0 -1
- package/dist/keyring.js +0 -88
- package/dist/keyring.js.map +0 -1
- package/dist/oidc-policy.d.ts +0 -145
- package/dist/oidc-policy.d.ts.map +0 -1
- package/dist/oidc-policy.js +0 -383
- package/dist/oidc-policy.js.map +0 -1
- package/dist/preflight-run.d.ts +0 -47
- package/dist/preflight-run.d.ts.map +0 -1
- package/dist/preflight-run.js +0 -197
- package/dist/preflight-run.js.map +0 -1
- package/dist/registries/crates-trust.d.ts +0 -69
- package/dist/registries/crates-trust.d.ts.map +0 -1
- package/dist/registries/crates-trust.js +0 -95
- package/dist/registries/crates-trust.js.map +0 -1
- package/dist/release.d.ts +0 -36
- package/dist/release.d.ts.map +0 -1
- package/dist/release.js +0 -102
- package/dist/release.js.map +0 -1
- package/dist/templates.d.ts +0 -43
- package/dist/templates.d.ts.map +0 -1
- package/dist/templates.js +0 -310
- package/dist/templates.js.map +0 -1
- package/dist/token-scope.d.ts +0 -65
- package/dist/token-scope.d.ts.map +0 -1
- package/dist/token-scope.js +0 -163
- package/dist/token-scope.js.map +0 -1
- package/dist/token.d.ts +0 -211
- package/dist/token.d.ts.map +0 -1
- package/dist/token.js +0 -719
- package/dist/token.js.map +0 -1
package/dist/templates.js
DELETED
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workflow templates emitted by `putitoutthere init`.
|
|
3
|
-
*
|
|
4
|
-
* Per plan.md §9.2 (immediate), §9.4 (scheduled), §9.5 (PR check).
|
|
5
|
-
*
|
|
6
|
-
* The `release.yml` templates follow the three-job shape
|
|
7
|
-
* (plan → build → publish) so users can drop their build tooling into
|
|
8
|
-
* the middle job without forking the orchestrator. Build steps are
|
|
9
|
-
* keyed on `matrix.kind` (crates | pypi | npm) and `matrix.build`
|
|
10
|
-
* (vanilla | maturin | napi | bundled-cli) so the right builder runs
|
|
11
|
-
* per row.
|
|
12
|
-
*
|
|
13
|
-
* Issue #25. Plan: §9.
|
|
14
|
-
*/
|
|
15
|
-
const TOML_SKELETON_BODY = `# Put It Out There — release orchestration config.
|
|
16
|
-
# Docs: https://github.com/thekevinscott/put-it-out-there
|
|
17
|
-
|
|
18
|
-
[putitoutthere]
|
|
19
|
-
version = 1
|
|
20
|
-
|
|
21
|
-
# Declare one [[package]] block per releasable artifact. Examples:
|
|
22
|
-
#
|
|
23
|
-
# [[package]]
|
|
24
|
-
# name = "my-crate"
|
|
25
|
-
# kind = "crates"
|
|
26
|
-
# path = "crates/my-crate" # dir containing Cargo.toml
|
|
27
|
-
# paths = ["crates/my-crate/**", "**/Cargo.toml", "**/Cargo.lock"]
|
|
28
|
-
# first_version = "0.1.0"
|
|
29
|
-
# # tag_format defaults to "{name}-v{version}". Single-package repos
|
|
30
|
-
# # often want "v{version}" to keep the existing v0.1.0-style timeline.
|
|
31
|
-
# # tag_format = "v{version}"
|
|
32
|
-
#
|
|
33
|
-
# [[package]]
|
|
34
|
-
# name = "my-py"
|
|
35
|
-
# kind = "pypi"
|
|
36
|
-
# path = "py/my-py" # dir containing pyproject.toml
|
|
37
|
-
# paths = ["py/my-py/**"]
|
|
38
|
-
# first_version = "0.1.0"
|
|
39
|
-
#
|
|
40
|
-
# [[package]]
|
|
41
|
-
# name = "my-pkg"
|
|
42
|
-
# kind = "npm"
|
|
43
|
-
# path = "packages/my-pkg" # dir containing package.json
|
|
44
|
-
# paths = ["packages/my-pkg/**"]
|
|
45
|
-
# first_version = "0.1.0"
|
|
46
|
-
`;
|
|
47
|
-
/**
|
|
48
|
-
* Emit the `putitoutthere.toml` skeleton. When `seeds.tag_format` is
|
|
49
|
-
* set, prepend a short comment explaining why plus a commented
|
|
50
|
-
* `# tag_format = "..."` hint inside the crates example block.
|
|
51
|
-
*
|
|
52
|
-
* Kept as a function (not a constant) so init can bake in
|
|
53
|
-
* per-repo detection results (#204). Callers without seeds get the
|
|
54
|
-
* plain skeleton.
|
|
55
|
-
*/
|
|
56
|
-
export function tomlSkeleton(seeds = null) {
|
|
57
|
-
if (seeds === null || seeds.tag_format === undefined) {
|
|
58
|
-
return TOML_SKELETON_BODY;
|
|
59
|
-
}
|
|
60
|
-
const reason = seeds.tag_format_reason ?? 'single-package repo';
|
|
61
|
-
const banner = `# piot init detected ${reason}; set tag_format = "${seeds.tag_format}" on\n` +
|
|
62
|
-
`# each [[package]] block below to keep that timeline, or remove this comment\n` +
|
|
63
|
-
`# to use the default "{name}-v{version}".\n` +
|
|
64
|
-
`# See https://thekevinscott.github.io/put-it-out-there/guide/configuration\n\n`;
|
|
65
|
-
return banner + TOML_SKELETON_BODY;
|
|
66
|
-
}
|
|
67
|
-
/** @deprecated use {@link tomlSkeleton}; kept for external consumers of the constant. */
|
|
68
|
-
export const TOML_SKELETON = TOML_SKELETON_BODY;
|
|
69
|
-
export const AGENTS_MD = `# Release signaling for Put It Out There
|
|
70
|
-
|
|
71
|
-
When you finish a unit of work and are preparing a PR or commit, add a git
|
|
72
|
-
trailer to the commit message body to signal a release:
|
|
73
|
-
|
|
74
|
-
release: <patch|minor|major|skip>
|
|
75
|
-
|
|
76
|
-
Rules:
|
|
77
|
-
- Omit the trailer for docs-only, CI-only, or internal-only changes.
|
|
78
|
-
- \`patch\` for bug fixes or internal refactors that don't change public API.
|
|
79
|
-
- \`minor\` for new features that are backwards-compatible.
|
|
80
|
-
- \`major\` for breaking changes.
|
|
81
|
-
- \`skip\` to suppress release when path filters would otherwise cascade.
|
|
82
|
-
|
|
83
|
-
The trailer on the merge commit determines the release. If merging via
|
|
84
|
-
"Squash and merge," include the trailer in the PR description so it ends up
|
|
85
|
-
in the squashed commit body.
|
|
86
|
-
|
|
87
|
-
## Scoping a release to specific packages
|
|
88
|
-
|
|
89
|
-
To release a subset of packages in a polyglot repo, append a bracketed list:
|
|
90
|
-
|
|
91
|
-
release: minor [my-crate, my-py]
|
|
92
|
-
|
|
93
|
-
Packages named in the list are bumped with the specified version. Other
|
|
94
|
-
packages cascaded by path filters still get a \`patch\`. Packages in the
|
|
95
|
-
list that *aren't* cascaded are force-included.
|
|
96
|
-
`;
|
|
97
|
-
const BUILD_JOB = ` build:
|
|
98
|
-
needs: plan
|
|
99
|
-
if: fromJSON(needs.plan.outputs.matrix || '[]')[0] != null
|
|
100
|
-
strategy:
|
|
101
|
-
fail-fast: false
|
|
102
|
-
matrix:
|
|
103
|
-
include: \${{ fromJSON(needs.plan.outputs.matrix) }}
|
|
104
|
-
runs-on: \${{ matrix.runs_on }}
|
|
105
|
-
steps:
|
|
106
|
-
- uses: actions/checkout@v4
|
|
107
|
-
with:
|
|
108
|
-
fetch-depth: 0
|
|
109
|
-
- name: Setup Rust (if crates)
|
|
110
|
-
if: matrix.kind == 'crates'
|
|
111
|
-
uses: dtolnay/rust-toolchain@stable
|
|
112
|
-
- name: Build crate
|
|
113
|
-
if: matrix.kind == 'crates'
|
|
114
|
-
run: cargo package --manifest-path \${{ matrix.path }}/Cargo.toml --target-dir \${{ matrix.path }}/target
|
|
115
|
-
- name: Setup Python (if pypi)
|
|
116
|
-
if: matrix.kind == 'pypi'
|
|
117
|
-
uses: actions/setup-python@v5
|
|
118
|
-
with:
|
|
119
|
-
python-version: '3.12'
|
|
120
|
-
# #217: when [package.bundle_cli] is declared, compile the CLI
|
|
121
|
-
# for this target and stage it into the package source tree so
|
|
122
|
-
# maturin includes it in the wheel that's built next.
|
|
123
|
-
- name: Setup Rust (if pypi bundle_cli)
|
|
124
|
-
if: matrix.kind == 'pypi' && matrix.bundle_cli.bin != '' && matrix.target != 'sdist'
|
|
125
|
-
uses: dtolnay/rust-toolchain@stable
|
|
126
|
-
with:
|
|
127
|
-
targets: \${{ matrix.target }}
|
|
128
|
-
- name: Build + stage bundled CLI
|
|
129
|
-
if: matrix.kind == 'pypi' && matrix.bundle_cli.bin != '' && matrix.target != 'sdist'
|
|
130
|
-
shell: bash
|
|
131
|
-
run: |
|
|
132
|
-
set -euo pipefail
|
|
133
|
-
cd "\${{ matrix.bundle_cli.crate_path }}"
|
|
134
|
-
cargo build --release --bin "\${{ matrix.bundle_cli.bin }}" --target "\${{ matrix.target }}"
|
|
135
|
-
cd "\${{ github.workspace }}"
|
|
136
|
-
dest="\${{ matrix.path }}/\${{ matrix.bundle_cli.stage_to }}"
|
|
137
|
-
mkdir -p "$dest"
|
|
138
|
-
# Windows targets produce .exe; Unix don't. Copy whatever's
|
|
139
|
-
# there matching the bin name.
|
|
140
|
-
src_dir="\${{ matrix.bundle_cli.crate_path }}/target/\${{ matrix.target }}/release"
|
|
141
|
-
if [[ -f "$src_dir/\${{ matrix.bundle_cli.bin }}.exe" ]]; then
|
|
142
|
-
cp "$src_dir/\${{ matrix.bundle_cli.bin }}.exe" "$dest/"
|
|
143
|
-
elif [[ -f "$src_dir/\${{ matrix.bundle_cli.bin }}" ]]; then
|
|
144
|
-
cp "$src_dir/\${{ matrix.bundle_cli.bin }}" "$dest/"
|
|
145
|
-
else
|
|
146
|
-
echo "bundle_cli: built binary not found at $src_dir/\${{ matrix.bundle_cli.bin }}[.exe]" >&2
|
|
147
|
-
exit 1
|
|
148
|
-
fi
|
|
149
|
-
- name: Build wheel (maturin)
|
|
150
|
-
if: matrix.kind == 'pypi' && matrix.build == 'maturin'
|
|
151
|
-
uses: PyO3/maturin-action@v1
|
|
152
|
-
with:
|
|
153
|
-
command: build
|
|
154
|
-
args: --release --out \${{ matrix.path }}/dist \${{ matrix.target == 'sdist' && '--sdist' || format('--target {0}', matrix.target) }}
|
|
155
|
-
working-directory: \${{ matrix.path }}
|
|
156
|
-
- name: Build sdist (setuptools/hatch)
|
|
157
|
-
if: matrix.kind == 'pypi' && matrix.build != 'maturin' && matrix.target == 'sdist'
|
|
158
|
-
run: |
|
|
159
|
-
cd \${{ matrix.path }}
|
|
160
|
-
python -m pip install build
|
|
161
|
-
python -m build --sdist --outdir dist
|
|
162
|
-
- name: Setup Node (if npm)
|
|
163
|
-
if: matrix.kind == 'npm'
|
|
164
|
-
uses: actions/setup-node@v4
|
|
165
|
-
with:
|
|
166
|
-
node-version: '24'
|
|
167
|
-
- name: Build npm package
|
|
168
|
-
if: matrix.kind == 'npm'
|
|
169
|
-
run: |
|
|
170
|
-
cd \${{ matrix.path }}
|
|
171
|
-
npm ci
|
|
172
|
-
npm run build --if-present
|
|
173
|
-
- uses: actions/upload-artifact@v4
|
|
174
|
-
with:
|
|
175
|
-
name: \${{ matrix.artifact_name }}
|
|
176
|
-
path: \${{ matrix.artifact_path }}
|
|
177
|
-
`;
|
|
178
|
-
const PUBLISH_JOB = ` publish:
|
|
179
|
-
needs: [plan, build]
|
|
180
|
-
runs-on: ubuntu-latest
|
|
181
|
-
permissions:
|
|
182
|
-
contents: write
|
|
183
|
-
id-token: write
|
|
184
|
-
steps:
|
|
185
|
-
- uses: actions/checkout@v4
|
|
186
|
-
with:
|
|
187
|
-
fetch-depth: 0
|
|
188
|
-
- uses: actions/setup-node@v4
|
|
189
|
-
with:
|
|
190
|
-
node-version: '24'
|
|
191
|
-
registry-url: 'https://registry.npmjs.org'
|
|
192
|
-
# PyPI publish shells out to \`twine\`. Hosted runners don't ship it;
|
|
193
|
-
# install it here so the publish job has twine on PATH regardless of
|
|
194
|
-
# whether the config has a pypi package today.
|
|
195
|
-
- uses: actions/setup-python@v5
|
|
196
|
-
with:
|
|
197
|
-
python-version: '3.12'
|
|
198
|
-
- name: Install twine
|
|
199
|
-
run: pip install twine
|
|
200
|
-
# piot cuts an annotated tag per publish (\`git tag -a\`). Hosted
|
|
201
|
-
# runners have no committer identity set; configure one before the
|
|
202
|
-
# piot step or tag creation fails with "Please tell me who you are."
|
|
203
|
-
- name: Configure git identity
|
|
204
|
-
run: |
|
|
205
|
-
git config --global user.name "github-actions[bot]"
|
|
206
|
-
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
207
|
-
- uses: actions/download-artifact@v4
|
|
208
|
-
with:
|
|
209
|
-
path: artifacts
|
|
210
|
-
- uses: thekevinscott/put-it-out-there@v0
|
|
211
|
-
with:
|
|
212
|
-
command: publish
|
|
213
|
-
dry_run: \${{ inputs.dry_run || 'false' }}
|
|
214
|
-
env:
|
|
215
|
-
# NODE_AUTH_TOKEN (not NPM_TOKEN) matches the .npmrc template that
|
|
216
|
-
# actions/setup-node writes when registry-url is set. putitoutthere's
|
|
217
|
-
# preflight also accepts NPM_TOKEN as a fallback, but npm itself
|
|
218
|
-
# reads this name. Store your npm secret under any name — we map it
|
|
219
|
-
# here.
|
|
220
|
-
NODE_AUTH_TOKEN: \${{ secrets.NPM_TOKEN }}
|
|
221
|
-
CARGO_REGISTRY_TOKEN: \${{ secrets.CARGO_TOKEN }}
|
|
222
|
-
PYPI_API_TOKEN: \${{ secrets.PYPI_API_TOKEN }}
|
|
223
|
-
`;
|
|
224
|
-
const PLAN_JOB = ` plan:
|
|
225
|
-
runs-on: ubuntu-latest
|
|
226
|
-
outputs:
|
|
227
|
-
matrix: \${{ steps.plan.outputs.matrix }}
|
|
228
|
-
steps:
|
|
229
|
-
- uses: actions/checkout@v4
|
|
230
|
-
with:
|
|
231
|
-
fetch-depth: 0
|
|
232
|
-
- id: plan
|
|
233
|
-
uses: thekevinscott/put-it-out-there@v0
|
|
234
|
-
with:
|
|
235
|
-
command: plan
|
|
236
|
-
`;
|
|
237
|
-
const IMMEDIATE_HEADER = `name: Release
|
|
238
|
-
|
|
239
|
-
on:
|
|
240
|
-
push:
|
|
241
|
-
branches: [main]
|
|
242
|
-
workflow_dispatch:
|
|
243
|
-
inputs:
|
|
244
|
-
dry_run:
|
|
245
|
-
description: 'Dry-run: compute plan, skip publish + tag'
|
|
246
|
-
type: boolean
|
|
247
|
-
default: false
|
|
248
|
-
|
|
249
|
-
concurrency:
|
|
250
|
-
group: release
|
|
251
|
-
cancel-in-progress: false
|
|
252
|
-
|
|
253
|
-
permissions:
|
|
254
|
-
contents: read
|
|
255
|
-
id-token: write
|
|
256
|
-
|
|
257
|
-
jobs:
|
|
258
|
-
`;
|
|
259
|
-
const SCHEDULED_HEADER = `name: Release (scheduled)
|
|
260
|
-
|
|
261
|
-
on:
|
|
262
|
-
schedule:
|
|
263
|
-
- cron: '0 2 * * *'
|
|
264
|
-
workflow_dispatch:
|
|
265
|
-
inputs:
|
|
266
|
-
dry_run:
|
|
267
|
-
description: 'Dry-run: compute plan, skip publish + tag'
|
|
268
|
-
type: boolean
|
|
269
|
-
default: false
|
|
270
|
-
|
|
271
|
-
concurrency:
|
|
272
|
-
group: release
|
|
273
|
-
cancel-in-progress: false
|
|
274
|
-
|
|
275
|
-
permissions:
|
|
276
|
-
contents: read
|
|
277
|
-
id-token: write
|
|
278
|
-
|
|
279
|
-
jobs:
|
|
280
|
-
`;
|
|
281
|
-
export const RELEASE_YML_IMMEDIATE = IMMEDIATE_HEADER + PLAN_JOB + '\n' + BUILD_JOB + '\n' + PUBLISH_JOB;
|
|
282
|
-
export const RELEASE_YML_SCHEDULED = SCHEDULED_HEADER + PLAN_JOB + '\n' + BUILD_JOB + '\n' + PUBLISH_JOB;
|
|
283
|
-
export const CHECK_YML = `name: Putitoutthere check
|
|
284
|
-
|
|
285
|
-
on:
|
|
286
|
-
pull_request:
|
|
287
|
-
branches: [main]
|
|
288
|
-
|
|
289
|
-
permissions:
|
|
290
|
-
contents: read
|
|
291
|
-
pull-requests: read
|
|
292
|
-
|
|
293
|
-
jobs:
|
|
294
|
-
dry-run:
|
|
295
|
-
runs-on: ubuntu-latest
|
|
296
|
-
steps:
|
|
297
|
-
- uses: actions/checkout@v4
|
|
298
|
-
with:
|
|
299
|
-
fetch-depth: 0
|
|
300
|
-
- uses: thekevinscott/put-it-out-there@v0
|
|
301
|
-
with:
|
|
302
|
-
command: plan
|
|
303
|
-
dry_run: true
|
|
304
|
-
fail_on_error: true
|
|
305
|
-
`;
|
|
306
|
-
export function releaseYml(cadence) {
|
|
307
|
-
/* v8 ignore next -- exhaustive switch */
|
|
308
|
-
return cadence === 'scheduled' ? RELEASE_YML_SCHEDULED : RELEASE_YML_IMMEDIATE;
|
|
309
|
-
}
|
|
310
|
-
//# sourceMappingURL=templates.js.map
|
package/dist/templates.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAeH,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B1B,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,QAA8B,IAAI;IAC7D,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACrD,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,iBAAiB,IAAI,qBAAqB,CAAC;IAChE,MAAM,MAAM,GACV,wBAAwB,MAAM,uBAAuB,KAAK,CAAC,UAAU,QAAQ;QAC7E,gFAAgF;QAChF,6CAA6C;QAC7C,gFAAgF,CAAC;IACnF,OAAO,MAAM,GAAG,kBAAkB,CAAC;AACrC,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,MAAM,aAAa,GAAG,kBAAkB,CAAC;AAEhD,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BxB,CAAC;AAEF,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgFjB,CAAC;AAEF,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CnB,CAAC;AAEF,MAAM,QAAQ,GAAG;;;;;;;;;;;;CAYhB,CAAC;AAEF,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBxB,CAAC;AAEF,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBxB,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,gBAAgB,GAAG,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,WAAW,CAAC;AACzG,MAAM,CAAC,MAAM,qBAAqB,GAAG,gBAAgB,GAAG,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,WAAW,CAAC;AAEzG,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsBxB,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,yCAAyC;IACzC,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,qBAAqB,CAAC;AACjF,CAAC"}
|
package/dist/token-scope.d.ts
DELETED
|
@@ -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"}
|
package/dist/token-scope.js
DELETED
|
@@ -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
|
package/dist/token-scope.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"token-scope.js","sourceRoot":"","sources":["../src/token-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAuB7D;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC;IACrD,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;QAAE,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC;IACnD,OAAO,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,CAAC;AAC/B,CAAC;AAQD;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAqB,EAAE,GAAY;IAClE,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IAC7E,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,MAAM;QAAE,OAAO,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClE,IAAI,MAAM,CAAC,QAAQ,KAAK,KAAK;QAAE,OAAO,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChE,sCAAsC;IACtC,OAAO,EAAE,KAAK,EAAE,8BAA8B,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AACrE,CAAC;AAED,SAAS,aAAa,CAAC,MAAyB,EAAE,GAAY;IAC5D,MAAM,OAAO,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAChD,CAAC;IACD,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,KAAK,EAAE,aAAa,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACpE,CAAC;IACD,OAAO;QACL,KAAK,EAAE,aAAa,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACzC,KAAK,EAAE,UAAU;QACjB,MAAM,EAAE,6BAA6B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,2BAA2B,IAAI,GAAG;KAC1F,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,MAAyB;IACxD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,qBAAqB,GAAG,KAAK,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACpC,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAC9B,qBAAqB,GAAG,IAAI,CAAC;YAC7B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IACD,OAAO,qBAAqB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACtD,CAAC;AAED,SAAS,YAAY,CAAC,MAAwB,EAAE,GAAY;IAC1D,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC;IAE7B,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,gEAAgE;QAChE,2DAA2D;QAC3D,OAAO,EAAE,KAAK,EAAE,IAAI,MAAM,CAAC,MAAM,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACpE,CAAC;IAED,MAAM,WAAW,GAAG,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;IACvC,MAAM,aAAa,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACvF,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;IAEnC,MAAM,cAAc,GAClB,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC;IACrF,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAClD,CAAC;IAED,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACrD,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,OAAO,KAAK,IAAI,IAAI,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACrD,CAAC;IACD,qEAAqE;IACrE,sEAAsE;IACtE,sDAAsD;IACtD,OAAO;QACL,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC;QAC1B,KAAK,EAAE,UAAU;QACjB,MAAM,EAAE,wBAAwB,CAAC,GAAG,WAAW,EAAE,GAAG,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,IAAI,GAAG;KAC5G,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,GAA+C;IACrE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7F,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzF,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjF,oFAAoF;IACpF,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,uEAAuE;IACvE,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,MAAM,CAAI,GAAiB;IAClC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAClC,CAAC;AAaD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAsB;IACpD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,IAAI,WAAW,CAAC;IAE9C,MAAM,IAAI,GAAmB,EAAE,CAAC;IAChC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAClE,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACzD,IAAI,CAAC,IAAI,CAAC;gBACR,OAAO,EAAE,GAAG,CAAC,IAAI;gBACjB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,KAAK,EAAE,qBAAqB;gBAC5B,KAAK,EAAE,OAAO;gBACd,MAAM,EAAE,2BAA2B,MAAM,IAAI,mBAAmB,EAAE;aACnE,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,CAAC;YACR,OAAO,EAAE,GAAG,CAAC,IAAI;YACjB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpE,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|