airport2 0.0.4 → 0.0.6

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 CHANGED
@@ -6,11 +6,12 @@
6
6
  bun add airport2
7
7
  ```
8
8
 
9
+
9
10
  ## 核心架构
10
11
 
11
12
  ```
12
13
  Airport
13
- ├── Pipeline: 管理多个Task的执行流程
14
+ ├── Pipeline
14
15
  │ ├── Task 1
15
16
  │ │ ├── Step 1
16
17
  │ │ ├── Step 2
@@ -22,15 +23,44 @@ Airport
22
23
  └── Remote: 处理远程服务器连接和操作
23
24
  ```
24
25
 
26
+ ```ts
27
+ export {
28
+ PipeLine, // 管道,串行执行多个Task
29
+ Task, // 任务,包含多个Step,可独立运行:Task().run()
30
+ Step, // 步骤,包含一个命令集,可独立运行:Step().run()
31
+ run, // 异步处理本地命令,基于`child_process.spawn`封装
32
+ exec, // 同步处理本地命令,基于`child_process.execSync`封装
33
+ remote, // 使用ssh在远程服务器执行命令,包含scp可以上传文件
34
+ log, // 日志输出
35
+ logError, // 日志输出,错误日志
36
+ color, // 日志染色,export = chalk
37
+ }
38
+ ```
39
+
25
40
 
26
41
  ## Usage
27
- 在项目根据目录下创建`airport.ts`文件
42
+
43
+ **范例:在项目根据目录下创建`airport.ts`文件**
28
44
 
29
45
  ```sh
30
- bun airport.ts // 也可以将命令添加到package.json中
46
+ bun run airport.ts # 也可以将命令添加到package.json中
31
47
  ```
32
48
 
33
- ## Example
49
+ **也可根据实际需求创建多个`airport`流水线**
50
+ ```sh
51
+ .airport
52
+ ├── deploy: 常规发布
53
+ ├── commit: git-commit
54
+ ├── docker: docker构建、推送、部署
55
+ └── ...
56
+
57
+ bun run .airport/deploy.ts
58
+ bun run .airport/commit.ts
59
+ bun run .airport/docker.ts
60
+ ```
61
+
62
+
63
+ ### Example
34
64
 
35
65
  **常规构建发布范例**
36
66
 
@@ -46,6 +76,7 @@ const deployTask = new Task({
46
76
  {
47
77
  name: '构建项目',
48
78
  run: [
79
+ 'npm run build',
49
80
  'mkdir -p .cache',
50
81
  'mv `npm pack` .cache/',
51
82
  ],
@@ -54,7 +85,7 @@ const deployTask = new Task({
54
85
  name: '发布到远程服务器',
55
86
  async run() {
56
87
  const ssh = remote('user@192.168.1.1')
57
- const dir = (path?: string) => join('/home/user/test', path ?? '')
88
+ const dir = (path?: string) => join('/apps', name, path ?? '')
58
89
 
59
90
  try {
60
91
  await ssh.run('rm -f', dir('latest'))
@@ -0,0 +1,39 @@
1
+ import { join } from 'path'
2
+ import { name, version } from '../package.json'
3
+ import { PipeLine, remote, logError } from '../src/airport'
4
+
5
+ const file = [name, version].join('-') + '.tgz'
6
+
7
+ // 创建部署任务
8
+ const deployTask = {
9
+ name: '部署应用',
10
+ steps: [
11
+ {
12
+ name: '构建项目',
13
+ run: [
14
+ 'mkdir -p .cache',
15
+ 'mv `npm pack` .cache/',
16
+ ],
17
+ },
18
+ {
19
+ name: '发布到远程服务器',
20
+ async run() {
21
+ const ssh = remote('gavin@192.168.5.121')
22
+ const dir = (path?: string) => join('/home/gavin/test', path ?? '')
23
+ try {
24
+ await ssh.run('rm -f', dir('latest'))
25
+ await ssh.run('mkdir -p', dir(version))
26
+ await ssh.scp(`.cache/${file}`, dir())
27
+ await ssh.run('tar -zxvf', dir(file), '-C', dir(version))
28
+ await ssh.run('ln -s', dir(version), dir('latest'))
29
+ }
30
+ catch (e) {
31
+ logError(e)
32
+ }
33
+ },
34
+ },
35
+ ],
36
+ }
37
+
38
+ // 执行流水线
39
+ PipeLine.run([deployTask])
@@ -0,0 +1,39 @@
1
+ import { join } from 'path'
2
+ import { name, version } from '../package.json'
3
+ import { PipeLine, Task, remote, logError } from '../src/airport'
4
+
5
+ const file = [name, version].join('-') + '.tgz'
6
+
7
+ // 创建部署任务
8
+ const deployTask = new Task({
9
+ name: '部署应用',
10
+ steps: [
11
+ {
12
+ name: '构建项目',
13
+ run: [
14
+ 'mkdir -p .cache',
15
+ 'mv `npm pack` .cache/',
16
+ ],
17
+ },
18
+ {
19
+ name: '发布到远程服务器',
20
+ async run() {
21
+ const ssh = remote('gavin@192.168.5.121')
22
+ const dir = (path?: string) => join('/home/gavin/test', path ?? '')
23
+ try {
24
+ await ssh.run('rm -f', dir('latest'))
25
+ await ssh.run('mkdir -p', dir(version))
26
+ await ssh.scp(`.cache/${file}`, dir())
27
+ await ssh.run('tar -zxvf', dir(file), '-C', dir(version))
28
+ await ssh.run('ln -s', dir(version), dir('latest'))
29
+ }
30
+ catch (e) {
31
+ logError(e)
32
+ }
33
+ },
34
+ },
35
+ ],
36
+ })
37
+
38
+ // 执行流水线
39
+ PipeLine.test([deployTask])
@@ -26,6 +26,7 @@ const deployTask = new Task({
26
26
  await ssh.scp(`.cache/${file}`, dir())
27
27
  await ssh.run('tar -zxvf', dir(file), '-C', dir(version))
28
28
  await ssh.run('ln -s', dir(version), dir('latest'))
29
+ await ssh.run('rm -f', dir(file))
29
30
  }
30
31
  catch (e) {
31
32
  logError(e)
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "airport2",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "main": "src/index.ts",
5
5
  "type": "module",
6
+ "files": [
7
+ "src",
8
+ "example"
9
+ ],
6
10
  "scripts": {
7
11
  "test": "vitest run",
8
12
  "test:watch": "vitest",
@@ -1,28 +1,58 @@
1
1
  import { Task } from './task'
2
- import { log, purple, gray } from '../lib'
2
+ import { logPipeStart, logPipeEnd } from '../lib'
3
+ import type { TaskRaw } from '../types'
3
4
 
4
5
  export class PipeLine {
5
6
  public name?: string
7
+ // public log: boolean = true // 决定是否打印日志
6
8
  private tasks: Task[]
7
9
 
8
- static run(tasks: Task[]) {
10
+ static run(tasks: Task[] | TaskRaw[]) {
9
11
  return new PipeLine(tasks).run()
10
12
  }
11
13
 
12
- constructor(tasks: Task[]) {
13
- this.tasks = tasks
14
+ static test(tasks: Task[] | TaskRaw[]) {
15
+ return new PipeLine(tasks).test()
16
+ }
17
+
18
+ constructor(tasks: Task[] | TaskRaw[]) {
19
+ if (tasks.length > 0 && tasks[0] instanceof Task) {
20
+ this.tasks = tasks as Task[]
21
+ } else {
22
+ this.tasks = (tasks as TaskRaw[]).map((task) => new Task(task))
23
+ }
14
24
  }
15
25
 
16
26
  /**
17
27
  * 执行任务中的所有步骤
18
28
  */
19
29
  async run() {
20
- log(purple('Pipe'), gray('Start'), '-------------------------')
30
+ this.beforeRun()
31
+ for (const [index, task] of this.tasks.entries()) {
32
+ if (!task.skip) {
33
+ task.index = index + 1
34
+ await task._runPipeLine()
35
+ }
36
+ }
37
+ this.afterRun()
38
+ }
21
39
 
22
- for (const task of this.tasks) {
23
- await task.run()
40
+ test() {
41
+ this.beforeRun()
42
+ for (const [index, task] of this.tasks.entries()) {
43
+ if (!task.skip) {
44
+ task.index = index + 1
45
+ task.test()
46
+ }
24
47
  }
48
+ this.afterRun()
49
+ }
50
+
51
+ private beforeRun() {
52
+ logPipeStart()
53
+ }
25
54
 
26
- log(`------------- ${purple("Pipe")} ${gray('End')} -------------`)
55
+ private afterRun() {
56
+ logPipeEnd()
27
57
  }
28
58
  }
@@ -1,35 +1,48 @@
1
- import { log, run } from '../lib'
2
1
  import type { StepRaw } from '../types'
2
+ import { log, run, logStepStart, logStepEnd, logTesting } from '../lib'
3
3
 
4
4
  export class Step {
5
5
  public name: string
6
6
  public skip: boolean = false
7
+ public index: number = 1 // 当前索引
7
8
  private step: StepRaw
8
- private test: boolean
9
+ private testing: boolean = false
9
10
 
10
- constructor(step: StepRaw, test: boolean = false) {
11
- this.test = test
11
+ constructor(step: StepRaw) {
12
12
  this.step = step
13
13
  this.name = step.name
14
14
  this.skip = step.skip ?? false
15
15
  }
16
16
 
17
+ async run() {
18
+ this.beforeRun()
19
+ await this.exec()
20
+ this.afterRun()
21
+ }
22
+
23
+ async test() {
24
+ this.testing = true
25
+ this.beforeRun()
26
+ if (typeof this.step.run === 'string') {
27
+ this.runStringTesting()
28
+ } else if (Array.isArray(this.step.run)) {
29
+ this.runArrayTesting()
30
+ } else {
31
+ logTesting('[async function run]')
32
+ }
33
+ this.afterRun()
34
+ }
35
+
17
36
  /**
18
37
  * 执行步骤
19
38
  */
20
- async run(): Promise<any> {
39
+ private async exec(): Promise<any> {
21
40
  if (typeof this.step.run === 'string') {
22
41
  return this.runString()
23
42
  } else if (Array.isArray(this.step.run)) {
24
43
  return this.runArray()
25
44
  } else {
26
- // 函数类型的步骤
27
- if (this.test) {
28
- log(`[TEST MODE] Would execute function: ${this.step.run.name}`)
29
- } else {
30
- // 实际执行函数
31
- return await this.step.run()
32
- }
45
+ return await this.step.run()
33
46
  }
34
47
  }
35
48
 
@@ -38,11 +51,7 @@ export class Step {
38
51
  */
39
52
  private async runString() {
40
53
  const runString = this.step.run as string
41
- if (this.test) {
42
- log(`[TEST MODE] Would execute: ${runString}`)
43
- } else {
44
- return await run(runString)
45
- }
54
+ return await run(runString)
46
55
  }
47
56
 
48
57
  /**
@@ -50,13 +59,28 @@ export class Step {
50
59
  */
51
60
  private async runArray() {
52
61
  const runArray = this.step.run as string[]
53
- if (this.test) {
54
- log(`[TEST MODE] Would execute array: ${runArray}`)
55
- } else {
56
- for (const cmd of runArray) {
57
- await run(cmd)
58
- }
62
+ for (const cmd of runArray) {
63
+ await run(cmd)
59
64
  }
60
65
  }
61
- }
62
66
 
67
+ private runStringTesting() {
68
+ const runString = this.step.run as string
69
+ logTesting(runString)
70
+ }
71
+
72
+ private runArrayTesting() {
73
+ const runArray = this.step.run as string[]
74
+ for (const cmd of runArray) {
75
+ logTesting(cmd)
76
+ }
77
+ }
78
+
79
+ private beforeRun() {
80
+ logStepStart(this)
81
+ }
82
+
83
+ private afterRun() {
84
+ logStepEnd(this)
85
+ }
86
+ }
@@ -1,34 +1,74 @@
1
1
  import { Step } from './step'
2
- import { log, purple, gray, blue } from '../lib'
3
- import type { TaskOptions, StepRaw } from '../types'
2
+ import { logTaskStart, logTaskEnd } from '../lib'
3
+ import type { TaskRaw, StepRaw } from '../types'
4
4
 
5
5
  export class Task {
6
+ // 任务名称
6
7
  public name: string
7
- public opt: TaskOptions
8
+
9
+ /** Task元数据 */
10
+ public opt: TaskRaw
11
+
12
+ /** 在流水线中的任务索引 */
13
+ public index: number = 1 // 当前索引
14
+
15
+ /** 流水线中是否跳过当前任务 */
16
+ public skip: boolean = false
17
+
18
+ // 是否无头模式,是否自调用
19
+ // true: PipeLine模式,Task由PipeLine.run调用
20
+ // false: 自调用,独立任务模式,外部直接调用Task.run
21
+ public inPipeLine: boolean = false
22
+
23
+ // 任务步骤
8
24
  private steps: StepRaw[]
9
25
 
10
- constructor(opt: TaskOptions) {
26
+ constructor(opt: TaskRaw) {
11
27
  this.opt = opt
12
28
  this.name = opt.name
13
29
  this.steps = opt.steps
30
+ this.skip = opt.skip ?? false
14
31
  }
15
32
 
16
33
  /**
17
34
  * 执行任务中的所有步骤
18
35
  */
19
- async run(test: boolean = false) {
20
- const steps = this.steps.map((step) => new Step(step, test))
21
-
22
- log(purple('Task'), gray('Start'), blue(this.name))
36
+ async run() {
37
+ this.beforeRun()
38
+ const steps = this.steps.map((step) => new Step(step))
23
39
 
24
- for (const step of steps) {
40
+ for (const [index, step] of steps.entries()) {
25
41
  if (!step.skip) {
26
- log(purple('Step'), gray('Start'), blue(step.name))
42
+ step.index = index + 1
27
43
  step.skip || (await step.run())
28
- log(purple('Step'), gray('End'), blue(step.name))
29
44
  }
30
45
  }
46
+ this.afterRun()
47
+ }
48
+
49
+ test() {
50
+ this.inPipeLine = true
51
+ this.beforeRun()
52
+ const steps = this.steps.map((step) => new Step(step))
53
+ for (const [index, step] of steps.entries()) {
54
+ if (!step.skip) {
55
+ step.index = index + 1
56
+ step.skip || (step.test())
57
+ }
58
+ }
59
+ this.afterRun()
60
+ }
61
+
62
+ async _runPipeLine() {
63
+ this.inPipeLine = true
64
+ await this.run()
65
+ }
66
+
67
+ private beforeRun() {
68
+ logTaskStart(this)
69
+ }
31
70
 
32
- log(purple('Task'), gray('End'), blue(this.name))
71
+ private afterRun() {
72
+ logTaskEnd(this)
33
73
  }
34
74
  }
@@ -0,0 +1,22 @@
1
+ import { gray } from './lib/color'
2
+
3
+ export const START = '🚀'
4
+
5
+ export const END = '🔚'
6
+
7
+ export const CORNER_TOP_LEFT = '┌'
8
+
9
+ export const CORNER_TOP_RIGHT = '┐'
10
+
11
+ export const CORNER_BOTTOM_LEFT = '└'
12
+
13
+ export const CORNER_BOTTOM_RIGHT = '┘'
14
+
15
+
16
+ export const PIPE_PREFIX = gray('├')
17
+
18
+ export const PIPE_TOP_LEFT = gray('┌───────────────────')
19
+ export const PIPE_TOP_RIGHT = gray('───────────────────┐')
20
+
21
+ export const PIPE_BOTTOM_LEFT = gray('└───────────────────')
22
+ export const PIPE_BOTTOM_RIGHT = gray('───────────────────┘')
@@ -1,5 +1,15 @@
1
- import { gray } from './color'
1
+ import { Writable } from 'stream'
2
+ import { blue, gray, purple } from './color'
2
3
  import { formatTimestamp } from './date'
4
+ import {
5
+ START,
6
+ END,
7
+ PIPE_PREFIX,
8
+ PIPE_TOP_LEFT,
9
+ PIPE_TOP_RIGHT,
10
+ PIPE_BOTTOM_LEFT,
11
+ PIPE_BOTTOM_RIGHT,
12
+ } from '../conf'
3
13
 
4
14
  export const log = (...args: any[]) => {
5
15
  console.log(gray(`[${formatTimestamp()}]`), ...args)
@@ -8,3 +18,76 @@ export const log = (...args: any[]) => {
8
18
  export const logError = (...args: any[]) => {
9
19
  console.error(`[${formatTimestamp()}]`, ...args)
10
20
  }
21
+
22
+ export const logStart = (...args: any[]) => {
23
+ log(PIPE_PREFIX, ...args)
24
+ }
25
+
26
+ export const logErrorStart = (...args: any[]) => {
27
+ logError(PIPE_PREFIX, ...args)
28
+ }
29
+
30
+ export const logTesting = (...args: any[]) => {
31
+ logStart(gray('Testing'), ...args)
32
+ }
33
+
34
+ // 日志流、用于子进程直接输出日志到控制台
35
+ export const createLogStream = (prefix?: string) =>
36
+ new Writable({
37
+ write(chunk: Buffer, _encoding, callback) {
38
+ const lines = chunk.toString().split('\n')
39
+
40
+ lines.forEach((line) => {
41
+ if (line.trim() === '') return
42
+
43
+ // 添加前缀标识
44
+ prefix ? log(prefix, line) : log(line)
45
+ })
46
+
47
+ callback()
48
+ },
49
+
50
+ final(callback) {
51
+ // 确保所有输出都已处理
52
+ callback()
53
+ },
54
+ })
55
+
56
+
57
+ // 流水线开始时日志
58
+ export const logPipeStart = () => {
59
+ log(PIPE_TOP_LEFT, purple('Airport PipeLine'), START, PIPE_TOP_RIGHT)
60
+ }
61
+
62
+ // 流水线结束时日志
63
+ export const logPipeEnd = () => {
64
+ log(PIPE_BOTTOM_LEFT, purple('Airport PipeLine'), END, PIPE_BOTTOM_RIGHT)
65
+ }
66
+
67
+
68
+ // 任务开始时日志
69
+ export const logTaskStart = ({ name, index, inPipeLine }) => {
70
+ if (!inPipeLine) {
71
+ logPipeStart()
72
+ }
73
+ logStart(purple('T' + index), START, blue(name))
74
+ }
75
+
76
+ // 任务结束时日志
77
+ export const logTaskEnd = ({ name, index, inPipeLine }) => {
78
+ logStart(purple('T' + index), END, blue(name))
79
+ if (!inPipeLine) {
80
+ logPipeEnd()
81
+ }
82
+ }
83
+
84
+
85
+ // 步骤开始时日志
86
+ export const logStepStart = ({ name, index }) => {
87
+ logStart(purple('S'+ index), START, blue(name))
88
+ }
89
+
90
+ // 步骤结束时日志
91
+ export const logStepEnd = ({ name, index }) => {
92
+ logStart(purple('S'+ index), END, blue(name))
93
+ }
@@ -1,4 +1,6 @@
1
- import { run } from './run'
1
+ import { logStart } from './log'
2
+ import { run, spawn } from './run'
3
+ import { green, gray } from './color'
2
4
 
3
5
  export interface RemoteConfig {
4
6
  ssh: string
@@ -18,7 +20,7 @@ class Remote {
18
20
  * @returns Promise<void>
19
21
  */
20
22
  async run(...cmd: string[]): Promise<void> {
21
- await run(`ssh ${this.opt.ssh} "${cmd.join(' ')}"`)
23
+ await this.sshRun(cmd.join(' '))
22
24
  }
23
25
 
24
26
  /**
@@ -30,4 +32,11 @@ class Remote {
30
32
  async scp(src: string, dist: string) {
31
33
  await run(`scp ${src} ${this.opt.ssh}:${dist}`)
32
34
  }
35
+
36
+ // 执行ssh命令
37
+ private sshRun(command: string) {
38
+ const cmd = `ssh ${this.opt.ssh} "${command}"`
39
+ logStart(gray(this.opt.ssh), green(command))
40
+ return spawn(cmd)
41
+ }
33
42
  }
@@ -1,6 +1,6 @@
1
- import { log } from './log'
2
1
  import { green, gray } from './color'
3
- import { spawn, execSync } from 'child_process'
2
+ import { logStart, createLogStream } from './log'
3
+ import { spawn as child_spawn, execSync } from 'child_process'
4
4
 
5
5
  /**
6
6
  * 异步执行,控制台直接输出,`child_process.spawn`
@@ -9,19 +9,11 @@ import { spawn, execSync } from 'child_process'
9
9
  * @example await run('npm install')
10
10
  * @example await run('npm run build')
11
11
  */
12
- export const run = (command: string) =>
13
- new Promise((resolve, reject) => {
14
- log(gray('Running:'), green(command))
15
- const child = spawn(command, {
16
- shell: true,
17
- stdio: 'inherit',
18
- env: process.env,
19
- cwd: process.cwd(),
20
- timeout: 30_000 // 30秒超时
21
- })
22
- child.on('exit', resolve)
23
- child.on('error', reject)
24
- })
12
+ export const run = (command: string) => {
13
+ logStart(gray('Running'), green(command))
14
+ return spawn(command)
15
+ }
16
+
25
17
 
26
18
  /**
27
19
  * 同步执行,`child_process.execSync`
@@ -40,8 +32,35 @@ export function exec(print: boolean | string, command?: string): string {
40
32
  }
41
33
  let output = execSync(command ?? 'echo').toString()
42
34
  if (print) {
43
- log(gray('Running:'), green(command))
44
- log(output)
35
+ logStart(gray('Running'), green(command))
36
+ logStart(output)
45
37
  }
46
38
  return output
47
39
  }
40
+
41
+
42
+ export const spawn = (command: string) =>
43
+ new Promise<void>((resolve, reject) => {
44
+ const child = child_spawn(command, {
45
+ shell: true,
46
+ cwd: process.cwd(),
47
+ env: process.env,
48
+ timeout: 30_000,
49
+ stdio: ['ignore', 'pipe', 'pipe'], // 捕获输出流
50
+ })
51
+
52
+ // 创建日志流实例
53
+ const stdoutLog = createLogStream(gray('├─'))
54
+ const stderrLog = createLogStream(gray('├─'))
55
+
56
+ // 连接输出流
57
+ child.stdout.pipe(stdoutLog)
58
+ child.stderr.pipe(stderrLog)
59
+
60
+ child.on('exit', (code) => {
61
+ code === 0 ? resolve() :
62
+ reject(new Error(`Command exited with code ${code}`))
63
+ })
64
+
65
+ child.on('error', reject)
66
+ })
@@ -6,30 +6,33 @@ export interface StepResult {
6
6
  output: string
7
7
  }
8
8
 
9
+
9
10
  /**
10
- * 步骤配置选项
11
+ * 任务执行结果
11
12
  */
12
- export interface StepRaw {
13
+ export interface TaskResult {
14
+ success: boolean
15
+ stepResults: StepResult[]
13
16
  name: string
14
- skip?: boolean
15
- run: string | string[] | ((...args: any[]) => Promise<any>)
16
17
  }
17
18
 
18
19
 
19
20
  /**
20
- * 任务执行结果
21
+ * 步骤配置选项
21
22
  */
22
- export interface TaskResult {
23
- success: boolean
24
- stepResults: StepResult[]
23
+ export interface StepRaw {
25
24
  name: string
25
+ skip?: boolean
26
+ run: string | string[] | ((...args: any[]) => Promise<any>)
26
27
  }
27
28
 
29
+
28
30
  /**
29
31
  * 任务配置选项
30
32
  */
31
- export interface TaskOptions {
33
+ export interface TaskRaw {
32
34
  name: string
33
35
  steps: StepRaw[]
34
36
  test?: boolean
37
+ skip?: boolean
35
38
  }
package/.editorconfig DELETED
@@ -1,24 +0,0 @@
1
- root = true
2
-
3
- [*]
4
- indent_style = space
5
- indent_size = 2
6
- end_of_line = lf
7
- charset = utf-8
8
- trim_trailing_whitespace = true
9
- insert_final_newline = true
10
- semi = false
11
- singleQuote = true
12
- quote_type = single
13
-
14
- [*.ts]
15
- semi = false
16
-
17
- [*.md]
18
-
19
- [{package.json,*.yml}]
20
- indent_style = space
21
- indent_size = 2
22
-
23
- [*.md]
24
- trim_trailing_whitespace = false
@@ -1,5 +0,0 @@
1
- {
2
- "cSpell.words": [
3
- "zxvf"
4
- ]
5
- }
package/CHANGELOG.md DELETED
@@ -1,31 +0,0 @@
1
- # CHANGELOG
2
-
3
-
4
- ## [0.0.4] - 2025-06-27
5
-
6
- * 一些优化
7
- * 更多范例详见`example`目录
8
- * `run`函数默认注入父进程的`env`环境变量
9
- * 统一Step和Task的`run`方法,支持直接运行`Step.run`和`Task.run`
10
-
11
-
12
- ## [0.0.3] - 2025-06-26
13
-
14
- * 日志染色,高亮关键信息,更容易区分日志信息
15
- * 优化部分代码,提高可读性和可维护性
16
- * Step添加`skip`属性,支持跳过执行,默认为`false`
17
-
18
-
19
- ## [0.0.2] - 2025-06-26
20
-
21
- * 一些优化
22
-
23
-
24
- ## [0.0.1] - 2025-06-25
25
-
26
- ### 初始版本发布
27
- - 实现Pipeline-Task-Step三级架构
28
- - 支持本地命令执行和远程SSH操作
29
- - 添加单元测试框架和示例测试
30
- - 实现测试模式,支持命令预览
31
- - 完成基础文档和开发计划
package/Dockerfile DELETED
@@ -1,14 +0,0 @@
1
- # ================================
2
- # Only For Test
3
- # ================================
4
- FROM node:24
5
-
6
- # Switch to the staging area
7
- WORKDIR /app
8
-
9
- # Let Docker bind to port 8080
10
- COPY ./src /app/src
11
-
12
- # Start the Vapor service when the image is run, default to listening on 8080 in production environment
13
- ENTRYPOINT ["ls"]
14
- CMD ["-a"]
package/Todo.md DELETED
@@ -1,104 +0,0 @@
1
- # 需求文档:Airport任务调度系统
2
-
3
- ## 项目概述
4
- Airport是一个基于TypeScript的现代化任务调度系统,支持本地和远程任务执行,采用Pipeline-Task-Step三级架构,可用于自动化部署、构建和运维流程。
5
-
6
- ## 开发计划
7
-
8
- ### 阶段一:核心架构设计与实现(已完成)
9
- - ✅ 设计并实现Step类,支持命令执行和函数调用
10
- - ✅ 设计并实现Task类,管理多个Step的串行执行
11
- - ✅ 设计并实现Pipeline类,管理多个Task的串行执行
12
- - ✅ 实现远程SSH连接功能,支持远程命令执行和文件传输
13
- - ✅ 添加单元测试,确保核心功能的正确性
14
-
15
- ### 阶段二:功能完善与文档(进行中)
16
- - ✅ 实现测试模式(test()方法)
17
- - ✅ 添加详细的代码注释和文档
18
- - ☐ 创建使用示例和教程文档
19
- - ☐ 完善错误处理和日志系统
20
-
21
- ### 阶段三:系统集成与优化
22
- - ☐ 实现配置文件支持
23
- - ☐ 添加任务并行执行功能
24
- - ☐ 实现任务重试机制
25
- - ☐ 添加任务依赖管理
26
-
27
- ## 技术栈
28
- - TypeScript
29
- - bun(运行时和依赖管理)
30
- - vitest(单元测试)
31
- - zx(命令执行)
32
- - ssh2(SSH远程连接)
33
- - TypeScript类型系统
34
-
35
- ## 核心功能
36
- 1. **Pipeline流水线**:管理多个任务的串行执行
37
- 2. **Task任务**:包含多个步骤的执行单元
38
- 3. **Step步骤**:执行单个命令或函数
39
- 4. **远程操作**:通过SSH连接远程服务器执行命令和传输文件
40
- 5. **测试模式**:支持仅输出命令而不实际执行
41
-
42
- ## 补充说明:
43
-
44
- ### Step类
45
- * Step.run有三种类型:`string | string[] | AnyFunction`,应该有两个私有函数来处理前两种情况,例如:
46
- ```ts
47
- class Step {
48
- private _runString()
49
- private _runArray()
50
- }
51
- ```
52
- * `_runString`用于处理run值是字符串的情况
53
- * `_runArray`用于处理run值是字符串数组的情况
54
- * `AnyFunction`的情况,直接执行即可
55
-
56
- ## 使用示例
57
- ```typescript
58
- import { Pipeline, Task, Step, remote } from './src/airport';
59
- import { $ } from 'zx';
60
-
61
- // 创建部署任务
62
- const deployTask = new Task({
63
- name: '部署应用',
64
- steps: [
65
- {
66
- name: '构建项目',
67
- run: [
68
- 'bun run build',
69
- 'bun run test'
70
- ]
71
- },
72
- {
73
- name: '远程部署',
74
- run: async () => {
75
- const ssh = remote({
76
- ssh: 'root@192.168.1.1',
77
- port: 22,
78
- private: '$HOME/.ssh/id_rsa'
79
- });
80
- await ssh.connect();
81
- await ssh.run('mkdir -p /data/app');
82
- await ssh.scp('dist/*', '/data/app/');
83
- await ssh.close();
84
- }
85
- }
86
- ]
87
- });
88
-
89
- // 执行流水线
90
- const pipeline = new Pipeline([deployTask]);
91
- await pipeline.run();
92
- ```
93
-
94
- ## 单元测试
95
- 已实现核心功能的单元测试,可通过以下命令执行:
96
- ```bash
97
- bun test
98
- ```
99
-
100
- ## 下一步计划
101
- 1. 完善测试覆盖率,添加更多边界情况测试
102
- 2. 实现dev.md文档,详细记录开发过程和架构设计
103
- 3. 添加CHANGELOG.md文件记录版本更新历史
104
- 4. 优化错误处理和日志系统
package/bun.lock DELETED
@@ -1,270 +0,0 @@
1
- {
2
- "lockfileVersion": 1,
3
- "workspaces": {
4
- "": {
5
- "name": "ts-cicd",
6
- "dependencies": {
7
- "chalk": "^5.4.1",
8
- },
9
- "devDependencies": {
10
- "@types/bun": "latest",
11
- "@types/node": "^20.12.7",
12
- "vitest": "^1.6.0",
13
- },
14
- "peerDependencies": {
15
- "typescript": "^5",
16
- },
17
- },
18
- },
19
- "packages": {
20
- "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="],
21
-
22
- "@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="],
23
-
24
- "@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="],
25
-
26
- "@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="],
27
-
28
- "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="],
29
-
30
- "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="],
31
-
32
- "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="],
33
-
34
- "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="],
35
-
36
- "@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="],
37
-
38
- "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="],
39
-
40
- "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="],
41
-
42
- "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="],
43
-
44
- "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="],
45
-
46
- "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="],
47
-
48
- "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="],
49
-
50
- "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="],
51
-
52
- "@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="],
53
-
54
- "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="],
55
-
56
- "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="],
57
-
58
- "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="],
59
-
60
- "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="],
61
-
62
- "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="],
63
-
64
- "@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="],
65
-
66
- "@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="],
67
-
68
- "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
69
-
70
- "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.44.0", "", { "os": "android", "cpu": "arm" }, "sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA=="],
71
-
72
- "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.44.0", "", { "os": "android", "cpu": "arm64" }, "sha512-uNSk/TgvMbskcHxXYHzqwiyBlJ/lGcv8DaUfcnNwict8ba9GTTNxfn3/FAoFZYgkaXXAdrAA+SLyKplyi349Jw=="],
73
-
74
- "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.44.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-VGF3wy0Eq1gcEIkSCr8Ke03CWT+Pm2yveKLaDvq51pPpZza3JX/ClxXOCmTYYq3us5MvEuNRTaeyFThCKRQhOA=="],
75
-
76
- "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.44.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-fBkyrDhwquRvrTxSGH/qqt3/T0w5Rg0L7ZIDypvBPc1/gzjJle6acCpZ36blwuwcKD/u6oCE/sRWlUAcxLWQbQ=="],
77
-
78
- "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.44.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-u5AZzdQJYJXByB8giQ+r4VyfZP+walV+xHWdaFx/1VxsOn6eWJhK2Vl2eElvDJFKQBo/hcYIBg/jaKS8ZmKeNQ=="],
79
-
80
- "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.44.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-qC0kS48c/s3EtdArkimctY7h3nHicQeEUdjJzYVJYR3ct3kWSafmn6jkNCA8InbUdge6PVx6keqjk5lVGJf99g=="],
81
-
82
- "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.44.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x+e/Z9H0RAWckn4V2OZZl6EmV0L2diuX3QB0uM1r6BvhUIv6xBPL5mrAX2E3e8N8rEHVPwFfz/ETUbV4oW9+lQ=="],
83
-
84
- "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.44.0", "", { "os": "linux", "cpu": "arm" }, "sha512-1exwiBFf4PU/8HvI8s80icyCcnAIB86MCBdst51fwFmH5dyeoWVPVgmQPcKrMtBQ0W5pAs7jBCWuRXgEpRzSCg=="],
85
-
86
- "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.44.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZTR2mxBHb4tK4wGf9b8SYg0Y6KQPjGpR4UWwTFdnmjB4qRtoATZ5dWn3KsDwGa5Z2ZBOE7K52L36J9LueKBdOQ=="],
87
-
88
- "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.44.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-GFWfAhVhWGd4r6UxmnKRTBwP1qmModHtd5gkraeW2G490BpFOZkFtem8yuX2NyafIP/mGpRJgTJ2PwohQkUY/Q=="],
89
-
90
- "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.44.0", "", { "os": "linux", "cpu": "none" }, "sha512-xw+FTGcov/ejdusVOqKgMGW3c4+AgqrfvzWEVXcNP6zq2ue+lsYUgJ+5Rtn/OTJf7e2CbgTFvzLW2j0YAtj0Gg=="],
91
-
92
- "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.44.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-bKGibTr9IdF0zr21kMvkZT4K6NV+jjRnBoVMt2uNMG0BYWm3qOVmYnXKzx7UhwrviKnmK46IKMByMgvpdQlyJQ=="],
93
-
94
- "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.44.0", "", { "os": "linux", "cpu": "none" }, "sha512-vV3cL48U5kDaKZtXrti12YRa7TyxgKAIDoYdqSIOMOFBXqFj2XbChHAtXquEn2+n78ciFgr4KIqEbydEGPxXgA=="],
95
-
96
- "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.44.0", "", { "os": "linux", "cpu": "none" }, "sha512-TDKO8KlHJuvTEdfw5YYFBjhFts2TR0VpZsnLLSYmB7AaohJhM8ctDSdDnUGq77hUh4m/djRafw+9zQpkOanE2Q=="],
97
-
98
- "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.44.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-8541GEyktXaw4lvnGp9m84KENcxInhAt6vPWJ9RodsB/iGjHoMB2Pp5MVBCiKIRxrxzJhGCxmNzdu+oDQ7kwRA=="],
99
-
100
- "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.44.0", "", { "os": "linux", "cpu": "x64" }, "sha512-iUVJc3c0o8l9Sa/qlDL2Z9UP92UZZW1+EmQ4xfjTc1akr0iUFZNfxrXJ/R1T90h/ILm9iXEY6+iPrmYB3pXKjw=="],
101
-
102
- "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.44.0", "", { "os": "linux", "cpu": "x64" }, "sha512-PQUobbhLTQT5yz/SPg116VJBgz+XOtXt8D1ck+sfJJhuEsMj2jSej5yTdp8CvWBSceu+WW+ibVL6dm0ptG5fcA=="],
103
-
104
- "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.44.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-M0CpcHf8TWn+4oTxJfh7LQuTuaYeXGbk0eageVjQCKzYLsajWS/lFC94qlRqOlyC2KvRT90ZrfXULYmukeIy7w=="],
105
-
106
- "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.44.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-3XJ0NQtMAXTWFW8FqZKcw3gOQwBtVWP/u8TpHP3CRPXD7Pd6s8lLdH3sHWh8vqKCyyiI8xW5ltJScQmBU9j7WA=="],
107
-
108
- "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.44.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Q2Mgwt+D8hd5FIPUuPDsvPR7Bguza6yTkJxspDGkZj7tBRn2y4KSWYuIXpftFSjBra76TbKerCV7rgFPQrn+wQ=="],
109
-
110
- "@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
111
-
112
- "@types/bun": ["@types/bun@1.2.17", "", { "dependencies": { "bun-types": "1.2.17" } }, "sha512-l/BYs/JYt+cXA/0+wUhulYJB6a6p//GTPiJ7nV+QHa8iiId4HZmnu/3J/SowP5g0rTiERY2kfGKXEK5Ehltx4Q=="],
113
-
114
- "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
115
-
116
- "@types/node": ["@types/node@20.19.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-jJD50LtlD2dodAEO653i3YF04NWak6jN3ky+Ri3Em3mGR39/glWiboM/IePaRbgwSfqM1TpGXfAg8ohn/4dTgA=="],
117
-
118
- "@vitest/expect": ["@vitest/expect@1.6.1", "", { "dependencies": { "@vitest/spy": "1.6.1", "@vitest/utils": "1.6.1", "chai": "^4.3.10" } }, "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog=="],
119
-
120
- "@vitest/runner": ["@vitest/runner@1.6.1", "", { "dependencies": { "@vitest/utils": "1.6.1", "p-limit": "^5.0.0", "pathe": "^1.1.1" } }, "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA=="],
121
-
122
- "@vitest/snapshot": ["@vitest/snapshot@1.6.1", "", { "dependencies": { "magic-string": "^0.30.5", "pathe": "^1.1.1", "pretty-format": "^29.7.0" } }, "sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ=="],
123
-
124
- "@vitest/spy": ["@vitest/spy@1.6.1", "", { "dependencies": { "tinyspy": "^2.2.0" } }, "sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw=="],
125
-
126
- "@vitest/utils": ["@vitest/utils@1.6.1", "", { "dependencies": { "diff-sequences": "^29.6.3", "estree-walker": "^3.0.3", "loupe": "^2.3.7", "pretty-format": "^29.7.0" } }, "sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g=="],
127
-
128
- "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
129
-
130
- "acorn-walk": ["acorn-walk@8.3.4", "", { "dependencies": { "acorn": "^8.11.0" } }, "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g=="],
131
-
132
- "ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
133
-
134
- "assertion-error": ["assertion-error@1.1.0", "", {}, "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw=="],
135
-
136
- "bun-types": ["bun-types@1.2.17", "", { "dependencies": { "@types/node": "*" } }, "sha512-ElC7ItwT3SCQwYZDYoAH+q6KT4Fxjl8DtZ6qDulUFBmXA8YB4xo+l54J9ZJN+k2pphfn9vk7kfubeSd5QfTVJQ=="],
137
-
138
- "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
139
-
140
- "chai": ["chai@4.5.0", "", { "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", "deep-eql": "^4.1.3", "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", "type-detect": "^4.1.0" } }, "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw=="],
141
-
142
- "chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="],
143
-
144
- "check-error": ["check-error@1.0.3", "", { "dependencies": { "get-func-name": "^2.0.2" } }, "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg=="],
145
-
146
- "confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
147
-
148
- "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
149
-
150
- "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
151
-
152
- "deep-eql": ["deep-eql@4.1.4", "", { "dependencies": { "type-detect": "^4.0.0" } }, "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg=="],
153
-
154
- "diff-sequences": ["diff-sequences@29.6.3", "", {}, "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q=="],
155
-
156
- "esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="],
157
-
158
- "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
159
-
160
- "execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="],
161
-
162
- "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
163
-
164
- "get-func-name": ["get-func-name@2.0.2", "", {}, "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ=="],
165
-
166
- "get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="],
167
-
168
- "human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="],
169
-
170
- "is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="],
171
-
172
- "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
173
-
174
- "js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
175
-
176
- "local-pkg": ["local-pkg@0.5.1", "", { "dependencies": { "mlly": "^1.7.3", "pkg-types": "^1.2.1" } }, "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ=="],
177
-
178
- "loupe": ["loupe@2.3.7", "", { "dependencies": { "get-func-name": "^2.0.1" } }, "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA=="],
179
-
180
- "magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
181
-
182
- "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
183
-
184
- "mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="],
185
-
186
- "mlly": ["mlly@1.7.4", "", { "dependencies": { "acorn": "^8.14.0", "pathe": "^2.0.1", "pkg-types": "^1.3.0", "ufo": "^1.5.4" } }, "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw=="],
187
-
188
- "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
189
-
190
- "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
191
-
192
- "npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="],
193
-
194
- "onetime": ["onetime@6.0.0", "", { "dependencies": { "mimic-fn": "^4.0.0" } }, "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ=="],
195
-
196
- "p-limit": ["p-limit@5.0.0", "", { "dependencies": { "yocto-queue": "^1.0.0" } }, "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ=="],
197
-
198
- "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
199
-
200
- "pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
201
-
202
- "pathval": ["pathval@1.1.1", "", {}, "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ=="],
203
-
204
- "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
205
-
206
- "pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="],
207
-
208
- "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
209
-
210
- "pretty-format": ["pretty-format@29.7.0", "", { "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } }, "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ=="],
211
-
212
- "react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
213
-
214
- "rollup": ["rollup@4.44.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.44.0", "@rollup/rollup-android-arm64": "4.44.0", "@rollup/rollup-darwin-arm64": "4.44.0", "@rollup/rollup-darwin-x64": "4.44.0", "@rollup/rollup-freebsd-arm64": "4.44.0", "@rollup/rollup-freebsd-x64": "4.44.0", "@rollup/rollup-linux-arm-gnueabihf": "4.44.0", "@rollup/rollup-linux-arm-musleabihf": "4.44.0", "@rollup/rollup-linux-arm64-gnu": "4.44.0", "@rollup/rollup-linux-arm64-musl": "4.44.0", "@rollup/rollup-linux-loongarch64-gnu": "4.44.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.44.0", "@rollup/rollup-linux-riscv64-gnu": "4.44.0", "@rollup/rollup-linux-riscv64-musl": "4.44.0", "@rollup/rollup-linux-s390x-gnu": "4.44.0", "@rollup/rollup-linux-x64-gnu": "4.44.0", "@rollup/rollup-linux-x64-musl": "4.44.0", "@rollup/rollup-win32-arm64-msvc": "4.44.0", "@rollup/rollup-win32-ia32-msvc": "4.44.0", "@rollup/rollup-win32-x64-msvc": "4.44.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-qHcdEzLCiktQIfwBq420pn2dP+30uzqYxv9ETm91wdt2R9AFcWfjNAmje4NWlnCIQ5RMTzVf0ZyisOKqHR6RwA=="],
215
-
216
- "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
217
-
218
- "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
219
-
220
- "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="],
221
-
222
- "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
223
-
224
- "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
225
-
226
- "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="],
227
-
228
- "std-env": ["std-env@3.9.0", "", {}, "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw=="],
229
-
230
- "strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="],
231
-
232
- "strip-literal": ["strip-literal@2.1.1", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q=="],
233
-
234
- "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="],
235
-
236
- "tinypool": ["tinypool@0.8.4", "", {}, "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ=="],
237
-
238
- "tinyspy": ["tinyspy@2.2.1", "", {}, "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A=="],
239
-
240
- "type-detect": ["type-detect@4.1.0", "", {}, "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw=="],
241
-
242
- "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
243
-
244
- "ufo": ["ufo@1.6.1", "", {}, "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA=="],
245
-
246
- "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
247
-
248
- "vite": ["vite@5.4.19", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA=="],
249
-
250
- "vite-node": ["vite-node@1.6.1", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.3.4", "pathe": "^1.1.1", "picocolors": "^1.0.0", "vite": "^5.0.0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA=="],
251
-
252
- "vitest": ["vitest@1.6.1", "", { "dependencies": { "@vitest/expect": "1.6.1", "@vitest/runner": "1.6.1", "@vitest/snapshot": "1.6.1", "@vitest/spy": "1.6.1", "@vitest/utils": "1.6.1", "acorn-walk": "^8.3.2", "chai": "^4.3.10", "debug": "^4.3.4", "execa": "^8.0.1", "local-pkg": "^0.5.0", "magic-string": "^0.30.5", "pathe": "^1.1.1", "picocolors": "^1.0.0", "std-env": "^3.5.0", "strip-literal": "^2.0.0", "tinybench": "^2.5.1", "tinypool": "^0.8.3", "vite": "^5.0.0", "vite-node": "1.6.1", "why-is-node-running": "^2.2.2" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", "@vitest/browser": "1.6.1", "@vitest/ui": "1.6.1", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag=="],
253
-
254
- "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
255
-
256
- "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="],
257
-
258
- "yocto-queue": ["yocto-queue@1.2.1", "", {}, "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg=="],
259
-
260
- "bun-types/@types/node": ["@types/node@24.0.4", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-ulyqAkrhnuNq9pB76DRBTkcS6YsmDALy6Ua63V8OhrOBgbcYt6IOdzpw5P1+dyRIyMerzLkeYWBeOXPpA9GMAA=="],
261
-
262
- "mlly/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
263
-
264
- "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="],
265
-
266
- "pkg-types/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
267
-
268
- "bun-types/@types/node/undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
269
- }
270
- }
package/dev.md DELETED
@@ -1,21 +0,0 @@
1
- # Airport任务调度系统开发文档
2
-
3
- ## 项目架构设计
4
-
5
- Airport采用三级架构设计:Pipeline-Task-Step,形成清晰的层次结构,便于扩展和维护。
6
-
7
- ### 核心架构
8
-
9
- ```
10
- Airport
11
- ├── Pipeline: 管理多个Task的执行流程
12
- │ ├── Task 1
13
- │ │ ├── Step 1
14
- │ │ ├── Step 2
15
- │ │ └── ...
16
- │ ├── Task 2
17
- │ └── ...
18
- ├── Run: 异步处理本地命令
19
- ├── Exec: 同步处理本地命令
20
- └── Remote: 处理远程服务器连接和操作
21
- ```