📄 utils.ts
¶
📊 Analysis Summary¶
Metric | Count |
---|---|
🔧 Functions | 13 |
📦 Imports | 12 |
📊 Variables & Constants | 24 |
⚡ Async/Await Patterns | 10 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 scripts/utils.ts
📦 Imports¶
Name | Source |
---|---|
PackageIndexes |
@vueuse/metadata |
VueUseFunction |
@vueuse/metadata |
existsSync |
node:fs |
join |
node:path |
resolve |
node:path |
fileURLToPath |
node:url |
matter |
gray-matter |
$fetch |
ofetch |
Git |
simple-git |
yaml |
yaml |
packages |
../meta/packages |
getCategories |
../packages/metadata/utils |
Variables & Constants¶
Name | Type | Kind | Value | Exported |
---|---|---|---|---|
DOCS_URL |
"https://vueuse.org" |
const | 'https://vueuse.org' |
✓ |
types |
string |
let/var | await fs.readFile(typingFilepath, 'utf-8') |
✗ |
prettier |
any |
let/var | await import('prettier') |
✗ |
imports |
string[] |
let/var | *not shown* |
✗ |
arr |
string[] |
const | [] |
✗ |
list |
string |
let/var | '' |
✗ |
desc |
string |
const | description ? — ${description}: '' |
✗ |
START |
string |
const | <!--${key}_STARTS--> |
✗ |
END |
string |
const | <!--${key}_ENDS--> |
✗ |
regex |
RegExp |
const | new RegExp( ${START}[\s\S]*?${END}, 'im') |
✗ |
target |
string |
const | value ? ${START}\n\n${value.trim()}\n\n${END}: ${START}${END}`` |
✗ |
readme |
string |
let/var | await fs.readFile(readmePath, 'utf-8') |
✗ |
readme |
string |
let/var | await fs.readFile('README.md', 'utf-8') |
✗ |
functionsCount |
any |
let/var | functions.filter(i => !i.internal).length |
✗ |
mdAddons |
string |
let/var | await fs.readFile('packages/add-ons.md', 'utf-8') |
✗ |
mdPath |
string |
let/var | packages/${fn.package}/${fn.name}/index.md |
✗ |
readme |
string |
let/var | await fs.readFile(mdPath, 'utf-8') |
✗ |
functionsCount |
any |
let/var | indexes.functions.filter(i => !i.internal).length |
✗ |
url |
string |
let/var | https://img.shields.io/badge/-${functionsCount}%20functions-13708a |
✗ |
data |
any |
let/var | await $fetch(url, { responseType: 'text' }) |
✗ |
additional |
string[] |
let/var | ['egoist', 'Tahul', 'BobbieGoede'] |
✗ |
collaborators |
string[] |
let/var | [] |
✗ |
data |
any |
let/var | await $fetch<{ login: string }[]>( https://api.github.com/repos/vueuse/vueuse/contributors?per_page=100&page=${page}`, { |
|
method: 'get', | ||||
headers: { | ||||
'content-type': 'application/json', | ||||
}, | ||||
}) | []` | ✗ | ||
collaborators |
string[] |
let/var | await fetchContributors() |
✗ |
Async/Await Patterns¶
Type | Function | Await Expressions | Promise Chains |
---|---|---|---|
async-function | getTypeDefinition |
fs.readFile(typingFilepath, 'utf-8'), import('prettier'), prettier | |
.format( | |||
types, | |||
{ | |||
semi: false, | |||
parser: 'typescript', | |||
}, | |||
) | none | ||
async-function | updateImport |
fs.writeFile(join(dir, 'index.ts'), ${imports.join('\n')}\n ), fs.rm(join(dir, 'index.mjs'), { force: true }) |
none |
async-function | updatePackageREADME |
fs.readFile(readmePath, 'utf-8'), fs.writeFile(readmePath, ${readme}\n , 'utf-8') |
none |
async-function | updateIndexREADME |
fs.readFile('README.md', 'utf-8'), fs.writeFile('README.md', ${readme}\n , 'utf-8') |
none |
async-function | updateFunctionsMD |
fs.readFile('packages/add-ons.md', 'utf-8'), fs.writeFile('packages/add-ons.md', mdAddons, 'utf-8') | none |
async-function | updateFunctionREADME |
fs.readFile(mdPath, 'utf-8'), fs.writeFile(mdPath, ${readme}\n , 'utf-8') |
none |
async-function | updateCountBadge |
$fetch(url, { responseType: 'text' }), fs.writeFile(join(DIR_ROOT, 'packages/public/badge-function-count.svg'), data, 'utf-8') | none |
async-function | updatePackageJSON |
fs.readFile('package.json', { encoding: 'utf8' }), fs.readFile(packageJSONPath, { encoding: 'utf8' }), fs.writeFile(packageJSONPath, ${JSON.stringify(packageJSON, null, 2)}\n ) |
none |
async-function | fetchContributors |
$fetch<{ login: string }[]>(https://api.github.com/repos/vueuse/vueuse/contributors?per_page=100&page=${page} , { |
|
method: 'get', | |||
headers: { | |||
'content-type': 'application/json', | |||
}, | |||
}), fetchContributors(page + 1) | none | ||
async-function | updateContributors |
fetchContributors(), fs.writeFile(join(DIR_SRC, './contributors.json'), ${JSON.stringify(collaborators, null, 2)}\n , 'utf8') |
none |
Functions¶
getTypeDefinition(pkg: string, name: string): Promise<string | undefined>
¶
Code
export async function getTypeDefinition(pkg: string, name: string): Promise<string | undefined> {
const typingFilepath = join(DIR_TYPES, `${pkg}/${name}/index.d.ts`)
if (!existsSync(typingFilepath))
return
let types = await fs.readFile(typingFilepath, 'utf-8')
if (!types)
return
// clean up types
types = types
.replace(/import\(.*?\)\./g, '')
.replace(/import[\s\S]+?from ?["'][\s\S]+?["']/g, '')
.replace(/export \{\}/g, '')
const prettier = await import('prettier')
return (await prettier
.format(
types,
{
semi: false,
parser: 'typescript',
},
))
.trim()
}
- Parameters:
pkg: string
name: string
- Return Type:
Promise<string | undefined>
- Calls:
join (from node:path)
existsSync (from node:fs)
fs.readFile
types .replace(/import\(.*?\)\./g, '') .replace(/import[\s\S]+?from ?["'][\s\S]+?["']/g, '') .replace
complex_call_1243
(await prettier .format( types, { semi: false, parser: 'typescript', }, )) .trim
prettier .format
- Internal Comments:
updateImport({ packages, functions }: PackageIndexes): Promise<void>
¶
Code
export async function updateImport({ packages, functions }: PackageIndexes) {
for (const { name, dir, manualImport } of Object.values(packages)) {
if (manualImport)
continue
let imports: string[]
if (name === 'components') {
imports = functions
.sort((a, b) => a.name.localeCompare(b.name))
.flatMap((fn) => {
const arr: string[] = []
// don't include integration components
if (fn.package === 'integrations')
return arr
if (fn.component)
arr.push(`export * from '../${fn.package}/${fn.name}/component'`)
if (fn.directive)
arr.push(`export * from '../${fn.package}/${fn.name}/directive'`)
return arr
})
}
else {
imports = functions
.filter(i => i.package === name)
.map(f => f.name)
.sort()
.map(name => `export * from './${name}'`)
}
if (name === 'core') {
imports.push(
'export * from \'./types\'',
'export * from \'@vueuse/shared\'',
'export * from \'./ssr-handlers\'',
)
}
if (name === 'nuxt') {
imports.push(
'export * from \'@vueuse/core\'',
)
}
await fs.writeFile(join(dir, 'index.ts'), `${imports.join('\n')}\n`)
// temporary file for export-size
await fs.rm(join(dir, 'index.mjs'), { force: true })
}
}
- Parameters:
{ packages, functions }: PackageIndexes
- Return Type:
Promise<void>
- Calls:
Object.values
functions .sort((a, b) => a.name.localeCompare(b.name)) .flatMap
arr.push
functions .filter(i => i.package === name) .map(f => f.name) .sort() .map
imports.push
fs.writeFile
join (from node:path)
imports.join
fs.rm
- Internal Comments:
uniq(a: T): any[]
¶
- Parameters:
a: T
- Return Type:
any[]
- Calls:
Array.from
stringifyFunctions(functions: VueUseFunction[], title: boolean): string
¶
Code
export function stringifyFunctions(functions: VueUseFunction[], title = true) {
let list = ''
const categories = getCategories(functions)
for (const category of categories) {
if (category.startsWith('_'))
continue
if (title)
list += `### ${category}\n`
const categoryFunctions = functions
.filter(i => i.category === category)
.sort((a, b) => a.name.localeCompare(b.name))
for (const { name, docs, description, deprecated } of categoryFunctions) {
if (deprecated)
continue
const desc = description ? ` — ${description}` : ''
list += `- [\`${name}\`](${docs})${desc}\n`
}
list += '\n'
}
return list
}
- Parameters:
functions: VueUseFunction[]
title: boolean
- Return Type:
string
- Calls:
getCategories (from ../packages/metadata/utils)
category.startsWith
functions .filter(i => i.category === category) .sort
a.name.localeCompare
replacer(code: string, value: string, key: string, insert: 'head' | 'tail' | 'none'): string
¶
Code
export function replacer(code: string, value: string, key: string, insert: 'head' | 'tail' | 'none' = 'none') {
const START = `<!--${key}_STARTS-->`
const END = `<!--${key}_ENDS-->`
const regex = new RegExp(`${START}[\\s\\S]*?${END}`, 'im')
const target = value ? `${START}\n\n${value.trim()}\n\n${END}` : `${START}${END}`
if (!code.match(regex)) {
if (insert === 'none')
return code
else if (insert === 'head')
return `${target}\n\n${code}`
else
return `${code}\n\n${target}`
}
return code.replace(regex, target)
}
- Parameters:
code: string
value: string
key: string
insert: 'head' | 'tail' | 'none'
- Return Type:
string
- Calls:
value.trim
code.match
code.replace
updatePackageREADME({ packages, functions }: PackageIndexes): Promise<void>
¶
Code
export async function updatePackageREADME({ packages, functions }: PackageIndexes) {
for (const { name, dir } of Object.values(packages)) {
const readmePath = join(dir, 'README.md')
if (!existsSync(readmePath))
continue
const functionMD = stringifyFunctions(functions.filter(i => i.package === name), false)
let readme = await fs.readFile(readmePath, 'utf-8')
readme = replacer(readme, functionMD, 'FUNCTIONS_LIST').trim().replace(/\r\n/g, '\n')
await fs.writeFile(readmePath, `${readme}\n`, 'utf-8')
}
}
- Parameters:
{ packages, functions }: PackageIndexes
- Return Type:
Promise<void>
- Calls:
Object.values
join (from node:path)
existsSync (from node:fs)
stringifyFunctions
functions.filter
fs.readFile
replacer(readme, functionMD, 'FUNCTIONS_LIST').trim().replace
fs.writeFile
updateIndexREADME({ packages, functions }: PackageIndexes): Promise<void>
¶
Code
export async function updateIndexREADME({ packages, functions }: PackageIndexes) {
let readme = await fs.readFile('README.md', 'utf-8')
const functionsCount = functions.filter(i => !i.internal).length
readme = readme.replace(
/img\.shields\.io\/badge\/-(.+?)%20functions/,
`img.shields.io/badge/-${functionsCount}%20functions`,
).trim().replace(/\r\n/g, '\n')
await fs.writeFile('README.md', `${readme}\n`, 'utf-8')
}
- Parameters:
{ packages, functions }: PackageIndexes
- Return Type:
Promise<void>
- Calls:
fs.readFile
functions.filter
readme.replace( /img\.shields\.io\/badge\/-(.+?)%20functions/,
img.shields.io/badge/-${functionsCount}%20functions, ).trim().replace
fs.writeFile
updateFunctionsMD({ packages, functions }: PackageIndexes): Promise<void>
¶
Code
export async function updateFunctionsMD({ packages, functions }: PackageIndexes) {
let mdAddons = await fs.readFile('packages/add-ons.md', 'utf-8')
const addons = Object.values(packages)
.filter(i => i.addon && !i.deprecated)
.map(({ docs, name, display, description }) => {
return `## ${display} - [\`@vueuse/${name}\`](${docs})\n\n${description?.trim()}\n\n${
stringifyFunctions(functions.filter(i => i.package === name), false)}`.trim()
})
.join('\n\n')
mdAddons = replacer(mdAddons, addons, 'ADDONS_LIST').replace(/\r\n/g, '\n')
await fs.writeFile('packages/add-ons.md', mdAddons, 'utf-8')
}
- Parameters:
{ packages, functions }: PackageIndexes
- Return Type:
Promise<void>
- Calls:
fs.readFile
Object.values(packages) .filter(i => i.addon && !i.deprecated) .map(({ docs, name, display, description }) => { return
## ${display} - `@vueuse/${name}`\n\n${description?.trim()}\n\n${ stringifyFunctions(functions.filter(i => i.package === name), false)}.trim() }) .join
replacer(mdAddons, addons, 'ADDONS_LIST').replace
fs.writeFile
updateFunctionREADME(indexes: PackageIndexes): Promise<void>
¶
Code
export async function updateFunctionREADME(indexes: PackageIndexes) {
const hasTypes = existsSync(DIR_TYPES)
if (!hasTypes)
console.warn('No types dist found, run `npm run build:types` first.')
for (const fn of indexes.functions) {
const mdPath = `packages/${fn.package}/${fn.name}/index.md`
if (!existsSync(mdPath))
continue
let readme = await fs.readFile(mdPath, 'utf-8')
const { content, data = {} } = matter(readme)
const yamlData = yaml.stringify(data, {
singleQuote: true,
})
data.category = fn.category || 'Unknown'
readme = `---\n${yamlData}---\n\n${content.trim()}`.trim().replace(/\r\n/g, '\n')
await fs.writeFile(mdPath, `${readme}\n`, 'utf-8')
}
}
- Parameters:
indexes: PackageIndexes
- Return Type:
Promise<void>
- Calls:
existsSync (from node:fs)
console.warn
fs.readFile
matter (from gray-matter)
yaml.stringify
`---\n${yamlData}---\n\n${content.trim()}
.trim().replace`fs.writeFile
updateCountBadge(indexes: PackageIndexes): Promise<void>
¶
Code
export async function updateCountBadge(indexes: PackageIndexes) {
const functionsCount = indexes.functions.filter(i => !i.internal).length
const url = `https://img.shields.io/badge/-${functionsCount}%20functions-13708a`
const data = await $fetch(url, { responseType: 'text' })
await fs.writeFile(join(DIR_ROOT, 'packages/public/badge-function-count.svg'), data, 'utf-8')
}
- Parameters:
indexes: PackageIndexes
- Return Type:
Promise<void>
- Calls:
indexes.functions.filter
$fetch (from ofetch)
fs.writeFile
join (from node:path)
updatePackageJSON(indexes: PackageIndexes): Promise<void>
¶
Code
export async function updatePackageJSON(indexes: PackageIndexes) {
const { version } = JSON.parse(await fs.readFile('package.json', { encoding: 'utf8' }))
for (const { name, description, author, submodules, iife } of packages) {
const packageDir = join(DIR_SRC, name)
const packageJSONPath = join(packageDir, 'package.json')
const packageJSON = JSON.parse(await fs.readFile(packageJSONPath, { encoding: 'utf8' }))
packageJSON.version = version
packageJSON.description = description || packageJSON.description
packageJSON.author = author || 'Anthony Fu <https://github.com/antfu>'
packageJSON.bugs = {
url: 'https://github.com/vueuse/vueuse/issues',
}
packageJSON.type = 'module'
packageJSON.homepage = name === 'core'
? 'https://github.com/vueuse/vueuse#readme'
: `https://github.com/vueuse/vueuse/tree/main/packages/${name}#readme`
packageJSON.repository = {
type: 'git',
url: 'git+https://github.com/vueuse/vueuse.git',
directory: `packages/${name}`,
}
packageJSON.main = './index.mjs'
packageJSON.types = './index.d.mts'
packageJSON.module = './index.mjs'
if (iife !== false) {
packageJSON.unpkg = './index.iife.min.js'
packageJSON.jsdelivr = './index.iife.min.js'
}
packageJSON.files = [
'*.d.mts',
'*.js',
'*.mjs',
]
if (submodules) {
packageJSON.files = packageJSON.files.map((i: string) => `**/${i}`)
}
if (name === 'metadata') {
packageJSON.files.push('index.json')
}
packageJSON.exports = {
'.': './index.mjs',
...packageJSON.exports,
'./*': './*',
}
if (submodules) {
indexes.functions
.filter(i => i.package === name)
.forEach((i) => {
packageJSON.exports[`./${i.name}`] = `./${i.name}.mjs`
if (i.component) {
packageJSON.exports[`./${i.name}/component`] = `./${i.name}/component.mjs`
}
})
}
await fs.writeFile(packageJSONPath, `${JSON.stringify(packageJSON, null, 2)}\n`)
}
}
- Parameters:
indexes: PackageIndexes
- Return Type:
Promise<void>
- Calls:
JSON.parse
fs.readFile
join (from node:path)
packageJSON.files.map
packageJSON.files.push
indexes.functions .filter(i => i.package === name) .forEach
fs.writeFile
JSON.stringify
fetchContributors(page: number): Promise<string[]>
¶
Code
async function fetchContributors(page = 1) {
// contributors that contribute to repos other than `vueuse/vueuse`, required for contributor avatar to work
const additional = ['egoist', 'Tahul', 'BobbieGoede']
const collaborators: string[] = []
const data = await $fetch<{ login: string }[]>(`https://api.github.com/repos/vueuse/vueuse/contributors?per_page=100&page=${page}`, {
method: 'get',
headers: {
'content-type': 'application/json',
},
}) || []
collaborators.push(...data.map(i => i.login))
if (data.length === 100)
collaborators.push(...(await fetchContributors(page + 1)))
return Array.from(new Set([
...collaborators.filter(collaborator => !['renovate[bot]', 'dependabot[bot]', 'renovate-bot'].includes(collaborator)),
...additional,
]))
}
- Parameters:
page: number
- Return Type:
Promise<string[]>
- Calls:
$fetch (from ofetch)
collaborators.push
data.map
fetchContributors
Array.from
collaborators.filter
['renovate[bot]', 'dependabot[bot]', 'renovate-bot'].includes
- Internal Comments:
updateContributors(): Promise<void>
¶
Code
- Return Type:
Promise<void>
- Calls:
fetchContributors
fs.writeFile
join (from node:path)
JSON.stringify