@jayrdeaton/scripts 1.1.0 → 1.1.2
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/README.md +56 -0
- package/bin/cli.mjs +3 -3
- package/package.json +2 -2
- package/src/commands/base64.mjs +6 -6
- package/src/commands/binary.mjs +6 -6
- package/src/commands/bump-ota.mjs +2 -2
- package/src/commands/check-domains.mjs +2 -2
- package/src/commands/check-scripts.mjs +149 -0
- package/src/commands/clean-builds.mjs +2 -2
- package/src/commands/clean-junk.mjs +4 -4
- package/src/commands/code-count.mjs +2 -2
- package/src/commands/find-dep.mjs +5 -9
- package/src/commands/focus.mjs +2 -2
- package/src/commands/folder-sizes.mjs +2 -2
- package/src/commands/new-expo-project.mjs +3 -3
- package/src/commands/npm-downloads.mjs +2 -2
- package/src/commands/npm-namer.mjs +2 -2
- package/src/commands/rename-season.mjs +2 -2
- package/src/commands/repo-status.mjs +2 -2
- package/src/commands/update-boilerplate.mjs +2 -2
- package/src/commands/update-deps.mjs +2 -2
package/README.md
CHANGED
|
@@ -69,6 +69,22 @@ Example: `jrd check-domains ??fu.com`
|
|
|
69
69
|
|
|
70
70
|
---
|
|
71
71
|
|
|
72
|
+
### `jrd check-scripts`
|
|
73
|
+
|
|
74
|
+
Compare `package.json` scripts across projects for consistency. Highlights scripts whose values differ from the most common value (or a reference project).
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
jrd check-scripts [scripts...] [options]
|
|
78
|
+
|
|
79
|
+
Options:
|
|
80
|
+
-d, --dir <dir> Root directory to scan (default: ~/Developer)
|
|
81
|
+
-r, --ref <ref> Reference project name to compare against
|
|
82
|
+
-a, --all Show all scripts, including matching ones
|
|
83
|
+
-f, --flat Show one line per project instead of grouping by value
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
72
88
|
### `jrd clean-builds`
|
|
73
89
|
|
|
74
90
|
Delete build artifacts (`build`, `dist`, `ios`, `android`) across one or more repos. Dry run by default.
|
|
@@ -118,6 +134,21 @@ Options:
|
|
|
118
134
|
|
|
119
135
|
---
|
|
120
136
|
|
|
137
|
+
### `jrd find-dep`
|
|
138
|
+
|
|
139
|
+
Find projects in a directory that use any of the given dependencies (searches `dependencies`, `devDependencies`, and `peerDependencies`).
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
jrd find-dep <deps...> [options]
|
|
143
|
+
|
|
144
|
+
Options:
|
|
145
|
+
-d, --dir <dir> Root directory to scan (default: ~/Developer)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Example: `jrd find-dep react-native expo`
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
121
152
|
### `jrd focus`
|
|
122
153
|
|
|
123
154
|
Bring an application to the front using AppleScript.
|
|
@@ -140,6 +171,21 @@ jrd folder-sizes [dir]
|
|
|
140
171
|
|
|
141
172
|
---
|
|
142
173
|
|
|
174
|
+
### `jrd new-expo-project`
|
|
175
|
+
|
|
176
|
+
Bootstrap a new Expo project from the boilerplate repo. Clones or updates the boilerplate, copies it to `~/Developer/<Name>`, rewrites `package.json` and `app.json` with the derived name/slug/bundle identifiers, and creates an initial git commit.
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
jrd new-expo-project [options]
|
|
180
|
+
|
|
181
|
+
Options:
|
|
182
|
+
-n, --name <name> Project name (required)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Example: `jrd new-expo-project --name MyApp`
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
143
189
|
### `jrd npm-downloads`
|
|
144
190
|
|
|
145
191
|
List all your npm packages sorted by total downloads.
|
|
@@ -188,6 +234,16 @@ jrd repo-status [dir]
|
|
|
188
234
|
|
|
189
235
|
---
|
|
190
236
|
|
|
237
|
+
### `jrd update-boilerplate`
|
|
238
|
+
|
|
239
|
+
Update the Expo boilerplate repo — clones it if absent, runs `jrd update-deps`, lint-fixes, type-checks, tests, then commits and pushes the result.
|
|
240
|
+
|
|
241
|
+
```
|
|
242
|
+
jrd update-boilerplate
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
191
247
|
### `jrd update-deps`
|
|
192
248
|
|
|
193
249
|
Update all npm dependencies to `@latest`. Automatically runs `npx expo install --fix` if the project uses Expo.
|
package/bin/cli.mjs
CHANGED
|
@@ -3,13 +3,13 @@ import { readdirSync } from 'node:fs'
|
|
|
3
3
|
import { dirname, resolve } from 'node:path'
|
|
4
4
|
import { fileURLToPath } from 'node:url'
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { Program } from 'termkit'
|
|
7
7
|
|
|
8
8
|
const __dir = dirname(fileURLToPath(import.meta.url))
|
|
9
9
|
const commandsDir = resolve(__dir, '../src/commands')
|
|
10
10
|
|
|
11
11
|
// Must be created first so termkit registers this as the root command
|
|
12
|
-
const program = command('jrd').description('Personal dev scripts')
|
|
12
|
+
const program = Program.command('jrd').description('Personal dev scripts')
|
|
13
13
|
|
|
14
14
|
const files = readdirSync(commandsDir).filter((f) => f.endsWith('.mjs'))
|
|
15
15
|
const mods = await Promise.all(files.map((f) => import(`../src/commands/${f}`)))
|
|
@@ -17,7 +17,7 @@ const mods = await Promise.all(files.map((f) => import(`../src/commands/${f}`)))
|
|
|
17
17
|
program.commands(mods.map((m) => m.command))
|
|
18
18
|
|
|
19
19
|
try {
|
|
20
|
-
await parse(process.argv)
|
|
20
|
+
await Program.parse(process.argv)
|
|
21
21
|
} catch (err) {
|
|
22
22
|
console.error(err.message)
|
|
23
23
|
process.exit(1)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jayrdeaton/scripts",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Personal dev scripts",
|
|
6
6
|
"repository": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"preversion": "npm ci && npm run lint"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"termkit": "
|
|
29
|
+
"termkit": "^2.2.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"eslint": "^10.4.1",
|
package/src/commands/base64.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'node:fs'
|
|
2
1
|
import { execSync } from 'node:child_process'
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
3
3
|
|
|
4
|
-
import { Color,
|
|
4
|
+
import { Color, Program } from 'termkit'
|
|
5
5
|
|
|
6
6
|
function resolveInput(value, file) {
|
|
7
7
|
if (file) {
|
|
@@ -20,10 +20,10 @@ function output(result, copy) {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export const command =
|
|
23
|
+
export const command = Program.command('base64')
|
|
24
24
|
.description('Encode or decode base64')
|
|
25
25
|
.commands([
|
|
26
|
-
|
|
26
|
+
Program.command('encode')
|
|
27
27
|
.description('Encode a string or file to base64')
|
|
28
28
|
.variable('<value>')
|
|
29
29
|
.option('f', 'file', null, 'treat value as a file path')
|
|
@@ -34,12 +34,12 @@ export const command = createCommand('base64')
|
|
|
34
34
|
output(result, copy)
|
|
35
35
|
}),
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Program.command('decode')
|
|
38
38
|
.description('Decode a base64 string')
|
|
39
39
|
.variable('<value>')
|
|
40
40
|
.option('c', 'copy', null, 'copy result to clipboard')
|
|
41
41
|
.action(({ value, copy }) => {
|
|
42
42
|
const result = Buffer.from(value, 'base64').toString('utf8')
|
|
43
43
|
output(result, copy)
|
|
44
|
-
})
|
|
44
|
+
})
|
|
45
45
|
])
|
package/src/commands/binary.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
2
1
|
import { execSync } from 'node:child_process'
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
3
3
|
|
|
4
|
-
import { Color,
|
|
4
|
+
import { Color, Program } from 'termkit'
|
|
5
5
|
|
|
6
|
-
export const command =
|
|
6
|
+
export const command = Program.command('binary')
|
|
7
7
|
.description('Encode or decode binary strings')
|
|
8
8
|
.commands([
|
|
9
|
-
|
|
9
|
+
Program.command('encode')
|
|
10
10
|
.description('Encode a file to a binary string')
|
|
11
11
|
.variable('<file>')
|
|
12
12
|
.option('c', 'copy', null, 'copy result to clipboard')
|
|
@@ -25,7 +25,7 @@ export const command = createCommand('binary')
|
|
|
25
25
|
}
|
|
26
26
|
}),
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Program.command('decode')
|
|
29
29
|
.description('Restore a binary string file back to its original format')
|
|
30
30
|
.variable('<file>')
|
|
31
31
|
.variable('<destination>')
|
|
@@ -34,5 +34,5 @@ export const command = createCommand('binary')
|
|
|
34
34
|
const buf = Buffer.from(JSON.parse(readFileSync(file, 'utf8')), 'binary')
|
|
35
35
|
writeFileSync(destination, buf)
|
|
36
36
|
console.log(`${Color.green('Success:')} Restored ${file} to ${destination}`)
|
|
37
|
-
})
|
|
37
|
+
})
|
|
38
38
|
])
|
|
@@ -2,9 +2,9 @@ import { execSync } from 'node:child_process'
|
|
|
2
2
|
import { readFileSync, writeFileSync } from 'node:fs'
|
|
3
3
|
import { resolve } from 'node:path'
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Program, Spinner } from 'termkit'
|
|
6
6
|
|
|
7
|
-
export const command =
|
|
7
|
+
export const command = Program.command('bump-ota')
|
|
8
8
|
.description('Bump otaVersion in src/constants/release.ts and commit')
|
|
9
9
|
.option('f', 'file', '[file]', 'Path to release file (default: src/constants/release.ts)')
|
|
10
10
|
.action(async (options) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { writeFile } from 'node:fs/promises'
|
|
2
2
|
|
|
3
|
-
import { Color,
|
|
3
|
+
import { Color, Program, Spinner } from 'termkit'
|
|
4
4
|
|
|
5
5
|
const RDAP = {
|
|
6
6
|
com: 'https://rdap.verisign.com/com/v1',
|
|
@@ -46,7 +46,7 @@ async function withConcurrency(items, limit, fn) {
|
|
|
46
46
|
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker))
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export const command =
|
|
49
|
+
export const command = Program.command('check-domains')
|
|
50
50
|
.description('Check domain availability via RDAP for a wildcard pattern (? = any letter)')
|
|
51
51
|
.variable('[pattern]')
|
|
52
52
|
.option('c', 'concurrency', '<n>', 'Concurrent requests (default: 5)')
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs'
|
|
2
|
+
import { homedir } from 'node:os'
|
|
3
|
+
import { join, resolve } from 'node:path'
|
|
4
|
+
|
|
5
|
+
import { Color, Program, Spinner } from 'termkit'
|
|
6
|
+
|
|
7
|
+
function loadProject(pkgPath) {
|
|
8
|
+
try {
|
|
9
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))
|
|
10
|
+
return { name: pkg.name, scripts: pkg.scripts ?? {} }
|
|
11
|
+
} catch {
|
|
12
|
+
return null
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function mostCommon(values) {
|
|
17
|
+
const freq = {}
|
|
18
|
+
for (const v of values) freq[v] = (freq[v] ?? 0) + 1
|
|
19
|
+
return Object.entries(freq).sort((a, b) => b[1] - a[1])[0][0]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const command = Program.command('check-scripts', '[scripts...]')
|
|
23
|
+
.description('Compare package.json scripts across projects for consistency')
|
|
24
|
+
.option('d', 'dir', '[dir]', 'Root directory to scan (default: ~/Developer)')
|
|
25
|
+
.option('r', 'ref', '[ref]', 'Reference project name to compare against')
|
|
26
|
+
.option('a', 'all', null, 'Show all scripts, including matching ones')
|
|
27
|
+
.option('f', 'flat', null, 'Show one line per project instead of grouping by value')
|
|
28
|
+
.action(async (options) => {
|
|
29
|
+
const root = resolve(options.dir ?? join(homedir(), 'Developer'))
|
|
30
|
+
const filterScripts = options.scripts ?? []
|
|
31
|
+
|
|
32
|
+
let entries
|
|
33
|
+
try {
|
|
34
|
+
entries = readdirSync(root)
|
|
35
|
+
} catch {
|
|
36
|
+
console.error(Color.red(`Could not read directory: ${root}`))
|
|
37
|
+
process.exit(1)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const spinner = new Spinner({ text: 'Scanning projects...' })
|
|
41
|
+
spinner.start()
|
|
42
|
+
|
|
43
|
+
const projects = []
|
|
44
|
+
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
const dir = join(root, entry)
|
|
47
|
+
try {
|
|
48
|
+
if (!statSync(dir).isDirectory()) continue
|
|
49
|
+
} catch {
|
|
50
|
+
continue
|
|
51
|
+
}
|
|
52
|
+
spinner.message(entry)
|
|
53
|
+
const result = loadProject(join(dir, 'package.json'))
|
|
54
|
+
if (result) projects.push({ dir: entry, ...result })
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
spinner.stop()
|
|
58
|
+
|
|
59
|
+
if (!projects.length) {
|
|
60
|
+
console.log(Color.yellow('No projects with package.json found.'))
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let refProject = null
|
|
65
|
+
if (options.ref) {
|
|
66
|
+
refProject = projects.find((p) => p.dir === options.ref || p.name === options.ref)
|
|
67
|
+
if (!refProject) {
|
|
68
|
+
console.error(Color.red(`Reference project not found: ${options.ref}`))
|
|
69
|
+
process.exit(1)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const allScriptNames = new Set()
|
|
74
|
+
for (const p of projects) {
|
|
75
|
+
for (const key of Object.keys(p.scripts)) {
|
|
76
|
+
if (!filterScripts.length || filterScripts.includes(key)) {
|
|
77
|
+
allScriptNames.add(key)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let printed = 0
|
|
83
|
+
|
|
84
|
+
for (const scriptName of [...allScriptNames].sort()) {
|
|
85
|
+
const withScript = projects.filter((p) => p.scripts[scriptName] !== undefined)
|
|
86
|
+
if (withScript.length < 2 && !refProject) continue
|
|
87
|
+
|
|
88
|
+
const expectedValue = refProject
|
|
89
|
+
? refProject.scripts[scriptName]
|
|
90
|
+
: mostCommon(withScript.map((p) => p.scripts[scriptName]))
|
|
91
|
+
|
|
92
|
+
const allMatch =
|
|
93
|
+
withScript.every((p) => p.scripts[scriptName] === expectedValue) &&
|
|
94
|
+
(!refProject || projects.every((p) => p.scripts[scriptName] !== undefined))
|
|
95
|
+
|
|
96
|
+
if (!options.all && allMatch) continue
|
|
97
|
+
|
|
98
|
+
console.log(`\n${Color.bold(scriptName)}`)
|
|
99
|
+
|
|
100
|
+
if (options.flat) {
|
|
101
|
+
// Per-project lines
|
|
102
|
+
const allRelevant = refProject ? projects : withScript
|
|
103
|
+
for (const p of allRelevant) {
|
|
104
|
+
const value = p.scripts[scriptName]
|
|
105
|
+
const missing = value === undefined
|
|
106
|
+
const matches = !missing && value === expectedValue
|
|
107
|
+
const icon = matches ? Color.green('✓') : Color.red('✗')
|
|
108
|
+
const label = matches ? Color.faint(p.dir) : Color.bold(p.dir)
|
|
109
|
+
const display = missing ? Color.faint('(missing)') : Color.faint(value)
|
|
110
|
+
console.log(` ${icon} ${label} ${display}`)
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
// Grouped by value
|
|
114
|
+
const groups = new Map()
|
|
115
|
+
const allRelevant = refProject ? projects : withScript
|
|
116
|
+
|
|
117
|
+
for (const p of allRelevant) {
|
|
118
|
+
const value = p.scripts[scriptName] ?? null
|
|
119
|
+
if (!groups.has(value)) groups.set(value, [])
|
|
120
|
+
groups.get(value).push(p.dir)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Sort: expected value first, then others, missing last
|
|
124
|
+
const sorted = [...groups.entries()].sort(([a], [b]) => {
|
|
125
|
+
if (a === expectedValue) return -1
|
|
126
|
+
if (b === expectedValue) return 1
|
|
127
|
+
if (a === null) return 1
|
|
128
|
+
if (b === null) return -1
|
|
129
|
+
return 0
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
for (const [value, dirs] of sorted) {
|
|
133
|
+
const matches = value === expectedValue
|
|
134
|
+
const icon = matches ? Color.green('✓') : Color.red('✗')
|
|
135
|
+
const label = matches ? Color.faint(dirs.join(', ')) : Color.bold(dirs.join(', '))
|
|
136
|
+
const display = value === null ? Color.faint('(missing)') : Color.faint(value)
|
|
137
|
+
console.log(` ${icon} ${label} ${display}`)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
printed++
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (!printed) {
|
|
145
|
+
console.log(Color.green('\nAll scripts are consistent across projects.'))
|
|
146
|
+
} else {
|
|
147
|
+
console.log()
|
|
148
|
+
}
|
|
149
|
+
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readdirSync, rmSync, statSync } from 'node:fs'
|
|
2
2
|
import { join, resolve } from 'node:path'
|
|
3
3
|
|
|
4
|
-
import { Color,
|
|
4
|
+
import { Color, Program, Spinner } from 'termkit'
|
|
5
5
|
|
|
6
6
|
const BUILD_TARGETS = ['build', 'dist', 'ios', 'android']
|
|
7
7
|
|
|
@@ -64,7 +64,7 @@ function resolveProjects(dirs) {
|
|
|
64
64
|
return projects
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
export const command =
|
|
67
|
+
export const command = Program.command('clean-builds')
|
|
68
68
|
.description('Delete build artifacts across repos — dry run by default')
|
|
69
69
|
.variable('[dir...]')
|
|
70
70
|
.option('m', 'modules', null, 'Also delete node_modules')
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { extname, basename } from 'node:path'
|
|
2
1
|
import { readdirSync, rmSync, statSync } from 'node:fs'
|
|
3
|
-
import {
|
|
2
|
+
import { basename, extname } from 'node:path'
|
|
4
3
|
import { join, resolve } from 'node:path'
|
|
4
|
+
import { createInterface } from 'node:readline'
|
|
5
5
|
|
|
6
|
-
import { Color,
|
|
6
|
+
import { Color, Program, Spinner } from 'termkit'
|
|
7
7
|
|
|
8
8
|
function prompt(question) {
|
|
9
9
|
return new Promise((res) => {
|
|
@@ -41,7 +41,7 @@ function getItemSize(itemPath) {
|
|
|
41
41
|
return total
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export const command =
|
|
44
|
+
export const command = Program.command('clean-junk')
|
|
45
45
|
.description('Delete files and directories matching given criteria')
|
|
46
46
|
.variable('[dir]')
|
|
47
47
|
.option('i', 'includes', '<str>', 'Delete items whose name includes this string')
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createReadStream, existsSync, lstatSync, readdirSync } from 'node:fs'
|
|
2
2
|
import { extname, join, resolve } from 'node:path'
|
|
3
3
|
|
|
4
|
-
import { Color,
|
|
4
|
+
import { Color, Program, Spinner } from 'termkit'
|
|
5
5
|
|
|
6
6
|
const WHITELIST = new Set(['.cjs', '.css', '.csv', '.ejs', '.env', '.gitignore', '.haml', '.html', '.java', '.js', '.json', '.mjs', '.paw', '.plist', '.py', '.rake', '.scss', '.sh', '.sql', '.stl', '.swift', '.ts', '.tsx', '.txt', '.xib', '.xml', '.yaml', '.yml'])
|
|
7
7
|
|
|
@@ -48,7 +48,7 @@ function commaString(n) {
|
|
|
48
48
|
return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
export const command =
|
|
51
|
+
export const command = Program.command('code-count')
|
|
52
52
|
.description('Count lines of code by file type')
|
|
53
53
|
.variable('[paths...]')
|
|
54
54
|
.option('i', 'ignore', '[types...]', 'ignore files or file types')
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs'
|
|
2
2
|
import { homedir } from 'node:os'
|
|
3
3
|
import { join, resolve } from 'node:path'
|
|
4
4
|
|
|
5
|
-
import { Color,
|
|
5
|
+
import { Color, Program, Spinner } from 'termkit'
|
|
6
6
|
|
|
7
7
|
const DEP_FIELDS = ['dependencies', 'devDependencies', 'peerDependencies']
|
|
8
8
|
|
|
@@ -27,7 +27,7 @@ function findMatches(pkgPath, targets) {
|
|
|
27
27
|
return found.length ? { projectName: pkg.name, found } : null
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export const command =
|
|
30
|
+
export const command = Program.command('find-dep', '[deps...]')
|
|
31
31
|
.description('Find projects in a directory that use any of the given dependencies')
|
|
32
32
|
.option('d', 'dir', '[dir]', 'Root directory to scan (default: ~/Developer)')
|
|
33
33
|
.action(async (options) => {
|
|
@@ -77,16 +77,12 @@ export const command = createCommand('find-dep', '[deps...]')
|
|
|
77
77
|
console.log(Color.bold(`\nFound ${results.length} project${results.length !== 1 ? 's' : ''}:\n`))
|
|
78
78
|
|
|
79
79
|
for (const result of results) {
|
|
80
|
-
const label = result.projectName && result.projectName !== result.dir
|
|
81
|
-
? `${Color.bold(result.dir)} ${Color.faint(`(${result.projectName})`)}`
|
|
82
|
-
: Color.bold(result.dir)
|
|
80
|
+
const label = result.projectName && result.projectName !== result.dir ? `${Color.bold(result.dir)} ${Color.faint(`(${result.projectName})`)}` : Color.bold(result.dir)
|
|
83
81
|
|
|
84
82
|
console.log(` ${label}`)
|
|
85
83
|
|
|
86
84
|
for (const dep of result.found) {
|
|
87
|
-
const fieldLabel = dep.field === 'dependencies' ? 'dep'
|
|
88
|
-
: dep.field === 'devDependencies' ? 'dev'
|
|
89
|
-
: 'peer'
|
|
85
|
+
const fieldLabel = dep.field === 'dependencies' ? 'dep' : dep.field === 'devDependencies' ? 'dev' : 'peer'
|
|
90
86
|
console.log(` ${Color.cyan(dep.name)} ${Color.faint(`${dep.version} [${fieldLabel}]`)}`)
|
|
91
87
|
}
|
|
92
88
|
}
|
package/src/commands/focus.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { execSync } from 'node:child_process'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { Program } from 'termkit'
|
|
4
4
|
|
|
5
|
-
export const command =
|
|
5
|
+
export const command = Program.command('focus')
|
|
6
6
|
.description('Bring an application to the front')
|
|
7
7
|
.variable('[app]')
|
|
8
8
|
.action((args) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readdirSync, statSync } from 'node:fs'
|
|
2
2
|
import { join, resolve } from 'node:path'
|
|
3
3
|
|
|
4
|
-
import { Color,
|
|
4
|
+
import { Color, Program, Spinner } from 'termkit'
|
|
5
5
|
|
|
6
6
|
function getDirSize(dirPath) {
|
|
7
7
|
let total = 0
|
|
@@ -28,7 +28,7 @@ function formatSize(bytes) {
|
|
|
28
28
|
return `${bytes} B`
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export const command =
|
|
31
|
+
export const command = Program.command('folder-sizes')
|
|
32
32
|
.description('List folders sorted by size, largest first')
|
|
33
33
|
.variable('[dir]')
|
|
34
34
|
.action(async (args) => {
|
|
@@ -3,7 +3,7 @@ import { cpSync, existsSync, readFileSync, rmSync, writeFileSync } from 'node:fs
|
|
|
3
3
|
import { homedir } from 'node:os'
|
|
4
4
|
import { join } from 'node:path'
|
|
5
5
|
|
|
6
|
-
import { Color,
|
|
6
|
+
import { Color, log, Program } from 'termkit'
|
|
7
7
|
|
|
8
8
|
const BOILERPLATE_REPO = 'git@github.com:jayrdeaton/Expo-Boilerplate.git'
|
|
9
9
|
const BOILERPLATE_DIR = join(homedir(), 'Developer', 'Expo-Boilerplate')
|
|
@@ -21,7 +21,7 @@ function parseWords(name) {
|
|
|
21
21
|
.filter(Boolean)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export const command =
|
|
24
|
+
export const command = Program.command('new-expo-project')
|
|
25
25
|
.description('Bootstrap a new Expo project from the boilerplate')
|
|
26
26
|
.option('n', 'name', '<name>', 'Project name')
|
|
27
27
|
.action(async (options) => {
|
|
@@ -49,7 +49,7 @@ export const command = createCommand('new-expo-project')
|
|
|
49
49
|
log.info(`Creating ${displayName}...`)
|
|
50
50
|
cpSync(BOILERPLATE_DIR, targetDir, {
|
|
51
51
|
recursive: true,
|
|
52
|
-
filter: (src) => !src.includes('/node_modules/')
|
|
52
|
+
filter: (src) => !src.includes('/node_modules/')
|
|
53
53
|
})
|
|
54
54
|
|
|
55
55
|
rmSync(join(targetDir, '.git'), { recursive: true, force: true })
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execSync } from 'node:child_process'
|
|
2
2
|
|
|
3
|
-
import { Color,
|
|
3
|
+
import { Color, Program, Spinner } from 'termkit'
|
|
4
4
|
|
|
5
5
|
async function fetchJson(url) {
|
|
6
6
|
const res = await fetch(url)
|
|
@@ -32,7 +32,7 @@ async function getDownloads(pkg, period) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export const command =
|
|
35
|
+
export const command = Program.command('npm-downloads')
|
|
36
36
|
.description('List all your npm packages sorted by total downloads')
|
|
37
37
|
.option('u', 'user', '<name>', 'npm username (defaults to npm whoami)')
|
|
38
38
|
.option('p', 'period', '<period>', 'last-day | last-week | last-month | last-year (default: last-month)')
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Color,
|
|
1
|
+
import { Color, Program, Spinner } from 'termkit'
|
|
2
2
|
|
|
3
3
|
async function isAvailable(name) {
|
|
4
4
|
try {
|
|
@@ -32,7 +32,7 @@ async function getSynonyms(word) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export const command =
|
|
35
|
+
export const command = Program.command('npm-namer')
|
|
36
36
|
.description('Check npm package name availability, including variations')
|
|
37
37
|
.variable('<name>')
|
|
38
38
|
.option('s', 'synonyms', null, 'Also check synonyms of the name')
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { readdirSync, renameSync, statSync } from 'node:fs'
|
|
2
2
|
import { extname, join } from 'node:path'
|
|
3
3
|
|
|
4
|
-
import { Color,
|
|
4
|
+
import { Color, log, Program } from 'termkit'
|
|
5
5
|
|
|
6
|
-
export const command =
|
|
6
|
+
export const command = Program.command('rename-season')
|
|
7
7
|
.description('Rename files in a directory to SxEE format for TV library pickup')
|
|
8
8
|
.variable('<season> [dir]')
|
|
9
9
|
.action(async (args) => {
|
|
@@ -2,7 +2,7 @@ import { execSync } from 'node:child_process'
|
|
|
2
2
|
import { readdirSync, statSync } from 'node:fs'
|
|
3
3
|
import { join, resolve } from 'node:path'
|
|
4
4
|
|
|
5
|
-
import { Color,
|
|
5
|
+
import { Color, Program, Spinner } from 'termkit'
|
|
6
6
|
|
|
7
7
|
function getGitStatus(dir) {
|
|
8
8
|
try {
|
|
@@ -33,7 +33,7 @@ function getGitStatus(dir) {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export const command =
|
|
36
|
+
export const command = Program.command('repo-status')
|
|
37
37
|
.description('Report dirty and untracked files across repos in a directory')
|
|
38
38
|
.variable('[dir]')
|
|
39
39
|
.action(async (args) => {
|
|
@@ -3,7 +3,7 @@ import { existsSync } from 'node:fs'
|
|
|
3
3
|
import { homedir } from 'node:os'
|
|
4
4
|
import { join } from 'node:path'
|
|
5
5
|
|
|
6
|
-
import { Color,
|
|
6
|
+
import { Color, log, Program } from 'termkit'
|
|
7
7
|
|
|
8
8
|
const BOILERPLATE_REPO = 'git@github.com:jayrdeaton/Expo-Boilerplate.git'
|
|
9
9
|
const BOILERPLATE_DIR = join(homedir(), 'Developer', 'Expo-Boilerplate')
|
|
@@ -13,7 +13,7 @@ function exec(cmd, opts = {}) {
|
|
|
13
13
|
execSync(cmd, { stdio: 'inherit', ...opts })
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export const command =
|
|
16
|
+
export const command = Program.command('update-boilerplate')
|
|
17
17
|
.description('Update Expo boilerplate — clones if absent, updates deps, commits, and pushes')
|
|
18
18
|
.action(async () => {
|
|
19
19
|
if (existsSync(BOILERPLATE_DIR)) {
|
|
@@ -2,7 +2,7 @@ import { execSync } from 'node:child_process'
|
|
|
2
2
|
import { readFileSync } from 'node:fs'
|
|
3
3
|
import { resolve } from 'node:path'
|
|
4
4
|
|
|
5
|
-
import { Color,
|
|
5
|
+
import { Color, log, Program } from 'termkit'
|
|
6
6
|
|
|
7
7
|
function exec(cmd) {
|
|
8
8
|
console.log(Color.faint(`$ ${cmd}`))
|
|
@@ -13,7 +13,7 @@ function latestPackages(deps = {}) {
|
|
|
13
13
|
return Object.keys(deps).map((name) => `${name}@latest`)
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export const command =
|
|
16
|
+
export const command = Program.command('update-deps')
|
|
17
17
|
.description('Update all npm deps to @latest, then run expo install --fix if applicable')
|
|
18
18
|
.option('d', 'dev', null, 'Only update devDependencies')
|
|
19
19
|
.option('p', 'prod', null, 'Only update dependencies')
|