Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions knip.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
"eslint-plugin-react-hooks",
// TypeScript native compiler, used as a dev tool not imported
"@typescript/native-preview",
// Runtime deps used by turbo/generators/scripts/*.cjs via require(), which knip cannot trace
"hosted-git-info",
"validate-npm-package-name",
// Provides type definitions for validate-npm-package-name, needed at dev time
"@types/validate-npm-package-name",
],
"ignoreBinaries": [
// Provided by sanity package in dev/test-studio, which is an ignored workspace
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
"@changesets/changelog-github": "^0.6.0",
"@changesets/cli": "^2.30.0",
"@turbo/gen": "^2.8.13",
"@types/hosted-git-info": "^3.0.5",
"@types/validate-npm-package-name": "^4.0.2",
"@typescript/native-preview": "catalog:",
"eslint-plugin-react-hooks": "^7.0.1",
Expand Down
8 changes: 0 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 40 additions & 15 deletions turbo/generators/config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,43 @@
import {execSync} from 'node:child_process'
import {execFileSync, execSync} from 'node:child_process'
import {readdirSync, rmSync} from 'node:fs'
import {join} from 'node:path'

import type {PlopTypes} from '@turbo/gen'
import hostedGitInfo from 'hosted-git-info'
import validateNpmPackageName from 'validate-npm-package-name'

// Helper functions that call external scripts to avoid bundling issues
function validatePackageName(name: string): {errors?: string[]} {
try {
// oxlint-disable-next-line no-restricted-globals
const scriptPath = join(__dirname, 'scripts/validate-package-name.cjs')
execFileSync(process.execPath, [scriptPath, name], {encoding: 'utf-8', stdio: 'pipe'})
return {}
Comment thread
jordanl17 marked this conversation as resolved.
} catch (error: any) {
const errorMessage = error.stderr?.toString().trim() || error.message
return {errors: [errorMessage]}
}
}

function parseRepositoryUrl(
repoUrl: string,
directory?: string,
): {repositoryUrl: string | undefined; sourceUrl: string | undefined} {
try {
// oxlint-disable-next-line no-restricted-globals
const scriptPath = join(__dirname, 'scripts/parse-repo-url.cjs')
const args = [scriptPath, repoUrl]
if (directory) {
args.push(directory)
}
const result = execFileSync(process.execPath, args, {encoding: 'utf-8'})
const parsed = JSON.parse(result.trim())
return {
repositoryUrl: parsed.repositoryUrl ?? undefined,
sourceUrl: parsed.sourceUrl ?? undefined,
}
} catch {
return {repositoryUrl: undefined, sourceUrl: undefined}
}
}

interface NpmPackageJson {
name: string
Expand Down Expand Up @@ -118,16 +151,8 @@ function getRepositoryUrls(packageJson: NpmPackageJson): RepositoryUrls {
const repoString = typeof repo === 'string' ? repo : repo.url
if (!repoString) return {repositoryUrl: undefined, sourceUrl: undefined}

const info = hostedGitInfo.fromUrl(repoString)
if (!info) return {repositoryUrl: undefined, sourceUrl: undefined}

const repositoryUrl = info.browse()
const directory = typeof repo === 'object' ? repo.directory : undefined

// If there's a directory, construct a URL to that path in the repo
const sourceUrl = directory ? `${repositoryUrl}/tree/main/${directory}` : repositoryUrl

return {repositoryUrl, sourceUrl}
return parseRepositoryUrl(repoString, directory)
}

/**
Expand Down Expand Up @@ -175,7 +200,7 @@ export default function generator(plop: PlopTypes.NodePlopAPI): void {
// Plugin names are already validated by npm package name rules, but double-check
// oxlint-disable-next-line no-unsafe-type-assertion
const pluginName = String((answers as any).name)
const {errors} = validateNpmPackageName(pluginName)
const {errors} = validatePackageName(pluginName)
if (errors?.length) {
throw new Error(`Invalid plugin name: ${pluginName}\n${errors.join(', ')}`)
}
Expand Down Expand Up @@ -279,7 +304,7 @@ export default function generator(plop: PlopTypes.NodePlopAPI): void {
if (!input) {
return 'Plugin name is required'
}
const {errors} = validateNpmPackageName(input)
const {errors} = validatePackageName(input)
if (errors?.length) {
return errors.join(', ')
}
Expand Down Expand Up @@ -461,7 +486,7 @@ export default function generator(plop: PlopTypes.NodePlopAPI): void {
if (!input) {
return 'Plugin name is required'
}
const {errors} = validateNpmPackageName(input)
const {errors} = validatePackageName(input)
if (errors?.length) {
return errors.join(', ')
}
Expand Down
28 changes: 28 additions & 0 deletions turbo/generators/scripts/parse-repo-url.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env node
// Helper script to parse git repository URLs
// This is executed via execSync to avoid bundling issues with turbo gen

const hostedGitInfo = require('hosted-git-info')

const repoUrl = process.argv[2]
if (!repoUrl) {
console.error('Usage: parse-repo-url.cjs <repo-url>')
process.exit(1)
}

const info = hostedGitInfo.fromUrl(repoUrl)
if (!info) {
// oxlint-disable-next-line no-console
console.log(JSON.stringify({repositoryUrl: null, sourceUrl: null}))
process.exit(0)
}

const repositoryUrl = info.browse()
const directory = process.argv[3] // Optional directory parameter

// If there's a directory, construct a URL to that path in the repo
const sourceUrl = directory ? `${repositoryUrl}/tree/main/${directory}` : repositoryUrl

// oxlint-disable-next-line no-console
console.log(JSON.stringify({repositoryUrl, sourceUrl}))
process.exit(0)
21 changes: 21 additions & 0 deletions turbo/generators/scripts/validate-package-name.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env node
// Helper script to validate npm package names
// This is executed via execSync to avoid bundling issues with turbo gen

const validateNpmPackageName = require('validate-npm-package-name')

const packageName = process.argv[2]
if (!packageName) {
console.error('Usage: validate-package-name.cjs <package-name>')
process.exit(1)
}

const result = validateNpmPackageName(packageName)
if (result.errors && result.errors.length > 0) {
console.error(result.errors.join(', '))
process.exit(1)
}

// oxlint-disable-next-line no-console
console.log('valid')
process.exit(0)
Loading