diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index f8f6a95..0000000 --- a/.eslintrc +++ /dev/null @@ -1,18 +0,0 @@ -{ - "parser": "@typescript-eslint/parser", - "extends": ["plugin:@typescript-eslint/recommended", "plugin:prettier/recommended", "prettier"], - "plugins": ["@typescript-eslint"], - "env": { - "browser": true, - "es6": true - }, - "rules": { - "@typescript-eslint/ban-ts-comment": "off", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-inferrable-types": "off", - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/no-empty-function": "off", - "@typescript-eslint/ban-types": "off", - "max-len": ["off", { "code": 120, "ignoreUrls": true }] - } -} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7653a57..2d875d7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,6 +20,14 @@ jobs: with: registry-url: "https://registry.npmjs.org" cache: "pnpm" + - name: Build + run: | + CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o bin/depker.win.amd64.exe bin/depker.go + CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build -o bin/depker.win.arm64.exe bin/depker.go + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/depker.win.amd64 bin/depker.go + CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o bin/depker.win.arm64 bin/depker.go + CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o bin/depker.mac.amd64 bin/depker.go + CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -o bin/depker.mac.arm64 bin/depker.go - name: Publish run: pnpm --package=@semantic-release/git --package=semantic-release-replace-plugin --package=semantic-release dlx semantic-release --branches master env: diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 963354f..0000000 --- a/.prettierrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "printWidth": 120 -} diff --git a/.releaserc.json b/.releaserc.json index b6e94d0..73f1b90 100644 --- a/.releaserc.json +++ b/.releaserc.json @@ -42,6 +42,18 @@ "assets": ["src/depker.ts"] } ], - "@semantic-release/github" + [ + "@semantic-release/github", + { + "assets": [ + { "label": "depker.win.amd64.exe", "path": "bin/depker.win.amd64.exe" }, + { "label": "depker.win.arm64.exe", "path": "bin/depker.win.arm64.exe" }, + { "label": "depker.linux.amd64", "path": "bin/depker.linux.amd64" }, + { "label": "depker.linux.arm64", "path": "bin/depker.linux.arm64" }, + { "label": "depker.mac.amd64", "path": "bin/depker.mac.amd64" }, + { "label": "depker.mac.arm64", "path": "bin/depker.mac.arm64" } + ] + } + ] ] } diff --git a/bin/depker.go b/bin/depker.go new file mode 100644 index 0000000..011c42f --- /dev/null +++ b/bin/depker.go @@ -0,0 +1,173 @@ +package main + +import ( + "errors" + "net/url" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" +) + +func main() { + deno := deno() + path := lookup() + + if len(os.Args) > 1 && os.Args[1] == "create" { + create(deno, path, os.Args[2:]...) + return + } + if len(os.Args) > 1 && os.Args[1] == "reload" { + reload(deno, path, os.Args[2:]...) + return + } + + depker(deno, path, os.Args[1:]...) +} + +func deno() string { + deno, err := exec.LookPath("deno") + if err == nil { + return deno + } + home, err := os.UserHomeDir() + if err != nil { + panic(err) + } + if runtime.GOOS == "windows" { + deno = filepath.Join(home, ".deno", "bin", "deno.exe") + look, err := exec.LookPath(deno) + if err == nil { + return look + } + execute("powershell.exe", "-Command", "irm https://deno.land/install.ps1 | iex") + return deno + } else { + deno = filepath.Join(home, ".deno", "bin", "deno") + look, err := exec.LookPath(deno) + if err == nil { + return look + } + execute("sh", "-c", "curl -fsSL https://deno.land/install.sh | sh") + return deno + } +} + +func lookup() string { + dir, err := os.Getwd() + if err != nil { + panic(err) + } + paths := []string{ + filepath.Join(dir, "depker.config.ts"), + filepath.Join(dir, "depker.config.js"), + filepath.Join(dir, ".depker/depker.config.ts"), + filepath.Join(dir, ".depker/depker.config.js"), + filepath.Join(dir, ".depker/depker.ts"), + filepath.Join(dir, ".depker/depker.js"), + filepath.Join(dir, ".depker/config.ts"), + filepath.Join(dir, ".depker/config.js"), + } + for _, path := range paths { + if _, err := os.Stat(path); !errors.Is(err, os.ErrNotExist) { + // Ref: https://github.com/sayjun0505/Golangvuln/blob/0c3dd31c3533348628b74edaa5230501afb69e29/internal/web/url.go + if !filepath.IsAbs(path) { + panic(errors.New("path is not absolute")) + } + u := url.URL{Scheme: "file"} + if vol := filepath.VolumeName(path); vol != "" { + if strings.HasPrefix(vol, `\\`) { + path = filepath.ToSlash(path[2:]) + i := strings.IndexByte(path, '/') + + if i < 0 { + u.Host = path + u.Path = "/" + } else { + u.Host = path[:i] + u.Path = filepath.ToSlash(path[i:]) + } + } else { + u.Path = "/" + filepath.ToSlash(path) + } + } else { + u.Path = filepath.ToSlash(path) + } + return u.String() + } + } + return "https://raw.githubusercontent.com/syfxlin/depker/master/mod.ts" +} + +func create(deno string, path string, args ...string) { + dir, err := os.Getwd() + if err != nil { + panic(err) + } + file, err1 := os.OpenFile(filepath.Join(dir, "depker.config.ts"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755) + if err1 != nil { + panic(err1) + } + _, err2 := file.WriteString(strings.Join( + []string{ + "import { depker } from \"https://raw.githubusercontent.com/syfxlin/depker/master/mod.ts\";", + "", + "const app = depker();", + "", + "export default app;", + "", + }, + "\n", + )) + if err2 != nil { + panic(err2) + } + err3 := file.Close() + if err3 != nil { + panic(err3) + } +} + +func reload(deno string, path string, args ...string) { + execute(deno, append([]string{"cache", "-r", path}, args...)...) +} + +func depker(deno string, path string, args ...string) { + file, err1 := os.CreateTemp("", "depker-cli-") + if err1 != nil { + panic(err1) + } + _, err2 := file.WriteString(strings.Join( + []string{ + "const depker = await import('" + path + "').then(mod => mod?.default ?? mod);", + "if (typeof depker.execute === 'function') {", + " await depker.execute();", + "} else {", + " throw new ReferenceError('Missing depker instance! Ensure your config file does export the Site instance as default.');", + "}", + }, + "\n", + )) + if err2 != nil { + panic(err2) + } + err3 := file.Close() + if err3 != nil { + panic(err3) + } + execute(deno, append([]string{"run", "-A", file.Name()}, args...)...) +} + +func execute(name string, args ...string) { + cmd := exec.Command(name, args...) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + if code, ok := err.(*exec.ExitError); ok { + os.Exit(code.ExitCode()) + } + panic(err) + } +} diff --git a/depker.ts b/depker.ts deleted file mode 100644 index 8f317a0..0000000 --- a/depker.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { fs, path } from "./src/deps.ts"; - -const lookup = async () => { - const paths = [] as string[]; - const roots = [Deno.cwd(), Deno.build.os === "windows" ? Deno.env.get("USERPROFILE") : Deno.env.get("HOME")]; - for (const r of roots) { - if (r) { - paths.push(path.join(r, "depker.config.ts")); - paths.push(path.join(r, "depker.config.js")); - paths.push(path.join(r, "depker.config.cjs")); - paths.push(path.join(r, "depker.config.mjs")); - paths.push(path.join(r, ".depker/depker.config.ts")); - paths.push(path.join(r, ".depker/depker.config.js")); - paths.push(path.join(r, ".depker/depker.config.cjs")); - paths.push(path.join(r, ".depker/depker.config.mjs")); - paths.push(path.join(r, ".depker/depker.ts")); - paths.push(path.join(r, ".depker/depker.js")); - paths.push(path.join(r, ".depker/depker.cjs")); - paths.push(path.join(r, ".depker/depker.mjs")); - paths.push(path.join(r, ".depker/config.ts")); - paths.push(path.join(r, ".depker/config.js")); - paths.push(path.join(r, ".depker/config.cjs")); - paths.push(path.join(r, ".depker/config.mjs")); - } - } - for (const p of paths) { - if (await fs.exists(p)) { - return path.toFileUrl(p).toString(); - } - } - return `https://raw.githubusercontent.com/syfxlin/depker/master/mod.ts`; -}; - -const execute = async (url: string) => { - const depker = await import(url).then((mod) => mod?.default ?? mod); - await depker.execute(); -}; - -await execute(await lookup()); diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..59dbbf2 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,17 @@ +import config from "@syfxlin/eslint-config"; + +export default config({ + stylistic: { + quotes: "double", + indent: 2, + semi: true, + }, + rules: { + "curly": ["error", "multi-line", "consistent"], + "no-console": ["off"], + "style/brace-style": ["error", "1tbs"], + "style/member-delimiter-style": ["error", { multiline: { delimiter: "semi" }, singleline: { delimiter: "semi" } }], + "ts/ban-ts-comment": ["off"], + "ts/consistent-type-imports": ["off"], + }, +}); diff --git a/mod.ts b/mod.ts index 71c7b76..8d23238 100644 --- a/mod.ts +++ b/mod.ts @@ -1,8 +1,11 @@ import { depker } from "./src/depker.ts"; +// dependencies +export * as deps from "./src/deps.ts"; + // services export * from "./src/depker.ts"; -export * from "./src/services/docker/index.ts"; +export * from "./src/services/run/index.ts"; // modules export * from "./src/modules/proxy/proxy.module.ts"; @@ -11,11 +14,13 @@ export * from "./src/modules/service/service.module.ts"; export * from "./src/modules/service/service.type.ts"; // packs +export * from "./src/modules/service/pack.context.ts"; export * from "./src/modules/service/packs/dockerfile/dockerfile.pack.ts"; export * from "./src/modules/service/packs/image/image.pack.ts"; -export * from "./src/modules/service/packs/nextjs/nextjs.pack.ts"; export * from "./src/modules/service/packs/nginx/nginx.pack.ts"; export * from "./src/modules/service/packs/nodejs/nodejs.pack.ts"; +export * from "./src/modules/service/packs/nextjs/nextjs.pack.ts"; +export * from "./src/modules/service/packs/coline/coline.pack.ts"; // default export default depker(); diff --git a/package.json b/package.json index 2051e5a..0529170 100644 --- a/package.json +++ b/package.json @@ -10,21 +10,14 @@ "license": "Apache-2.0", "private": true, "type": "module", - "scripts": { - "dev": "deno run -A depker.ts" - }, "engines": { "node": ">=16.0.0", "npm": ">=8.0.0" }, "devDependencies": { + "@syfxlin/eslint-config": "^1.0.1", "@types/node": "^20.10.6", - "@typescript-eslint/eslint-plugin": "^6.17.0", - "@typescript-eslint/parser": "^6.17.0", "eslint": "8.56.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.1.2", - "prettier": "^3.1.1", "typescript": "^5.3.3", "typescript-deno-plugin": "^1.31.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bc17954..00005c7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,27 +5,15 @@ settings: excludeLinksFromLockfile: false devDependencies: + '@syfxlin/eslint-config': + specifier: ^1.0.1 + version: 1.0.1(@vue/compiler-sfc@3.4.10)(eslint@8.56.0)(typescript@5.3.3) '@types/node': specifier: ^20.10.6 version: 20.10.6 - '@typescript-eslint/eslint-plugin': - specifier: ^6.17.0 - version: 6.17.0(@typescript-eslint/parser@6.17.0)(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/parser': - specifier: ^6.17.0 - version: 6.17.0(eslint@8.56.0)(typescript@5.3.3) eslint: specifier: 8.56.0 version: 8.56.0 - eslint-config-prettier: - specifier: ^9.1.0 - version: 9.1.0(eslint@8.56.0) - eslint-plugin-prettier: - specifier: ^5.1.2 - version: 5.1.2(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.1.1) - prettier: - specifier: ^3.1.1 - version: 3.1.1 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -40,6 +28,169 @@ packages: engines: {node: '>=0.10.0'} dev: true + /@antfu/eslint-config@2.6.2(@unocss/eslint-plugin@0.58.3)(@vue/compiler-sfc@3.4.10)(eslint-plugin-format@0.1.0)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react-refresh@0.4.5)(eslint-plugin-react@7.33.2)(eslint-plugin-svelte@2.35.1)(eslint@8.56.0)(svelte-eslint-parser@0.33.1)(typescript@5.3.3): + resolution: {integrity: sha512-iHJtFrJLE0gc+oQGxe8I2vpXwhn2wAbz2kqunSPhiOt39yV6yuoE+NJt5nstzy0INKfjSL2teQKlr4g7E2bVhA==} + hasBin: true + peerDependencies: + '@unocss/eslint-plugin': '>=0.50.0' + eslint: '>=8.40.0' + eslint-plugin-format: '>=0.1.0' + eslint-plugin-react: ^7.33.2 + eslint-plugin-react-hooks: ^4.6.0 + eslint-plugin-react-refresh: ^0.4.4 + eslint-plugin-svelte: ^2.34.1 + svelte-eslint-parser: ^0.33.1 + peerDependenciesMeta: + '@unocss/eslint-plugin': + optional: true + eslint-plugin-format: + optional: true + eslint-plugin-react: + optional: true + eslint-plugin-react-hooks: + optional: true + eslint-plugin-react-refresh: + optional: true + eslint-plugin-svelte: + optional: true + svelte-eslint-parser: + optional: true + dependencies: + '@antfu/eslint-define-config': 1.23.0-2 + '@antfu/install-pkg': 0.3.1 + '@eslint-types/jsdoc': 46.8.2-1 + '@eslint-types/typescript-eslint': 6.18.1 + '@eslint-types/unicorn': 50.0.1 + '@stylistic/eslint-plugin': 1.5.3(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/eslint-plugin': 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + '@unocss/eslint-plugin': 0.58.3(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-config-flat-gitignore: 0.1.2 + eslint-merge-processors: 0.1.0(eslint@8.56.0) + eslint-plugin-antfu: 2.1.1(eslint@8.56.0) + eslint-plugin-eslint-comments: 3.2.0(eslint@8.56.0) + eslint-plugin-format: 0.1.0(eslint@8.56.0) + eslint-plugin-i: 2.29.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0) + eslint-plugin-jsdoc: 48.0.2(eslint@8.56.0) + eslint-plugin-jsonc: 2.11.2(eslint@8.56.0) + eslint-plugin-markdown: 3.0.1(eslint@8.56.0) + eslint-plugin-n: 16.6.2(eslint@8.56.0) + eslint-plugin-no-only-tests: 3.1.0 + eslint-plugin-perfectionist: 2.5.0(eslint@8.56.0)(svelte-eslint-parser@0.33.1)(typescript@5.3.3)(vue-eslint-parser@9.4.0) + eslint-plugin-react: 7.33.2(eslint@8.56.0) + eslint-plugin-react-hooks: 4.6.0(eslint@8.56.0) + eslint-plugin-react-refresh: 0.4.5(eslint@8.56.0) + eslint-plugin-svelte: 2.35.1(eslint@8.56.0) + eslint-plugin-toml: 0.8.0(eslint@8.56.0) + eslint-plugin-unicorn: 50.0.1(eslint@8.56.0) + eslint-plugin-unused-imports: 3.0.0(@typescript-eslint/eslint-plugin@6.18.1)(eslint@8.56.0) + eslint-plugin-vitest: 0.3.20(@typescript-eslint/eslint-plugin@6.18.1)(eslint@8.56.0)(typescript@5.3.3) + eslint-plugin-vue: 9.20.0(eslint@8.56.0) + eslint-plugin-yml: 1.11.0(eslint@8.56.0) + eslint-processor-vue-blocks: 0.1.1(@vue/compiler-sfc@3.4.10)(eslint@8.56.0) + globals: 13.24.0 + jsonc-eslint-parser: 2.4.0 + local-pkg: 0.5.0 + parse-gitignore: 2.0.0 + picocolors: 1.0.0 + prompts: 2.4.2 + svelte-eslint-parser: 0.33.1 + toml-eslint-parser: 0.9.3 + vue-eslint-parser: 9.4.0(eslint@8.56.0) + yaml-eslint-parser: 1.2.2 + yargs: 17.7.2 + transitivePeerDependencies: + - '@vue/compiler-sfc' + - astro-eslint-parser + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + - svelte + - typescript + - vitest + dev: true + + /@antfu/eslint-define-config@1.23.0-2: + resolution: {integrity: sha512-LvxY21+ZhpuBf/aHeBUtGQhSEfad4PkNKXKvDOSvukaM3XVTfBhwmHX2EKwAsdq5DlfjbT3qqYyMiueBIO5iDQ==} + engines: {node: '>=18.0.0', npm: '>=9.0.0', pnpm: '>= 8.6.0'} + dev: true + + /@antfu/install-pkg@0.3.1: + resolution: {integrity: sha512-A3zWY9VeTPnxlMiZtsGHw2lSd3ghwvL8s9RiGOtqvDxhhFfZ781ynsGBa/iUnDJ5zBrmTFQrJDud3TGgRISaxw==} + dependencies: + execa: 8.0.1 + dev: true + + /@antfu/utils@0.7.7: + resolution: {integrity: sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==} + dev: true + + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.23.4 + chalk: 2.4.2 + dev: true + + /@babel/helper-string-parser@7.23.4: + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/highlight@7.23.4: + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser@7.23.6: + resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/types@7.23.6: + resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + dev: true + + /@dprint/formatter@0.2.1: + resolution: {integrity: sha512-GCzgRt2o4mhZLy8L47k2A+q9EMG/jWhzZebE29EqKsxmjDrSfv2VisEj/Q+39OOf04jTkEfB/TRO+IZSyxHdYg==} + dev: true + + /@dprint/markdown@0.16.3: + resolution: {integrity: sha512-KvwUrCdHR1spFk0EcdW33KEGFLfkcdx6hJN8mwipGBw0b40sl5oPtVUTgRiH70eV7VUhPfycDfIsDutWNHb17w==} + dev: true + + /@dprint/toml@0.5.4: + resolution: {integrity: sha512-d+5GwwzztZD0QixmOBhaO6nWVLsAeYsJ1HJYNxDoDRbASFCpza9BBVshG5ctBRXCkkIHhD9BO1SnbOoRQltUQw==} + dev: true + + /@es-joy/jsdoccomment@0.41.0: + resolution: {integrity: sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==} + engines: {node: '>=16'} + dependencies: + comment-parser: 1.4.1 + esquery: 1.5.0 + jsdoc-type-pratt-parser: 4.0.0 + dev: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -55,6 +206,18 @@ packages: engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true + /@eslint-types/jsdoc@46.8.2-1: + resolution: {integrity: sha512-FwD7V0xX0jyaqj8Ul5ZY+TAAPohDfVqtbuXJNHb+OIv1aTIqZi5+Zn3F2UwQ5O3BnQd2mTduyK0+HjGx3/AMFg==} + dev: true + + /@eslint-types/typescript-eslint@6.18.1: + resolution: {integrity: sha512-sROyc1rWhtvSdszkR3VAv2fioXIyKNFFRbIgoiije2FA+iNn4FEDhP2+kvbq8wPda2adcrNhSZyWSEFsef+lbg==} + dev: true + + /@eslint-types/unicorn@50.0.1: + resolution: {integrity: sha512-nuJuipTNcg9f+oxZ+3QZw4tuDLmir4RJOPfM/oujgToiy1s+tePDZhwg5jUGc3q8OzTtPbVpsFSYX7QApjO3EA==} + dev: true + /@eslint/eslintrc@2.1.4: resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -97,6 +260,10 @@ packages: resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} dev: true + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -123,22 +290,128 @@ packages: engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} dev: true + /@stylistic/eslint-plugin-js@1.5.3(eslint@8.56.0): + resolution: {integrity: sha512-XlKnm82fD7Sw9kQ6FFigE0tobvptNBXZWsdfoKmUyK7bNxHsAHOFT8zJGY3j3MjZ0Fe7rLTu86hX/vOl0bRRdQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: '>=8.40.0' + dependencies: + acorn: 8.11.3 + escape-string-regexp: 4.0.0 + eslint: 8.56.0 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + dev: true + + /@stylistic/eslint-plugin-jsx@1.5.3(eslint@8.56.0): + resolution: {integrity: sha512-gKXWFmvg3B4e6G+bVz2p37icjj3gS5lzazZD6oLjmQ2b0Lw527VpnxGjWxQ16keKXtrVzUfebakjskOoALg3CQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: '>=8.40.0' + dependencies: + '@stylistic/eslint-plugin-js': 1.5.3(eslint@8.56.0) + eslint: 8.56.0 + estraverse: 5.3.0 + dev: true + + /@stylistic/eslint-plugin-plus@1.5.3(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-fuOBySbH4dbfY4Dwvu+zg5y+e0lALHTyQske5+a2zNC8Ejnx4rFlVjYOmaVFtxFhTD4V0vM7o21Ozci0igcxKg==} + peerDependencies: + eslint: '*' + dependencies: + '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@stylistic/eslint-plugin-ts@1.5.3(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-/gUEqGo0gpFeu220YmC0788VliKnmTaAz4pI82KA5cUuCp6OzEhGlrNkb1eevMwH0RRgyND20HJxOYvEGlwu+w==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: '>=8.40.0' + dependencies: + '@stylistic/eslint-plugin-js': 1.5.3(eslint@8.56.0) + '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@stylistic/eslint-plugin@1.5.3(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-Vee+hHKaCd8DPRoRJTCV+mOFz+zFIaA9QiNJaAvgBzmPkcDnSC7Ewh518fN6SSNe9psS8TDIpcxd1g5v4MSY5A==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: '>=8.40.0' + dependencies: + '@stylistic/eslint-plugin-js': 1.5.3(eslint@8.56.0) + '@stylistic/eslint-plugin-jsx': 1.5.3(eslint@8.56.0) + '@stylistic/eslint-plugin-plus': 1.5.3(eslint@8.56.0)(typescript@5.3.3) + '@stylistic/eslint-plugin-ts': 1.5.3(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@syfxlin/eslint-config@1.0.1(@vue/compiler-sfc@3.4.10)(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-cfMI1KGcZciertbO0FyQqDAZ7O2QsV1WHmxzn8MttiR9fOGhso25OsyRCU35MBgG6jgIYGjCJBtCPVylkmxbQA==} + peerDependencies: + eslint: '>=8.40.0' + dependencies: + '@antfu/eslint-config': 2.6.2(@unocss/eslint-plugin@0.58.3)(@vue/compiler-sfc@3.4.10)(eslint-plugin-format@0.1.0)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react-refresh@0.4.5)(eslint-plugin-react@7.33.2)(eslint-plugin-svelte@2.35.1)(eslint@8.56.0)(svelte-eslint-parser@0.33.1)(typescript@5.3.3) + '@unocss/eslint-plugin': 0.58.3(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-plugin-format: 0.1.0(eslint@8.56.0) + eslint-plugin-react: 7.33.2(eslint@8.56.0) + eslint-plugin-react-hooks: 4.6.0(eslint@8.56.0) + eslint-plugin-react-refresh: 0.4.5(eslint@8.56.0) + eslint-plugin-svelte: 2.35.1(eslint@8.56.0) + svelte-eslint-parser: 0.33.1 + transitivePeerDependencies: + - '@vue/compiler-sfc' + - astro-eslint-parser + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + - svelte + - ts-node + - typescript + - vitest + dev: true + /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true + /@types/mdast@3.0.15: + resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + dependencies: + '@types/unist': 2.0.10 + dev: true + /@types/node@20.10.6: resolution: {integrity: sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==} dependencies: undici-types: 5.26.5 dev: true + /@types/normalize-package-data@2.4.4: + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + dev: true + /@types/semver@7.5.6: resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} dev: true - /@typescript-eslint/eslint-plugin@6.17.0(@typescript-eslint/parser@6.17.0)(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-Vih/4xLXmY7V490dGwBQJTpIZxH4ZFH6eCVmQ4RFkB+wmaCTDAx4dtgoWwMNGKLkqRY1L6rPqzEbjorRnDo4rQ==} + /@types/unist@2.0.10: + resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} + dev: true + + /@typescript-eslint/eslint-plugin@6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-nISDRYnnIpk7VCFrGcu1rnZfM1Dh9LRHnfgdkjcbi/l7g16VYRri3TjXi9Ir4lOZSw5N/gnV/3H7jIPQ8Q4daA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -149,11 +422,11 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.17.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/scope-manager': 6.17.0 - '@typescript-eslint/type-utils': 6.17.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/utils': 6.17.0(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.17.0 + '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.18.1 + '@typescript-eslint/type-utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.18.1 debug: 4.3.4 eslint: 8.56.0 graphemer: 1.4.0 @@ -166,8 +439,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@6.17.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-C4bBaX2orvhK+LlwrY8oWGmSl4WolCfYm513gEccdWZj0CwGadbIADb0FtVEcI+WzUyjyoBj2JRP8g25E6IB8A==} + /@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-zct/MdJnVaRRNy9e84XnVtRv9Vf91/qqe+hZJtKanjojud4wAVy/7lXxJmMyX6X6J+xc6c//YEWvpeif8cAhWA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -176,10 +449,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.17.0 - '@typescript-eslint/types': 6.17.0 - '@typescript-eslint/typescript-estree': 6.17.0(typescript@5.3.3) - '@typescript-eslint/visitor-keys': 6.17.0 + '@typescript-eslint/scope-manager': 6.18.1 + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.18.1 debug: 4.3.4 eslint: 8.56.0 typescript: 5.3.3 @@ -187,16 +460,16 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager@6.17.0: - resolution: {integrity: sha512-RX7a8lwgOi7am0k17NUO0+ZmMOX4PpjLtLRgLmT1d3lBYdWH4ssBUbwdmc5pdRX8rXon8v9x8vaoOSpkHfcXGA==} + /@typescript-eslint/scope-manager@6.18.1: + resolution: {integrity: sha512-BgdBwXPFmZzaZUuw6wKiHKIovms97a7eTImjkXCZE04TGHysG+0hDQPmygyvgtkoB/aOQwSM/nWv3LzrOIQOBw==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.17.0 - '@typescript-eslint/visitor-keys': 6.17.0 + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/visitor-keys': 6.18.1 dev: true - /@typescript-eslint/type-utils@6.17.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-hDXcWmnbtn4P2B37ka3nil3yi3VCQO2QEB9gBiHJmQp5wmyQWqnjA85+ZcE8c4FqnaB6lBwMrPkgd4aBYz3iNg==} + /@typescript-eslint/type-utils@6.18.1(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-wyOSKhuzHeU/5pcRDP2G2Ndci+4g653V43gXTpt4nbyoIOAASkGDA9JIAgbQCdCkcr1MvpSYWzxTz0olCn8+/Q==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -205,8 +478,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.17.0(typescript@5.3.3) - '@typescript-eslint/utils': 6.17.0(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) + '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) debug: 4.3.4 eslint: 8.56.0 ts-api-utils: 1.0.3(typescript@5.3.3) @@ -215,13 +488,13 @@ packages: - supports-color dev: true - /@typescript-eslint/types@6.17.0: - resolution: {integrity: sha512-qRKs9tvc3a4RBcL/9PXtKSehI/q8wuU9xYJxe97WFxnzH8NWWtcW3ffNS+EWg8uPvIerhjsEZ+rHtDqOCiH57A==} + /@typescript-eslint/types@6.18.1: + resolution: {integrity: sha512-4TuMAe+tc5oA7wwfqMtB0Y5OrREPF1GeJBAjqwgZh1lEMH5PJQgWgHGfYufVB51LtjD+peZylmeyxUXPfENLCw==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.17.0(typescript@5.3.3): - resolution: {integrity: sha512-gVQe+SLdNPfjlJn5VNGhlOhrXz4cajwFd5kAgWtZ9dCZf4XJf8xmgCTLIqec7aha3JwgLI2CK6GY1043FRxZwg==} + /@typescript-eslint/typescript-estree@6.18.1(typescript@5.3.3): + resolution: {integrity: sha512-fv9B94UAhywPRhUeeV/v+3SBDvcPiLxRZJw/xZeeGgRLQZ6rLMG+8krrJUyIf6s1ecWTzlsbp0rlw7n9sjufHA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -229,8 +502,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.17.0 - '@typescript-eslint/visitor-keys': 6.17.0 + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/visitor-keys': 6.18.1 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -242,8 +515,8 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@6.17.0(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-LofsSPjN/ITNkzV47hxas2JCsNCEnGhVvocfyOcLzT9c/tSZE7SfhS/iWtzP1lKNOEfLhRTZz6xqI8N2RzweSQ==} + /@typescript-eslint/utils@6.18.1(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-zZmTuVZvD1wpoceHvoQpOiewmWu3uP9FuTWo8vqpy2ffsmfCE8mklRPi+vmnIYAIk9t/4kOThri2QCDgor+OpQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -251,9 +524,9 @@ packages: '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.6 - '@typescript-eslint/scope-manager': 6.17.0 - '@typescript-eslint/types': 6.17.0 - '@typescript-eslint/typescript-estree': 6.17.0(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.18.1 + '@typescript-eslint/types': 6.18.1 + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.3.3) eslint: 8.56.0 semver: 7.5.4 transitivePeerDependencies: @@ -261,11 +534,11 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys@6.17.0: - resolution: {integrity: sha512-H6VwB/k3IuIeQOyYczyyKN8wH6ed8EwliaYHLxOIhyF0dYEIsN8+Bk3GE19qafeMKyZJJHP8+O1HiFhFLUNKSg==} + /@typescript-eslint/visitor-keys@6.18.1: + resolution: {integrity: sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.17.0 + '@typescript-eslint/types': 6.18.1 eslint-visitor-keys: 3.4.3 dev: true @@ -273,6 +546,75 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true + /@unocss/config@0.58.3: + resolution: {integrity: sha512-8BQDoLzf/BkyfnkQsjnXI84oj+Spqkr7Bf2AbOGcX14vof0qqHSDvJXQV1e0u7jv2QETe2D1+PI4fnkJCumaRw==} + engines: {node: '>=14'} + dependencies: + '@unocss/core': 0.58.3 + unconfig: 0.3.11 + dev: true + + /@unocss/core@0.58.3: + resolution: {integrity: sha512-9hTxzsrSLh+07ql/lGhE+8ZbE9MTTeZeMx131cPf2jDJUxAZooLE5pBCoK0k77ZJGcribRrwPGkUScBNOK0cYQ==} + dev: true + + /@unocss/eslint-plugin@0.58.3(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-5E55Oz13aPpbKblR/DQfjahl/CNChHI97P19Flv2CslS2rNjPwI2c1nV7He3SJdJtnfd88To78ltlz7UOZzOqA==} + engines: {node: '>=14'} + dependencies: + '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + '@unocss/config': 0.58.3 + '@unocss/core': 0.58.3 + magic-string: 0.30.5 + synckit: 0.8.8 + transitivePeerDependencies: + - eslint + - supports-color + - typescript + dev: true + + /@vue/compiler-core@3.4.10: + resolution: {integrity: sha512-53vxh7K9qbx+JILnGEhrFRyr7H7e4NdT8RuTNU3m6HhJKFvcAqFTNXpYMHnyuAzzRGdsbsYHBgQC3H6xEXTG6w==} + dependencies: + '@babel/parser': 7.23.6 + '@vue/shared': 3.4.10 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.0.2 + dev: true + + /@vue/compiler-dom@3.4.10: + resolution: {integrity: sha512-QAALBJksIFpXGYuo74rtMgnwpVZDvd3kYbUa4gYX9s/5QiqEvZSgbKtOdUGydXcxKPt3ifC+0/bhPVHXN2694A==} + dependencies: + '@vue/compiler-core': 3.4.10 + '@vue/shared': 3.4.10 + dev: true + + /@vue/compiler-sfc@3.4.10: + resolution: {integrity: sha512-sTOssaQySgrMjrhZxmAqdp6n+E51VteIVIDaOR537H2P63DyzMmig21U0XXFxiXmMIfrK91lAInnc+bIAYemGw==} + dependencies: + '@babel/parser': 7.23.6 + '@vue/compiler-core': 3.4.10 + '@vue/compiler-dom': 3.4.10 + '@vue/compiler-ssr': 3.4.10 + '@vue/shared': 3.4.10 + estree-walker: 2.0.2 + magic-string: 0.30.5 + postcss: 8.4.33 + source-map-js: 1.0.2 + dev: true + + /@vue/compiler-ssr@3.4.10: + resolution: {integrity: sha512-Y90TL1abretWbUiK5rv+9smS1thCHE5sSuhZgiLh6cxgZ2Pcy3BEvDd3reID0iwNcTdMbTeE6NI3Aq4Mux6hqQ==} + dependencies: + '@vue/compiler-dom': 3.4.10 + '@vue/shared': 3.4.10 + dev: true + + /@vue/shared@3.4.10: + resolution: {integrity: sha512-C0mIVhwW1xQLMFyqMJxnhq6fWyE02lCgcE+TDdtGpg6B3H6kh/0YcqS54qYc76UJNlWegf3VgsLqgk6D9hBmzQ==} + dev: true + /acorn-jsx@5.3.2(acorn@8.11.3): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -301,6 +643,13 @@ packages: engines: {node: '>=8'} dev: true + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -308,6 +657,11 @@ packages: color-convert: 2.0.1 dev: true + /are-docs-informative@0.0.2: + resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} + engines: {node: '>=14'} + dev: true + /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true @@ -317,15 +671,91 @@ packages: engines: {node: '>=0.10.0'} dev: true + /array-buffer-byte-length@1.0.0: + resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + dependencies: + call-bind: 1.0.5 + is-array-buffer: 3.0.2 + dev: true + + /array-includes@3.1.7: + resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + is-string: 1.0.7 + dev: true + /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.tosorted@1.1.2: + resolution: {integrity: sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 + get-intrinsic: 1.2.2 + dev: true + + /arraybuffer.prototype.slice@1.0.2: + resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + is-array-buffer: 3.0.2 + is-shared-array-buffer: 1.0.2 + dev: true + + /asynciterator.prototype@1.0.0: + resolution: {integrity: sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==} + dependencies: + has-symbols: 1.0.3 + dev: true + + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true + /boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -346,11 +776,54 @@ packages: fill-range: 7.0.1 dev: true + /browserslist@4.22.2: + resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001576 + electron-to-chromium: 1.4.629 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.22.2) + dev: true + + /builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + dev: true + + /builtins@5.0.1: + resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} + dependencies: + semver: 7.5.4 + dev: true + + /call-bind@1.0.5: + resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + dependencies: + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + set-function-length: 1.1.1 + dev: true + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} dev: true + /caniuse-lite@1.0.30001576: + resolution: {integrity: sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==} + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -359,6 +832,39 @@ packages: supports-color: 7.2.0 dev: true + /character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + dev: true + + /character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + dev: true + + /character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + dev: true + + /ci-info@4.0.0: + resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} + engines: {node: '>=8'} + dev: true + + /clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + /clone-deep@0.2.4: resolution: {integrity: sha512-we+NuQo2DHhSl+DP6jlUiAhyAjBQrYnpOk15rN6c6JSPScjiCLh8IbSU+VTcph6YS3o7mASE8a0+gbZ7ChLpgg==} engines: {node: '>=0.10.0'} @@ -370,6 +876,12 @@ packages: shallow-clone: 0.1.2 dev: true + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -377,14 +889,29 @@ packages: color-name: 1.1.4 dev: true + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true + /comment-parser@1.4.1: + resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + engines: {node: '>= 12.0.0'} + dev: true + /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true + /core-js-compat@3.35.0: + resolution: {integrity: sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==} + dependencies: + browserslist: 4.22.2 + dev: true + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -394,6 +921,23 @@ packages: which: 2.0.2 dev: true + /cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -410,6 +954,28 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true + /define-data-property@1.1.1: + resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + has-property-descriptors: 1.0.1 + object-keys: 1.1.1 + dev: true + + /defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + dev: true + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -417,6 +983,13 @@ packages: path-type: 4.0.0 dev: true + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -424,41 +997,569 @@ packages: esutils: 2.0.3 dev: true - /escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} + /electron-to-chromium@1.4.629: + resolution: {integrity: sha512-5UUkr3k3CZ/k+9Sw7vaaIMyOzMC0XbPyprKI3n0tbKDqkzTDOjK4izm7DxlkueRMim6ZZQ1ja9F7hoFVplHihA==} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract@1.22.3: + resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + arraybuffer.prototype.slice: 1.0.2 + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + es-set-tostringtag: 2.0.2 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.2 + get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + has-proto: 1.0.1 + has-symbols: 1.0.3 + hasown: 2.0.0 + internal-slot: 1.0.6 + is-array-buffer: 3.0.2 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-typed-array: 1.1.12 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.1 + safe-array-concat: 1.0.1 + safe-regex-test: 1.0.2 + string.prototype.trim: 1.2.8 + string.prototype.trimend: 1.0.7 + string.prototype.trimstart: 1.0.7 + typed-array-buffer: 1.0.0 + typed-array-byte-length: 1.0.0 + typed-array-byte-offset: 1.0.0 + typed-array-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.13 + dev: true + + /es-iterator-helpers@1.0.15: + resolution: {integrity: sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==} + dependencies: + asynciterator.prototype: 1.0.0 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-set-tostringtag: 2.0.2 + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + globalthis: 1.0.3 + has-property-descriptors: 1.0.1 + has-proto: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.6 + iterator.prototype: 1.1.2 + safe-array-concat: 1.0.1 + dev: true + + /es-set-tostringtag@2.0.2: + resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + has-tostringtag: 1.0.0 + hasown: 2.0.0 + dev: true + + /es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + dependencies: + hasown: 2.0.0 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} dev: true - /eslint-config-prettier@9.1.0(eslint@8.56.0): - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} - hasBin: true + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-compat-utils@0.1.2(eslint@8.56.0): + resolution: {integrity: sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==} + engines: {node: '>=12'} peerDependencies: - eslint: '>=7.0.0' + eslint: '>=6.0.0' dependencies: eslint: 8.56.0 dev: true - /eslint-plugin-prettier@5.1.2(eslint-config-prettier@9.1.0)(eslint@8.56.0)(prettier@3.1.1): - resolution: {integrity: sha512-dhlpWc9vOwohcWmClFcA+HjlvUpuyynYs0Rf+L/P6/0iQE6vlHW9l5bkfzN62/Stm9fbq8ku46qzde76T1xlSg==} - engines: {node: ^14.18.0 || >=16.0.0} + /eslint-config-flat-gitignore@0.1.2: + resolution: {integrity: sha512-PcBsqtd5QHEZH4ROvpnRN4EP0qcHh9voCCHgtyHxnJZHGspJREcZn7oPqRG/GfWt9m3C0fkC2l5CuBtMig2wXQ==} + dependencies: + parse-gitignore: 2.0.0 + dev: true + + /eslint-formatting-reporter@0.0.0(eslint@8.56.0): + resolution: {integrity: sha512-k9RdyTqxqN/wNYVaTk/ds5B5rA8lgoAmvceYN7bcZMBwU7TuXx5ntewJv81eF3pIL/CiJE+pJZm36llG8yhyyw==} peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '*' - prettier: '>=3.0.0' + eslint: '>=8.40.0' + dependencies: + eslint: 8.56.0 + prettier-linter-helpers: 1.0.0 + dev: true + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + dependencies: + debug: 3.2.7 + is-core-module: 2.13.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-merge-processors@0.1.0(eslint@8.56.0): + resolution: {integrity: sha512-IvRXXtEajLeyssvW4wJcZ2etxkR9mUf4zpNwgI+m/Uac9RfXHskuJefkHUcawVzePnd6xp24enp5jfgdHzjRdQ==} + peerDependencies: + eslint: '*' + dependencies: + eslint: 8.56.0 + dev: true + + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.18.1)(eslint-import-resolver-node@0.3.9)(eslint@8.56.0): + resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' peerDependenciesMeta: - '@types/eslint': + '@typescript-eslint/parser': + optional: true + eslint: optional: true - eslint-config-prettier: + eslint-import-resolver-node: optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + debug: 3.2.7 + eslint: 8.56.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-parser-plain@0.1.0: + resolution: {integrity: sha512-oOeA6FWU0UJT/Rxc3XF5Cq0nbIZbylm7j8+plqq0CZoE6m4u32OXJrR+9iy4srGMmF6v6pmgvP1zPxSRIGh3sg==} + dev: true + + /eslint-plugin-antfu@2.1.1(eslint@8.56.0): + resolution: {integrity: sha512-HCPo3IP15/gOaruIb1ce6R4LUv/MKBZCmWzqYiLGDFW43WW4juPURnjaQIE3AgWNSoCURqD3wxerXYKzokKTgA==} + peerDependencies: + eslint: '*' + dependencies: + eslint: 8.56.0 + dev: true + + /eslint-plugin-es-x@7.5.0(eslint@8.56.0): + resolution: {integrity: sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint-community/regexpp': 4.10.0 + eslint: 8.56.0 + eslint-compat-utils: 0.1.2(eslint@8.56.0) + dev: true + + /eslint-plugin-eslint-comments@3.2.0(eslint@8.56.0): + resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} + engines: {node: '>=6.5.0'} + peerDependencies: + eslint: '>=4.19.1' dependencies: + escape-string-regexp: 1.0.5 eslint: 8.56.0 - eslint-config-prettier: 9.1.0(eslint@8.56.0) + ignore: 5.3.0 + dev: true + + /eslint-plugin-format@0.1.0(eslint@8.56.0): + resolution: {integrity: sha512-IgOu+GEH+PdKnpuPrFzY8q8QgnzAUijDZsNLhpp5jx0Lbu9u968/STcmEZGnIMVBw3zeTNN/FsU6d2Rdgcy6Aw==} + peerDependencies: + eslint: ^8.40.0 + dependencies: + '@dprint/formatter': 0.2.1 + '@dprint/markdown': 0.16.3 + '@dprint/toml': 0.5.4 + eslint: 8.56.0 + eslint-formatting-reporter: 0.0.0(eslint@8.56.0) + eslint-parser-plain: 0.1.0 prettier: 3.1.1 - prettier-linter-helpers: 1.0.0 synckit: 0.8.8 dev: true + /eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0): + resolution: {integrity: sha512-ORizX37MelIWLbMyqI7hi8VJMf7A0CskMmYkB+lkCX3aF4pkGV7kwx5bSEb4qx7Yce2rAf9s34HqDRPjGRZPNQ==} + engines: {node: '>=12'} + peerDependencies: + eslint: ^7.2.0 || ^8 + dependencies: + debug: 4.3.4 + doctrine: 3.0.0 + eslint: 8.56.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.18.1)(eslint-import-resolver-node@0.3.9)(eslint@8.56.0) + get-tsconfig: 4.7.2 + is-glob: 4.0.3 + minimatch: 3.1.2 + semver: 7.5.4 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-jsdoc@48.0.2(eslint@8.56.0): + resolution: {integrity: sha512-CBFl5Jc7+jlV36RwDm+PQ8Uw5r28pn2/uW/OaB+Gw5bFwn4Py/1eYMZ3hGf9S4meUFZ/sRvS+hVif2mRAp6WqQ==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + dependencies: + '@es-joy/jsdoccomment': 0.41.0 + are-docs-informative: 0.0.2 + comment-parser: 1.4.1 + debug: 4.3.4 + escape-string-regexp: 4.0.0 + eslint: 8.56.0 + esquery: 1.5.0 + is-builtin-module: 3.2.1 + semver: 7.5.4 + spdx-expression-parse: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-jsonc@2.11.2(eslint@8.56.0): + resolution: {integrity: sha512-F6A0MZhIGRBPOswzzn4tJFXXkPLiLwJaMlQwz/Qj1qx+bV5MCn79vBeJh2ynMmtqqHloi54KDCnsT/KWrcCcnQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + eslint: 8.56.0 + eslint-compat-utils: 0.1.2(eslint@8.56.0) + espree: 9.6.1 + graphemer: 1.4.0 + jsonc-eslint-parser: 2.4.0 + natural-compare: 1.4.0 + dev: true + + /eslint-plugin-markdown@3.0.1(eslint@8.56.0): + resolution: {integrity: sha512-8rqoc148DWdGdmYF6WSQFT3uQ6PO7zXYgeBpHAOAakX/zpq+NvFYbDA/H7PYzHajwtmaOzAwfxyl++x0g1/N9A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.56.0 + mdast-util-from-markdown: 0.8.5 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-n@16.6.2(eslint@8.56.0): + resolution: {integrity: sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + builtins: 5.0.1 + eslint: 8.56.0 + eslint-plugin-es-x: 7.5.0(eslint@8.56.0) + get-tsconfig: 4.7.2 + globals: 13.24.0 + ignore: 5.3.0 + is-builtin-module: 3.2.1 + is-core-module: 2.13.1 + minimatch: 3.1.2 + resolve: 1.22.8 + semver: 7.5.4 + dev: true + + /eslint-plugin-no-only-tests@3.1.0: + resolution: {integrity: sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==} + engines: {node: '>=5.0.0'} + dev: true + + /eslint-plugin-perfectionist@2.5.0(eslint@8.56.0)(svelte-eslint-parser@0.33.1)(typescript@5.3.3)(vue-eslint-parser@9.4.0): + resolution: {integrity: sha512-F6XXcq4mKKUe/SREoMGQqzgw6cgCgf3pFzkFfQVIGtqD1yXVpQjnhTepzhBeZfxZwgMzR9HO4yH4CUhIQ2WBcQ==} + peerDependencies: + astro-eslint-parser: ^0.16.0 + eslint: '>=8.0.0' + svelte: '>=3.0.0' + svelte-eslint-parser: ^0.33.0 + vue-eslint-parser: '>=9.0.0' + peerDependenciesMeta: + astro-eslint-parser: + optional: true + svelte: + optional: true + svelte-eslint-parser: + optional: true + vue-eslint-parser: + optional: true + dependencies: + '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + minimatch: 9.0.3 + natural-compare-lite: 1.4.0 + svelte-eslint-parser: 0.33.1 + vue-eslint-parser: 9.4.0(eslint@8.56.0) + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-plugin-react-hooks@4.6.0(eslint@8.56.0): + resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + dependencies: + eslint: 8.56.0 + dev: true + + /eslint-plugin-react-refresh@0.4.5(eslint@8.56.0): + resolution: {integrity: sha512-D53FYKJa+fDmZMtriODxvhwrO+IOqrxoEo21gMA0sjHdU6dPVH4OhyFip9ypl8HOF5RV5KdTo+rBQLvnY2cO8w==} + peerDependencies: + eslint: '>=7' + dependencies: + eslint: 8.56.0 + dev: true + + /eslint-plugin-react@7.33.2(eslint@8.56.0): + resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + array-includes: 3.1.7 + array.prototype.flatmap: 1.3.2 + array.prototype.tosorted: 1.1.2 + doctrine: 2.1.0 + es-iterator-helpers: 1.0.15 + eslint: 8.56.0 + estraverse: 5.3.0 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.7 + object.fromentries: 2.0.7 + object.hasown: 1.1.3 + object.values: 1.1.7 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.10 + dev: true + + /eslint-plugin-svelte@2.35.1(eslint@8.56.0): + resolution: {integrity: sha512-IF8TpLnROSGy98Z3NrsKXWDSCbNY2ReHDcrYTuXZMbfX7VmESISR78TWgO9zdg4Dht1X8coub5jKwHzP0ExRug==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0-0 + svelte: ^3.37.0 || ^4.0.0 + peerDependenciesMeta: + svelte: + optional: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@jridgewell/sourcemap-codec': 1.4.15 + debug: 4.3.4 + eslint: 8.56.0 + eslint-compat-utils: 0.1.2(eslint@8.56.0) + esutils: 2.0.3 + known-css-properties: 0.29.0 + postcss: 8.4.33 + postcss-load-config: 3.1.4(postcss@8.4.33) + postcss-safe-parser: 6.0.0(postcss@8.4.33) + postcss-selector-parser: 6.0.15 + semver: 7.5.4 + svelte-eslint-parser: 0.33.1 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + + /eslint-plugin-toml@0.8.0(eslint@8.56.0): + resolution: {integrity: sha512-vNfoLQq60nK5FTr6x9F/SK3ZcbMsHzfgXsoDLhoCqgGtpzoAmsZrFB+efKEjjLT9wdIL6sKbz4taLKpB9sU8Hw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.4 + eslint: 8.56.0 + eslint-compat-utils: 0.1.2(eslint@8.56.0) + lodash: 4.17.21 + toml-eslint-parser: 0.9.3 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-unicorn@50.0.1(eslint@8.56.0): + resolution: {integrity: sha512-KxenCZxqSYW0GWHH18okDlOQcpezcitm5aOSz6EnobyJ6BIByiPDviQRjJIUAjG/tMN11958MxaQ+qCoU6lfDA==} + engines: {node: '>=16'} + peerDependencies: + eslint: '>=8.56.0' + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint/eslintrc': 2.1.4 + ci-info: 4.0.0 + clean-regexp: 1.0.0 + core-js-compat: 3.35.0 + eslint: 8.56.0 + esquery: 1.5.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.0.2 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.10.0 + semver: 7.5.4 + strip-indent: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-unused-imports@3.0.0(@typescript-eslint/eslint-plugin@6.18.1)(eslint@8.56.0): + resolution: {integrity: sha512-sduiswLJfZHeeBJ+MQaG+xYzSWdRXoSw61DpU13mzWumCkR0ufD0HmO4kdNokjrkluMHpj/7PJeN35pgbhW3kw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^6.0.0 + eslint: ^8.0.0 + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + eslint-rule-composer: 0.3.0 + dev: true + + /eslint-plugin-vitest@0.3.20(@typescript-eslint/eslint-plugin@6.18.1)(eslint@8.56.0)(typescript@5.3.3): + resolution: {integrity: sha512-O05k4j9TGMOkkghj9dRgpeLDyOSiVIxQWgNDPfhYPm5ioJsehcYV/zkRLekQs+c8+RBCVXucSED3fYOyy2EoWA==} + engines: {node: ^18.0.0 || >= 20.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': '*' + eslint: '>=8.0.0' + vitest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + vitest: + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 6.18.1(@typescript-eslint/parser@6.18.1)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.3.3) + eslint: 8.56.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-plugin-vue@9.20.0(eslint@8.56.0): + resolution: {integrity: sha512-9/DV5CM7ItfgWmXjL6j3zyDtVTrslYdnEm+rnYNajdElx17b3erxi/Wc6FY7t3BQ6dgo0t/UBpgiWCOKtJyN8Q==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + eslint: 8.56.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.0.15 + semver: 7.5.4 + vue-eslint-parser: 9.4.0(eslint@8.56.0) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-yml@1.11.0(eslint@8.56.0): + resolution: {integrity: sha512-NBZP1NDGy0u38pY5ieix75jxS9GNOJy9xd4gQa0rU4gWbfEsVhKDwuFaQ6RJpDbv6Lq5TtcAZS/YnAc0oeRw0w==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.4 + eslint: 8.56.0 + eslint-compat-utils: 0.1.2(eslint@8.56.0) + lodash: 4.17.21 + natural-compare: 1.4.0 + yaml-eslint-parser: 1.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-processor-vue-blocks@0.1.1(@vue/compiler-sfc@3.4.10)(eslint@8.56.0): + resolution: {integrity: sha512-9+dU5lU881log570oBwpelaJmOfOzSniben7IWEDRYQPPWwlvaV7NhOtsTuUWDqpYT+dtKKWPsgz4OkOi+aZnA==} + peerDependencies: + '@vue/compiler-sfc': ^3.3.0 + eslint: ^8.50.0 + dependencies: + '@vue/compiler-sfc': 3.4.10 + eslint: 8.56.0 + dev: true + + /eslint-rule-composer@0.3.0: + resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} + engines: {node: '>=4.0.0'} + dev: true + /eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -547,11 +1648,30 @@ packages: engines: {node: '>=4.0'} dev: true + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} dev: true + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + 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.2.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true @@ -599,6 +1719,14 @@ packages: to-regex-range: 5.0.1 dev: true + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -620,6 +1748,12 @@ packages: resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} dev: true + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + /for-in@0.1.8: resolution: {integrity: sha512-F0to7vbBSHP8E3l6dCjxNOLuSFAACIxFy3UehTUlG7svlXi37HHsDkyVcHo0Pq8QwrE+pXvWSVX3ZT1T9wAZ9g==} engines: {node: '>=0.10.0'} @@ -641,18 +1775,69 @@ packages: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true - /glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: true + + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} dependencies: - is-glob: 4.0.3 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + functions-have-names: 1.2.3 dev: true - /glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-intrinsic@1.2.2: + resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} dependencies: - is-glob: 4.0.3 + function-bind: 1.1.2 + has-proto: 1.0.1 + has-symbols: 1.0.3 + hasown: 2.0.0 + dev: true + + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + + /get-symbol-description@1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + dev: true + + /get-tsconfig@4.7.2: + resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 dev: true /glob@7.2.3: @@ -673,6 +1858,13 @@ packages: type-fest: 0.20.2 dev: true + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + dev: true + /globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -685,15 +1877,69 @@ packages: slash: 3.0.0 dev: true + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.2 + dev: true + /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: true + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} dev: true + /has-property-descriptors@1.0.1: + resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} + dependencies: + get-intrinsic: 1.2.2 + dev: true + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /hasown@2.0.0: + resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: true + + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + /ignore@5.3.0: resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} engines: {node: '>= 4'} @@ -716,6 +1962,11 @@ packages: engines: {node: '>=0.8.19'} dev: true + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + /inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: @@ -727,10 +1978,92 @@ packages: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} dev: true + /internal-slot@1.0.6: + resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + hasown: 2.0.0 + side-channel: 1.0.4 + dev: true + + /is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + dev: true + + /is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + dev: true + + /is-array-buffer@3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + is-typed-array: 1.1.12 + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + has-tostringtag: 1.0.0 + dev: true + /is-buffer@1.1.6: resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} dev: true + /is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + dependencies: + builtin-modules: 3.3.0 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.0 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + dev: true + /is-extendable@0.1.1: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} @@ -741,6 +2074,24 @@ packages: engines: {node: '>=0.10.0'} dev: true + /is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + dependencies: + call-bind: 1.0.5 + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -748,6 +2099,26 @@ packages: is-extglob: 2.1.1 dev: true + /is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + dev: true + + /is-map@2.0.2: + resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + dev: true + + /is-negative-zero@2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -765,6 +2136,71 @@ packages: isobject: 3.0.1 dev: true + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + has-tostringtag: 1.0.0 + dev: true + + /is-set@2.0.2: + resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + dev: true + + /is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.5 + dev: true + + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.12: + resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.13 + dev: true + + /is-weakmap@2.0.1: + resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.5 + dev: true + + /is-weakset@2.0.2: + resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true @@ -774,6 +2210,25 @@ packages: engines: {node: '>=0.10.0'} dev: true + /iterator.prototype@1.1.2: + resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + dependencies: + define-properties: 1.2.1 + get-intrinsic: 1.2.2 + has-symbols: 1.0.3 + reflect.getprototypeof: 1.0.4 + set-function-name: 2.0.1 + dev: true + + /jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + hasBin: true + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -781,10 +2236,30 @@ packages: argparse: 2.0.1 dev: true + /jsdoc-type-pratt-parser@4.0.0: + resolution: {integrity: sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==} + engines: {node: '>=12.0.0'} + dev: true + + /jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + + /jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + dev: true + /json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} dev: true + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true @@ -793,6 +2268,30 @@ packages: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true + /jsonc-eslint-parser@2.4.0: + resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.11.3 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + semver: 7.5.4 + dev: true + + /jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: true + + /jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + dependencies: + array-includes: 3.1.7 + array.prototype.flat: 1.3.2 + object.assign: 4.1.5 + object.values: 1.1.7 + dev: true + /keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: @@ -813,6 +2312,15 @@ packages: is-buffer: 1.1.6 dev: true + /kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + + /known-css-properties@0.29.0: + resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==} + dev: true + /lazy-cache@0.2.7: resolution: {integrity: sha512-gkX52wvU/R8DVMMt78ATVPFMJqfW8FPz1GZ1sVHBVQHmu/WvhIWE4cE1GBzhJNFicDeYhnwp6Rl35BcAIM3YOQ==} engines: {node: '>=0.10.0'} @@ -831,6 +2339,30 @@ packages: type-check: 0.4.0 dev: true + /lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + dependencies: + mlly: 1.5.0 + pkg-types: 1.0.3 + dev: true + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -842,6 +2374,17 @@ packages: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -849,6 +2392,29 @@ packages: yallist: 4.0.0 dev: true + /magic-string@0.30.5: + resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /mdast-util-from-markdown@0.8.5: + resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} + dependencies: + '@types/mdast': 3.0.15 + mdast-util-to-string: 2.0.0 + micromark: 2.11.4 + parse-entities: 2.0.0 + unist-util-stringify-position: 2.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-to-string@2.0.0: + resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} + dev: true + /merge-deep@3.0.3: resolution: {integrity: sha512-qtmzAS6t6grwEkNrunqTBdn0qKwFgNWvlxUbAV8es9M7Ot1EbyApytCnvE0jALPa46ZpKDUo527kKiaWplmlFA==} engines: {node: '>=0.10.0'} @@ -858,11 +2424,24 @@ packages: kind-of: 3.2.2 dev: true + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} dev: true + /micromark@2.11.4: + resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} + dependencies: + debug: 4.3.4 + parse-entities: 2.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -871,6 +2450,16 @@ packages: picomatch: 2.3.1 dev: true + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -892,59 +2481,214 @@ packages: is-extendable: 0.1.1 dev: true + /mlly@1.5.0: + resolution: {integrity: sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==} + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.0.3 + ufo: 1.3.2 + dev: true + /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + dev: true + /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} dev: true - /optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} - engines: {node: '>= 0.8.0'} + /normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 dev: true - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + /npm-run-path@5.2.0: + resolution: {integrity: sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: - yocto-queue: 0.1.0 + path-key: 4.0.0 dev: true - /p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + /nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} dependencies: - p-limit: 3.1.0 + boolbase: 1.0.0 dev: true - /parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - dependencies: - callsites: 3.1.0 + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} dev: true - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} dev: true - /path-is-absolute@1.0.1: + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.entries@1.1.7: + resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /object.fromentries@2.0.7: + resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /object.hasown@1.1.3: + resolution: {integrity: sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==} + dependencies: + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /object.values@1.1.7: + resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + dev: true + + /parse-gitignore@2.0.0: + resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==} + engines: {node: '>=14'} + dev: true + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.23.5 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} dev: true @@ -954,16 +2698,98 @@ packages: engines: {node: '>=8'} dev: true + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} dev: true + /pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} dev: true + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.5.0 + pathe: 1.1.2 + dev: true + + /pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + dev: true + + /postcss-load-config@3.1.4(postcss@8.4.33): + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.1.0 + postcss: 8.4.33 + yaml: 1.10.2 + dev: true + + /postcss-safe-parser@6.0.0(postcss@8.4.33): + resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.3.3 + dependencies: + postcss: 8.4.33 + dev: true + + /postcss-scss@4.0.9(postcss@8.4.33): + resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.4.29 + dependencies: + postcss: 8.4.33 + dev: true + + /postcss-selector-parser@6.0.15: + resolution: {integrity: sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss@8.4.33: + resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -982,6 +2808,22 @@ packages: hasBin: true dev: true + /prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -991,11 +2833,94 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + + /read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + + /reflect.getprototypeof@1.0.4: + resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + globalthis: 1.0.3 + which-builtin-type: 1.1.3 + dev: true + + /regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + dev: true + + /regexp.prototype.flags@1.5.1: + resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + set-function-name: 2.0.1 + dev: true + + /regjsparser@0.10.0: + resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} dev: true + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -1014,6 +2939,35 @@ packages: queue-microtask: 1.2.3 dev: true + /safe-array-concat@1.0.1: + resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + + /safe-regex-test@1.0.2: + resolution: {integrity: sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + is-regex: 1.1.4 + dev: true + + /semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + /semver@7.5.4: resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} engines: {node: '>=10'} @@ -1022,6 +2976,25 @@ packages: lru-cache: 6.0.0 dev: true + /set-function-length@1.1.1: + resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /set-function-name@2.0.1: + resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.1 + dev: true + /shallow-clone@0.1.2: resolution: {integrity: sha512-J1zdXCky5GmNnuauESROVu31MQSnLoYvlyEn6j2Ztk6Q5EHFIhxkMhYcv6vuDzl2XEzoRr856QwzMgWM/TmZgw==} engines: {node: '>=0.10.0'} @@ -1044,11 +3017,110 @@ packages: engines: {node: '>=8'} dev: true + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + object-inspect: 1.13.1 + dev: true + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} dev: true + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.16 + dev: true + + /spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.16 + dev: true + + /spdx-expression-parse@4.0.0: + resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.16 + dev: true + + /spdx-license-ids@3.0.16: + resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==} + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string.prototype.matchall@4.0.10: + resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + has-symbols: 1.0.3 + internal-slot: 1.0.6 + regexp.prototype.flags: 1.5.1 + set-function-name: 2.0.1 + side-channel: 1.0.4 + dev: true + + /string.prototype.trim@1.2.8: + resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /string.prototype.trimend@1.0.7: + resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + + /string.prototype.trimstart@1.0.7: + resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + dev: true + /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -1056,11 +3128,30 @@ packages: ansi-regex: 5.0.1 dev: true + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: true + + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} dev: true + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -1068,6 +3159,27 @@ packages: has-flag: 4.0.0 dev: true + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /svelte-eslint-parser@0.33.1: + resolution: {integrity: sha512-vo7xPGTlKBGdLH8T5L64FipvTrqv3OQRx9d2z5X05KKZDlF4rQk8KViZO4flKERY+5BiVdOh7zZ7JGJWo5P0uA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + svelte: ^3.37.0 || ^4.0.0 + peerDependenciesMeta: + svelte: + optional: true + dependencies: + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + postcss: 8.4.33 + postcss-scss: 4.0.9(postcss@8.4.33) + dev: true + /synckit@0.8.8: resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -1080,6 +3192,11 @@ packages: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -1087,6 +3204,13 @@ packages: is-number: 7.0.0 dev: true + /toml-eslint-parser@0.9.3: + resolution: {integrity: sha512-moYoCvkNUAPCxSW9jmHmRElhm4tVJpHL8ItC/+uYD0EpPSFXbck7yREz9tNdJVTSpHVod8+HoipcpbQ0oE6gsw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + eslint-visitor-keys: 3.4.3 + dev: true + /ts-api-utils@1.0.3(typescript@5.3.3): resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} engines: {node: '>=16.13.0'} @@ -1112,6 +3236,54 @@ packages: engines: {node: '>=10'} dev: true + /type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + + /typed-array-buffer@1.0.0: + resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-length@1.0.0: + resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-offset@1.0.0: + resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-length@1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.5 + for-each: 0.3.3 + is-typed-array: 1.1.12 + dev: true + /typescript-deno-plugin@1.31.0: resolution: {integrity: sha512-IoF5c8EubyNgjxxarguZfMx8Ph9Av9XqjySop0orepXv8wr02ND3DNNDFFdQyZfQAAcv1/v/u14MQIp8Os4c1w==} dependencies: @@ -1125,16 +3297,132 @@ packages: hasBin: true dev: true + /ufo@1.3.2: + resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} + dev: true + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.5 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /unconfig@0.3.11: + resolution: {integrity: sha512-bV/nqePAKv71v3HdVUn6UefbsDKQWRX+bJIkiSm0+twIds6WiD2bJLWWT3i214+J/B4edufZpG2w7Y63Vbwxow==} + dependencies: + '@antfu/utils': 0.7.7 + defu: 6.1.4 + jiti: 1.21.0 + mlly: 1.5.0 + dev: true + /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} dev: true + /unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + dependencies: + '@types/unist': 2.0.10 + dev: true + + /update-browserslist-db@1.0.13(browserslist@4.22.2): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.22.2 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.3.1 dev: true + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + + /vue-eslint-parser@9.4.0(eslint@8.56.0): + resolution: {integrity: sha512-7KsNBb6gHFA75BtneJsoK/dbZ281whUIwFYdQxA68QrCrGMXYzUMbPDHGcOQ0OocIVKrWSKWXZ4mL7tonCXoUw==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.4 + eslint: 8.56.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + lodash: 4.17.21 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-builtin-type@1.1.3: + resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} + engines: {node: '>= 0.4'} + dependencies: + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.0 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.0.2 + is-generator-function: 1.0.10 + is-regex: 1.1.4 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.1 + which-typed-array: 1.1.13 + dev: true + + /which-collection@1.0.1: + resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + dependencies: + is-map: 2.0.2 + is-set: 2.0.2 + is-weakmap: 2.0.1 + is-weakset: 2.0.2 + dev: true + + /which-typed-array@1.1.13: + resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -1143,14 +3431,70 @@ packages: isexe: 2.0.0 dev: true + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true + /xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true + /yaml-eslint-parser@1.2.2: + resolution: {integrity: sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==} + engines: {node: ^14.17.0 || >=16.0.0} + dependencies: + eslint-visitor-keys: 3.4.3 + lodash: 4.17.21 + yaml: 2.3.4 + dev: true + + /yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: true + + /yaml@2.3.4: + resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} + engines: {node: '>= 14'} + dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} diff --git a/src/depker.ts b/src/depker.ts index 68832d2..b1666c8 100644 --- a/src/depker.ts +++ b/src/depker.ts @@ -1,16 +1,14 @@ -import "https://deno.land/std@0.210.0/dotenv/load.ts"; import { fs, path } from "./deps.ts"; -import { Dax, dax } from "./services/dax/index.ts"; -import { DockerNode } from "./services/docker/index.ts"; +import { Dax, createDax } from "./services/dax/index.ts"; +import { DockerNode } from "./services/run/index.ts"; import { ProxyModule } from "./modules/proxy/proxy.module.ts"; import { ServiceModule } from "./modules/service/service.module.ts"; import { CliModule } from "./services/cli/index.ts"; -import { LogModule } from "./services/log/index.ts"; +import { CfgModule } from "./services/cfg/index.ts"; import { OpsModule } from "./services/ops/index.ts"; -import { UtiModule } from "./services/uti/index.ts"; import { EvsModule } from "./services/evs/index.ts"; -import { CfgModule } from "./services/cfg/index.ts"; -import { DepkerMaster, DepkerRunner } from "./services/docker/types.ts"; +import { LogModule } from "./services/log/index.ts"; +import { DepkerMaster, DepkerRunner } from "./services/run/types.ts"; export type DepkerCallback = T | ((depker: DepkerApp) => T); @@ -20,6 +18,10 @@ export interface DepkerModule { destroy?: () => Promise | void; } +declare global { + interface DepkerApp extends Depker {} +} + export function depker(): DepkerApp { return Depker.create(); } @@ -34,23 +36,14 @@ export class Depker { // runner private _master: DepkerMaster; private _runner: DepkerRunner; + private _modules: Array; // service public readonly dax: Dax; public readonly cli: CliModule; - public readonly log: LogModule; + public readonly cfg: CfgModule; public readonly ops: OpsModule; public readonly evs: EvsModule; - public readonly uti: UtiModule; - public readonly cfg: CfgModule; - // module - private readonly _modules: Array; - - public static create(): DepkerApp { - if (!Depker.instance) { - Depker.instance = new Depker() as DepkerApp; - } - return Depker.instance; - } + public readonly log: LogModule; private constructor() { // info @@ -58,13 +51,12 @@ export class Depker { this.version = "5.1.4"; this.description = "docker-based cloud deployment tool."; // service - this.dax = dax(); + this.dax = createDax(); this.cli = new CliModule(this); - this.log = new LogModule(this); + this.cfg = new CfgModule(this); this.ops = new OpsModule(this); this.evs = new EvsModule(this); - this.uti = new UtiModule(this); - this.cfg = new CfgModule(this); + this.log = new LogModule(this); // runner this._master = new DockerNode(this); this._runner = this._master; @@ -74,6 +66,13 @@ export class Depker { this._modules.push(new ServiceModule(this)); } + public static create(): DepkerApp { + if (!Depker.instance) { + Depker.instance = new Depker() as DepkerApp; + } + return Depker.instance; + } + public cwd(dir?: string): string { if (dir) { Deno.chdir(dir); @@ -151,7 +150,7 @@ export class Depker { } public module(name: string): M { - const module = this._modules.find((i) => i.name === name); + const module = this._modules.find(i => i.name === name); if (!module) { throw new Error(`Not found module ${name}`); } @@ -168,13 +167,13 @@ export class Depker { } public inject(name: string, builder: (depker: Depker) => any): DepkerApp { - // @ts-ignore + // @ts-expect-error this[name] = builder(this); return this as unknown as DepkerApp; } public dependency(name: string, builder: (depker: Depker) => DepkerModule): DepkerApp { - if (!this._modules.find((i) => i.name === name)) { + if (!this._modules.find(i => i.name === name)) { this.use(builder(this)); } return this as unknown as DepkerApp; @@ -203,13 +202,9 @@ export class Depker { // execute try { - await this.emit("depker:before-init", this); - await this._init_module(); - await this.emit("depker:after-init", this); + await this._init(); await this.cli.parse(Deno.args); - await this.emit("depker:before-destroy", this); - await this._destroy_module(); - await this.emit("depker:after-destroy", this); + await this._destroy(); } catch (e) { this.log.error(e); await this.emit("depker:exit", 1, this); @@ -217,6 +212,18 @@ export class Depker { } } + private async _init(): Promise { + await this.emit("depker:before-init", this); + await this._init_module(); + await this.emit("depker:after-init", this); + } + + private async _destroy(): Promise { + await this.emit("depker:before-destroy", this); + await this._destroy_module(); + await this.emit("depker:after-destroy", this); + } + private async _init_module(): Promise { await this.emit("depker:modules:before-init", this._modules); for (const module of this._modules) { @@ -237,8 +244,3 @@ export class Depker { await this.emit("depker:modules:after-destroy", this._modules); } } - -declare global { - // eslint-disable-next-line @typescript-eslint/no-empty-interface - interface DepkerApp extends Depker {} -} diff --git a/src/deps.ts b/src/deps.ts index 60552ca..6ecbb70 100644 --- a/src/deps.ts +++ b/src/deps.ts @@ -1,34 +1,34 @@ -import * as fs from "https://deno.land/std@0.210.0/fs/mod.ts"; -import * as path from "https://deno.land/std@0.210.0/path/mod.ts"; -import * as yaml from "https://deno.land/std@0.210.0/yaml/mod.ts"; +import * as fs from "https://deno.land/std@0.212.0/fs/mod.ts"; +import * as dax from "https://deno.land/x/dax@0.36.0/mod.ts"; +import * as path from "https://deno.land/std@0.212.0/path/mod.ts"; +import * as yaml from "https://deno.land/std@0.212.0/yaml/mod.ts"; +import * as date from "https://deno.land/x/ptera@v1.0.2/mod.ts"; +import * as ansi from "https://deno.land/x/cliffy@v0.25.7/ansi/mod.ts"; +import * as table from "https://deno.land/x/cliffy@v0.25.7/table/mod.ts"; +import * as event from "https://deno.land/x/event@2.0.1/mod.ts"; +import * as dotenv from "https://deno.land/std@0.212.0/dotenv/mod.ts"; +import * as prompt from "https://deno.land/x/cliffy@v0.25.7/prompt/mod.ts"; +import * as command from "https://deno.land/x/cliffy@v0.25.7/command/mod.ts"; +import * as collections from "https://deno.land/std@0.212.0/collections/mod.ts"; +import hash from "https://deno.land/x/object_hash@2.0.3.1/mod.ts"; import ignore from "https://esm.sh/v128/ignore@5.2.4/deno/ignore.mjs"; import nunjucks from "https://deno.land/x/nunjucks@3.2.4/mod.js"; -export { fs, path, yaml, ignore, nunjucks }; -export { osType } from "https://deno.land/std@0.210.0/path/_os.ts"; -export { colors } from "https://deno.land/x/cliffy@v0.25.7/ansi/mod.ts"; -export { datetime } from "https://deno.land/x/ptera@v1.0.2/mod.ts"; -export { load } from "https://deno.land/std@0.210.0/dotenv/mod.ts"; -export { deepMerge } from "https://deno.land/std@0.210.0/collections/mod.ts"; -export { Command, EnumType } from "https://deno.land/x/cliffy@v0.25.7/command/mod.ts"; -export { Table } from "https://deno.land/x/cliffy@v0.25.7/table/mod.ts"; -export { EventEmitter } from "https://deno.land/x/event@2.0.1/mod.ts"; -export { build$, CommandBuilder, RequestBuilder } from "https://deno.land/x/dax@0.36.0/mod.ts"; -export { isSubdir } from "https://deno.land/std@0.210.0/fs/_is_subdir.ts"; -export { toPathString } from "https://deno.land/std@0.210.0/fs/_to_path_string.ts"; -export { getFileInfoType } from "https://deno.land/std@0.210.0/fs/_get_file_info_type.ts"; -export type { $BuiltInProperties } from "https://deno.land/x/dax@0.36.0/mod.ts"; +export { fs, dax, path, yaml, hash, date, ansi, table, event, dotenv, prompt, command, ignore, nunjucks, collections }; +export { isSubdir } from "https://deno.land/std@0.212.0/fs/_is_subdir.ts"; +export { toPathString } from "https://deno.land/std@0.212.0/fs/_to_path_string.ts"; +export { getFileInfoType } from "https://deno.land/std@0.212.0/fs/_get_file_info_type.ts"; declare module "https://deno.land/x/dax@0.36.0/mod.ts" { - // @ts-ignore + // @ts-expect-error import { CommandBuilder as CB, RequestBuilder as RB } from "https://deno.land/x/dax@0.36.0/mod.ts"; - // @ts-ignore + // @ts-expect-error interface CommandBuilder extends CB { jsonl(): Promise; } - // @ts-ignore + // @ts-expect-error interface RequestBuilder extends RB { jsonl(): Promise; } diff --git a/src/modules/proxy/proxy.module.ts b/src/modules/proxy/proxy.module.ts index f85f4da..383e682 100644 --- a/src/modules/proxy/proxy.module.ts +++ b/src/modules/proxy/proxy.module.ts @@ -1,5 +1,5 @@ -import { Command } from "../../deps.ts"; import { Depker, DepkerModule } from "../../depker.ts"; +import { command } from "../../deps.ts"; import { defaults } from "./proxy.config.ts"; import { ProxyConfig } from "./proxy.type.ts"; @@ -14,8 +14,8 @@ export class ProxyModule implements DepkerModule { } public async init(): Promise { - const proxy = new Command().description("Manage proxy"); - const ports = new Command().description("Manage ports").alias("port").alias("po"); + const proxy = new command.Command().description("Manage proxy"); + const ports = new command.Command().description("Manage ports").alias("port").alias("po"); proxy .command("reload", "Reload or create a new proxy service") @@ -41,10 +41,8 @@ export class ProxyModule implements DepkerModule { this.depker.log.render(options.format, data); } else if (options.json) { this.depker.log.json(data); - } else if (options.yaml) { - this.depker.log.yaml(data); } else { - this.depker.log.json(data); + this.depker.log.yaml(data); } }); proxy @@ -79,10 +77,7 @@ export class ProxyModule implements DepkerModule { } else if (options.yaml) { this.depker.log.yaml(ports); } else { - this.depker.log.table( - ["Port"], - ports.map((p) => [String(p)]), - ); + this.depker.log.table(["Port"], ports.map(p => [String(p)])); } } catch (e) { this.depker.log.error(`Listing ports failed.`, e); @@ -128,10 +123,10 @@ export class ProxyModule implements DepkerModule { if (!operate || !diffs?.length) { return config.ports; } - if (operate === "insert" && !diffs.find((p) => !config.ports.includes(p))) { + if (operate === "insert" && !diffs.find(p => !config.ports.includes(p))) { return config.ports; } - if (operate === "remove" && !diffs.find((p) => config.ports.includes(p))) { + if (operate === "remove" && !diffs.find(p => config.ports.includes(p))) { return config.ports; } if (operate === "insert") { @@ -148,7 +143,6 @@ export class ProxyModule implements DepkerModule { } config.ports = [...ports]; } - // prettier-ignore this.depker.log.debug(`The current port status does not match the requirements and is in the process of reloading proxy. current=${config.ports}, required=${diffs}`); await this.reload(config); return config.ports; @@ -194,15 +188,22 @@ export class ProxyModule implements DepkerModule { Restart: "always", Envs: config.envs, Labels: config.labels, - Commands: [...options], - Networks: [await this.depker.ops.network.default()], - Volumes: [`/var/depker/proxy:/etc/traefik`, `/var/run/docker.sock:/var/run/docker.sock`], + Commands: [ + ...options, + ], + Networks: [ + await this.depker.ops.network.default(), + ], + Volumes: [ + `/var/depker/proxy:/etc/traefik`, + `/var/run/docker.sock:/var/run/docker.sock`, + ], Ports: [ `80:80/tcp`, `443:443/tcp`, `443:443/udp`, - ...config.ports.map((i) => `${i}:${i}/tcp`), - ...config.ports.map((i) => `${i}:${i}/udp`), + ...config.ports.map(i => `${i}:${i}/tcp`), + ...config.ports.map(i => `${i}:${i}/udp`), ], }); diff --git a/src/modules/service/pack.context.ts b/src/modules/service/pack.context.ts index fa071c4..6779bfd 100644 --- a/src/modules/service/pack.context.ts +++ b/src/modules/service/pack.context.ts @@ -1,175 +1,119 @@ import { Depker } from "../../depker.ts"; -import { deepMerge, fs, ignore, load, nunjucks, osType, path, yaml } from "../../deps.ts"; -import { BuildAtConfig, DeployAtConfig, Pack, ServiceConfig, StartAtConfig } from "./service.type.ts"; -import { BuilderBuildOptions, ContainerCreateOptions } from "../../services/docker/types.ts"; +import { + collections, + dotenv, + fs, + getFileInfoType, + ignore, + isSubdir, + nunjucks, + path, + toPathString, + yaml, +} from "../../deps.ts"; +import { BuilderBuildOptions, ContainerCreateOptions } from "../../services/run/types.ts"; import { ServiceModule } from "./service.module.ts"; +import { Pack, ServiceConfig } from "./service.type.ts"; -interface PackOptions { +interface PackOptions { depker: Depker; - config: ServiceConfig; - pack: Pack; + config: Config; source: string; target: string; } -export const sym = Symbol("pack"); +interface CopyOptions { + filter?: (path: string) => boolean; + folder?: boolean; +} export function pack(pack: Pack) { return (config: C) => { - // @ts-ignore - config[sym] = pack; + // @ts-expect-error + config.$$pack = pack; return config; }; } export class PackContext { - // constants - public static readonly OS_TYPE = osType; - // defined public readonly depker: Depker; public readonly config: Config; // generated + public readonly id: string; public readonly pack: Pack; public readonly source: string; public readonly target: string; - private constructor(options: PackOptions) { + public static create(depker: Depker, input: ServiceConfig) { + const config = collections.deepMerge({}, input); + const source = path.resolve(config.path ?? Deno.cwd()); + const target = Deno.makeTempDirSync({ prefix: `deploy-${config.name}-` }); + return new PackContext({ depker, config, source, target }); + } + + private constructor(options: PackOptions) { + this.id = String(Date.now()); + this.pack = options.config.$$pack; this.depker = options.depker; - this.config = options.config as Config; - this.pack = options.pack; + this.config = options.config; this.source = options.source; this.target = options.target; } - // region public operators - - public static async execute(depker: Depker, input: ServiceConfig): Promise { - const config = deepMerge({}, input); - const source = path.resolve(config.path ?? Deno.cwd()); - const target = Deno.makeTempDirSync({ prefix: `deploy-${config.name}-` }); - - // unpack - await depker.emit("service:deploy:before-unpack", config, source, target); - depker.log.info(`Unpacking service ${config.name} started.`); - const ig = ignore() as any; - const gi = path.join(source, ".gitignore"); - const di = path.join(source, ".depkerignore"); - if (await fs.exists(gi)) { - ig.add(await Deno.readTextFile(gi)); - } - if (await fs.exists(di)) { - ig.add(await Deno.readTextFile(di)); - } - await depker.uti.copy(source, target, { - overwrite: true, - filter: (p) => { - const r = path.relative(source, p); - return !r || !ig.ignores(r); - }, - }); - const envs = await load({ examplePath: undefined }); - if (Object.keys(envs).length) { - config.secrets = { ...config.secrets, ...envs }; - } - if (config.volumes) { - for (const value of config.volumes) { - value.hpath = depker.uti.replace(value.hpath, (key) => { - return depker.cfg.path(key); - }); - } - } - if (config.labels || config.secrets || config.build_args) { - const secrets = await depker.cfg.secret(); - if (config.labels) { - for (const [name, value] of Object.entries(config.labels)) { - config.labels[name] = depker.uti.replace(value, (key) => { - return secrets[key]; - }); - } - } - if (config.secrets) { - for (const [name, value] of Object.entries(config.secrets)) { - config.secrets[name] = depker.uti.replace(value, (key) => { - if (secrets[key] !== undefined && secrets[key] !== null) { - return String(secrets[key]); - } else { - return key; - } - }); - } - } - if (config.build_args) { - for (const [name, value] of Object.entries(config.build_args)) { - config.build_args[name] = depker.uti.replace(value, (key) => { - if (secrets[key] !== undefined && secrets[key] !== null) { - return String(secrets[key]); - } else { - return key; - } - }); - } - } - } - await depker.emit("service:deploy:after-unpack", config, source, target); - depker.log.done(`Unpacking service ${config.name} successfully.`); - - // create context - const context = new PackContext({ - depker: depker, - source: source, - target: target, - config: config, - pack: config[sym] as Pack, - }); - + public async execute() { try { + // unpack + this.depker.log.info(`Unpacking service ${this.config.name} started.`); + await this._copy(this.source, this.target); + this.depker.log.done(`Unpacking service ${this.config.name} successfully.`); + // log started - await depker.emit("service:deploy:started", context); - depker.log.step(`Deployment service ${config.name} started.`); + await this.depker.emit("service:deploy:started", this); + this.depker.log.step(`Deployment service ${this.config.name} started.`); // emit init event - await depker.emit("service:deploy:before-init", context); - depker.log.debug(`Deployment service ${config.name} initing.`); - await context.pack.init?.(context); - await depker.emit("service:deploy:after-init", context); + await this.depker.emit("service:deploy:before-init", this); + this.depker.log.debug(`Deployment service ${this.config.name} initing.`); + await this.pack.init?.(this); + await this.depker.emit("service:deploy:after-init", this); // deployment containers - await depker.emit("service:deploy:before-build", context); - depker.log.debug(`Deployment service ${config.name} building.`); - await context.pack.build?.(context); - await depker.emit("service:deploy:after-build", context); + await this.depker.emit("service:deploy:before-build", this); + this.depker.log.debug(`Deployment service ${this.config.name} building.`); + await this.pack.build?.(this); + await this.depker.emit("service:deploy:after-build", this); // purge images and volumes - await depker.emit("service:deploy:before-purge", context); - depker.log.debug(`Deployment service ${config.name} purging.`); - await Promise.all([depker.ops.image.prune(), depker.ops.volume.prune(), depker.ops.network.prune()]); - await depker.emit("service:deploy:after-purge", context); + await this.depker.emit("service:deploy:before-purge", this); + this.depker.log.debug(`Deployment service ${this.config.name} purging.`); + await Promise.all([ + this.depker.ops.image.prune(), + this.depker.ops.volume.prune(), + this.depker.ops.network.prune(), + ]); + await this.depker.emit("service:deploy:after-purge", this); // emit destroy event - await depker.emit("service:deploy:before-destroy", context); - depker.log.debug(`Deployment service ${config.name} destroying.`); - await context.pack.destroy?.(context); - await depker.emit("service:deploy:after-destroy", context); + await this.depker.emit("service:deploy:before-destroy", this); + this.depker.log.debug(`Deployment service ${this.config.name} destroying.`); + await this.pack.destroy?.(this); + await this.depker.emit("service:deploy:after-destroy", this); // log successfully - await depker.emit("service:deploy:successfully", context); - depker.log.done(`Deployment service ${config.name} successfully.`); + await this.depker.emit("service:deploy:successfully", this); + this.depker.log.done(`Deployment service ${this.config.name} successfully.`); } catch (e) { // log failed - await depker.emit("service:deploy:failure", context); - depker.log.error(`Deployment service ${config.name} failure.`, e); - throw new Error(`Deployment service ${config.name} failure.`, { cause: e }); + await this.depker.emit("service:deploy:failure", this); + this.depker.log.error(`Deployment service ${this.config.name} failure.`, e); + throw new Error(`Deployment service ${this.config.name} failure.`, { cause: e }); } } - // endregion - - // region public functions - public dockerfile(data: string) { - this.overwrite("Dockerfile", data); + this.overwrite("Dockerfile", data.trim()); } public exists(file: string) { @@ -197,7 +141,7 @@ export class PackContext { public async render(value: string, context?: Record) { // template - // eslint-disable-next-line @typescript-eslint/no-this-alias + // eslint-disable-next-line ts/no-this-alias const self = this; const loader = new nunjucks.FileSystemLoader(path.resolve(this.target)); const template = new nunjucks.Environment(loader, { autoescape: false, noCache: true }); @@ -212,24 +156,24 @@ export class PackContext { template.addGlobal("source", this.source); template.addGlobal("target", this.target); // filters - template.addFilter("command", function (this: any, value: string | string[]) { + template.addFilter("command", (value: string | string[]) => { return typeof value === "string" ? value : JSON.stringify(value); }); - template.addFilter("render", function (this: any, value: string) { - return value ? this.env.renderString(value, this.ctx) : ""; - }); - template.addFilter("exists", function (this: any, file: string) { + template.addFilter("exists", (file: string) => { return self.exists(file); }); - template.addFilter("read", function (this: any, file: string) { + template.addFilter("read", (file: string) => { return self.read(file); }); - template.addFilter("write", function (this: any, value: string, file: string) { + template.addFilter("write", (value: string, file: string) => { return self.write(file, value); }); - template.addFilter("overwrite", function (this: any, value: string, file: string) { + template.addFilter("overwrite", (value: string, file: string) => { return self.overwrite(file, value); }); + template.addFilter("render", function (this: any, value: string) { + return value ? this.env.renderString(value, this.ctx) : ""; + }); template.addFilter("render_write", function (this: any, value: string, file: string) { if (self.exists(file)) { const content = this.env.renderString(self.read(file), this.ctx); @@ -246,50 +190,42 @@ export class PackContext { return template.renderString(value, context ?? {}); } - public async deploy() { - return await this.deployAt(this.target, this.config); - } - - public async deployAt(target: string, config: DeployAtConfig) { - return await this.startAt(await this.buildAt(target, config), config); - } + public async build(apply?: (config: Config) => Promise | Config): Promise { + // config + const config: Config = apply ? await apply(this.config) : this.config; - public async buildAt(target: string, config: BuildAtConfig): Promise { - const image = `depker/${config.name}:${Date.now()}`; + // values + const image = `depker/${config.name}:${this.id}`; // create options const options: BuilderBuildOptions = { File: config.file, Pull: config.pull, Cache: config.cache, - Args: config.build_args, Hosts: config.hosts, - Labels: config.labels, - Secrets: {}, }; - // write secrets - if (config.secrets && options.Secrets) { - // prettier-ignore - const values = Object.entries(config.secrets).map(([k, v]) => `${k}=${v}\n`); - if (values.length) { - const file1 = await Deno.makeTempFile(); - await Deno.writeTextFile(file1, values.join("")); - const file2 = await Deno.makeTempFile(); - await Deno.writeTextFile(file2, values.map((i) => `export ${i}`).join("")); - options.Secrets.secrets = file1; - options.Secrets.envs = file2; + if (config.build_args || config.secrets || config.labels) { + const dotenvs = await dotenv.load({ examplePath: undefined, defaultsPath: undefined }); + const secrets = await this.depker.cfg.secret(); + if (config.build_args) { + for (const [key, val] of Object.entries(config.build_args)) { + options.Args = options.Args ?? {}; + options.Args[key] = this._placeholder(val, name => dotenvs[name] ?? secrets[name]); + } + } + if (config.secrets) { + for (const [key, val] of Object.entries(config.secrets)) { + options.Envs = options.Envs ?? {}; + options.Envs[key] = this._placeholder(val, name => dotenvs[name] ?? secrets[name]); + } + } + if (config.labels) { + for (const [key, val] of Object.entries(config.labels)) { + options.Labels = options.Labels ?? {}; + options.Labels[key] = this._placeholder(val, name => dotenvs[name] ?? secrets[name]); + } } - } - if (!options.Secrets?.secrets && options.Secrets) { - const file = await Deno.makeTempFile(); - await Deno.writeTextFile(file, "\n"); - options.Secrets.secrets = file; - } - if (!options.Secrets?.envs && options.Secrets) { - const file = await Deno.makeTempFile(); - await Deno.writeTextFile(file, "\n"); - options.Secrets.envs = file; } try { @@ -298,7 +234,7 @@ export class PackContext { // build image await this.depker.ops.builder - .build(image, target, options) + .build(image, this.target, options) .stdin("inherit") .stdout("inherit") .stderr("inherit") @@ -312,15 +248,14 @@ export class PackContext { throw new Error(`Building image ${image} failed.`); } - // prettier-ignore try { // log started this.depker.log.step(`Transferring image ${image} started.`); // transfer image const size = { value: 0 }; - const interval = setInterval(() => this.depker.log.raw(`Transferring: ${this.depker.uti.bytes(size.value)}`), 2000); - await this.depker.ops.transfer(image, (v) => (size.value = v ?? size.value)); + const interval = setInterval(() => this.depker.log.raw(`Transferring: ${this.depker.log.byte(size.value)}`), 2000); + await this.depker.ops.transfer(image, v => (size.value = v ?? size.value)); clearInterval(interval); // log successfully @@ -330,31 +265,29 @@ export class PackContext { this.depker.log.error(`Transferring image ${image} failed.`); throw new Error(`Transferring image ${image} failed.`); } - - return image; } - public async startAt(target: string, config: StartAtConfig): Promise { + public async start(apply?: (config: Config) => Promise | Config): Promise { + // config + const config: Config = apply ? await apply(this.config) : this.config; + // values - const id = `${Date.now()}`; - const name = `${config.name}`; - const full = `${name}-i${id}`; + const name = `${config.name}-i${this.id}`; + const image = config.$$image ? config.$$image : `depker/${config.name}:${this.id}`; const network = await this.depker.ops.network.default(); // started - this.depker.log.step(`Start container ${full} started.`); + this.depker.log.step(`Start container ${name} started.`); // config const envs: Record = { - ...config.secrets, - DEPKER_ID: id, - DEPKER_NAME: name, + DEPKER_ID: this.id, + DEPKER_NAME: config.name, DEPKER_VERSION: this.depker.version, }; const labels: Record = { - ...config.labels, - "depker.id": id, - "depker.name": name, + "depker.id": this.id, + "depker.name": config.name, "depker.version": this.depker.version, "traefik.enable": "true", "traefik.docker.network": network, @@ -403,9 +336,8 @@ export class PackContext { }; // web - // prettier-ignore if (config.rule || config.domain?.length) { - const rule = (config.rule || [config.domain]?.flat()?.map((d) => `Host(\`${d}\`)`).join(" || ")); + const rule = (config.rule || [config.domain]?.flat()?.map(d => `Host(\`${d}\`)`).join(" || ")); const port = config.port ?? 80; const scheme = config.scheme ?? "http"; const middlewares: string[] = []; @@ -444,7 +376,6 @@ export class PackContext { } // ports - // prettier-ignore for (const port of config.ports ?? []) { const proto = port.proto; const hport = port.hport; @@ -457,23 +388,44 @@ export class PackContext { labels[`traefik.${proto}.services.${name}-${proto}-${cport}.loadbalancer.server.port`] = String(cport); } + // secrets + if (config.secrets || config.labels) { + const dotenvs = await dotenv.load({ examplePath: undefined, defaultsPath: undefined }); + const secrets = await this.depker.cfg.secret(); + if (config.secrets) { + for (const [key, val] of Object.entries(config.secrets)) { + options.Envs = options.Envs ?? {}; + options.Envs[key] = this._placeholder(val, name => dotenvs[name] ?? secrets[name]); + } + } + if (config.labels) { + for (const [key, val] of Object.entries(config.labels)) { + options.Labels = options.Labels ?? {}; + options.Labels[key] = this._placeholder(val, name => dotenvs[name] ?? secrets[name]); + } + } + } + // volumes for (const volume of config.volumes ?? []) { + const hpath = this._placeholder(volume.hpath, key => this.depker.cfg.path(key)); + const cpath = volume.cpath; + const readonly = volume.readonly ? "ro" : "rw"; options.Volumes = options.Volumes ?? []; - options.Volumes.push(`${volume.hpath}:${volume.cpath}:${volume.readonly ? "ro" : "rw"}`); + options.Volumes.push(`${hpath}:${cpath}:${readonly ? "ro" : "rw"}`); } try { // creating - await this.depker.ops.container.create(full, target, options); + await this.depker.ops.container.create(name, image, options); // starting - await this.depker.ops.container.start([full]); + await this.depker.ops.container.start([name]); // wait healthcheck, max timeout 1h - this.depker.log.info(`Waiting container ${full} to finished.`); + this.depker.log.info(`Waiting container ${name} to finished.`); for (let i = 1; i <= 1200; i++) { - await new Promise((resolve) => setTimeout(resolve, 2000)); - const infos = await this.depker.ops.container.inspect([full]); + await new Promise(resolve => setTimeout(resolve, 2000)); + const infos = await this.depker.ops.container.inspect([name]); if (infos) { const status = infos[0].State.Status.toLowerCase(); const health = infos[0].State.Health?.Status?.toLowerCase(); @@ -481,7 +433,7 @@ export class PackContext { if (status === "running" && (!health || health === "healthy")) { break; } else { - throw new Error(`Start container ${full} is unhealthy.`); + throw new Error(`Start container ${name} is unhealthy.`); } } } @@ -490,17 +442,126 @@ export class PackContext { } } - this.depker.log.done(`Start container ${full} successfully.`); - return full; + this.depker.log.done(`Start container ${name} successfully.`); } catch (e) { // failure - this.depker.log.error(`Start container ${full} failure.`, e); - throw new Error(`Start container ${full} failure.`, { cause: e }); + this.depker.log.error(`Start container ${name} failure.`, e); + throw new Error(`Start container ${name} failure.`, { cause: e }); } finally { // cleanup await this.depker.module(ServiceModule.NAME)?.prune("pre"); } } - // endregion + public async deploy(apply?: (config: Config) => Promise | Config): Promise { + await this.build(apply); + await this.start(apply); + } + + private _placeholder(value: string, replacer: (name: string) => string | boolean | number | null | undefined) { + return value.replace(/(?<=^|[^@])(?:@([a-zA-Z][a-zA-Z0-9_]*)|@\{([a-zA-Z][a-zA-Z0-9]*)})/g, (a, n) => { + const r = replacer(n); + return r === null || r === undefined ? a : String(r); + }); + } + + private async _copy(source: string, target: string) { + const _source = path.resolve(toPathString(source)); + const _target = path.resolve(toPathString(target)); + + if (_source === _target) { + throw new Error("Source and destination cannot be the same."); + } + + const info = await Deno.lstat(_source); + if (info.isDirectory && isSubdir(_source, _target)) { + throw new Error(`Cannot copy '${_source}' to a subdirectory of itself, '${_target}'.`); + } + + const ig = ignore() as any; + const gi = path.join(_source, ".gitignore"); + const di = path.join(_source, ".depkerignore"); + if (await fs.exists(gi)) { + ig.add(await Deno.readTextFile(gi)); + } + if (await fs.exists(di)) { + ig.add(await Deno.readTextFile(di)); + } + + const _options: CopyOptions = { + filter: (p) => { + const r = path.relative(source, p); + return !r || !ig.ignores(r); + }, + }; + + if (info.isSymlink) { + await this._copyLink(_source, _target, _options); + } else if (info.isDirectory) { + await this._copyDir(_source, _target, _options); + } else if (info.isFile) { + await this._copyFile(_source, _target, _options); + } + } + + private async _validCopy(source: string, target: string, options?: CopyOptions) { + let info: Deno.FileInfo | undefined; + try { + info = await Deno.lstat(target); + } catch (err) { + if (err instanceof Deno.errors.NotFound) { + return; + } + throw err; + } + if (options?.folder && !info.isDirectory) { + throw new Error(`Cannot overwrite non-directory '${source}' with directory '${target}'.`); + } + } + + private async _copyLink(source: string, target: string, options?: CopyOptions) { + if (options?.filter && !options.filter(source)) { + return; + } + await this._validCopy(source, target, options); + const origin = await Deno.readLink(source); + const type = getFileInfoType(await Deno.lstat(source)); + if (Deno.build.os === "windows") { + await Deno.symlink(origin, target, { type: type === "dir" ? "dir" : "file" }); + } else { + await Deno.symlink(origin, target); + } + } + + private async _copyDir(source: string, target: string, options?: CopyOptions) { + if (options?.filter && !options.filter(source)) { + return; + } + + await this._validCopy(source, target, { ...options, folder: true }); + await fs.ensureDir(target); + + source = toPathString(source); + target = toPathString(target); + + for await (const entry of Deno.readDir(source)) { + const sourcePath = path.join(source, entry.name); + const targetPath = path.join(target, path.basename(sourcePath)); + if (entry.isSymlink) { + await this._copyLink(sourcePath, targetPath, options); + } else if (entry.isDirectory) { + await this._copyDir(sourcePath, targetPath, options); + } else if (entry.isFile) { + await this._copyFile(sourcePath, targetPath, options); + } + } + } + + private async _copyFile(source: string, target: string, options?: CopyOptions) { + if (options?.filter && !options.filter(source)) { + return; + } + await this._validCopy(source, target, options); + await Deno.copyFile(source, target); + } } diff --git a/src/modules/service/packs/coline/coline.pack.ts b/src/modules/service/packs/coline/coline.pack.ts new file mode 100644 index 0000000..89f0bea --- /dev/null +++ b/src/modules/service/packs/coline/coline.pack.ts @@ -0,0 +1,27 @@ +import { ServiceConfig } from "../../service.type.ts"; +import { pack } from "../../pack.context.ts"; +import { dockerfile } from "./coline.template.ts"; + +export interface ColineConfig extends ServiceConfig { + coline?: { + version?: string; + memory?: string; + install?: string | string[]; + build?: string | string[]; + start?: string | string[]; + inject?: { + before_install?: string; + after_install?: string; + before_build?: string; + after_build?: string; + dockerfile?: string; + }; + }; +} + +export const coline = pack({ + build: async (ctx) => { + ctx.dockerfile(await ctx.render(dockerfile)); + await ctx.deploy(); + }, +}); diff --git a/src/modules/service/packs/coline/coline.template.ts b/src/modules/service/packs/coline/coline.template.ts new file mode 100644 index 0000000..ce38aae --- /dev/null +++ b/src/modules/service/packs/coline/coline.template.ts @@ -0,0 +1,69 @@ +export const dockerfile = ` +# syntax=docker/dockerfile:1 +# from nodejs +FROM gplane/pnpm:{{ config.coline.version | d("alpine") }} AS builder + +# workdir +WORKDIR /app + +# set max old space size +ENV NODE_OPTIONS="--max_old_space_size={{ config.coline.memory | d("4096") }}" + +# clone project +ADD https://github.com/syfxlin/next-theme-coline.git#master /app + +# inject before install +{{ config.coline.inject.before_install | render }} + +# install node modules +{% if config.coline.install %} + RUN {{ config.coline.install | command }} +{% else %} + RUN --mount=type=cache,target=/root/.local/share/pnpm/store \ + apk add --no-cache --virtual .gyp python3 make g++ && \ + pnpm install --frozen-lockfile && \ + apk del .gyp +{% endif %} + +# copy project +RUN rm -rf /app/public +COPY . . + +# inject after install +{{ config.coline.inject.after_install | render }} + +# inject before build +{{ config.coline.inject.before_build | render }} + +# build nodejs +{% if config.coline.build %} + RUN {{ config.coline.build | command }} +{% else %} + RUN --mount=type=cache,target=/app/.next/cache --mount=type=secret,id==depker-envs,dst=/app/.env pnpm run build +{% endif %} + +# inject after build +{{ config.coline.inject.after_build | render }} + +# from nodejs +FROM gplane/pnpm:{{ config.coline.version | d("alpine") }} + +# workdir +WORKDIR /app + +# copy project +COPY --from=builder /app/.next/standalone /app +COPY --from=builder /app/.next/static /app/.next/static +COPY --from=builder /app/public /app/public + +# inject +{{ config.coline.inject.dockerfile | render }} + +# start coline +EXPOSE 80 +ENV PORT=80 +ENV HOSTNAME=0.0.0.0 +ENV NODE_ENV production +HEALTHCHECK CMD nc -vz -w1 127.0.0.1 80 +CMD ["node", "server.js"] +`; diff --git a/src/modules/service/packs/dockerfile/dockerfile.pack.ts b/src/modules/service/packs/dockerfile/dockerfile.pack.ts index 364276c..606dac4 100644 --- a/src/modules/service/packs/dockerfile/dockerfile.pack.ts +++ b/src/modules/service/packs/dockerfile/dockerfile.pack.ts @@ -1,6 +1,5 @@ import { ServiceConfig } from "../../service.type.ts"; import { pack } from "../../pack.context.ts"; -import { path } from "../../../../deps.ts"; export interface DockerfileConfig extends ServiceConfig { dockerfile?: string; @@ -11,13 +10,11 @@ export const dockerfile = pack({ build: async (ctx) => { const config = ctx.config; if (config.dockerfile) { - const target = await Deno.makeTempDir(); - await Deno.writeTextFile(path.join(target, `Dockerfile`), config.dockerfile); - await ctx.startAt(await ctx.buildAt(target, config), config); + ctx.dockerfile(config.dockerfile); + await ctx.deploy(); } else if (config.dockerfile_path) { - const target = await Deno.makeTempDir(); - await Deno.copyFile(path.resolve(config.dockerfile_path), path.join(target, `Dockerfile`)); - await ctx.startAt(await ctx.buildAt(target, config), config); + ctx.dockerfile(Deno.readTextFileSync(config.dockerfile_path)); + await ctx.deploy(); } else { throw new Error(`Dockerfile content or Dockerfile path must be set.`); } diff --git a/src/modules/service/packs/image/image.pack.ts b/src/modules/service/packs/image/image.pack.ts index abc879d..feca1d0 100644 --- a/src/modules/service/packs/image/image.pack.ts +++ b/src/modules/service/packs/image/image.pack.ts @@ -7,7 +7,7 @@ export interface ImageConfig extends ServiceConfig { export const image = pack({ build: async (ctx) => { - const config = ctx.config; - await ctx.startAt(config.image, config); + ctx.config.$$image = ctx.config.image; + await ctx.start(); }, }); diff --git a/src/modules/service/packs/nextjs/nextjs.template.ts b/src/modules/service/packs/nextjs/nextjs.template.ts index 734fc86..d0d0792 100644 --- a/src/modules/service/packs/nextjs/nextjs.template.ts +++ b/src/modules/service/packs/nextjs/nextjs.template.ts @@ -1,6 +1,6 @@ export const dockerfile = ` # from nodejs -FROM gplane/pnpm:{{ config.nextjs.version | d("alpine") }} as builder +FROM gplane/pnpm:{{ config.nextjs.version | d("alpine") }} AS builder # workdir WORKDIR /app @@ -21,8 +21,8 @@ ENV NODE_OPTIONS="--max_old_space_size={{ config.nextjs.memory | d("4096") }}" {{ config.nextjs.inject.before_install | render }} # install node modules -{% if config.nodejs.install %} - RUN {{ config.nodejs.install | command }} +{% if config.nextjs.install %} + RUN {{ config.nextjs.install | command }} {% elif self.exists("pnpm-lock.yaml") %} RUN --mount=type=cache,target=/root/.local/share/pnpm/store \ apk add --no-cache --virtual .gyp python3 make g++ && \ @@ -58,11 +58,11 @@ COPY . . {% if config.nextjs.build %} RUN {{ config.nextjs.build | command }} {% elif self.exists("pnpm-lock.yaml") %} - RUN --mount=type=cache,target=/app/.next/cache --mount=type=secret,id=secrets,dst=/app/.env pnpm run build + RUN --mount=type=cache,target=/app/.next/cache --mount=type=secret,id==depker-envs,dst=/app/.env pnpm run build {% elif self.exists("yarn.lock") %} - RUN --mount=type=cache,target=/app/.next/cache --mount=type=secret,id=secrets,dst=/app/.env yarn run build + RUN --mount=type=cache,target=/app/.next/cache --mount=type=secret,id==depker-envs,dst=/app/.env yarn run build {% elif self.exists("package.json") %} - RUN --mount=type=cache,target=/app/.next/cache --mount=type=secret,id=secrets,dst=/app/.env npm run build + RUN --mount=type=cache,target=/app/.next/cache --mount=type=secret,id==depker-envs,dst=/app/.env npm run build {% endif %} # inject after build @@ -86,6 +86,7 @@ COPY --from=builder /app/public /app/public EXPOSE 80 ENV PORT=80 ENV HOSTNAME=0.0.0.0 +ENV NODE_ENV production HEALTHCHECK CMD nc -vz -w1 127.0.0.1 80 CMD ["node", "server.js"] `; diff --git a/src/modules/service/packs/nodejs/nodejs.template.ts b/src/modules/service/packs/nodejs/nodejs.template.ts index 26ec4d3..0be20ab 100644 --- a/src/modules/service/packs/nodejs/nodejs.template.ts +++ b/src/modules/service/packs/nodejs/nodejs.template.ts @@ -2,7 +2,7 @@ import { dockerfile as dockerfile_nginx } from "../nginx/nginx.template.ts"; export const dockerfile_common = ` # from nodejs -FROM gplane/pnpm:{{ config.nodejs.version | d("alpine") }} as builder +FROM gplane/pnpm:{{ config.nodejs.version | d("alpine") }} AS builder # workdir WORKDIR /app diff --git a/src/modules/service/service.module.ts b/src/modules/service/service.module.ts index ce1638a..e7054be 100644 --- a/src/modules/service/service.module.ts +++ b/src/modules/service/service.module.ts @@ -9,13 +9,12 @@ import { ContainerStatsOptions, ContainerStopOptions, ContainerTopOptions, -} from "../../services/docker/types.ts"; +} from "../../services/run/types.ts"; +import { command } from "../../deps.ts"; import { Depker, DepkerModule } from "../../depker.ts"; -import { Command, EnumType } from "../../deps.ts"; +import { ProxyModule } from "../proxy/proxy.module.ts"; import { PackContext } from "./pack.context.ts"; import { ServiceConfig } from "./service.type.ts"; -import { ProxyModule } from "../proxy/proxy.module.ts"; -import { ArgumentValue } from "https://deno.land/x/cliffy@v0.25.7/flags/types.ts"; declare global { interface DepkerApp { @@ -29,28 +28,28 @@ type ActiveSelect = "active" | "latest" | string; type AllSelect = "active" | "latest" | "inactive" | "all" | string; -class PruneSelectType extends EnumType { +class PruneSelectType extends command.EnumType { constructor() { super(["all", "pre"]); } } -class ActiveSelectType extends EnumType { +class ActiveSelectType extends command.EnumType { constructor() { super(["active", "latest", ""]); } - public parse(type: ArgumentValue): "active" | "latest" | string { + public parse(type: command.ArgumentValue): "active" | "latest" | string { return type.value; } } -class AllSelectType extends EnumType { +class AllSelectType extends command.EnumType { constructor() { super(["active", "latest", "inactive", "all", ""]); } - public parse(type: ArgumentValue): "active" | "latest" | "inactive" | "all" | string { + public parse(type: command.ArgumentValue): "active" | "latest" | "inactive" | "all" | string { return type.value; } } @@ -72,7 +71,7 @@ export class ServiceModule implements DepkerModule { } public async init() { - const service = new Command().description("Manage services").alias("service").alias("svc").default("list"); + const service = new command.Command().description("Manage services").alias("service").alias("svc").default("list"); this._deploy(service); this._list(service); this._inspect(service); @@ -153,7 +152,7 @@ export class ServiceModule implements DepkerModule { } else { const outputs: Array = []; for (const item of inputs) { - if (select === item.Id || select === item.Name || select === this.depker.uti.short(item.Id)) { + if (select === item.Id || select === item.Name || (select.length > 7 && item.Id.startsWith(select))) { outputs.push(item); break; } @@ -166,24 +165,24 @@ export class ServiceModule implements DepkerModule { if (configs.length) { for (const config of configs) { if (typeof config === "string") { - const service = this.services.find((s) => s.name === config); + const service = this.services.find(s => s.name === config); if (service) { - await PackContext.execute(this.depker, service); + await PackContext.create(this.depker, service).execute(); } } else if (config) { - await PackContext.execute(this.depker, config); + await PackContext.create(this.depker, config).execute(); } } } else { for (const service of this.services) { - await PackContext.execute(this.depker, service); + await PackContext.create(this.depker, service).execute(); } } } public async list(names: string[] = [], select?: AllSelect): Promise>> { const infos = await this.depker.ops.container.list(); - const insps = await this.depker.ops.container.inspect(infos.map((i) => i.Id)); + const insps = await this.depker.ops.container.inspect(infos.map(i => i.Id)); const services: Record> = {}; for (const insp of insps) { const exec = /^([a-zA-Z0-9][a-zA-Z0-9_.-]*)-i(\d+)$/.exec(insp.Name); @@ -207,7 +206,7 @@ export class ServiceModule implements DepkerModule { public async start(names: string[], select?: AllSelect, options?: ContainerStartOptions): Promise { const ids: string[] = []; for (const infos of Object.values(await this.list(names, select))) { - ids.push(...infos.map((i) => i.Id)); + ids.push(...infos.map(i => i.Id)); } if (ids.length) { await this.depker.ops.container.start(ids, options); @@ -217,7 +216,7 @@ export class ServiceModule implements DepkerModule { public async stop(names: string[], select?: AllSelect, options?: ContainerStopOptions): Promise { const ids: string[] = []; for (const infos of Object.values(await this.list(names, select))) { - ids.push(...infos.map((i) => i.Id)); + ids.push(...infos.map(i => i.Id)); } if (ids.length) { await this.depker.ops.container.stop(ids, options); @@ -227,7 +226,7 @@ export class ServiceModule implements DepkerModule { public async kill(names: string[], select?: AllSelect, options?: ContainerKillOptions): Promise { const ids: string[] = []; for (const infos of Object.values(await this.list(names, select))) { - ids.push(...infos.map((i) => i.Id)); + ids.push(...infos.map(i => i.Id)); } if (ids.length) { await this.depker.ops.container.kill(ids, options); @@ -237,7 +236,7 @@ export class ServiceModule implements DepkerModule { public async remove(names: string[], select?: AllSelect, options?: ContainerRemoveOptions): Promise { const ids: string[] = []; for (const infos of Object.values(await this.list(names, select))) { - ids.push(...infos.map((i) => i.Id)); + ids.push(...infos.map(i => i.Id)); } if (ids.length) { await this.depker.ops.container.remove(ids, options); @@ -261,14 +260,13 @@ export class ServiceModule implements DepkerModule { const sources = source.split(":"); const targets = target.split(":"); if (sources.length > 1) { - const inspect = await this.list([sources[0]], select ?? "active").then((a) => a[sources[0]]?.[0]); + const inspect = await this.list([sources[0]], select ?? "active").then(a => a[sources[0]]?.[0]); sources[0] = inspect.Id; } if (targets.length > 1) { - const inspect = await this.list([targets[0]], select ?? "active").then((a) => a[targets[0]]?.[0]); + const inspect = await this.list([targets[0]], select ?? "active").then(a => a[targets[0]]?.[0]); targets[0] = inspect.Id; } - // prettier-ignore await this.depker.ops.container .copy(sources.join(":"), targets.join(":"), options) .stdin("inherit") @@ -313,7 +311,7 @@ export class ServiceModule implements DepkerModule { public async wait(names: string[], select?: AllSelect): Promise { const ids: string[] = []; for (const infos of Object.values(await this.list(names, select))) { - ids.push(...infos.map((i) => i.Id)); + ids.push(...infos.map(i => i.Id)); } if (ids.length) { await this.depker.ops.container.wait(ids); @@ -321,11 +319,10 @@ export class ServiceModule implements DepkerModule { } public async logs(name: string, select?: ActiveSelect, options?: ContainerLogsOptions) { - const inspect = await this.list([name], select ?? "active").then((a) => a[name]?.[0]); + const inspect = await this.list([name], select ?? "active").then(a => a[name]?.[0]); if (!inspect) { throw new Error(`No suck container: ${name}`); } - // prettier-ignore await this.depker.ops.container .logs(inspect.Id, options) .stdin("inherit") @@ -335,11 +332,10 @@ export class ServiceModule implements DepkerModule { } public async top(name: string, select?: ActiveSelect, options?: ContainerTopOptions) { - const inspect = await this.list([name], select ?? "active").then((a) => a[name]?.[0]); + const inspect = await this.list([name], select ?? "active").then(a => a[name]?.[0]); if (!inspect) { throw new Error(`No suck container: ${name}`); } - // prettier-ignore await this.depker.ops.container .top(inspect.Id, options) .stdin("inherit") @@ -349,11 +345,10 @@ export class ServiceModule implements DepkerModule { } public async stats(name: string, select?: ActiveSelect, options?: ContainerStatsOptions) { - const inspect = await this.list([name], select ?? "active").then((a) => a[name]?.[0]); + const inspect = await this.list([name], select ?? "active").then(a => a[name]?.[0]); if (!inspect) { throw new Error(`No suck container: ${name}`); } - // prettier-ignore await this.depker.ops.container .stats(inspect.Id, options) .stdin("inherit") @@ -363,11 +358,10 @@ export class ServiceModule implements DepkerModule { } public async exec(name: string, commands: string[], select?: ActiveSelect, options?: ContainerExecOptions) { - const inspect = await this.list([name], select ?? "active").then((a) => a[name]?.[0]); + const inspect = await this.list([name], select ?? "active").then(a => a[name]?.[0]); if (!inspect) { throw new Error(`No suck container: ${name}`); } - // prettier-ignore await this.depker.ops.container .exec(inspect.Id, commands, options) .stdin("inherit") @@ -380,7 +374,7 @@ export class ServiceModule implements DepkerModule { // region private commands - private _deploy(cmd: Command) { + private _deploy(cmd: command.Command) { cmd .command("deploy [name...:string]", "Deploy services") .alias("dep") @@ -389,7 +383,7 @@ export class ServiceModule implements DepkerModule { }); } - private _list(cmd: Command) { + private _list(cmd: command.Command) { cmd .command("list [name...:string]", "List services") .alias("ls") @@ -399,7 +393,7 @@ export class ServiceModule implements DepkerModule { .option("--json", "Pretty-print using json") .option("--yaml", "Pretty-print using yaml") .action(async (options, ...names) => { - const infos = Object.entries(await this.list(names, options.select)).map((e) => ({ Name: e[0], Items: e[1] })); + const infos = Object.entries(await this.list(names, options.select)).map(e => ({ Name: e[0], Items: e[1] })); if (options.format) { this.depker.log.render(options.format, infos); } else if (options.json) { @@ -410,14 +404,13 @@ export class ServiceModule implements DepkerModule { const header = ["Name", "Activated", "Status", "Image", "CreatedAt", "Containers"]; const body = infos.map((info) => { const item = this.select(info.Items, "active")[0] ?? this.select(info.Items, "latest")[0]; - // prettier-ignore return [ `${info.Name}`, `${item.Name}`, - `${this.depker.uti.status(item.State.Status, item.State?.Health?.Status)}`, + `${item.State.Status}${item.State?.Health?.Status ? ` (${item.State?.Health?.Status})` : ``}`, `${item.Config.Image}`, - `${this.depker.uti.date(item.Created)}`, - `${info.Items.map((i) => `${i.Name} [${this.depker.uti.status(i.State.Status, i.State?.Health?.Status)}]`).join("\n")}`, + `${this.depker.log.date(item.Created)}`, + `${info.Items.map(i => `${i.Name} [${i.State.Status}${i.State?.Health?.Status ? ` (${i.State?.Health?.Status})` : ``}]`).join("\n")}`, ]; }); this.depker.log.table(header, body); @@ -425,7 +418,7 @@ export class ServiceModule implements DepkerModule { }); } - private _inspect(cmd: Command) { + private _inspect(cmd: command.Command) { cmd .command("inspect ", "Display detailed information on one or more services") .alias("is") @@ -435,27 +428,24 @@ export class ServiceModule implements DepkerModule { .option("--json", "Pretty-print using json") .option("--yaml", "Pretty-print using yaml") .action(async (options, ...names) => { - const infos = Object.entries(await this.list(names, options.select)).map((e) => ({ Name: e[0], Items: e[1] })); + const infos = Object.entries(await this.list(names, options.select)).map(e => ({ Name: e[0], Items: e[1] })); if (options.format) { this.depker.log.render(options.format, infos); } else if (options.json) { this.depker.log.json(infos); - } else if (options.yaml) { - this.depker.log.yaml(infos); } else { - this.depker.log.json(infos); + this.depker.log.yaml(infos); } }); } - private _start(cmd: Command) { + private _start(cmd: command.Command) { cmd .command("start ", "Start one or more stopped services") .type("select", new AllSelectType()) .option("-s, --select ", "Select the container to display in services", { default: "all" }) .option("-i, --interactive", "Attach service's STDIN") .option("-a, --attach", "Attach STDOUT/STDERR and forward signals") - .option("-k, --detach-keys ", "Override the key sequence for detaching a service") .action(async (options, ...names) => { this.depker.log.step(`Starting services started.`); try { @@ -466,9 +456,6 @@ export class ServiceModule implements DepkerModule { if (options.attach !== undefined) { opts.Attach = options.attach; } - if (options.detachKeys !== undefined) { - opts.DetachKeys = options.detachKeys; - } await this.start(names, options.select, opts); this.depker.log.done(`Starting services successfully.`); } catch (e) { @@ -477,7 +464,7 @@ export class ServiceModule implements DepkerModule { }); } - private _stop(cmd: Command) { + private _stop(cmd: command.Command) { cmd .command("stop ", "Stop one or more running services") .type("select", new AllSelectType()) @@ -502,7 +489,7 @@ export class ServiceModule implements DepkerModule { }); } - private _kill(cmd: Command) { + private _kill(cmd: command.Command) { cmd .command("kill ", "Kill one or more running services") .type("select", new AllSelectType()) @@ -523,7 +510,7 @@ export class ServiceModule implements DepkerModule { }); } - private _remove(cmd: Command) { + private _remove(cmd: command.Command) { cmd .command("remove ", "Remove one or more services") .alias("rm") @@ -553,7 +540,7 @@ export class ServiceModule implements DepkerModule { }); } - private _rename(cmd: Command) { + private _rename(cmd: command.Command) { cmd .command("rename ", "Rename a service") .type("select", new AllSelectType()) @@ -569,7 +556,7 @@ export class ServiceModule implements DepkerModule { }); } - private _prune(cmd: Command) { + private _prune(cmd: command.Command) { cmd .command("prune", "Remove all abnormal services") .type("select", new PruneSelectType()) @@ -591,7 +578,7 @@ export class ServiceModule implements DepkerModule { }); } - private _exec(cmd: Command) { + private _exec(cmd: command.Command) { cmd .command("exec ", "Run a command in a running service") .type("select", new ActiveSelectType()) @@ -602,9 +589,6 @@ export class ServiceModule implements DepkerModule { .option("-p, --privileged", "Give extended privileges to the command") .option("-u, --user ", "Username or UID (format: [:])") .option("-w, --workdir ", "Working directory inside the service") - .option("-e, --env ", "Set environment variables", { collect: true }) - .option("-n, --env-file ", "Read in a file of environment variables", { collect: true }) - .option("-k, --detach-keys ", "Override the key sequence for detaching a service") .action(async (options, name, ...commands) => { const opts: ContainerExecOptions = {}; if (options.tty !== undefined) { @@ -613,9 +597,6 @@ export class ServiceModule implements DepkerModule { if (options.detach !== undefined) { opts.Detach = options.detach; } - if (options.detachKeys !== undefined) { - opts.DetachKeys = options.detachKeys; - } if (options.interactive !== undefined) { opts.Interactive = options.interactive; } @@ -628,17 +609,11 @@ export class ServiceModule implements DepkerModule { if (options.workdir !== undefined) { opts.Workdir = options.workdir; } - if (options.env !== undefined) { - opts.Envs = this.depker.uti.kv(options.env); - } - if (options.envFile !== undefined) { - opts.EnvFiles = options.envFile; - } await this.exec(name, commands, options.select, opts); }); } - private _logs(cmd: Command) { + private _logs(cmd: command.Command) { cmd .command("logs ", "Fetch the logs of a service") .type("select", new ActiveSelectType()) @@ -673,7 +648,7 @@ export class ServiceModule implements DepkerModule { }); } - private _top(cmd: Command) { + private _top(cmd: command.Command) { cmd .command("top ", "Display the running processes of a service") .type("select", new ActiveSelectType()) @@ -688,7 +663,7 @@ export class ServiceModule implements DepkerModule { }); } - private _stats(cmd: Command) { + private _stats(cmd: command.Command) { cmd .command("stats ", "Display a live stream of service resource usage statistics") .type("select", new ActiveSelectType()) @@ -707,7 +682,7 @@ export class ServiceModule implements DepkerModule { }); } - private _copy(cmd: Command) { + private _copy(cmd: command.Command) { cmd .command("copy ", "Copy files/folders between a service and the local filesystem") .alias("cp") @@ -727,7 +702,7 @@ export class ServiceModule implements DepkerModule { }); } - private _wait(cmd: Command) { + private _wait(cmd: command.Command) { cmd .command("wait ", "Block until one or more service stop, then print their exit codes") .type("select", new AllSelectType()) diff --git a/src/services/cfg/index.ts b/src/services/cfg/index.ts index 7912305..2b3da04 100644 --- a/src/services/cfg/index.ts +++ b/src/services/cfg/index.ts @@ -1,6 +1,6 @@ import { Depker } from "../../depker.ts"; +import { command, dotenv, path, yaml } from "../../deps.ts"; import { Configs, Secrets } from "./types.ts"; -import { Command, yaml } from "../../deps.ts"; export * from "./types.ts"; @@ -16,7 +16,7 @@ export class CfgModule { this.instance = undefined; // commands - const config = new Command().description("Manage configs").alias("config").alias("cfg").default("view"); + const config = new command.Command().description("Manage configs").alias("config").alias("cfg").default("view"); config .command("view", "View configs") .alias("show") @@ -29,10 +29,8 @@ export class CfgModule { this.depker.log.render(options.format, data); } else if (options.json) { this.depker.log.json(data); - } else if (options.yaml) { - this.depker.log.yaml(data); } else { - this.depker.log.json(data); + this.depker.log.yaml(data); } }); config @@ -41,8 +39,34 @@ export class CfgModule { .action(async (options) => { await this.manual(options.editor); }); + config + .command("load ", "Load configs") + .option("--json", "Pretty-print using json") + .option("--yaml", "Pretty-print using yaml") + .action(async (options, file) => { + const ext = path.extname(file); + const value = await Deno.readTextFile(file); + if (options.json || ext === ".json") { + await this.config(JSON.parse(value) as Configs); + } else { + await this.config(yaml.parse(value) as Configs); + } + }); + config + .command("save ", "Save configs") + .option("--json", "Pretty-print using json") + .option("--yaml", "Pretty-print using yaml") + .action(async (options, file) => { + const ext = path.extname(file); + const config = await this.config(); + if (options.json || ext === ".json") { + await Deno.writeTextFile(file, JSON.stringify(config)); + } else { + await Deno.writeTextFile(file, yaml.stringify(config)); + } + }); - const secret = new Command().description("Manage secrets").alias("secret").alias("sec").default("list"); + const secret = new command.Command().description("Manage secrets").alias("secret").alias("sec").default("list"); secret .command("list", "List secrets") .alias("ls") @@ -107,6 +131,37 @@ export class CfgModule { this.depker.log.error(`Removing secrets failed.`, e); } }); + secret + .command("load ", "Load secrets") + .option("--json", "Pretty-print using json") + .option("--yaml", "Pretty-print using yaml") + .action(async (options, file) => { + const ext = path.extname(file); + const value = await Deno.readTextFile(file); + if (options.json || ext === ".json") { + await this.secret(JSON.parse(value) as Secrets); + } else if (options.yaml || ext === ".yaml" || ext === ".yml") { + await this.secret(yaml.parse(value) as Secrets); + } else { + await this.secret(dotenv.parse(file)); + } + }); + secret + .command("save ", "Save secrets") + .option("--json", "Pretty-print using json") + .option("--yaml", "Pretty-print using yaml") + .action(async (options, file) => { + const ext = path.extname(file); + const config = await this.secret(); + if (options.json || ext === ".json") { + await Deno.writeTextFile(file, JSON.stringify(config)); + } else if (options.yaml || ext === ".yaml" || ext === ".yml") { + await Deno.writeTextFile(file, yaml.stringify(config)); + } else { + const values = Object.fromEntries(Object.entries(config).map(([k, v]) => [k, String(v)])); + await Deno.writeTextFile(file, dotenv.stringify(values)); + } + }); this.depker.cli.command("configs", config); this.depker.cli.command("secrets", secret); @@ -132,8 +187,12 @@ export class CfgModule { } public async config(): Promise; + public async config(config: Configs): Promise; public async config(name: string, value?: T | undefined | null): Promise; - public async config(name?: string, value?: T | undefined | null): Promise { + public async config( + name?: string | Configs, + value?: T | undefined | null, + ): Promise { if (this.instance === undefined) { this.depker.log.debug(`Config loading started.`); try { @@ -148,16 +207,20 @@ export class CfgModule { } if (name !== undefined && value !== undefined) { await this.depker.emit("depker:before-config", this.instance); - if (value === null) { - delete this.instance[name]; + if (typeof name === "string") { + if (value === null) { + delete this.instance[name]; + } else { + // @ts-expect-error + this.instance[name] = value; + } } else { - // @ts-ignore - this.instance[name] = value; + this.instance = name; } await this.write(CfgModule.PATH, yaml.stringify(this.instance)); await this.depker.emit("depker:after-config", this.instance); } - if (name !== undefined) { + if (name !== undefined && typeof name === "string") { return (this.instance[name] ?? {}) as T; } return this.instance ?? {}; diff --git a/src/services/cli/index.ts b/src/services/cli/index.ts index 26d892e..e19fc36 100644 --- a/src/services/cli/index.ts +++ b/src/services/cli/index.ts @@ -1,7 +1,7 @@ import { Depker } from "../../depker.ts"; -import { Command } from "../../deps.ts"; +import { command } from "../../deps.ts"; -export class CliModule extends Command { +export class CliModule extends command.Command { constructor(private readonly depker: Depker) { super(); this.name(depker.name); diff --git a/src/services/dax/index.ts b/src/services/dax/index.ts index 19c439a..35bdd34 100644 --- a/src/services/dax/index.ts +++ b/src/services/dax/index.ts @@ -1,20 +1,20 @@ -import { $BuiltInProperties, build$, CommandBuilder, RequestBuilder } from "../../deps.ts"; +import { dax } from "../../deps.ts"; -CommandBuilder.prototype.jsonl = async function (this: CommandBuilder): Promise { +dax.CommandBuilder.prototype.jsonl = async function (this: dax.CommandBuilder): Promise { const lines = await this.lines(); - return lines.map((i) => JSON.parse(i)) as T; + return lines.map(i => JSON.parse(i)) as T; }; -RequestBuilder.prototype.jsonl = async function (this: RequestBuilder): Promise { +dax.RequestBuilder.prototype.jsonl = async function (this: dax.RequestBuilder): Promise { const texts = await this.text(); const lines = texts.split(/\r?\n/g); - return lines.map((i) => JSON.parse(i)) as T; + return lines.map(i => JSON.parse(i)) as T; }; -interface Template +interface Template extends Omit< - // @ts-ignore - $BuiltInProperties, + // @ts-expect-error + dax.$BuiltInProperties, | "log" | "logLight" | "logStep" @@ -36,13 +36,13 @@ interface Template | "prompt" | "progress" > { - (strings: TemplateStringsArray, ...exprs: any[]): CommandBuilder; + (strings: TemplateStringsArray, ...exprs: any[]): dax.CommandBuilder; } -export type Dax = Template & TExtras; +export type Dax = Template & TExtras; -export function dax(): Dax { - const command = new CommandBuilder().stdin("null").stdout("piped").stderr("inherit").env(Deno.env.toObject()); - // @ts-ignore - return build$({ commandBuilder: command }); +export function createDax(): Dax { + const command = new dax.CommandBuilder().stdin("null").stdout("piped").stderr("inherit").env(Deno.env.toObject()); + // @ts-expect-error + return dax.build$({ commandBuilder: command }); } diff --git a/src/services/evs/index.ts b/src/services/evs/index.ts index b7c8ff1..f71b154 100644 --- a/src/services/evs/index.ts +++ b/src/services/evs/index.ts @@ -1,8 +1,7 @@ import { Depker } from "../../depker.ts"; -import { EventEmitter } from "../../deps.ts"; +import { event } from "../../deps.ts"; -export class EvsModule extends EventEmitter { - // eslint-disable-next-line @typescript-eslint/no-unused-vars +export class EvsModule extends event.EventEmitter { constructor(private readonly depker: Depker) { super(0); } diff --git a/src/services/log/index.ts b/src/services/log/index.ts index e04d37d..1b92dd0 100644 --- a/src/services/log/index.ts +++ b/src/services/log/index.ts @@ -1,19 +1,19 @@ import { Depker } from "../../depker.ts"; -import { colors, datetime, nunjucks, Table, yaml } from "../../deps.ts"; +import { ansi, date, nunjucks, table, yaml } from "../../deps.ts"; import { LogLevel } from "./types.ts"; export * from "./types.ts"; export class LogModule { - // eslint-disable-next-line @typescript-eslint/no-unused-vars constructor(private readonly depker: Depker) {} public format(...messages: any[]) { const results: string[] = []; for (let message of messages) { if (message instanceof Error) { - // @ts-ignore + // @ts-expect-error results.push(message?.response?.body?.message ?? message.message); + // eslint-disable-next-line no-cond-assign while ((message = message.cause)) { results.push(` [cause]: ${message?.response?.body?.message ?? message.message}`); } @@ -31,10 +31,10 @@ export class LogModule { template.addFilter("json", (value: any) => JSON.stringify(value, undefined, 2), false); template.addFilter("yaml", (value: any) => yaml.stringify(value), false); if (data instanceof Object) { - // @ts-ignore + // @ts-expect-error return template.renderString(value, data, undefined, undefined).trim(); } else { - // @ts-ignore + // @ts-expect-error return template.renderString(value, { it: data }, undefined, undefined).trim(); } } @@ -47,6 +47,19 @@ export class LogModule { this.raw(yaml.stringify(obj, { skipInvalid: true, noRefs: true, indent: 2 }).trim()); } + public byte(value: number) { + const units = [`B`, `KB`, `MB`, `GB`, `TB`, `PB`]; + while (value > 1024 && units.length > 1) { + units.shift(); + value /= 1024; + } + return `${value.toFixed(2)} ${units[0]}`; + } + + public date(value: string | number) { + return date.datetime(value).toLocal().format("YYYY-MM-dd HH:mm:ss"); + } + public raw(...message: string[]) { this._output("raw", Date.now(), this.format(...message)); } @@ -72,15 +85,15 @@ export class LogModule { } public table(header: string[], body: string[][]) { - const table = new Table() - .header(header.map((i) => colors.bold.cyan(i))) + const t = new table.Table() + .header(header.map(i => ansi.colors.bold.cyan(i))) .body(body) .border(true); - this._output("raw", Date.now(), table.toString()); + this._output("raw", Date.now(), t.toString()); } public render(value: string, data: any) { - if (data instanceof Array) { + if (Array.isArray(data)) { for (const context of data) { this._output("raw", Date.now(), this.parse(value, context)); } @@ -97,18 +110,17 @@ export class LogModule { console.log(message); return; } - // prettier-ignore - const data = Deno.env.get("DEPKER_OPTION_TIMESTAMP") ? `[${datetime(parseInt(time as any)).format("yyyy/MM/dd HH:mm:ss")}] ${message}` : message; + const data = Deno.env.get("DEPKER_OPTION_TIMESTAMP") ? `[${this.date(Number.parseInt(time as any))}] ${message}` : message; if (level === "step") { - console.log(`${colors.bold.cyan("[STEP] ❯ ")}${data}`); + console.log(`${ansi.colors.bold.cyan("[STEP] ❯ ")}${data}`); } else if (level === "debug") { - console.log(`${colors.bold.gray("[DEBUG] ☰ ")}${data}`); + console.log(`${ansi.colors.bold.gray("[DEBUG] ☰ ")}${data}`); } else if (level === "info") { - console.log(`${colors.bold.blue("[INFO] i ")}${data}`); + console.log(`${ansi.colors.bold.blue("[INFO] i ")}${data}`); } else if (level === "done") { - console.log(`${colors.bold.green("[DONE] ✔ ")}${data}`); + console.log(`${ansi.colors.bold.green("[DONE] ✔ ")}${data}`); } else if (level === "error") { - console.error(`${colors.bold.red("[ERROR] ✖ ")}${data}`); + console.error(`${ansi.colors.bold.red("[ERROR] ✖ ")}${data}`); } } } diff --git a/src/services/ops/index.ts b/src/services/ops/index.ts index eeb907c..a4d01e8 100644 --- a/src/services/ops/index.ts +++ b/src/services/ops/index.ts @@ -5,12 +5,19 @@ import { ImageOperation, NetworkOperation, VolumeOperation, -} from "../docker/types.ts"; +} from "../run/types.ts"; import { Depker } from "../../depker.ts"; +import { hash } from "../../deps.ts"; export class OpsModule implements DepkerMaster { constructor(private readonly depker: Depker) {} + public get id() { + const master = this.depker.master(); + const runner = this.depker.runner(); + return hash([master.id, runner.id]); + } + public get container(): ContainerOperation { return this.depker.master().container; } @@ -32,10 +39,12 @@ export class OpsModule implements DepkerMaster { } public async transfer(name: string, progress: (size: number | null) => void): Promise { - if (this.depker.master() != this.depker.runner()) { + const master = this.depker.master(); + const runner = this.depker.runner(); + if (master.id !== runner.id) { const size = { value: 0 }; - const save = this.depker.runner().builder.save(name).spawn(); - const load = this.depker.master().builder.load().spawn(); + const save = runner.builder.save(name).spawn(); + const load = master.builder.load().spawn(); const transform = new TransformStream({ transform: (chunk, controller) => { size.value += chunk.length; diff --git a/src/services/docker/index.ts b/src/services/run/index.ts similarity index 91% rename from src/services/docker/index.ts rename to src/services/run/index.ts index 5b3367d..4b4f2a2 100644 --- a/src/services/docker/index.ts +++ b/src/services/run/index.ts @@ -1,3 +1,5 @@ +import { Depker } from "../../depker.ts"; +import { dax, hash } from "../../deps.ts"; import { BuilderBuildOptions, BuilderOperation, @@ -12,7 +14,6 @@ import { ContainerRemoveOptions, ContainerRestartOptions, ContainerRunOptions, - containers, ContainerStartOptions, ContainerStatsOptions, ContainerStopOptions, @@ -25,7 +26,6 @@ import { ImagePullOptions, ImagePushOptions, ImageRemoveOptions, - images, NetworkConnectOptions, NetworkCreateOptions, NetworkDisconnectOptions, @@ -33,16 +33,13 @@ import { NetworkInspect, NetworkOperation, NetworkRemoveOptions, - networks, VolumeCreateOptions, VolumeInfo, VolumeInspect, VolumeOperation, VolumeRemoveOptions, - volumes, } from "./types.ts"; -import { Depker } from "../../depker.ts"; -import { CommandBuilder } from "../../deps.ts"; +import { containers, images, networks, volumes } from "./parser.ts"; export * from "./types.ts"; @@ -51,6 +48,7 @@ export function docker(options?: DockerNodeOptions) { } export class DockerNode implements DepkerMaster { + public readonly id: string; public readonly docker: string[]; public readonly container: DockerContainerOperation; public readonly builder: DockerBuilderOperation; @@ -113,6 +111,8 @@ export class DockerNode implements DepkerMaster { } else { this.docker = [`docker`]; } + + this.id = hash(this.docker); } } @@ -128,7 +128,7 @@ class DockerContainerOperation implements ContainerOperation { public async list(): Promise> { const infos = await this.depker.dax`${this.docker} ls --all --no-trunc --format '{{json .}}'`.jsonl>(); - return infos.map((info) => containers.info(info)); + return infos.map(info => containers.info(info)); } public async find(name: string): Promise { @@ -143,7 +143,7 @@ class DockerContainerOperation implements ContainerOperation { public async inspect(name: string[]): Promise> { const infos = await this.depker.dax`${this.docker} inspect ${name}`.json>(); - return infos.map((info) => containers.inspect(info)); + return infos.map(info => containers.inspect(info)); } public async start(name: string[], options?: ContainerStartOptions): Promise { @@ -218,19 +218,19 @@ class DockerContainerOperation implements ContainerOperation { await this.depker.dax`${this.docker} prune --force --filter until=24h`; } - public create(name: string, target: string, options?: ContainerCreateOptions): CommandBuilder { + public create(name: string, target: string, options?: ContainerCreateOptions): dax.CommandBuilder { return this.depker.dax`${this.docker} create ${this.create_args(name, target, options)}`; } - public run(name: string, target: string, options?: ContainerRunOptions): CommandBuilder { + public run(name: string, target: string, options?: ContainerRunOptions): dax.CommandBuilder { return this.depker.dax`${this.docker} run ${this.run_args(name, target, options)}`; } - public exec(name: string, commands: string[], options?: ContainerExecOptions): CommandBuilder { + public exec(name: string, commands: string[], options?: ContainerExecOptions): dax.CommandBuilder { return this.depker.dax`${this.docker} exec ${this.exec_args(name, commands, options)}`; } - public logs(name: string, options?: ContainerLogsOptions): CommandBuilder { + public logs(name: string, options?: ContainerLogsOptions): dax.CommandBuilder { const args: string[] = []; if (options?.Details) { @@ -258,11 +258,11 @@ class DockerContainerOperation implements ContainerOperation { return this.depker.dax`${this.docker} logs ${name} ${args}`; } - public top(name: string, options?: ContainerTopOptions): CommandBuilder { + public top(name: string, options?: ContainerTopOptions): dax.CommandBuilder { return this.depker.dax`${this.docker} top ${name} ${options?.Options ? [options.Options] : []}`; } - public stats(name: string, options?: ContainerStatsOptions): CommandBuilder { + public stats(name: string, options?: ContainerStatsOptions): dax.CommandBuilder { const args: string[] = []; if (options?.All) { @@ -278,7 +278,7 @@ class DockerContainerOperation implements ContainerOperation { return this.depker.dax`${this.docker} stats ${args} ${name}`; } - public copy(source: string, target: string, options?: ContainerCopyOptions): CommandBuilder { + public copy(source: string, target: string, options?: ContainerCopyOptions): dax.CommandBuilder { const args: string[] = []; if (options?.Archive) { @@ -320,18 +320,10 @@ class DockerContainerOperation implements ContainerOperation { args.push(`--env`); args.push(`${name}=${value}`); } - for (const value of options?.EnvFiles ?? []) { - args.push(`--env-file`); - args.push(value); - } for (const [name, value] of Object.entries(options?.Labels ?? {})) { args.push(`--label`); args.push(`${name}=${value}`); } - for (const value of options?.LabelFiles ?? []) { - args.push(`--label-file`); - args.push(value); - } for (const value of options?.Ports ?? []) { args.push(`--publish`); args.push(value); @@ -506,10 +498,6 @@ class DockerContainerOperation implements ContainerOperation { args.push(`--env`); args.push(`${name}=${value}`); } - for (const value of options?.EnvFiles ?? []) { - args.push(`--env-file`); - args.push(value); - } args.push(name); args.push(...commands); @@ -523,7 +511,7 @@ class DockerBuilderOperation implements BuilderOperation { private readonly node: DockerNode, ) {} - public build(name: string, target: string, options?: BuilderBuildOptions): CommandBuilder { + public build(name: string, target: string, options?: BuilderBuildOptions): dax.CommandBuilder { const args = [`--tag`, name]; if (options?.File) { @@ -539,6 +527,10 @@ class DockerBuilderOperation implements BuilderOperation { if (options?.Remove) { args.push(`--rm`); } + for (const name of options?.Networks ?? []) { + args.push(`--network`); + args.push(name); + } for (const [name, value] of Object.entries(options?.Args ?? {})) { args.push(`--build-arg`); args.push(`${name}=${value}`); @@ -555,9 +547,25 @@ class DockerBuilderOperation implements BuilderOperation { args.push(`--add-host`); args.push(`${name}:${value}`); } - for (const name of options?.Networks ?? []) { - args.push(`--network`); - args.push(name); + if (options?.Envs) { + const values = Object.entries(options.Envs).map(([k, v]) => `${k}=${v}\n`); + const file1 = Deno.makeTempFileSync(); + Deno.writeTextFileSync(file1, values.join("")); + args.push(`--secret`); + args.push(`id=depker-envs,src=${file1}`); + const file2 = Deno.makeTempFileSync(); + Deno.writeTextFileSync(file2, values.map(i => `export ${i}`).join("")); + args.push(`--secret`); + args.push(`id=depker-export-envs,src=${file2}`); + } else { + const file1 = Deno.makeTempFileSync(); + Deno.writeTextFileSync(file1, "\n"); + args.push(`--secret`); + args.push(`id=depker-envs,src=${file1}`); + const file2 = Deno.makeTempFileSync(); + Deno.writeTextFileSync(file2, "\n"); + args.push(`--secret`); + args.push(`id=depker-export-envs,src=${file2}`); } // extensions @@ -602,7 +610,7 @@ class DockerNetworkOperation implements NetworkOperation { public async list(): Promise> { const infos = await this.depker.dax`${this.docker} ls --no-trunc --format '{{json .}}'`.jsonl>(); - return infos.map((info) => networks.info(info)); + return infos.map(info => networks.info(info)); } public async find(name: string): Promise { @@ -617,7 +625,7 @@ class DockerNetworkOperation implements NetworkOperation { public async inspect(name: string[]): Promise> { const infos = await this.depker.dax`${this.docker} inspect ${name}`.json>(); - return infos.map((info) => networks.inspect(info)); + return infos.map(info => networks.inspect(info)); } public async create(name: string, options?: NetworkCreateOptions): Promise { @@ -709,7 +717,7 @@ class DockerVolumeOperation implements VolumeOperation { public async list(): Promise> { const infos = await this.depker.dax`${this.docker} ls --format '{{json .}}'`.jsonl>(); - return infos.map((info) => volumes.info(info)); + return infos.map(info => volumes.info(info)); } public async find(name: string): Promise { @@ -724,7 +732,7 @@ class DockerVolumeOperation implements VolumeOperation { public async inspect(name: string[]): Promise> { const infos = await this.depker.dax`${this.docker} inspect ${name}`.json>(); - return infos.map((info) => volumes.inspect(info)); + return infos.map(info => volumes.inspect(info)); } public async create(name: string, options?: VolumeCreateOptions): Promise { @@ -752,7 +760,6 @@ class DockerVolumeOperation implements VolumeOperation { await this.depker.dax`${this.docker} rm ${args} ${name}`; } - // prettier-ignore public async prune(): Promise { const volumes = await this.depker.dax`${this.docker} ls --quiet --filter dangling=true`.lines(); if (!volumes.length) { @@ -762,7 +769,7 @@ class DockerVolumeOperation implements VolumeOperation { if (!inspects.length) { return; } - const names = inspects.filter((i) => /^[0-9a-f]{64}$/.test(i.Name) && Math.abs(Date.now() - new Date(i.Created).getTime()) > 86_400_000).map((i) => i.Name); + const names = inspects.filter(i => /^[0-9a-f]{64}$/.test(i.Name) && Math.abs(Date.now() - new Date(i.Created).getTime()) > 86_400_000).map(i => i.Name); if (!names.length) { return; } @@ -782,7 +789,7 @@ class DockerImageOperation implements ImageOperation { public async list(): Promise> { const infos = await this.depker.dax`${this.docker} ls --no-trunc --format '{{json .}}'`.jsonl>(); - return infos.map((info) => images.info(info)); + return infos.map(info => images.info(info)); } public async find(name: string): Promise { @@ -797,10 +804,10 @@ class DockerImageOperation implements ImageOperation { public async inspect(name: string[]): Promise> { const infos = await this.depker.dax`${this.docker} inspect ${name}`.jsonl>(); - return infos.map((info) => images.inspect(info)); + return infos.map(info => images.inspect(info)); } - public pull(name: string, options?: ImagePullOptions): CommandBuilder { + public pull(name: string, options?: ImagePullOptions): dax.CommandBuilder { const args: string[] = []; if (options?.AllTags) { args.push(`--all-tags`); @@ -812,7 +819,7 @@ class DockerImageOperation implements ImageOperation { return this.depker.dax`${this.docker} pull ${args} ${name}`; } - public push(name: string, options?: ImagePushOptions): CommandBuilder { + public push(name: string, options?: ImagePushOptions): dax.CommandBuilder { const args: string[] = []; if (options?.AllTags) { args.push(`--all-tags`); diff --git a/src/services/run/parser.ts b/src/services/run/parser.ts new file mode 100644 index 0000000..c3727c4 --- /dev/null +++ b/src/services/run/parser.ts @@ -0,0 +1,133 @@ +import { + ContainerInfo, + ContainerInspect, + ImageInfo, + ImageInspect, + NetworkInfo, + NetworkInspect, + VolumeInfo, + VolumeInspect, +} from "./types.ts"; + +export const networks = { + info: (data: Record): NetworkInfo => ({ + Id: data.ID, + Name: data.Name, + Scope: data.Scope, + Driver: data.Driver, + IPv6: data.IPv6 === "true", + Internal: data.Internal === "true", + Created: new Date(data.CreatedAt).toISOString(), + }), + inspect: (data: Record): NetworkInspect => ({ + Id: data.Id, + Name: data.Name, + Created: new Date(data.Created).toISOString(), + Scope: data.Scope, + Driver: data.Driver, + EnableIPv6: data.EnableIPv6, + IPAM: data.IPAM, + Internal: data.Internal, + Attachable: data.Attachable, + Ingress: data.Ingress, + ConfigFrom: data.ConfigFrom, + ConfigOnly: data.ConfigOnly, + Containers: data.Containers, + Options: data.Options, + Labels: data.Labels, + }), +}; + +export const volumes = { + info: (data: Record): VolumeInfo => ({ + Name: data.Name, + Scope: data.Scope, + Driver: data.Driver, + Size: data.Size, + Links: data.Links, + Mountpoint: data.Mountpoint, + }), + inspect: (data: Record): VolumeInspect => ({ + Name: data.Name, + Scope: data.Scope, + Driver: data.Driver, + Created: new Date(data.CreatedAt).toISOString(), + Mountpoint: data.Mountpoint, + Labels: data.Labels, + Options: data.Options, + }), +}; + +export const images = { + info: (data: Record): ImageInfo => ({ + Id: data.ID, + Repository: data.Repository, + Tag: data.Tag, + Digest: data.Digest, + Created: new Date(data.CreatedAt).toISOString(), + CreatedSince: data.CreatedSince, + Size: data.Size, + VirtualSize: data.VirtualSize, + }), + inspect: (data: Record): ImageInspect => ({ + Id: data.Id, + RepoTags: data.RepoTags, + RepoDigests: data.RepoDigests, + Parent: data.Parent, + Comment: data.Comment, + Created: new Date(data.Created).toISOString(), + Container: data.Container, + ContainerConfig: data.ContainerConfig, + DockerVersion: data.DockerVersion, + Author: data.Author, + Config: data.Config, + Architecture: data.Architecture, + Os: data.Os, + Size: data.Size, + VirtualSize: data.VirtualSize, + GraphDriver: data.GraphDriver, + RootFS: data.RootFS, + Metadata: data.Metadata, + }), +}; + +export const containers = { + info: (data: Record): ContainerInfo => ({ + Id: data.ID, + Name: data.Names, + Image: data.Image, + State: data.State, + Status: data.Status, + Size: data.Size, + Created: new Date(data.CreatedAt).toISOString(), + Ports: data.Ports, + Mounts: data.Mounts, + Labels: data.Labels, + Networks: data.Networks, + }), + inspect: (data: Record): ContainerInspect => ({ + Id: data.Id, + Created: new Date(data.Created).toISOString(), + Path: data.Path, + Args: data.Args, + State: data.State, + Image: data.Image, + ResolvConfPath: data.ResolvConfPath, + HostnamePath: data.HostnamePath, + HostsPath: data.HostsPath, + LogPath: data.LogPath, + Name: data.Name.substring(1), + RestartCount: data.RestartCount, + Driver: data.Driver, + Platform: data.Platform, + MountLabel: data.MountLabel, + ProcessLabel: data.ProcessLabel, + AppArmorProfile: data.AppArmorProfile, + ExecIDs: data.ExecIDs, + HostConfig: data.HostConfig, + GraphDriver: data.GraphDriver, + Mounts: data.Mounts, + Config: data.Config, + NetworkSettings: data.NetworkSettings, + }), +}; diff --git a/src/services/docker/types.ts b/src/services/run/types.ts similarity index 75% rename from src/services/docker/types.ts rename to src/services/run/types.ts index 0f6da63..1dc3d7f 100644 --- a/src/services/docker/types.ts +++ b/src/services/run/types.ts @@ -1,33 +1,33 @@ -import { CommandBuilder } from "../../deps.ts"; +import { dax } from "../../deps.ts"; // region common export type DockerNodeOptions = | { - type: "local"; - } + type: "local"; + } | { - type: "context"; - name?: string; - } + type: "context"; + name?: string; + } | { - type: "ssh"; - host?: string; - } + type: "ssh"; + host?: string; + } | { - type: "http"; - host?: string; - port?: number | string; - } + type: "http"; + host?: string; + port?: number | string; + } | { - type: "https"; - host?: string; - port?: number | string; - ca?: string; - cert?: string; - key?: string; - verify?: boolean; - }; + type: "https"; + host?: string; + port?: number | string; + ca?: string; + cert?: string; + key?: string; + verify?: boolean; + }; export interface ContainerConfig { Hostname?: string; @@ -37,7 +37,7 @@ export interface ContainerConfig { AttachStdout?: boolean; AttachStderr?: boolean; ExposedPorts?: { - [portAndProtocol: string]: {}; + [portAndProtocol: string]: object; }; Tty?: boolean; OpenStdin?: boolean; @@ -54,7 +54,7 @@ export interface ContainerConfig { ArgsEscaped?: boolean; Image?: string; Volumes?: { - [path: string]: {}; + [path: string]: object; }; WorkingDir?: string; Entrypoint?: string | string[]; @@ -232,14 +232,14 @@ export interface ContainerInspect { AttachStdin: boolean; AttachStdout: boolean; AttachStderr: boolean; - ExposedPorts: { [portAndProtocol: string]: {} }; + ExposedPorts: { [portAndProtocol: string]: object }; Tty: boolean; OpenStdin: boolean; StdinOnce: boolean; Env: string[]; Cmd: string[]; Image: string; - Volumes: { [volume: string]: {} }; + Volumes: { [volume: string]: object }; WorkingDir: string; Entrypoint?: string | string[]; OnBuild?: any; @@ -330,9 +330,7 @@ export interface ContainerCreateOptions { Init?: boolean; Remove?: boolean; Envs?: Record; - EnvFiles?: string[]; Labels?: Record; - LabelFiles?: string[]; Ports?: string[]; Volumes?: string[]; // healthcheck @@ -384,7 +382,6 @@ export interface ContainerExecOptions { User?: string; Workdir?: string; Envs?: Record; - EnvFiles?: string[]; } export interface ContainerLogsOptions { @@ -477,6 +474,7 @@ export interface BuilderBuildOptions { Remove?: boolean; // values Args?: Record; + Envs?: Record; Labels?: Record; Secrets?: Record; // networks @@ -627,13 +625,13 @@ export interface ContainerOperation { remove(name: string[], options?: ContainerRemoveOptions): Promise; rename(name: string, rename: string): Promise; prune(): Promise; - create(name: string, target: string, options?: ContainerCreateOptions): CommandBuilder; - run(name: string, target: string, options?: ContainerRunOptions): CommandBuilder; - exec(name: string, commands: string[], options?: ContainerExecOptions): CommandBuilder; - logs(name: string, options?: ContainerLogsOptions): CommandBuilder; - top(name: string, options?: ContainerTopOptions): CommandBuilder; - stats(name: string, options?: ContainerStatsOptions): CommandBuilder; - copy(source: string, target: string, options?: ContainerCopyOptions): CommandBuilder; + create(name: string, target: string, options?: ContainerCreateOptions): dax.CommandBuilder; + run(name: string, target: string, options?: ContainerRunOptions): dax.CommandBuilder; + exec(name: string, commands: string[], options?: ContainerExecOptions): dax.CommandBuilder; + logs(name: string, options?: ContainerLogsOptions): dax.CommandBuilder; + top(name: string, options?: ContainerTopOptions): dax.CommandBuilder; + stats(name: string, options?: ContainerStatsOptions): dax.CommandBuilder; + copy(source: string, target: string, options?: ContainerCopyOptions): dax.CommandBuilder; wait(name: string[]): Promise; } @@ -642,8 +640,8 @@ export interface ImageOperation { find(name: string): Promise; inspect(name: string[]): Promise>; tag(source: string, target: string): Promise; - pull(name: string, options?: ImagePullOptions): CommandBuilder; - push(name: string, options?: ImagePushOptions): CommandBuilder; + pull(name: string, options?: ImagePullOptions): dax.CommandBuilder; + push(name: string, options?: ImagePushOptions): dax.CommandBuilder; remove(name: string[], options?: ImageRemoveOptions): Promise; prune(): Promise; } @@ -670,7 +668,7 @@ export interface NetworkOperation { } export interface BuilderOperation { - build(name: string, target: string, options?: BuilderBuildOptions): CommandBuilder; + build(name: string, target: string, options?: BuilderBuildOptions): dax.CommandBuilder; save(name: string): Deno.Command; load(): Deno.Command; } @@ -680,10 +678,12 @@ export interface BuilderOperation { // region node export interface DepkerRunner { + id: string; builder: BuilderOperation; } export interface DepkerMaster extends DepkerRunner { + id: string; container: ContainerOperation; network: NetworkOperation; volume: VolumeOperation; @@ -691,131 +691,3 @@ export interface DepkerMaster extends DepkerRunner { } // endregion - -// region parser - -export const networks = { - info: (data: Record): NetworkInfo => ({ - Id: data.ID, - Name: data.Name, - Scope: data.Scope, - Driver: data.Driver, - IPv6: data.IPv6 === "true", - Internal: data.Internal === "true", - Created: new Date(data.CreatedAt).toISOString(), - }), - inspect: (data: Record): NetworkInspect => ({ - Id: data.Id, - Name: data.Name, - Created: new Date(data.Created).toISOString(), - Scope: data.Scope, - Driver: data.Driver, - EnableIPv6: data.EnableIPv6, - IPAM: data.IPAM, - Internal: data.Internal, - Attachable: data.Attachable, - Ingress: data.Ingress, - ConfigFrom: data.ConfigFrom, - ConfigOnly: data.ConfigOnly, - Containers: data.Containers, - Options: data.Options, - Labels: data.Labels, - }), -}; - -export const volumes = { - info: (data: Record): VolumeInfo => ({ - Name: data.Name, - Scope: data.Scope, - Driver: data.Driver, - Size: data.Size, - Links: data.Links, - Mountpoint: data.Mountpoint, - }), - inspect: (data: Record): VolumeInspect => ({ - Name: data.Name, - Scope: data.Scope, - Driver: data.Driver, - Created: new Date(data.CreatedAt).toISOString(), - Mountpoint: data.Mountpoint, - Labels: data.Labels, - Options: data.Options, - }), -}; - -export const images = { - info: (data: Record): ImageInfo => ({ - Id: data.ID, - Repository: data.Repository, - Tag: data.Tag, - Digest: data.Digest, - Created: new Date(data.CreatedAt).toISOString(), - CreatedSince: data.CreatedSince, - Size: data.Size, - VirtualSize: data.VirtualSize, - }), - inspect: (data: Record): ImageInspect => ({ - Id: data.Id, - RepoTags: data.RepoTags, - RepoDigests: data.RepoDigests, - Parent: data.Parent, - Comment: data.Comment, - Created: new Date(data.Created).toISOString(), - Container: data.Container, - ContainerConfig: data.ContainerConfig, - DockerVersion: data.DockerVersion, - Author: data.Author, - Config: data.Config, - Architecture: data.Architecture, - Os: data.Os, - Size: data.Size, - VirtualSize: data.VirtualSize, - GraphDriver: data.GraphDriver, - RootFS: data.RootFS, - Metadata: data.Metadata, - }), -}; - -export const containers = { - // prettier-ignore - info: (data: Record): ContainerInfo => ({ - Id: data.ID, - Name: data.Names, - Image: data.Image, - State: data.State, - Status: data.Status, - Size: data.Size, - Created: new Date(data.CreatedAt).toISOString(), - Ports: data.Ports, - Mounts: data.Mounts, - Labels: data.Labels, - Networks: data.Networks, - }), - inspect: (data: Record): ContainerInspect => ({ - Id: data.Id, - Created: new Date(data.Created).toISOString(), - Path: data.Path, - Args: data.Args, - State: data.State, - Image: data.Image, - ResolvConfPath: data.ResolvConfPath, - HostnamePath: data.HostnamePath, - HostsPath: data.HostsPath, - LogPath: data.LogPath, - Name: data.Name.substring(1), - RestartCount: data.RestartCount, - Driver: data.Driver, - Platform: data.Platform, - MountLabel: data.MountLabel, - ProcessLabel: data.ProcessLabel, - AppArmorProfile: data.AppArmorProfile, - ExecIDs: data.ExecIDs, - HostConfig: data.HostConfig, - GraphDriver: data.GraphDriver, - Mounts: data.Mounts, - Config: data.Config, - NetworkSettings: data.NetworkSettings, - }), -}; - -// endregion diff --git a/src/services/uti/index.ts b/src/services/uti/index.ts deleted file mode 100644 index 843b015..0000000 --- a/src/services/uti/index.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { Depker } from "../../depker.ts"; -import { datetime, fs, getFileInfoType, isSubdir, osType, path, toPathString } from "../../deps.ts"; - -interface CopyOptions { - overwrite?: boolean; - filter?: (path: string) => boolean; -} - -interface IntCopyOptions extends CopyOptions { - folder?: boolean; -} - -export class UtiModule { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - constructor(private readonly depker: Depker) {} - - public kv(values: string | string[]): Record { - if (typeof values === "string") { - if (values) { - const split = values.split("="); - const k = split.shift() as string; - const v = split.join("=") as string; - return { [k]: v }; - } else { - return {}; - } - } else { - const results: Record = {}; - for (const value of values) { - if (value) { - const split = value.split("="); - const k = split.shift() as string; - results[k] = split.join("="); - } - } - return results; - } - } - - public short(value: string) { - return value.substring(0, 10); - } - - public bytes(value: number) { - const units = [`B`, `KB`, `MB`, `GB`, `TB`, `PB`]; - while (value > 1024 && units.length > 1) { - units.shift(); - value /= 1024; - } - return `${value.toFixed(2)} ${units[0]}`; - } - - public date(value: string | number) { - return datetime(value).toLocal().format("YYYY/MM/dd HH:mm:ss"); - } - - public status(status: string, health?: string) { - if (health) { - return `${status} (${health})`; - } else { - return `${status}`; - } - } - - public replace(value: string, replacer: (name: string) => string | boolean | number | null | undefined) { - return value.replace(/(?<=^|[^@])(?:@([a-zA-Z][a-zA-Z0-9_]*)|@\{([a-zA-Z][a-zA-Z0-9]*)})/g, (a, n) => { - const r = replacer(n); - return r === null || r === undefined ? a : String(r); - }); - } - - public async copy(source: string, target: string, options?: CopyOptions) { - source = path.resolve(toPathString(source)); - target = path.resolve(toPathString(target)); - - if (source === target) { - throw new Error("Source and destination cannot be the same."); - } - - const info = await Deno.lstat(source); - if (info.isDirectory && isSubdir(source, target)) { - throw new Error(`Cannot copy '${source}' to a subdirectory of itself, '${target}'.`); - } - - if (info.isSymlink) { - await this._copyLink(source, target, options); - } else if (info.isDirectory) { - await this._copyDir(source, target, options); - } else if (info.isFile) { - await this._copyFile(source, target, options); - } - } - - private async _validCopy(source: string, target: string, options?: IntCopyOptions): Promise { - let info: Deno.FileInfo | undefined = undefined; - try { - info = await Deno.lstat(target); - } catch (err) { - if (err instanceof Deno.errors.NotFound) { - return; - } - throw err; - } - if (options?.folder && !info.isDirectory) { - throw new Error(`Cannot overwrite non-directory '${source}' with directory '${target}'.`); - } - if (!options?.overwrite) { - throw new Deno.errors.AlreadyExists(`'${target}' already exists.`); - } - } - - private async _copyLink(source: string, target: string, options?: IntCopyOptions) { - if (options?.filter && !options.filter(source)) { - return; - } - await this._validCopy(source, target, options); - const origin = await Deno.readLink(source); - const type = getFileInfoType(await Deno.lstat(source)); - if (osType === "windows") { - await Deno.symlink(origin, target, { type: type === "dir" ? "dir" : "file" }); - } else { - await Deno.symlink(origin, target); - } - } - - private async _copyDir(source: string, target: string, options?: IntCopyOptions) { - if (options?.filter && !options.filter(source)) { - return; - } - - await this._validCopy(source, target, { ...options, folder: true }); - await fs.ensureDir(target); - - source = toPathString(source); - target = toPathString(target); - - for await (const entry of Deno.readDir(source)) { - const sourcePath = path.join(source, entry.name); - const targetPath = path.join(target, path.basename(sourcePath)); - if (entry.isSymlink) { - await this._copyLink(sourcePath, targetPath, options); - } else if (entry.isDirectory) { - await this._copyDir(sourcePath, targetPath, options); - } else if (entry.isFile) { - await this._copyFile(sourcePath, targetPath, options); - } - } - } - - private async _copyFile(source: string, target: string, options?: IntCopyOptions) { - if (options?.filter && !options.filter(source)) { - return; - } - await this._validCopy(source, target, options); - await Deno.copyFile(source, target); - } -} diff --git a/test/coline/depker.config.ts b/test/coline/depker.config.ts new file mode 100644 index 0000000..15313c0 --- /dev/null +++ b/test/coline/depker.config.ts @@ -0,0 +1,24 @@ +import { coline, depker } from "../../mod.ts"; + +const app = depker(); + +app.service( + coline({ + name: "coline", + domain: "coline.test", + secrets: { + NEXT_PUBLIC_COLINE_LANGUAGE: "@COLINE_LANGUAGE", + NEXT_PUBLIC_COLINE_GOOGLE_ANALYTICS: "@COLINE_GOOGLE_ANALYTICS", + NEXT_PUBLIC_COLINE_ARTALK_SITE_NAME: "@COLINE_ARTALK_SITE_NAME", + NEXT_PUBLIC_COLINE_ARTALK_SERVER_URL: "@COLINE_ARTALK_SERVER_URL", + NEXT_PUBLIC_COLINE_GITHUB_REPO: "@COLINE_GITHUB_REPO", + COLINE_GITHUB_TOKEN: "@COLINE_GITHUB_TOKEN", + KEYSTATIC_SECRET: "@KEYSTATIC_SECRET", + KEYSTATIC_GITHUB_CLIENT_ID: "@KEYSTATIC_GITHUB_CLIENT_ID", + KEYSTATIC_GITHUB_CLIENT_SECRET: "@KEYSTATIC_GITHUB_CLIENT_SECRET", + NEXT_PUBLIC_KEYSTATIC_GITHUB_APP_SLUG: "@KEYSTATIC_GITHUB_APP_SLUG", + }, + }), +); + +export default app; diff --git a/test/coline/public/content/config/author.yaml b/test/coline/public/content/config/author.yaml new file mode 100644 index 0000000..1836efc --- /dev/null +++ b/test/coline/public/content/config/author.yaml @@ -0,0 +1,5 @@ +username: syfxlin +firstname: Otstar +lastname: Lin +description: 站在时光一端,回忆过往记忆。 +avatar: /image/config/author/avatar.400x400.png diff --git a/test/coline/public/content/config/footer.yaml b/test/coline/public/content/config/footer.yaml new file mode 100644 index 0000000..36e254c --- /dev/null +++ b/test/coline/public/content/config/footer.yaml @@ -0,0 +1,7 @@ +main: + - title: Home + link: https://ixk.me + - title: GitHub + link: https://github.com/syfxlin + - title: Status + link: https://status.ixk.me diff --git a/test/coline/public/content/config/friends.yaml b/test/coline/public/content/config/friends.yaml new file mode 100644 index 0000000..257224f --- /dev/null +++ b/test/coline/public/content/config/friends.yaml @@ -0,0 +1,20 @@ +display: top +links: + - name: 个人主页 + link: https://ixk.me + avatar: /image/config/friends/links/0/avatar.400x400.png + author: Otstar Lin + description: Otstar's Space的源码,个人主页。 + - name: 青空之蓝 + link: https://blog.ixk.me + avatar: /image/config/friends/links/1/avatar.400x400.png + author: Otstar Lin + description: 站在时光一端,回忆过往记忆。 + - name: GitHub + link: https://github.com/syfxlin + avatar: /image/config/friends/links/2/avatar.400x400.png + author: Otstar Lin + description: >- + 💻Coding / 🎉GuGuGu / 📖 Learning / 🚩 Open Source developer / 🐛 Bug + making machine +lost_links: [] diff --git a/test/coline/public/content/config/friends/content.mdoc b/test/coline/public/content/config/friends/content.mdoc new file mode 100644 index 0000000..e69de29 diff --git a/test/coline/public/content/config/header.yaml b/test/coline/public/content/config/header.yaml new file mode 100644 index 0000000..5344e11 --- /dev/null +++ b/test/coline/public/content/config/header.yaml @@ -0,0 +1,29 @@ +main: + - title: 项目 + link: /projects + icon: ri:box-3-line + view: elastic + - title: 友邻 + link: /links + icon: ri:heart-line + view: elastic + - title: 归档 + link: /archives + icon: ri:archive-line + view: elastic-text + - title: 留言 + link: /message-board + icon: ri:message-3-line + view: elastic-text + - title: GitHub + link: https://github.com/syfxlin + icon: uil:github-alt + view: elastic-icon + - title: Twitter + link: https://twitter.com/syfxlin + icon: uil:twitter-alt + view: elastic-icon + - title: Telegram + link: https://t.me/otstar + icon: uil:telegram-alt + view: elastic-icon diff --git a/test/coline/public/content/config/home.yaml b/test/coline/public/content/config/home.yaml new file mode 100644 index 0000000..989b1d8 --- /dev/null +++ b/test/coline/public/content/config/home.yaml @@ -0,0 +1 @@ +display: articles diff --git a/test/coline/public/content/config/home/content.mdoc b/test/coline/public/content/config/home/content.mdoc new file mode 100644 index 0000000..e69de29 diff --git a/test/coline/public/content/config/license.yaml b/test/coline/public/content/config/license.yaml new file mode 100644 index 0000000..c0cfbdd --- /dev/null +++ b/test/coline/public/content/config/license.yaml @@ -0,0 +1,2 @@ +name: BY-NC-SA +link: https://creativecommons.org/licenses/by-nc-sa/4.0/ diff --git a/test/coline/public/content/config/projects.yaml b/test/coline/public/content/config/projects.yaml new file mode 100644 index 0000000..c00a428 --- /dev/null +++ b/test/coline/public/content/config/projects.yaml @@ -0,0 +1,262 @@ +display: none +categories: + - name: Focus + projects: + - name: Depker + link: https://github.com/syfxlin/depker + description: >- + A deployment tool based on Docker, designed to lower the difficulty of + automating application deployment for low-performance self-hosted + servers, and provide continuous deployment capabilities. + components: + - simple-icons:deno + - simple-icons:typescript + - simple-icons:docker + - ri:server-line + - name: Frameworks + projects: + - name: XKJava + link: https://github.com/syfxlin/xkjava + description: A Lightweight Spring-like Java Framework + components: + - simple-icons:spring + - la:java + - name: XK-Server + link: https://github.com/syfxlin/xkserver + description: A lightweight Java web server, not finished. + components: + - la:java + - name: XK-PHP + link: https://github.com/syfxlin/xkphp + description: A Lightweight Laravel-like PHP Framework + components: + - simple-icons:laravel + - simple-icons:php + - name: Tools / Utility Libraries + projects: + - name: Reve + link: https://github.com/syfxlin/reve + description: >- + Reve is a library of enhancements to vanilla-extract to improve the + experience of using vanilla-extract and reduce unnecessary time + consumption due to specific programming paradigms. + components: + - simple-icons:typescript + - simple-icons:css3 + - simple-icons:styledcomponents + - name: Reks + link: https://github.com/syfxlin/reks + description: >- + Reks is a library of enhancements to reks to improve the experience of + using keystatic. + components: + - simple-icons:typescript + - name: Ustyled + link: https://github.com/syfxlin/ustyled + description: A CSS-in-JS utility library based on Emotion.js. + components: + - simple-icons:typescript + - simple-icons:css3 + - simple-icons:styledcomponents + - name: Note System / WYSIWYG Editor + projects: + - name: Hoshi Note (Service) + link: https://github.com/syfxlin/hoshi-note + description: >- + Hoshi-Note is a cloud note system, based on Spring Boot and Spring + Cloud development, using microservices and distributed model + deployment. + components: + - simple-icons:spring + - la:java + - simple-icons:kubernetes + - simple-icons:redis + - simple-icons:cockroachlabs + - simple-icons:rabbitmq + - simple-icons:minio + - simple-icons:nginx + - name: Hoshi Note (UI) + link: https://github.com/syfxlin/hoshi-ui + description: >- + Hoshi-Note is a cloud note system, based on Spring Boot and Spring + Cloud development, using microservices and distributed model + deployment. + components: + - simple-icons:react + - simple-icons:typescript + - simple-icons:vite + - name: Tiptap Starter Kit + link: https://github.com/syfxlin/tiptap-starter-kit + description: >- + An unofficial suite of Tiptap editors with a collection of common + extensions. + components: + - simple-icons:typescript + - simple-icons:css3 + - name: XK-Editor Next + link: https://github.com/syfxlin/xkeditor-next + description: An editor with rich text support, based on Rich Markdown Editor. + components: + - simple-icons:react + - simple-icons:typescript + - simple-icons:markdown + - name: XK-Note + link: https://github.com/syfxlin/xknote + description: A cloud notebook with all sorts of amazing features. + components: + - simple-icons:laravel + - simple-icons:php + - simple-icons:vuedotjs + - simple-icons:javascript + - simple-icons:markdown + - name: XK-Editor + link: https://github.com/syfxlin/xkeditor + description: An editor with rich text and Markdown support. + components: + - simple-icons:vuedotjs + - simple-icons:javascript + - simple-icons:markdown + - name: Websites + projects: + - name: Home + link: https://github.com/syfxlin/home + description: Source code for Otstar's Space, personal home page. + components: + - simple-icons:nextdotjs + - simple-icons:typescript + - name: Blog + link: https://github.com/syfxlin/blog + description: >- + Otstar Lin's personal blog repository / Next.js / React / TypeScript / + Keystatic CMS + components: + - simple-icons:nextdotjs + - simple-icons:typescript + - name: Contributed + projects: + - name: vanilla-extract + link: https://github.com/vanilla-extract-css/vanilla-extract + description: >- + Zero-runtime Stylesheets-in-TypeScript. Write your styles in + TypeScript (or JavaScript) with locally scoped class names and CSS + Variables, then generate static CSS files at build time. + components: + - simple-icons:typescript + - simple-icons:css3 + - simple-icons:webpack + - name: Artalk + link: https://github.com/ArtalkJS/Artalk + description: Your self-hosted comment system. + components: + - simple-icons:typescript + - simple-icons:go + - name: RSSHub + link: https://github.com/DIYgod/RSSHub + description: >- + RSSHub is an open source, easy to use, and extensible RSS feed + generator. It's capable of generating RSS feeds from pretty much + everything. + components: + - ri:rss-line + - simple-icons:javascript + - name: Gatsby Ecosystem + projects: + - name: Coline Theme for Gatsby + link: https://github.com/syfxlin/gatsby-theme-coline + description: A Gatsby theme for publishing articles to your website. + components: + - simple-icons:gatsby + - simple-icons:typescript + - simple-icons:mdx + - simple-icons:decapcms + - name: Express Server for Gatsby + link: https://github.com/syfxlin/gatsby-plugin-express + description: >- + Gives you a way to integrate your Gatsby site with the Node.js server + using Express + components: + - simple-icons:gatsby + - simple-icons:express + - simple-icons:typescript + - name: Directus Source for Gatsby + link: https://github.com/syfxlin/gatsby-source-directus + description: The unofficial Gatsby source plugin for Directus CMS projects. + components: + - simple-icons:gatsby + - simple-icons:typescript + - name: WordPress Ecosystem + projects: + - name: Origami + link: https://github.com/syfxlin/origami + description: A WordPress theme with many powerful features, clean, light and fast. + components: + - simple-icons:wordpress + - simple-icons:php + - simple-icons:javascript + - name: Origami to Hexo Converter + link: https://github.com/syfxlin/origami-wp-hexo + description: >- + Origami wp hexo is a WordPress to Hexo conversion solution for + Origami! + components: + - simple-icons:wordpress + - simple-icons:hexo + - name: Hermit-X Blocks + link: https://github.com/syfxlin/hermit-x-blocks + description: Gutenberg blocks for Hermit-X Music WordPress Plugin. + components: + - simple-icons:wordpress + - simple-icons:javascript + - name: Toast for WordPress + link: https://github.com/syfxlin/toast-for-wp + description: Toastr.js WordPress Plugin + components: + - simple-icons:wordpress + - simple-icons:javascript + - name: Toys + projects: + - name: Graffit Board + link: https://github.com/syfxlin/graffiti-board + description: A simple Canvas or SVG-based graffiti board. + components: + - simple-icons:javascript + - simple-icons:svg + - name: Docset Generator + link: https://github.com/syfxlin/docset-generator + description: Dash Document Generator. + components: + - simple-icons:javascript + - simple-icons:nodedotjs + - name: VSCode Acrylic Plugin + link: https://github.com/syfxlin/vscode-acrylic + description: >- + Add Acrylic,BlurBehind,TransparentGradient background effects to + VSCode(Windows). + components: + - simple-icons:visualstudiocode + - name: Spring Learn Monorepo + link: https://github.com/syfxlin/spring-learn + description: My code repository for learning Spring. + components: + - simple-icons:spring + - la:java + - name: Useless Code + link: https://github.com/syfxlin/code + description: The place where I keep my useless code. + components: + - la:java + - simple-icons:php + - name: Obsidian Prettier + link: https://github.com/syfxlin/obsidian-prettier + description: Plugin for formatting Obsidian documents using Prettier + components: + - simple-icons:obsidian + - simple-icons:javascript + - name: Obsidian Autolinker + link: https://github.com/syfxlin/obsidian-autolinker + description: >- + Plugin to automatically add bi-directional links to Obsidian + documents. + components: + - simple-icons:obsidian + - simple-icons:javascript diff --git a/test/coline/public/content/config/projects/content.mdoc b/test/coline/public/content/config/projects/content.mdoc new file mode 100644 index 0000000..e69de29 diff --git a/test/coline/public/content/config/seo.yaml b/test/coline/public/content/config/seo.yaml new file mode 100644 index 0000000..65d8f06 --- /dev/null +++ b/test/coline/public/content/config/seo.yaml @@ -0,0 +1,15 @@ +link: https://coline.ixk.me +logo: /image/config/seo/logo.400x400.jpg +title: Coline +subtitle: 轻快、简洁、优雅的 Next.js 模板 +description: >- + Coline(connect, line)是一个基于 Next.js App Router + 开发的博客模板,建立在轻快与简洁的设计理念上,摒弃花里胡哨的界面,专注于内容创作。 +birthday: 2024-01-01T00:00 +keywords: + - Otstar Lin + - syfxlin + - Blog + - 博客 + - Next.js + - Next.js App Router diff --git a/test/coline/public/content/pages/message-board/index.mdoc b/test/coline/public/content/pages/message-board/index.mdoc new file mode 100644 index 0000000..56d99a1 --- /dev/null +++ b/test/coline/public/content/pages/message-board/index.mdoc @@ -0,0 +1,7 @@ +--- +title: 留言 +layout: page +status: publish +published_time: 2018-04-12T00:00 +modified_time: 2024-01-09T00:17 +--- diff --git a/test/coline/public/content/posts/hello-world/index.mdoc b/test/coline/public/content/posts/hello-world/index.mdoc new file mode 100644 index 0000000..0421c1d --- /dev/null +++ b/test/coline/public/content/posts/hello-world/index.mdoc @@ -0,0 +1,29 @@ +--- +title: Coline - 轻快、简洁、优雅的 Next.js 模板 +layout: post +status: publish +published_time: 2017-06-30T00:00 +modified_time: 2024-01-09T00:35 +categories: + - 折腾记录 +tags: + - Next.js + - React.js +--- +Coline(**co**nnect, **line**)是一个基于 Next.js App Router 开发的博客模板,建立在轻快与简洁的设计理念上,摒弃花里胡哨的界面,专注于内容创作。 + +## 设计理念 + +- **简洁清新**:人的注意力是有限的,为了使读者能聚焦于内容之上。Coline 仅保留了少量色彩,大范围使用中性色,鲜明的色彩仅用于特殊场景,同时任何与内容无关的信息都不应该出现。 +- **轻量快速**:人的容忍度是有限的,通常一个网站如果不能在 3 秒内加载出大部分内容,读者就会失去等待的耐心。Coline 在 LightHouse 中表现优秀,Performance > 98%,Best practice 100%。 +- **SEO 100%**:网站不仅要给人类看,还需要给机器看。Coline 在 LightHouse 中 SEO 评分达到了 100%。同时也支持了 RSS,使读者能够使用 RSS 阅读器订阅博客。 +- **无障碍支持**:不是所有人都是完美的,不应该歧视任何不完美的人。Coline 尽可能降低障碍人士使用难度,在 LightHouse 中 Accessibility > 90%。 +- **写作友好**:网站的内容是作者产出的,如果不能有良好的写作体验,那么其他都是泡沫。Coline 集成了 Keystatic CMS,支持可视化编辑,仅需 GitHub 与 Vercel 即可启动一个 Coline 站点。 + +## 技术栈 + +- Next.js 14 (App Router) +- Vanilla Extract +- Keystatic +- Artalk +- Fuse.js diff --git a/test/coline/public/image/config/author/avatar.400x400.png b/test/coline/public/image/config/author/avatar.400x400.png new file mode 100644 index 0000000..3e9a299 Binary files /dev/null and b/test/coline/public/image/config/author/avatar.400x400.png differ diff --git a/test/coline/public/image/config/friends/links/0/avatar.400x400.png b/test/coline/public/image/config/friends/links/0/avatar.400x400.png new file mode 100644 index 0000000..3e9a299 Binary files /dev/null and b/test/coline/public/image/config/friends/links/0/avatar.400x400.png differ diff --git a/test/coline/public/image/config/friends/links/1/avatar.400x400.png b/test/coline/public/image/config/friends/links/1/avatar.400x400.png new file mode 100644 index 0000000..3e9a299 Binary files /dev/null and b/test/coline/public/image/config/friends/links/1/avatar.400x400.png differ diff --git a/test/coline/public/image/config/friends/links/2/avatar.400x400.png b/test/coline/public/image/config/friends/links/2/avatar.400x400.png new file mode 100644 index 0000000..3e9a299 Binary files /dev/null and b/test/coline/public/image/config/friends/links/2/avatar.400x400.png differ diff --git a/test/coline/public/image/config/seo/logo.400x400.jpg b/test/coline/public/image/config/seo/logo.400x400.jpg new file mode 100644 index 0000000..3e9a299 Binary files /dev/null and b/test/coline/public/image/config/seo/logo.400x400.jpg differ diff --git a/test/nodejs_server/main.js b/test/nodejs_server/main.js index ac6b346..4efdddc 100644 --- a/test/nodejs_server/main.js +++ b/test/nodejs_server/main.js @@ -1,4 +1,4 @@ -const { createServer } = require("http"); +const { createServer } = require("node:http"); const app = createServer((req, res) => { res.end("

depker

");