Skip to content

Commit d0ee386

Browse files
danielroeserhalp
andauthored
feat(cli): add validation for connector api (#150)
Co-authored-by: Philippe Serhal <philippe.serhal@gmail.com>
1 parent 4f50fc9 commit d0ee386

8 files changed

Lines changed: 907 additions & 73 deletions

File tree

cli/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"obug": "^2.1.1",
3838
"picocolors": "^1.1.1",
3939
"srvx": "^0.10.1",
40+
"valibot": "^1.2.0",
4041
"validate-npm-package-name": "^7.0.2"
4142
},
4243
"devDependencies": {

cli/src/npm-client.ts

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,21 @@ import { promisify } from 'node:util'
55
import { mkdtemp, writeFile, rm } from 'node:fs/promises'
66
import { tmpdir } from 'node:os'
77
import { join } from 'node:path'
8-
import validateNpmPackageName from 'validate-npm-package-name'
8+
import * as v from 'valibot'
9+
import { PackageNameSchema, UsernameSchema, OrgNameSchema, ScopeTeamSchema } from './schemas.ts'
910
import { logCommand, logSuccess, logError } from './logger.ts'
1011

1112
const execFileAsync = promisify(execFile)
1213

13-
// Validation pattern for npm usernames/org names
14-
// These follow similar rules: lowercase alphanumeric with hyphens, can't start/end with hyphen
15-
const NPM_USERNAME_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/i
16-
1714
/**
1815
* Validates an npm package name using the official npm validation package
1916
* @throws Error if the name is invalid
2017
*/
2118
export function validatePackageName(name: string): void {
22-
const result = validateNpmPackageName(name)
23-
if (!result.validForNewPackages && !result.validForOldPackages) {
24-
const errors = result.errors || result.warnings || ['Invalid package name']
25-
throw new Error(`Invalid package name "${name}": ${errors.join(', ')}`)
19+
const result = v.safeParse(PackageNameSchema, name)
20+
if (!result.success) {
21+
const message = result.issues[0]?.message || 'Invalid package name'
22+
throw new Error(`Invalid package name "${name}": ${message}`)
2623
}
2724
}
2825

@@ -31,7 +28,8 @@ export function validatePackageName(name: string): void {
3128
* @throws Error if the username is invalid
3229
*/
3330
export function validateUsername(name: string): void {
34-
if (!name || name.length > 50 || !NPM_USERNAME_RE.test(name)) {
31+
const result = v.safeParse(UsernameSchema, name)
32+
if (!result.success) {
3533
throw new Error(`Invalid username: ${name}`)
3634
}
3735
}
@@ -41,7 +39,8 @@ export function validateUsername(name: string): void {
4139
* @throws Error if the org name is invalid
4240
*/
4341
export function validateOrgName(name: string): void {
44-
if (!name || name.length > 50 || !NPM_USERNAME_RE.test(name)) {
42+
const result = v.safeParse(OrgNameSchema, name)
43+
if (!result.success) {
4544
throw new Error(`Invalid org name: ${name}`)
4645
}
4746
}
@@ -51,20 +50,9 @@ export function validateOrgName(name: string): void {
5150
* @throws Error if the scope:team is invalid
5251
*/
5352
export function validateScopeTeam(scopeTeam: string): void {
54-
if (!scopeTeam || scopeTeam.length > 100) {
55-
throw new Error(`Invalid scope:team: ${scopeTeam}`)
56-
}
57-
// Format: @scope:team
58-
const match = scopeTeam.match(/^@([^:]+):(.+)$/)
59-
if (!match) {
60-
throw new Error(`Invalid scope:team format: ${scopeTeam}`)
61-
}
62-
const [, scope, team] = match
63-
if (!scope || !NPM_USERNAME_RE.test(scope)) {
64-
throw new Error(`Invalid scope in scope:team: ${scopeTeam}`)
65-
}
66-
if (!team || !NPM_USERNAME_RE.test(team)) {
67-
throw new Error(`Invalid team name in scope:team: ${scopeTeam}`)
53+
const result = v.safeParse(ScopeTeamSchema, scopeTeam)
54+
if (!result.success) {
55+
throw new Error(`Invalid scope:team format: ${scopeTeam}. Expected @scope:team`)
6856
}
6957
}
7058

0 commit comments

Comments
 (0)