Skip to content

Commit 3be30b1

Browse files
authored
Merge branch 'npmx-dev:main' into feat/changelog-1
2 parents 17d570e + 4f45d5b commit 3be30b1

24 files changed

+1137
-666
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: dependency-diff-comment
2+
3+
on:
4+
workflow_run:
5+
workflows: ['dependency-diff']
6+
types:
7+
- completed
8+
9+
permissions:
10+
pull-requests: write
11+
actions: read
12+
13+
jobs:
14+
dependency-diff-comment:
15+
name: 💬 Dependency diff comment
16+
runs-on: ubuntu-slim
17+
if: github.event.workflow_run.conclusion == 'success'
18+
19+
steps:
20+
- name: 📥 Download artifact
21+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
22+
with:
23+
name: e18e-diff-result
24+
run-id: ${{ github.event.workflow_run.id }}
25+
github-token: ${{ secrets.GITHUB_TOKEN }}
26+
27+
- name: 💬 Post comment
28+
uses: e18e/action-dependency-diff@f825d5b5c5ce0a42dc46c47ec20de24460affcd8 # v1.5.0
29+
with:
30+
mode: comment-from-artifact
31+
artifact-path: e18e-diff-result.json
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: dependency-diff
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
- release
8+
paths:
9+
- package.json
10+
- pnpm-lock.yaml
11+
- pnpm-workspace.yaml
12+
- docs/package.json
13+
- cli/package.json
14+
15+
concurrency:
16+
group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
17+
cancel-in-progress: true
18+
19+
permissions:
20+
contents: read
21+
22+
jobs:
23+
dependency-diff:
24+
name: 🔎 Dependency diff
25+
runs-on: ubuntu-slim
26+
27+
steps:
28+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
29+
with:
30+
fetch-depth: 0
31+
32+
- name: 🔎 Compare dependencies
33+
id: analyze
34+
uses: e18e/action-dependency-diff@f825d5b5c5ce0a42dc46c47ec20de24460affcd8 # v1.5.0
35+
with:
36+
mode: artifact
37+
detect-replacements: 'true'
38+
duplicate-threshold: '4'
39+
dependency-threshold: '15'
40+
size-threshold: '200000'
41+
42+
- name: 📤 Upload artifact
43+
if: steps.analyze.outputs.artifact-path
44+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
45+
with:
46+
name: e18e-diff-result
47+
path: ${{ steps.analyze.outputs.artifact-path }}

.github/workflows/remove-needs-review-on-review.yml

Lines changed: 0 additions & 69 deletions
This file was deleted.

.github/workflows/welcome-close.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
const body = [
4040
`Thanks for your first contribution, @${author}! ${emoji}`,
4141
'',
42-
`We'd love to welcome you to the npmx community. Come and say hi on [Discord](https://chat.npmx.dev)! And once you've joined, visit [npmx.wamellow.com](https://npmx.wamellow.com/) to claim the **contributor** role.`,
42+
`We'd love to welcome you to the npmx community. Come and say hi on [Discord](https://build.npmx.dev)! And once you've joined, visit [npmx.wamellow.com](https://npmx.wamellow.com/) to claim the **contributor** role.`,
4343
].join('\n');
4444
4545
await github.rest.issues.createComment({

.vite-hooks/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
vp staged

app/pages/compare.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ async function exportComparisonDataAsMarkdown() {
140140
}
141141
142142
defineOgImageComponent('Compare', {
143-
packages: () => packages.value,
143+
packages: () => packages.value.toSorted((a, b) => a.localeCompare(b)),
144144
emptyDescription: () => $t('compare.packages.meta_description_empty'),
145145
})
146146

cli/src/npm-client.ts

Lines changed: 19 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ const AUTH_URL_TIMEOUT_MS = 90_000
157157
export interface ExecNpmOptions {
158158
otp?: string
159159
silent?: boolean
160+
/** Working directory for the npm command. */
161+
cwd?: string
160162
/** When true, use PTY-based interactive execution instead of execFile. */
161163
interactive?: boolean
162164
/** When true, npm opens auth URLs in the user's browser.
@@ -214,6 +216,7 @@ async function execNpmInteractive(
214216
name: 'xterm-256color',
215217
cols: 120,
216218
rows: 30,
219+
cwd: options.cwd,
217220
env,
218221
})
219222

@@ -337,6 +340,7 @@ async function execNpm(args: string[], options: ExecNpmOptions = {}): Promise<Np
337340
const { command, args: processArgs } = resolveNpmProcessCommand(npmArgs)
338341
const { stdout, stderr } = await execFileAsync(command, processArgs, {
339342
timeout: 60000,
343+
cwd: options.cwd,
340344
env: createNpmEnv(),
341345
})
342346

@@ -559,12 +563,12 @@ export async function listUserPackages(user: string): Promise<NpmExecResult> {
559563
* Creates a minimal package.json in a temp directory and publishes it.
560564
* @param name Package name to claim
561565
* @param author npm username of the publisher (for author field)
562-
* @param otp Optional OTP for 2FA
566+
* @param options Execution options (otp, interactive, etc.)
563567
*/
564568
export async function packageInit(
565569
name: string,
566570
author?: string,
567-
otp?: string,
571+
options?: ExecNpmOptions,
568572
): Promise<NpmExecResult> {
569573
validatePackageName(name)
570574

@@ -600,52 +604,22 @@ export async function packageInit(
600604
args.push('--access', access)
601605
}
602606

603-
// Run npm publish from the temp directory
604-
const npmArgs = otp ? [...args, '--otp', otp] : args
605-
606-
// Log the command being run (hide OTP value for security)
607-
const displayCmd = otp ? `npm ${args.join(' ')} --otp ******` : `npm ${args.join(' ')}`
607+
const displayCmd = options?.otp
608+
? ['npm', ...args, '--otp', '******'].join(' ')
609+
: ['npm', ...args].join(' ')
608610
logCommand(`${displayCmd} (in temp dir for ${name})`)
609611

610-
try {
611-
const { command, args: processArgs } = resolveNpmProcessCommand(npmArgs)
612-
const { stdout, stderr } = await execFileAsync(command, processArgs, {
613-
timeout: 60000,
614-
cwd: tempDir.path,
615-
env: createNpmEnv(),
616-
})
612+
const result = await execNpm(args, { ...options, cwd: tempDir.path, silent: true })
617613

614+
if (result.exitCode === 0) {
618615
logSuccess(`Published ${name}@0.0.0`)
619-
620-
return {
621-
stdout: stdout.trim(),
622-
stderr: filterNpmWarnings(stderr),
623-
exitCode: 0,
624-
}
625-
} catch (error) {
626-
const err = error as { stdout?: string; stderr?: string; code?: number }
627-
const stderr = err.stderr?.trim() ?? String(error)
628-
const requiresOtp = detectOtpRequired(stderr)
629-
const authFailure = detectAuthFailure(stderr)
630-
631-
if (requiresOtp) {
632-
logError('OTP required')
633-
} else if (authFailure) {
634-
logError('Authentication required - please run "npm login" and restart the connector')
635-
} else {
636-
logError(filterNpmWarnings(stderr).split('\n')[0] || 'Command failed')
637-
}
638-
639-
return {
640-
stdout: err.stdout?.trim() ?? '',
641-
stderr: requiresOtp
642-
? 'This operation requires a one-time password (OTP).'
643-
: authFailure
644-
? 'Authentication failed. Please run "npm login" and restart the connector.'
645-
: filterNpmWarnings(stderr),
646-
exitCode: err.code ?? 1,
647-
requiresOtp,
648-
authFailure,
649-
}
616+
} else if (result.requiresOtp) {
617+
logError('OTP required')
618+
} else if (result.authFailure) {
619+
logError('Authentication required - please run "npm login" and restart the connector')
620+
} else {
621+
logError(result.stderr.split('\n')[0] || 'Command failed')
650622
}
623+
624+
return result
651625
}

cli/src/server.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -809,9 +809,7 @@ async function executeOperation(
809809
result = await ownerRemove(params.user, params.pkg, execOptions)
810810
break
811811
case 'package:init':
812-
// package:init has its own special execution path (temp dir + publish)
813-
// and does not support interactive mode
814-
result = await packageInit(params.name, params.author, options.otp)
812+
result = await packageInit(params.name, params.author, execOptions)
815813
break
816814
default:
817815
return {

i18n/locales/fr-FR.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@
314314
"warnings": "Avertissements :",
315315
"go_back_home": "Retour à l'accueil",
316316
"per_week": "/ semaine",
317+
"yes": "Oui",
318+
"no": "Non",
317319
"vanity_downloads_hint": "Métrique de vanité : aucun paquet affiché | Métrique de vanité : pour le paquet affiché | Métrique de vanité : somme des {count} paquets affichés",
318320
"sort": {
319321
"name": "nom",
@@ -336,6 +338,7 @@
336338
"gitea": "Voir sur Gitea",
337339
"gitee": "Voir sur Gitee",
338340
"radicle": "Voir sur Radicle",
341+
"socket_dev": "Voir sur socket.dev",
339342
"sourcehut": "Voir sur SourceHut",
340343
"tangled": "Voir sur Tangled"
341344
},
@@ -944,8 +947,11 @@
944947
"lines": "{count} lignes",
945948
"toggle_tree": "Basculer l'arborescence",
946949
"close_tree": "Fermer l'arborescence",
950+
"copy_content": "Copier le contenu du fichier",
947951
"copy_link": "Copier le lien",
948952
"view_raw": "Voir le fichier brut",
953+
"toggle_container": "Changer la largeur du conteneur",
954+
"open_raw_file": "Ouvrir le fichier brut",
949955
"file_too_large": "Fichier trop volumineux pour l'aperçu",
950956
"file_size_warning": "{size} dépasse la limite de 500 Ko pour la coloration syntaxique",
951957
"failed_to_load": "Échec du chargement du fichier",

0 commit comments

Comments
 (0)