@gutenye/script.js 2.0.0 → 2.2.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gutenye/script.js",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "Write shell scripts in JavaScript",
5
5
  "keywords": [
6
6
  "shell",
package/src/Command.ts CHANGED
@@ -210,6 +210,7 @@ export class Command {
210
210
  context: Context,
211
211
  ) {
212
212
  const error =
213
+ Command.#validateRequired(command, positionals) ??
213
214
  Command.#validateOptions(command, options) ??
214
215
  Command.#validateChoices(command, positionals)
215
216
  if (error) {
@@ -229,6 +230,19 @@ export class Command {
229
230
  return this.arguments.map(String).join(' ')
230
231
  }
231
232
 
233
+ static #validateRequired(
234
+ command: Command,
235
+ positionals: any[],
236
+ ): string | null {
237
+ for (let i = 0; i < command.arguments.length; i++) {
238
+ const arg = command.arguments[i]
239
+ if (arg.required && positionals[i] == null) {
240
+ return `Missing required argument: ${arg.rawName}`
241
+ }
242
+ }
243
+ return null
244
+ }
245
+
232
246
  static #validateOptions(
233
247
  command: Command,
234
248
  options: Record<string, any>,
package/src/ake/README.md CHANGED
@@ -4,17 +4,26 @@
4
4
 
5
5
  ## Start
6
6
 
7
+ Install it
8
+
9
+ ```sh
10
+ npm install -g @gutenye/script.js
11
+ ```
12
+
7
13
  1. Create an ake file
8
14
 
9
- edit `./ake` file, and make it executable `chmod +x ake`
15
+ Create a `./ake` file, and make it executable `chmod +x ake`
10
16
 
11
17
  ```ts
12
- #!/usr/bin/env script.js
18
+ #!/usr/bin/env bun
13
19
 
14
- app.cmd('greetings')
15
- .add(() => {
16
- console.log('greetings')
17
- })
20
+ import { app, $ } from "@gutenye/script.js";
21
+
22
+ app.cmd("greetings").add(() => {
23
+ $`echo greetings`;
24
+ });
25
+
26
+ await app.run();
18
27
  ```
19
28
 
20
29
  2. Run it
@@ -23,7 +32,7 @@ app.cmd('greetings')
23
32
  ake greetings # find the ake file and runs it
24
33
  ```
25
34
 
26
- 3. Supports Shell Completion
35
+ 3. Supports Shell Completion
27
36
 
28
37
  - Follow [guide](./completions) to setup
29
38
 
@@ -31,14 +40,12 @@ ake greetings # find the ake file and runs it
31
40
  ake <Tab> # uses ake file's completion
32
41
  ```
33
42
 
34
- ## Use a template
43
+ ## Use a template / another location
35
44
 
36
45
  Create `~/bin.src/ake/template`
37
46
 
38
- ## Put ake file in another location
39
-
40
- Doesn't touch original project files
41
-
42
47
  ```sh
43
- akectl init remote # create in ~/bin.src/ake/<dir>
48
+ akectl init local # create a ake file from template in currenct directory
49
+ akectl init remote # create in ~/bin.src/ake/<dir>, doesn't touch original project files
50
+ akectl edit # Opens a editor to edit the ake file
44
51
  ```
package/src/ake/akectl.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  import { castArray } from 'lodash-es'
4
4
  import fs from '../utils/fs'
5
5
  import {
6
+ AKE_FILENAMES,
6
7
  exitWithError,
7
8
  findAkeFiles,
8
9
  getRemoteDir,
@@ -23,11 +24,11 @@ app
23
24
  if (akeFiles.length > 0) {
24
25
  exitWithError('Already have an ake file, cannot create a new one')
25
26
  }
26
- let target = 'ake'
27
+ let target = AKE_FILENAMES[0]
27
28
  if (place === 'remote') {
28
29
  const remoteDir = getRemoteDir()
29
30
  await fs.mkdirp(remoteDir)
30
- target = `${remoteDir}/ake`
31
+ target = `${remoteDir}/${AKE_FILENAMES[0]}`
31
32
  }
32
33
  const templateFile = `${STORAGE_DIR}/${TEMPLATE_NAME}`
33
34
  if (await fs.pathExists(templateFile)) {
package/src/ake/shared.ts CHANGED
@@ -5,6 +5,7 @@ import fs from '../utils/fs'
5
5
  const HOME = os.homedir()
6
6
  const CWD = process.cwd()
7
7
 
8
+ export const AKE_FILENAMES = ['ake', 'ake.ts']
8
9
  export const STORAGE_DIR = `${HOME}/bin.src/ake`
9
10
  export const TEMPLATE_NAME = 'template'
10
11
 
@@ -14,10 +15,12 @@ export async function findAkeFiles(): Promise<string[]> {
14
15
  const dirsToCheck = [localDir, remoteDir]
15
16
 
16
17
  const akeFiles = await Promise.all(
17
- dirsToCheck.map(async (dir) => {
18
- const akeFile = `${dir}/ake`
19
- return (await fs.pathExists(akeFile)) ? akeFile : null
20
- }),
18
+ dirsToCheck.flatMap((dir) =>
19
+ AKE_FILENAMES.map(async (name) => {
20
+ const akeFile = `${dir}/${name}`
21
+ return (await fs.pathExists(akeFile)) ? akeFile : null
22
+ }),
23
+ ),
21
24
  )
22
25
 
23
26
  return akeFiles.filter(Boolean) as string[]
package/src/completion.ts CHANGED
@@ -2,7 +2,7 @@ import nodeFs from 'node:fs'
2
2
  import os from 'node:os'
3
3
  import path from 'node:path'
4
4
  import * as yaml from 'yaml'
5
- import { getCompletionName } from './ake/shared'
5
+ import { AKE_FILENAMES, getCompletionName } from './ake/shared'
6
6
  import type { Command } from './Command'
7
7
 
8
8
  export type CompletionValue = string[] | (() => string[])
@@ -126,7 +126,7 @@ export async function installCompletion(
126
126
  try {
127
127
  if (!command.name && options.scriptPath) {
128
128
  const basename = path.basename(options.scriptPath)
129
- if (basename === 'ake') {
129
+ if (AKE_FILENAMES.includes(basename)) {
130
130
  command.name = getCompletionName()
131
131
  }
132
132
  }