@pnpm/registry-access.commands 1100.4.0 → 1100.5.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.
- package/CHANGELOG.md +448 -0
- package/lib/access.js +1 -33
- package/lib/common.d.ts +6 -0
- package/lib/common.js +37 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +2 -1
- package/lib/team.d.ts +17 -0
- package/lib/team.js +341 -0
- package/package.json +20 -20
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
# @pnpm/registry-access.commands
|
|
2
|
+
|
|
3
|
+
## 1100.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added the `team` command for managing organization teams and team memberships on the registry, with create, destroy, add, rm, and ls subcommands and support for --otp, --parseable, and --json flags.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies:
|
|
12
|
+
- @pnpm/cli.utils@1101.0.14
|
|
13
|
+
- @pnpm/config.pick-registry-for-package@1100.0.10
|
|
14
|
+
- @pnpm/config.reader@1101.12.0
|
|
15
|
+
- @pnpm/network.auth-header@1101.1.4
|
|
16
|
+
- @pnpm/network.fetch@1100.1.5
|
|
17
|
+
- @pnpm/registry-access.client@1100.1.7
|
|
18
|
+
- @pnpm/resolving.registry.types@1100.1.4
|
|
19
|
+
- @pnpm/types@1101.4.0
|
|
20
|
+
|
|
21
|
+
## 1100.4.1
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- @pnpm/config.reader@1101.11.2
|
|
26
|
+
|
|
27
|
+
## 1100.4.0
|
|
28
|
+
|
|
29
|
+
### Minor Changes
|
|
30
|
+
|
|
31
|
+
- 508b8c2: Added the `pnpm access` command for managing package access and visibility on the registry, supporting listing packages and collaborators, getting and setting package status and MFA requirements, and granting or revoking team access.
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- Updated dependencies [9318a11]
|
|
36
|
+
- Updated dependencies [5a4daec]
|
|
37
|
+
- @pnpm/config.reader@1101.11.1
|
|
38
|
+
|
|
39
|
+
## 1100.3.7
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- Updated dependencies [3425e80]
|
|
44
|
+
- Updated dependencies [806c3ec]
|
|
45
|
+
- Updated dependencies [c121235]
|
|
46
|
+
- Updated dependencies [1e81761]
|
|
47
|
+
- @pnpm/config.reader@1101.11.0
|
|
48
|
+
- @pnpm/network.web-auth@1101.2.0
|
|
49
|
+
- @pnpm/registry-access.client@1100.1.6
|
|
50
|
+
|
|
51
|
+
## 1100.3.6
|
|
52
|
+
|
|
53
|
+
### Patch Changes
|
|
54
|
+
|
|
55
|
+
- Updated dependencies [05b95ab]
|
|
56
|
+
- Updated dependencies [852d537]
|
|
57
|
+
- @pnpm/network.fetch@1100.1.4
|
|
58
|
+
- @pnpm/error@1100.0.1
|
|
59
|
+
- @pnpm/registry-access.client@1100.1.5
|
|
60
|
+
- @pnpm/cli.utils@1101.0.13
|
|
61
|
+
- @pnpm/config.reader@1101.10.1
|
|
62
|
+
- @pnpm/network.auth-header@1101.1.3
|
|
63
|
+
- @pnpm/network.web-auth@1101.1.2
|
|
64
|
+
|
|
65
|
+
## 1100.3.5
|
|
66
|
+
|
|
67
|
+
### Patch Changes
|
|
68
|
+
|
|
69
|
+
- Updated dependencies [302a2f7]
|
|
70
|
+
- Updated dependencies [0474a9c]
|
|
71
|
+
- @pnpm/config.reader@1101.10.0
|
|
72
|
+
|
|
73
|
+
## 1100.3.4
|
|
74
|
+
|
|
75
|
+
### Patch Changes
|
|
76
|
+
|
|
77
|
+
- a31faa7: Updated dependency ranges. Notably:
|
|
78
|
+
|
|
79
|
+
- `@pnpm/logger` peer dependency range moved to `^1100.0.0`.
|
|
80
|
+
- `msgpackr` 1.11.8 → 2.0.4 (store index files remain byte-compatible in both directions).
|
|
81
|
+
- `open` ^7.4.2 → ^11.0.0, `memoize` ^10 → ^11, `cli-truncate` ^5 → ^6, `pidtree` ^0.6 → ^1.
|
|
82
|
+
- `@yarnpkg/core` 4.5.0 → 4.8.0, `@rushstack/worker-pool` 0.7.7 → 0.7.18, `@cyclonedx/cyclonedx-library` 10.0.0 → 10.1.0, `@pnpm/config.nerf-dart` ^1 → ^2, `@pnpm/log.group` 3.0.2 → 4.0.1, `@pnpm/util.lex-comparator` ^3 → ^4.
|
|
83
|
+
|
|
84
|
+
- Updated dependencies [61810aa]
|
|
85
|
+
- Updated dependencies [681b593]
|
|
86
|
+
- Updated dependencies [a31faa7]
|
|
87
|
+
- @pnpm/config.reader@1101.9.0
|
|
88
|
+
- @pnpm/network.auth-header@1101.1.2
|
|
89
|
+
- @pnpm/types@1101.3.2
|
|
90
|
+
- @pnpm/cli.utils@1101.0.12
|
|
91
|
+
- @pnpm/network.fetch@1100.1.3
|
|
92
|
+
- @pnpm/network.web-auth@1101.1.1
|
|
93
|
+
- @pnpm/config.pick-registry-for-package@1100.0.9
|
|
94
|
+
- @pnpm/resolving.registry.types@1100.1.3
|
|
95
|
+
- @pnpm/registry-access.client@1100.1.4
|
|
96
|
+
|
|
97
|
+
## 1100.3.3
|
|
98
|
+
|
|
99
|
+
### Patch Changes
|
|
100
|
+
|
|
101
|
+
- Updated dependencies [bc9ed78]
|
|
102
|
+
- Updated dependencies [615c669]
|
|
103
|
+
- @pnpm/config.reader@1101.8.0
|
|
104
|
+
- @pnpm/network.fetch@1100.1.2
|
|
105
|
+
- @pnpm/cli.utils@1101.0.11
|
|
106
|
+
- @pnpm/registry-access.client@1100.1.3
|
|
107
|
+
|
|
108
|
+
## 1100.3.2
|
|
109
|
+
|
|
110
|
+
### Patch Changes
|
|
111
|
+
|
|
112
|
+
- Updated dependencies [822beb5]
|
|
113
|
+
- Updated dependencies [3537020]
|
|
114
|
+
- Updated dependencies [894ea6a]
|
|
115
|
+
- Updated dependencies [6b5d91a]
|
|
116
|
+
- Updated dependencies [027196b]
|
|
117
|
+
- Updated dependencies [1017c36]
|
|
118
|
+
- Updated dependencies [bf1b731]
|
|
119
|
+
- @pnpm/config.reader@1101.7.0
|
|
120
|
+
- @pnpm/types@1101.3.1
|
|
121
|
+
- @pnpm/cli.utils@1101.0.10
|
|
122
|
+
- @pnpm/config.pick-registry-for-package@1100.0.8
|
|
123
|
+
- @pnpm/network.auth-header@1101.1.1
|
|
124
|
+
- @pnpm/network.fetch@1100.1.1
|
|
125
|
+
- @pnpm/resolving.registry.types@1100.1.2
|
|
126
|
+
- @pnpm/registry-access.client@1100.1.2
|
|
127
|
+
|
|
128
|
+
## 1100.3.1
|
|
129
|
+
|
|
130
|
+
### Patch Changes
|
|
131
|
+
|
|
132
|
+
- Updated dependencies [60a1eec]
|
|
133
|
+
- Updated dependencies [5192edf]
|
|
134
|
+
- Updated dependencies [a017bf3]
|
|
135
|
+
- @pnpm/network.fetch@1100.1.0
|
|
136
|
+
- @pnpm/network.auth-header@1101.1.0
|
|
137
|
+
- @pnpm/config.reader@1101.6.0
|
|
138
|
+
- @pnpm/types@1101.3.0
|
|
139
|
+
- @pnpm/registry-access.client@1100.1.1
|
|
140
|
+
- @pnpm/cli.utils@1101.0.9
|
|
141
|
+
- @pnpm/config.pick-registry-for-package@1100.0.7
|
|
142
|
+
- @pnpm/resolving.registry.types@1100.1.1
|
|
143
|
+
|
|
144
|
+
## 1100.3.0
|
|
145
|
+
|
|
146
|
+
### Minor Changes
|
|
147
|
+
|
|
148
|
+
- 2cadfb5: Replaced `enquirer` with `@inquirer/prompts` for all interactive prompts. Fixes the `update -i` scrolling overflow bug where long choice lists were clipped in the terminal [#6643](https://github.com/pnpm/pnpm/issues/6643).
|
|
149
|
+
|
|
150
|
+
**User-facing changes:**
|
|
151
|
+
|
|
152
|
+
- `pnpm update -i` / `pnpm update -i --latest`: Scrolling now works correctly when many packages are available; the new library uses visual-line-aware pagination via `usePagination`
|
|
153
|
+
- `pnpm audit --fix -i`: Same scrolling fix for vulnerability selection
|
|
154
|
+
- `pnpm approve-builds`: Interactive build approval prompts updated
|
|
155
|
+
- `pnpm patch`: Version selection and "apply to all" prompts updated
|
|
156
|
+
- `pnpm patch-remove`: Patch removal selection updated
|
|
157
|
+
- `pnpm publish`: Branch confirmation prompt updated
|
|
158
|
+
- `pnpm login`: Credential prompts updated
|
|
159
|
+
- `pnpm run` / `pnpm exec` (with `verifyDepsBeforeRun=prompt`): Confirmation prompt updated
|
|
160
|
+
|
|
161
|
+
Vim-style `j`/`k` keys still work for up/down navigation in all interactive prompts.
|
|
162
|
+
|
|
163
|
+
**Internal:** The `OtpEnquirer` and `LoginEnquirer` DI interfaces changed from `{ prompt }` to `{ input }` / `{ input, password }` respectively. Plugins or custom builds that inject their own enquirer mock will need to update.
|
|
164
|
+
|
|
165
|
+
### Patch Changes
|
|
166
|
+
|
|
167
|
+
- b1fa2d5: Fix `pnpm dist-tag add` and `pnpm dist-tag rm` against npmjs.org failing without `--otp` with `[ERR_PNPM_UNAUTHORIZED] You must be logged in to set dist-tag … "You must provide a one-time pass. Upgrade your client to npm@latest in order to use 2FA."`. pnpm now sends `npm-auth-type: web` on dist-tag writes and surfaces the resulting OTP challenge through the existing browser-based 2FA flow (the same `withOtpHandling` helper used by `pnpm publish`), so the browser opens, the user authenticates, and the dist-tag is set on retry. `--otp=<code>` continues to work via the classic flow.
|
|
168
|
+
- Updated dependencies [b1fa2d5]
|
|
169
|
+
- Updated dependencies [a39a83d]
|
|
170
|
+
- Updated dependencies [2cadfb5]
|
|
171
|
+
- Updated dependencies [1e9ab29]
|
|
172
|
+
- @pnpm/registry-access.client@1100.1.0
|
|
173
|
+
- @pnpm/network.fetch@1100.0.8
|
|
174
|
+
- @pnpm/config.reader@1101.5.0
|
|
175
|
+
- @pnpm/network.web-auth@1101.1.0
|
|
176
|
+
- @pnpm/resolving.registry.types@1100.1.0
|
|
177
|
+
|
|
178
|
+
## 1100.2.16
|
|
179
|
+
|
|
180
|
+
### Patch Changes
|
|
181
|
+
|
|
182
|
+
- ae21758: Refactor the dist-tag-add and login (classic adduser) handlers to delegate their PUTs to a new shared package `@pnpm/registry-access.client`. Downstream tests in this monorepo now use these helpers (via `@pnpm/testing.registry-mock`) instead of `addDistTag` / `addUser` from `@pnpm/registry-mock`, which relied on the unmaintained `anonymous-npm-registry-client`.
|
|
183
|
+
- Updated dependencies [a23956e]
|
|
184
|
+
- Updated dependencies [35d2355]
|
|
185
|
+
- @pnpm/config.reader@1101.4.1
|
|
186
|
+
- @pnpm/network.auth-header@1101.0.0
|
|
187
|
+
- @pnpm/types@1101.2.0
|
|
188
|
+
- @pnpm/cli.utils@1101.0.8
|
|
189
|
+
- @pnpm/config.pick-registry-for-package@1100.0.6
|
|
190
|
+
- @pnpm/network.fetch@1100.0.7
|
|
191
|
+
- @pnpm/resolving.registry.types@1100.0.5
|
|
192
|
+
- @pnpm/registry-access.client@1100.0.1
|
|
193
|
+
|
|
194
|
+
## 1100.2.15
|
|
195
|
+
|
|
196
|
+
### Patch Changes
|
|
197
|
+
|
|
198
|
+
- Updated dependencies [3b62f9d]
|
|
199
|
+
- Updated dependencies [212315d]
|
|
200
|
+
- @pnpm/config.reader@1101.4.0
|
|
201
|
+
- @pnpm/cli.utils@1101.0.7
|
|
202
|
+
|
|
203
|
+
## 1100.2.14
|
|
204
|
+
|
|
205
|
+
### Patch Changes
|
|
206
|
+
|
|
207
|
+
- Updated dependencies [097983f]
|
|
208
|
+
- @pnpm/config.pick-registry-for-package@1100.0.5
|
|
209
|
+
|
|
210
|
+
## 1100.2.13
|
|
211
|
+
|
|
212
|
+
### Patch Changes
|
|
213
|
+
|
|
214
|
+
- d1b340f: Fixed `pnpm login` and `pnpm logout` ignoring `registries.default` from `pnpm-workspace.yaml` [#10099](https://github.com/pnpm/pnpm/issues/10099).
|
|
215
|
+
- Updated dependencies [3687b0e]
|
|
216
|
+
- Updated dependencies [ced20cb]
|
|
217
|
+
- Updated dependencies [d1b340f]
|
|
218
|
+
- Updated dependencies [64afc92]
|
|
219
|
+
- @pnpm/config.reader@1101.3.3
|
|
220
|
+
- @pnpm/types@1101.1.1
|
|
221
|
+
- @pnpm/cli.utils@1101.0.6
|
|
222
|
+
- @pnpm/config.pick-registry-for-package@1100.0.4
|
|
223
|
+
- @pnpm/network.auth-header@1100.0.3
|
|
224
|
+
- @pnpm/network.fetch@1100.0.6
|
|
225
|
+
- @pnpm/resolving.registry.types@1100.0.4
|
|
226
|
+
|
|
227
|
+
## 1100.2.12
|
|
228
|
+
|
|
229
|
+
### Patch Changes
|
|
230
|
+
|
|
231
|
+
- Updated dependencies [020ac45]
|
|
232
|
+
- Updated dependencies [d3f8408]
|
|
233
|
+
- Updated dependencies [a62f959]
|
|
234
|
+
- Updated dependencies [ba2c884]
|
|
235
|
+
- Updated dependencies [8df408c]
|
|
236
|
+
- @pnpm/config.reader@1101.3.2
|
|
237
|
+
- @pnpm/network.fetch@1100.0.5
|
|
238
|
+
- @pnpm/cli.utils@1101.0.5
|
|
239
|
+
|
|
240
|
+
## 1100.2.11
|
|
241
|
+
|
|
242
|
+
### Patch Changes
|
|
243
|
+
|
|
244
|
+
- Updated dependencies [18a464f]
|
|
245
|
+
- @pnpm/network.fetch@1100.0.4
|
|
246
|
+
- @pnpm/cli.utils@1101.0.4
|
|
247
|
+
- @pnpm/config.reader@1101.3.1
|
|
248
|
+
|
|
249
|
+
## 1100.2.10
|
|
250
|
+
|
|
251
|
+
### Patch Changes
|
|
252
|
+
|
|
253
|
+
- 601317e: Added `pnpm owner` command to manage package owners on the registry.
|
|
254
|
+
- Updated dependencies [20e7aff]
|
|
255
|
+
- Updated dependencies [b61e268]
|
|
256
|
+
- Updated dependencies [e1e29c1]
|
|
257
|
+
- @pnpm/network.fetch@1100.0.3
|
|
258
|
+
- @pnpm/config.reader@1101.3.0
|
|
259
|
+
- @pnpm/types@1101.1.0
|
|
260
|
+
- @pnpm/cli.utils@1101.0.3
|
|
261
|
+
- @pnpm/config.pick-registry-for-package@1100.0.3
|
|
262
|
+
- @pnpm/network.auth-header@1100.0.2
|
|
263
|
+
- @pnpm/resolving.registry.types@1100.0.3
|
|
264
|
+
|
|
265
|
+
## 1100.2.9
|
|
266
|
+
|
|
267
|
+
### Patch Changes
|
|
268
|
+
|
|
269
|
+
- Updated dependencies [e9e876c]
|
|
270
|
+
- @pnpm/config.reader@1101.2.2
|
|
271
|
+
|
|
272
|
+
## 1100.2.8
|
|
273
|
+
|
|
274
|
+
### Patch Changes
|
|
275
|
+
|
|
276
|
+
- Updated dependencies [707a879]
|
|
277
|
+
- @pnpm/config.reader@1101.2.1
|
|
278
|
+
|
|
279
|
+
## 1100.2.7
|
|
280
|
+
|
|
281
|
+
### Patch Changes
|
|
282
|
+
|
|
283
|
+
- Updated dependencies [8fdd9a9]
|
|
284
|
+
- Updated dependencies [5f34a8d]
|
|
285
|
+
- Updated dependencies [c969392]
|
|
286
|
+
- Updated dependencies [817b1b4]
|
|
287
|
+
- Updated dependencies [c969392]
|
|
288
|
+
- Updated dependencies [2de318b]
|
|
289
|
+
- @pnpm/config.reader@1101.2.0
|
|
290
|
+
|
|
291
|
+
## 1100.2.6
|
|
292
|
+
|
|
293
|
+
### Patch Changes
|
|
294
|
+
|
|
295
|
+
- Updated dependencies [42a8f29]
|
|
296
|
+
- @pnpm/config.reader@1101.1.4
|
|
297
|
+
|
|
298
|
+
## 1100.2.5
|
|
299
|
+
|
|
300
|
+
### Patch Changes
|
|
301
|
+
|
|
302
|
+
- Updated dependencies [184ce26]
|
|
303
|
+
- @pnpm/config.pick-registry-for-package@1100.0.2
|
|
304
|
+
- @pnpm/resolving.registry.types@1100.0.2
|
|
305
|
+
- @pnpm/config.reader@1101.1.3
|
|
306
|
+
- @pnpm/network.fetch@1100.0.2
|
|
307
|
+
- @pnpm/cli.utils@1101.0.2
|
|
308
|
+
|
|
309
|
+
## 1100.2.4
|
|
310
|
+
|
|
311
|
+
### Patch Changes
|
|
312
|
+
|
|
313
|
+
- @pnpm/cli.utils@1101.0.1
|
|
314
|
+
|
|
315
|
+
## 1100.2.3
|
|
316
|
+
|
|
317
|
+
### Patch Changes
|
|
318
|
+
|
|
319
|
+
- Updated dependencies [0fbcf74]
|
|
320
|
+
- @pnpm/config.reader@1101.1.2
|
|
321
|
+
|
|
322
|
+
## 1100.2.2
|
|
323
|
+
|
|
324
|
+
### Patch Changes
|
|
325
|
+
|
|
326
|
+
- @pnpm/config.reader@1101.1.1
|
|
327
|
+
|
|
328
|
+
## 1100.2.1
|
|
329
|
+
|
|
330
|
+
### Patch Changes
|
|
331
|
+
|
|
332
|
+
- Updated dependencies [7d25bc1]
|
|
333
|
+
- Updated dependencies [9e0833c]
|
|
334
|
+
- @pnpm/config.reader@1101.1.0
|
|
335
|
+
|
|
336
|
+
## 1100.2.0
|
|
337
|
+
|
|
338
|
+
### Minor Changes
|
|
339
|
+
|
|
340
|
+
- 75942bf: Implemented native `star`, `unstar`, `stars`, and `whoami` commands.
|
|
341
|
+
|
|
342
|
+
### Patch Changes
|
|
343
|
+
|
|
344
|
+
- Updated dependencies [cee550a]
|
|
345
|
+
- Updated dependencies [4ab3d9b]
|
|
346
|
+
- Updated dependencies [9af708a]
|
|
347
|
+
- Updated dependencies [ea2a7fb]
|
|
348
|
+
- Updated dependencies [ff7733c]
|
|
349
|
+
- @pnpm/cli.utils@1101.0.0
|
|
350
|
+
- @pnpm/config.reader@1101.0.0
|
|
351
|
+
|
|
352
|
+
## 1100.1.0
|
|
353
|
+
|
|
354
|
+
### Minor Changes
|
|
355
|
+
|
|
356
|
+
- b738043: Add native `pnpm ping` command to test registry connectivity.
|
|
357
|
+
Provides a simple way to verify connectivity to the configured registry without requiring external tools.
|
|
358
|
+
- f2083f4: Implemented native `search` command and its aliases (`s`, `se`, `find`).
|
|
359
|
+
|
|
360
|
+
### Patch Changes
|
|
361
|
+
|
|
362
|
+
- Updated dependencies [ff28085]
|
|
363
|
+
- @pnpm/types@1101.0.0
|
|
364
|
+
- @pnpm/cli.utils@1100.0.1
|
|
365
|
+
- @pnpm/config.pick-registry-for-package@1100.0.1
|
|
366
|
+
- @pnpm/config.reader@1100.0.1
|
|
367
|
+
- @pnpm/network.auth-header@1100.0.1
|
|
368
|
+
- @pnpm/network.fetch@1100.0.1
|
|
369
|
+
- @pnpm/resolving.registry.types@1100.0.1
|
|
370
|
+
|
|
371
|
+
## 1000.1.0
|
|
372
|
+
|
|
373
|
+
### Minor Changes
|
|
374
|
+
|
|
375
|
+
- 853be66: Added native `pnpm dist-tag` command with `ls`, `add`, and `rm` subcommands [#11128](https://github.com/pnpm/pnpm/issues/11128).
|
|
376
|
+
- 2c90d40: Added native `pnpm deprecate` and `pnpm undeprecate` commands that interact with the npm registry directly instead of delegating to the npm CLI [#11120](https://github.com/pnpm/pnpm/pull/11120).
|
|
377
|
+
|
|
378
|
+
### Patch Changes
|
|
379
|
+
|
|
380
|
+
- Updated dependencies [7730a7f]
|
|
381
|
+
- Updated dependencies [ae8b816]
|
|
382
|
+
- Updated dependencies [facdd71]
|
|
383
|
+
- Updated dependencies [3c72b6b]
|
|
384
|
+
- Updated dependencies [9f5c0e3]
|
|
385
|
+
- Updated dependencies [76718b3]
|
|
386
|
+
- Updated dependencies [a8f016c]
|
|
387
|
+
- Updated dependencies [cc1b8e3]
|
|
388
|
+
- Updated dependencies [90bd3c3]
|
|
389
|
+
- Updated dependencies [1cc61e8]
|
|
390
|
+
- Updated dependencies [606f53e]
|
|
391
|
+
- Updated dependencies [c7203b9]
|
|
392
|
+
- Updated dependencies [bb17724]
|
|
393
|
+
- Updated dependencies [da2429d]
|
|
394
|
+
- Updated dependencies [1cc61e8]
|
|
395
|
+
- Updated dependencies [491a84f]
|
|
396
|
+
- Updated dependencies [fb8962f]
|
|
397
|
+
- Updated dependencies [f0ae1b9]
|
|
398
|
+
- Updated dependencies [b1ad9c7]
|
|
399
|
+
- Updated dependencies [0dfa8b8]
|
|
400
|
+
- Updated dependencies [7fab2a2]
|
|
401
|
+
- Updated dependencies [cb367b9]
|
|
402
|
+
- Updated dependencies [543c7e4]
|
|
403
|
+
- Updated dependencies [075aa99]
|
|
404
|
+
- Updated dependencies [ae43ac7]
|
|
405
|
+
- Updated dependencies [ccec8e7]
|
|
406
|
+
- Updated dependencies [4158906]
|
|
407
|
+
- Updated dependencies [ac944ef]
|
|
408
|
+
- Updated dependencies [d3d6938]
|
|
409
|
+
- Updated dependencies [7d2fd48]
|
|
410
|
+
- Updated dependencies [cc7c0d2]
|
|
411
|
+
- Updated dependencies [efb48dc]
|
|
412
|
+
- Updated dependencies [d5d4eed]
|
|
413
|
+
- Updated dependencies [095f659]
|
|
414
|
+
- Updated dependencies [96704a1]
|
|
415
|
+
- Updated dependencies [bb8baa7]
|
|
416
|
+
- Updated dependencies [cb367b9]
|
|
417
|
+
- Updated dependencies [7b1c189]
|
|
418
|
+
- Updated dependencies [51b04c3]
|
|
419
|
+
- Updated dependencies [6c480a4]
|
|
420
|
+
- Updated dependencies [d01b81f]
|
|
421
|
+
- Updated dependencies [3ed41f4]
|
|
422
|
+
- Updated dependencies [8ffb1a7]
|
|
423
|
+
- Updated dependencies [05fb1ae]
|
|
424
|
+
- Updated dependencies [71de2b3]
|
|
425
|
+
- Updated dependencies [10bc391]
|
|
426
|
+
- Updated dependencies [831f574]
|
|
427
|
+
- Updated dependencies [2df8b71]
|
|
428
|
+
- Updated dependencies [ed1a7fe]
|
|
429
|
+
- Updated dependencies [15549a9]
|
|
430
|
+
- Updated dependencies [cc7c0d2]
|
|
431
|
+
- Updated dependencies [5bf7768]
|
|
432
|
+
- Updated dependencies [ae43ac7]
|
|
433
|
+
- Updated dependencies [a5fdbf9]
|
|
434
|
+
- Updated dependencies [9d3f00b]
|
|
435
|
+
- Updated dependencies [efb48dc]
|
|
436
|
+
- Updated dependencies [6b3d87a]
|
|
437
|
+
- Updated dependencies [9587dac]
|
|
438
|
+
- Updated dependencies [09a999a]
|
|
439
|
+
- Updated dependencies [559f903]
|
|
440
|
+
- Updated dependencies [3574905]
|
|
441
|
+
- @pnpm/config.reader@1005.0.0
|
|
442
|
+
- @pnpm/types@1001.0.0
|
|
443
|
+
- @pnpm/cli.utils@1002.0.0
|
|
444
|
+
- @pnpm/config.pick-registry-for-package@1001.0.0
|
|
445
|
+
- @pnpm/network.auth-header@1001.0.0
|
|
446
|
+
- @pnpm/error@1001.0.0
|
|
447
|
+
- @pnpm/network.fetch@1001.0.0
|
|
448
|
+
- @pnpm/resolving.registry.types@1000.1.0
|
package/lib/access.js
CHANGED
|
@@ -5,10 +5,9 @@ import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header';
|
|
|
5
5
|
import { createFetchFromRegistry } from '@pnpm/network.fetch';
|
|
6
6
|
import npa from '@pnpm/npm-package-arg';
|
|
7
7
|
import { renderHelp } from 'render-help';
|
|
8
|
-
import { normalizeRegistryUrl, rcOptionsTypes } from './common.js';
|
|
8
|
+
import { normalizeRegistryUrl, rcOptionsTypes, readErrorBody } from './common.js';
|
|
9
9
|
export { rcOptionsTypes };
|
|
10
10
|
const DEFAULT_REGISTRY_URL = 'https://registry.npmjs.org/';
|
|
11
|
-
const ERROR_BODY_LIMIT = 64 * 1024;
|
|
12
11
|
function getRegistries(opts) {
|
|
13
12
|
return opts.registries ?? { default: DEFAULT_REGISTRY_URL };
|
|
14
13
|
}
|
|
@@ -452,37 +451,6 @@ async function throwRegistryError(response, action) {
|
|
|
452
451
|
}
|
|
453
452
|
throw new PnpmError('REGISTRY_ERROR', `Failed to ${action} package: ${response.status} ${response.statusText}. ${errorBody}`);
|
|
454
453
|
}
|
|
455
|
-
async function readErrorBody(response) {
|
|
456
|
-
const reader = response.body?.getReader();
|
|
457
|
-
if (reader == null)
|
|
458
|
-
return '';
|
|
459
|
-
const chunks = [];
|
|
460
|
-
let total = 0;
|
|
461
|
-
let truncated = false;
|
|
462
|
-
while (total < ERROR_BODY_LIMIT) {
|
|
463
|
-
// eslint-disable-next-line no-await-in-loop
|
|
464
|
-
const { done, value } = await reader.read();
|
|
465
|
-
if (done)
|
|
466
|
-
break;
|
|
467
|
-
const need = ERROR_BODY_LIMIT - total;
|
|
468
|
-
if (value.length > need) {
|
|
469
|
-
chunks.push(value.subarray(0, need));
|
|
470
|
-
truncated = true;
|
|
471
|
-
break;
|
|
472
|
-
}
|
|
473
|
-
chunks.push(value);
|
|
474
|
-
total += value.length;
|
|
475
|
-
}
|
|
476
|
-
reader.cancel().catch(() => { });
|
|
477
|
-
let body = new TextDecoder().decode(Buffer.concat(chunks));
|
|
478
|
-
if (truncated) {
|
|
479
|
-
if (body.length > 0 && !body.endsWith(' ')) {
|
|
480
|
-
body += ' ';
|
|
481
|
-
}
|
|
482
|
-
body += '(response body truncated)';
|
|
483
|
-
}
|
|
484
|
-
return body;
|
|
485
|
-
}
|
|
486
454
|
function sanitize(text) {
|
|
487
455
|
let result = '';
|
|
488
456
|
for (let i = 0; i < text.length; i++) {
|
package/lib/common.d.ts
CHANGED
|
@@ -5,3 +5,9 @@ export declare function parsePackageSpec(spec: string): {
|
|
|
5
5
|
versionRange: string | undefined;
|
|
6
6
|
};
|
|
7
7
|
export declare function normalizeRegistryUrl(registryUrl: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Reads at most ERROR_BODY_LIMIT bytes of the response body. Registry
|
|
10
|
+
* responses are untrusted, so the read is bounded before decoding rather
|
|
11
|
+
* than truncated after buffering the whole body.
|
|
12
|
+
*/
|
|
13
|
+
export declare function readErrorBody(response: Response): Promise<string>;
|
package/lib/common.js
CHANGED
|
@@ -24,4 +24,41 @@ export function parsePackageSpec(spec) {
|
|
|
24
24
|
export function normalizeRegistryUrl(registryUrl) {
|
|
25
25
|
return registryUrl.endsWith('/') ? registryUrl : `${registryUrl}/`;
|
|
26
26
|
}
|
|
27
|
+
const ERROR_BODY_LIMIT = 64 * 1024;
|
|
28
|
+
/**
|
|
29
|
+
* Reads at most ERROR_BODY_LIMIT bytes of the response body. Registry
|
|
30
|
+
* responses are untrusted, so the read is bounded before decoding rather
|
|
31
|
+
* than truncated after buffering the whole body.
|
|
32
|
+
*/
|
|
33
|
+
export async function readErrorBody(response) {
|
|
34
|
+
const reader = response.body?.getReader();
|
|
35
|
+
if (reader == null)
|
|
36
|
+
return '';
|
|
37
|
+
const chunks = [];
|
|
38
|
+
let total = 0;
|
|
39
|
+
let truncated = false;
|
|
40
|
+
while (total < ERROR_BODY_LIMIT) {
|
|
41
|
+
// eslint-disable-next-line no-await-in-loop
|
|
42
|
+
const { done, value } = await reader.read();
|
|
43
|
+
if (done)
|
|
44
|
+
break;
|
|
45
|
+
const need = ERROR_BODY_LIMIT - total;
|
|
46
|
+
if (value.length > need) {
|
|
47
|
+
chunks.push(value.subarray(0, need));
|
|
48
|
+
truncated = true;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
chunks.push(value);
|
|
52
|
+
total += value.length;
|
|
53
|
+
}
|
|
54
|
+
reader.cancel().catch(() => { });
|
|
55
|
+
let body = new TextDecoder().decode(Buffer.concat(chunks));
|
|
56
|
+
if (truncated) {
|
|
57
|
+
if (body.length > 0 && !body.endsWith(' ')) {
|
|
58
|
+
body += ' ';
|
|
59
|
+
}
|
|
60
|
+
body += '(response body truncated)';
|
|
61
|
+
}
|
|
62
|
+
return body;
|
|
63
|
+
}
|
|
27
64
|
//# sourceMappingURL=common.js.map
|
package/lib/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import * as search from './search.js';
|
|
|
8
8
|
import * as star from './star/star.js';
|
|
9
9
|
import * as stars from './star/stars.js';
|
|
10
10
|
import * as unstar from './star/unstar.js';
|
|
11
|
+
import * as team from './team.js';
|
|
11
12
|
import * as unpublish from './unpublish.js';
|
|
12
13
|
import * as whoami from './whoami.js';
|
|
13
|
-
export { access, deprecate, distTag, owner, ping, search, star, stars, undeprecate, unpublish, unstar, whoami };
|
|
14
|
+
export { access, deprecate, distTag, owner, ping, search, star, stars, team, undeprecate, unpublish, unstar, whoami };
|
package/lib/index.js
CHANGED
|
@@ -8,7 +8,8 @@ import * as search from './search.js';
|
|
|
8
8
|
import * as star from './star/star.js';
|
|
9
9
|
import * as stars from './star/stars.js';
|
|
10
10
|
import * as unstar from './star/unstar.js';
|
|
11
|
+
import * as team from './team.js';
|
|
11
12
|
import * as unpublish from './unpublish.js';
|
|
12
13
|
import * as whoami from './whoami.js';
|
|
13
|
-
export { access, deprecate, distTag, owner, ping, search, star, stars, undeprecate, unpublish, unstar, whoami };
|
|
14
|
+
export { access, deprecate, distTag, owner, ping, search, star, stars, team, undeprecate, unpublish, unstar, whoami };
|
|
14
15
|
//# sourceMappingURL=index.js.map
|
package/lib/team.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type CreateFetchFromRegistryOptions } from '@pnpm/network.fetch';
|
|
2
|
+
import type { Registries, RegistryConfig } from '@pnpm/types';
|
|
3
|
+
import { rcOptionsTypes } from './common.js';
|
|
4
|
+
export { rcOptionsTypes };
|
|
5
|
+
export declare function cliOptionsTypes(): Record<string, unknown>;
|
|
6
|
+
export declare const commandNames: string[];
|
|
7
|
+
export declare function help(): string;
|
|
8
|
+
export interface TeamOptions extends CreateFetchFromRegistryOptions {
|
|
9
|
+
cliOptions?: {
|
|
10
|
+
otp?: string;
|
|
11
|
+
parseable?: boolean;
|
|
12
|
+
json?: boolean;
|
|
13
|
+
};
|
|
14
|
+
configByUri?: Record<string, RegistryConfig>;
|
|
15
|
+
registries?: Registries;
|
|
16
|
+
}
|
|
17
|
+
export declare function handler(opts: TeamOptions, params: string[]): Promise<string>;
|
package/lib/team.js
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { docsUrl } from '@pnpm/cli.utils';
|
|
2
|
+
import { pickRegistryForPackage } from '@pnpm/config.pick-registry-for-package';
|
|
3
|
+
import { PnpmError } from '@pnpm/error';
|
|
4
|
+
import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header';
|
|
5
|
+
import { createFetchFromRegistry } from '@pnpm/network.fetch';
|
|
6
|
+
import { renderHelp } from 'render-help';
|
|
7
|
+
import { normalizeRegistryUrl, rcOptionsTypes, readErrorBody } from './common.js';
|
|
8
|
+
export { rcOptionsTypes };
|
|
9
|
+
export function cliOptionsTypes() {
|
|
10
|
+
return {
|
|
11
|
+
...rcOptionsTypes(),
|
|
12
|
+
otp: String,
|
|
13
|
+
parseable: Boolean,
|
|
14
|
+
json: Boolean,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export const commandNames = ['team'];
|
|
18
|
+
export function help() {
|
|
19
|
+
return renderHelp({
|
|
20
|
+
description: 'Manage organization teams and team memberships.',
|
|
21
|
+
descriptionLists: [
|
|
22
|
+
{
|
|
23
|
+
title: 'Commands',
|
|
24
|
+
list: [
|
|
25
|
+
{
|
|
26
|
+
description: 'Create a new team in an organization.',
|
|
27
|
+
name: 'create',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
description: 'Destroy an existing team.',
|
|
31
|
+
name: 'destroy',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
description: 'Add a user to an existing team.',
|
|
35
|
+
name: 'add',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
description: 'Remove a user from an existing team.',
|
|
39
|
+
name: 'rm',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
description: 'List teams in an organization or users in a team.',
|
|
43
|
+
name: 'ls',
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
title: 'Options',
|
|
49
|
+
list: [
|
|
50
|
+
{
|
|
51
|
+
description: 'The base URL of the npm registry.',
|
|
52
|
+
name: '--registry <url>',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
description: 'One-time password for registries that require two-factor authentication.',
|
|
56
|
+
name: '--otp',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
description: 'Output parseable results.',
|
|
60
|
+
name: '--parseable',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
description: 'Output results as JSON.',
|
|
64
|
+
name: '--json',
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
url: docsUrl('team'),
|
|
70
|
+
usages: [
|
|
71
|
+
'pnpm team create <scope:team> [--otp <code>]',
|
|
72
|
+
'pnpm team destroy <scope:team> [--otp <code>]',
|
|
73
|
+
'pnpm team add <scope:team> <user> [--otp <code>]',
|
|
74
|
+
'pnpm team rm <scope:team> <user> [--otp <code>]',
|
|
75
|
+
'pnpm team ls <scope|scope:team>',
|
|
76
|
+
],
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
export async function handler(opts, params) {
|
|
80
|
+
switch (params[0]) {
|
|
81
|
+
case 'create':
|
|
82
|
+
return teamCreate(opts, params.slice(1));
|
|
83
|
+
case 'destroy':
|
|
84
|
+
return teamDestroy(opts, params.slice(1));
|
|
85
|
+
case 'add':
|
|
86
|
+
return teamAdd(opts, params.slice(1));
|
|
87
|
+
case 'rm':
|
|
88
|
+
return teamRm(opts, params.slice(1));
|
|
89
|
+
case 'ls':
|
|
90
|
+
case 'list':
|
|
91
|
+
return teamLs(opts, params.slice(1));
|
|
92
|
+
default:
|
|
93
|
+
// When no subcommand is given, assume the first arg is a scope:team
|
|
94
|
+
// and list members, or a scope and list teams. This matches npm behavior
|
|
95
|
+
// where `npm team ls` is the default.
|
|
96
|
+
if (params.length > 0 && (params[0].startsWith('@') || params[0].startsWith(':'))) {
|
|
97
|
+
return teamLs(opts, params);
|
|
98
|
+
}
|
|
99
|
+
throw new PnpmError('TEAM_SUBCOMMAND_REQUIRED', 'Subcommand is required (create, destroy, add, rm, ls). Use `pnpm team ls <scope>` to list teams.');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async function teamCreate(opts, params) {
|
|
103
|
+
if (params.length === 0) {
|
|
104
|
+
throw new PnpmError('TEAM_CREATE_SCOPE_REQUIRED', 'Team scope is required (e.g., pnpm team create @org:newteam)');
|
|
105
|
+
}
|
|
106
|
+
const { scope, team } = parseScopeTeam(params[0]);
|
|
107
|
+
if (!team) {
|
|
108
|
+
throw new PnpmError('TEAM_CREATE_NAME_REQUIRED', 'Team name is required (e.g., pnpm team create @org:newteam)');
|
|
109
|
+
}
|
|
110
|
+
const { registryUrl, authHeader } = getRegistryAndAuthForOrg(opts, scope);
|
|
111
|
+
const fetchFromRegistry = createFetchFromRegistry(opts);
|
|
112
|
+
const otp = opts.cliOptions?.otp;
|
|
113
|
+
const teamUrl = getOrgTeamsUrl(registryUrl, scope);
|
|
114
|
+
const response = await fetchFromRegistry(teamUrl, {
|
|
115
|
+
authHeaderValue: authHeader,
|
|
116
|
+
method: 'PUT',
|
|
117
|
+
headers: {
|
|
118
|
+
'content-type': 'application/json',
|
|
119
|
+
...(otp ? { 'npm-otp': otp } : {}),
|
|
120
|
+
},
|
|
121
|
+
body: JSON.stringify({ name: team }),
|
|
122
|
+
});
|
|
123
|
+
if (!response.ok) {
|
|
124
|
+
await throwRegistryError(response, `create team "${scope}:${team}"`);
|
|
125
|
+
}
|
|
126
|
+
return `+${scope}:${team}`;
|
|
127
|
+
}
|
|
128
|
+
async function teamDestroy(opts, params) {
|
|
129
|
+
if (params.length === 0) {
|
|
130
|
+
throw new PnpmError('TEAM_DESTROY_SCOPE_REQUIRED', 'Team scope is required (e.g., pnpm team destroy @org:newteam)');
|
|
131
|
+
}
|
|
132
|
+
const { scope, team } = parseScopeTeam(params[0]);
|
|
133
|
+
if (!team) {
|
|
134
|
+
throw new PnpmError('TEAM_DESTROY_NAME_REQUIRED', 'Team name is required (e.g., pnpm team destroy @org:newteam)');
|
|
135
|
+
}
|
|
136
|
+
const { registryUrl, authHeader } = getRegistryAndAuthForOrg(opts, scope);
|
|
137
|
+
const fetchFromRegistry = createFetchFromRegistry(opts);
|
|
138
|
+
const otp = opts.cliOptions?.otp;
|
|
139
|
+
const teamUrl = getTeamUrl(registryUrl, scope, team);
|
|
140
|
+
const response = await fetchFromRegistry(teamUrl, {
|
|
141
|
+
authHeaderValue: authHeader,
|
|
142
|
+
method: 'DELETE',
|
|
143
|
+
headers: {
|
|
144
|
+
...(otp ? { 'npm-otp': otp } : {}),
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
if (!response.ok) {
|
|
148
|
+
await throwRegistryError(response, `destroy team "${scope}:${team}"`);
|
|
149
|
+
}
|
|
150
|
+
return `-${scope}:${team}`;
|
|
151
|
+
}
|
|
152
|
+
async function teamAdd(opts, params) {
|
|
153
|
+
if (params.length < 2) {
|
|
154
|
+
throw new PnpmError('TEAM_ADD_ARGS_REQUIRED', 'Team scope and user are required (e.g., pnpm team add @org:team username)');
|
|
155
|
+
}
|
|
156
|
+
const { scope, team } = parseScopeTeam(params[0]);
|
|
157
|
+
if (!team) {
|
|
158
|
+
throw new PnpmError('TEAM_ADD_NAME_REQUIRED', 'Team name is required (e.g., pnpm team add @org:team username)');
|
|
159
|
+
}
|
|
160
|
+
const username = params[1];
|
|
161
|
+
const { registryUrl, authHeader } = getRegistryAndAuthForOrg(opts, scope);
|
|
162
|
+
const fetchFromRegistry = createFetchFromRegistry(opts);
|
|
163
|
+
const otp = opts.cliOptions?.otp;
|
|
164
|
+
const membersUrl = getTeamMembersUrl(registryUrl, scope, team);
|
|
165
|
+
const response = await fetchFromRegistry(membersUrl, {
|
|
166
|
+
authHeaderValue: authHeader,
|
|
167
|
+
method: 'PUT',
|
|
168
|
+
headers: {
|
|
169
|
+
'content-type': 'application/json',
|
|
170
|
+
...(otp ? { 'npm-otp': otp } : {}),
|
|
171
|
+
},
|
|
172
|
+
body: JSON.stringify({ user: username }),
|
|
173
|
+
});
|
|
174
|
+
if (!response.ok) {
|
|
175
|
+
await throwRegistryError(response, `add user "${username}" to team "${scope}:${team}"`);
|
|
176
|
+
}
|
|
177
|
+
return `+${username} added to @${scope}:${team}`;
|
|
178
|
+
}
|
|
179
|
+
async function teamRm(opts, params) {
|
|
180
|
+
if (params.length < 2) {
|
|
181
|
+
throw new PnpmError('TEAM_RM_ARGS_REQUIRED', 'Team scope and user are required (e.g., pnpm team rm @org:team username)');
|
|
182
|
+
}
|
|
183
|
+
const { scope, team } = parseScopeTeam(params[0]);
|
|
184
|
+
if (!team) {
|
|
185
|
+
throw new PnpmError('TEAM_RM_NAME_REQUIRED', 'Team name is required (e.g., pnpm team rm @org:team username)');
|
|
186
|
+
}
|
|
187
|
+
const username = params[1];
|
|
188
|
+
const { registryUrl, authHeader } = getRegistryAndAuthForOrg(opts, scope);
|
|
189
|
+
const fetchFromRegistry = createFetchFromRegistry(opts);
|
|
190
|
+
const otp = opts.cliOptions?.otp;
|
|
191
|
+
const membersUrl = getTeamMembersUrl(registryUrl, scope, team);
|
|
192
|
+
const response = await fetchFromRegistry(membersUrl, {
|
|
193
|
+
authHeaderValue: authHeader,
|
|
194
|
+
method: 'DELETE',
|
|
195
|
+
headers: {
|
|
196
|
+
'content-type': 'application/json',
|
|
197
|
+
...(otp ? { 'npm-otp': otp } : {}),
|
|
198
|
+
},
|
|
199
|
+
body: JSON.stringify({ user: username }),
|
|
200
|
+
});
|
|
201
|
+
if (!response.ok) {
|
|
202
|
+
await throwRegistryError(response, `remove user "${username}" from team "${scope}:${team}"`);
|
|
203
|
+
}
|
|
204
|
+
return `-${username} removed from @${scope}:${team}`;
|
|
205
|
+
}
|
|
206
|
+
async function teamLs(opts, params) {
|
|
207
|
+
if (params.length === 0) {
|
|
208
|
+
throw new PnpmError('TEAM_LS_SCOPE_REQUIRED', 'Organization scope is required (e.g., pnpm team ls @org or pnpm team ls @org:team)');
|
|
209
|
+
}
|
|
210
|
+
const { scope, team } = parseScopeTeam(params[0]);
|
|
211
|
+
const { registryUrl, authHeader } = getRegistryAndAuthForOrg(opts, scope);
|
|
212
|
+
const fetchFromRegistry = createFetchFromRegistry(opts);
|
|
213
|
+
const parseable = opts.cliOptions?.parseable ?? false;
|
|
214
|
+
const json = opts.cliOptions?.json ?? false;
|
|
215
|
+
if (team) {
|
|
216
|
+
return teamListMembers({ scope, team, registryUrl, fetchFromRegistry, authHeader, parseable, json });
|
|
217
|
+
}
|
|
218
|
+
return teamListTeams({ scope, registryUrl, fetchFromRegistry, authHeader, parseable, json });
|
|
219
|
+
}
|
|
220
|
+
async function teamListTeams(options) {
|
|
221
|
+
const { scope, registryUrl, fetchFromRegistry, authHeader, parseable, json } = options;
|
|
222
|
+
const teamsUrl = getOrgTeamsUrl(registryUrl, scope);
|
|
223
|
+
const response = await fetchFromRegistry(teamsUrl, {
|
|
224
|
+
authHeaderValue: authHeader,
|
|
225
|
+
});
|
|
226
|
+
if (!response.ok) {
|
|
227
|
+
if (response.status === 404) {
|
|
228
|
+
throw new PnpmError('ORG_NOT_FOUND', `Organization "@${scope}" not found in registry`);
|
|
229
|
+
}
|
|
230
|
+
await throwRegistryError(response, `fetch teams for "@${scope}"`);
|
|
231
|
+
}
|
|
232
|
+
const teams = await response.json();
|
|
233
|
+
if (json) {
|
|
234
|
+
return JSON.stringify(teams.map(t => t.name), null, 2);
|
|
235
|
+
}
|
|
236
|
+
if (parseable) {
|
|
237
|
+
return teams.map(t => t.name).join('\n');
|
|
238
|
+
}
|
|
239
|
+
if (teams.length === 0) {
|
|
240
|
+
return `@${scope} has no teams`;
|
|
241
|
+
}
|
|
242
|
+
const lines = [`@${scope} has the following teams:`];
|
|
243
|
+
for (const { name } of teams) {
|
|
244
|
+
lines.push(` @${scope}:${name}`);
|
|
245
|
+
}
|
|
246
|
+
return lines.join('\n');
|
|
247
|
+
}
|
|
248
|
+
async function teamListMembers(options) {
|
|
249
|
+
const { scope, team, registryUrl, fetchFromRegistry, authHeader, parseable, json } = options;
|
|
250
|
+
const membersUrl = getTeamMembersUrl(registryUrl, scope, team);
|
|
251
|
+
const response = await fetchFromRegistry(membersUrl, {
|
|
252
|
+
authHeaderValue: authHeader,
|
|
253
|
+
});
|
|
254
|
+
if (!response.ok) {
|
|
255
|
+
if (response.status === 404) {
|
|
256
|
+
throw new PnpmError('TEAM_NOT_FOUND', `Team "@${scope}:${team}" not found in registry`);
|
|
257
|
+
}
|
|
258
|
+
await throwRegistryError(response, `fetch team members for "@${scope}:${team}"`);
|
|
259
|
+
}
|
|
260
|
+
const members = await response.json();
|
|
261
|
+
if (json) {
|
|
262
|
+
return JSON.stringify(members.map(m => m.name), null, 2);
|
|
263
|
+
}
|
|
264
|
+
if (parseable) {
|
|
265
|
+
return members.map(m => m.name).join('\n');
|
|
266
|
+
}
|
|
267
|
+
if (members.length === 0) {
|
|
268
|
+
return `@${scope}:${team} has no members`;
|
|
269
|
+
}
|
|
270
|
+
const lines = [`@${scope}:${team} has the following members:`];
|
|
271
|
+
for (const { name } of members) {
|
|
272
|
+
lines.push(` ${name}`);
|
|
273
|
+
}
|
|
274
|
+
return lines.join('\n');
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Parse a scope:team string. Returns the scope (without @) and optional team name.
|
|
278
|
+
* Format: @scope or @scope:team
|
|
279
|
+
*/
|
|
280
|
+
function parseScopeTeam(spec) {
|
|
281
|
+
if (!spec.startsWith('@')) {
|
|
282
|
+
throw new PnpmError('TEAM_INVALID_SCOPE', `Team spec must start with @scope, got "${spec}". Use @scope or @scope:team format.`);
|
|
283
|
+
}
|
|
284
|
+
const inner = spec.slice(1);
|
|
285
|
+
if (!inner) {
|
|
286
|
+
throw new PnpmError('TEAM_INVALID_SCOPE', `Team spec must start with @scope, got "${spec}". Use @scope or @scope:team format.`);
|
|
287
|
+
}
|
|
288
|
+
const colonIndex = inner.indexOf(':');
|
|
289
|
+
if (colonIndex === -1) {
|
|
290
|
+
return { scope: inner };
|
|
291
|
+
}
|
|
292
|
+
const scope = inner.slice(0, colonIndex);
|
|
293
|
+
const team = inner.slice(colonIndex + 1);
|
|
294
|
+
if (!scope || !team) {
|
|
295
|
+
throw new PnpmError('TEAM_INVALID_SCOPE', `Team spec must start with @scope, got "${spec}". Use @scope or @scope:team format.`);
|
|
296
|
+
}
|
|
297
|
+
return { scope, team };
|
|
298
|
+
}
|
|
299
|
+
function getRegistryAndAuthForOrg(opts, scope) {
|
|
300
|
+
const pkgName = `@${scope}/__pnpm_team__`;
|
|
301
|
+
const registryUrl = pickRegistryForPackage(opts.registries ?? { default: 'https://registry.npmjs.org/' }, pkgName);
|
|
302
|
+
const authHeader = getAuthHeaderForRegistry(opts.configByUri, registryUrl, pkgName);
|
|
303
|
+
return { registryUrl, authHeader };
|
|
304
|
+
}
|
|
305
|
+
function getAuthHeaderForRegistry(configByUri, registryUrl, packageName) {
|
|
306
|
+
const getAuthHeader = createGetAuthHeaderByURI(configByUri ?? {});
|
|
307
|
+
return getAuthHeader(registryUrl, { pkgName: packageName });
|
|
308
|
+
}
|
|
309
|
+
function getOrgTeamsUrl(registryUrl, scope) {
|
|
310
|
+
return new URL(`-/org/${encodeURIComponent(scope)}/team`, normalizeRegistryUrl(registryUrl)).href;
|
|
311
|
+
}
|
|
312
|
+
function getTeamUrl(registryUrl, scope, team) {
|
|
313
|
+
return new URL(`-/team/${encodeURIComponent(scope)}/${encodeURIComponent(team)}`, normalizeRegistryUrl(registryUrl)).href;
|
|
314
|
+
}
|
|
315
|
+
function getTeamMembersUrl(registryUrl, scope, team) {
|
|
316
|
+
return new URL(`-/team/${encodeURIComponent(scope)}/${encodeURIComponent(team)}/user`, normalizeRegistryUrl(registryUrl)).href;
|
|
317
|
+
}
|
|
318
|
+
async function throwRegistryError(response, action) {
|
|
319
|
+
const errorBody = await readErrorBody(response);
|
|
320
|
+
const safeErrorBody = [...errorBody]
|
|
321
|
+
.filter(c => {
|
|
322
|
+
const code = c.charCodeAt(0);
|
|
323
|
+
return code > 0x1f && (code < 0x7f || code > 0x9f);
|
|
324
|
+
})
|
|
325
|
+
.join('')
|
|
326
|
+
.slice(0, 500);
|
|
327
|
+
if (response.status === 401) {
|
|
328
|
+
throw new PnpmError('UNAUTHORIZED', `You must be logged in to ${action}. ${safeErrorBody}`);
|
|
329
|
+
}
|
|
330
|
+
if (response.status === 403) {
|
|
331
|
+
throw new PnpmError('FORBIDDEN', `You do not have permission to ${action}. ${safeErrorBody}`);
|
|
332
|
+
}
|
|
333
|
+
if (response.status === 404) {
|
|
334
|
+
throw new PnpmError('NOT_FOUND', `Organization or team not found. ${safeErrorBody}`);
|
|
335
|
+
}
|
|
336
|
+
if (response.status === 409) {
|
|
337
|
+
throw new PnpmError('TEAM_CONFLICT', `Team operation failed due to conflict. ${safeErrorBody}`);
|
|
338
|
+
}
|
|
339
|
+
throw new PnpmError('REGISTRY_ERROR', `Failed to ${action}: ${response.status} ${response.statusText}. ${safeErrorBody}`);
|
|
340
|
+
}
|
|
341
|
+
//# sourceMappingURL=team.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/registry-access.commands",
|
|
3
|
-
"version": "1100.
|
|
3
|
+
"version": "1100.5.0",
|
|
4
4
|
"description": "Commands for managing packages on the registry",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -28,37 +28,37 @@
|
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@inquirer/prompts": "^8.4.3",
|
|
31
|
+
"@pnpm/cli.utils": "1101.0.14",
|
|
32
|
+
"@pnpm/config.pick-registry-for-package": "1100.0.10",
|
|
33
|
+
"@pnpm/config.reader": "1101.12.0",
|
|
34
|
+
"@pnpm/error": "1100.0.1",
|
|
35
|
+
"@pnpm/network.auth-header": "1101.1.4",
|
|
36
|
+
"@pnpm/network.fetch": "1100.1.5",
|
|
37
|
+
"@pnpm/network.web-auth": "1101.2.0",
|
|
31
38
|
"@pnpm/npm-package-arg": "^2.0.0",
|
|
39
|
+
"@pnpm/registry-access.client": "1100.1.7",
|
|
40
|
+
"@pnpm/resolving.registry.types": "1100.1.4",
|
|
41
|
+
"@pnpm/types": "1101.4.0",
|
|
32
42
|
"chalk": "^5.6.2",
|
|
33
43
|
"ramda": "npm:@pnpm/ramda@0.28.1",
|
|
34
44
|
"render-help": "^2.0.0",
|
|
35
|
-
"semver": "^7.8.4"
|
|
36
|
-
"@pnpm/cli.utils": "1101.0.13",
|
|
37
|
-
"@pnpm/config.pick-registry-for-package": "1100.0.9",
|
|
38
|
-
"@pnpm/config.reader": "1101.11.1",
|
|
39
|
-
"@pnpm/error": "1100.0.1",
|
|
40
|
-
"@pnpm/network.fetch": "1100.1.4",
|
|
41
|
-
"@pnpm/network.web-auth": "1101.2.0",
|
|
42
|
-
"@pnpm/network.auth-header": "1101.1.3",
|
|
43
|
-
"@pnpm/registry-access.client": "1100.1.6",
|
|
44
|
-
"@pnpm/resolving.registry.types": "1100.1.3",
|
|
45
|
-
"@pnpm/types": "1101.3.2"
|
|
45
|
+
"semver": "^7.8.4"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"@pnpm/logger": "^1100.0.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@jest/globals": "30.4.1",
|
|
52
|
+
"@pnpm/logger": "1100.0.0",
|
|
53
|
+
"@pnpm/prepare": "1100.0.19",
|
|
54
|
+
"@pnpm/registry-access.commands": "1100.5.0",
|
|
55
|
+
"@pnpm/releasing.commands": "1100.6.0",
|
|
56
|
+
"@pnpm/testing.command-defaults": "1100.0.9",
|
|
57
|
+
"@pnpm/testing.mock-agent": "1101.0.5",
|
|
58
|
+
"@pnpm/testing.registry-mock": "1100.0.9",
|
|
52
59
|
"@types/ramda": "0.31.1",
|
|
53
60
|
"@types/semver": "7.7.1",
|
|
54
|
-
"execa": "npm:safe-execa@0.3.0"
|
|
55
|
-
"@pnpm/logger": "1100.0.0",
|
|
56
|
-
"@pnpm/registry-access.commands": "1100.4.0",
|
|
57
|
-
"@pnpm/releasing.commands": "1100.5.4",
|
|
58
|
-
"@pnpm/testing.command-defaults": "1100.0.8",
|
|
59
|
-
"@pnpm/testing.mock-agent": "1101.0.4",
|
|
60
|
-
"@pnpm/prepare": "1100.0.18",
|
|
61
|
-
"@pnpm/testing.registry-mock": "1100.0.8"
|
|
61
|
+
"execa": "npm:safe-execa@0.3.0"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=22.13"
|